Bug 1865563 - Rustfmt servo/. r=firefox-style-system-reviewers,emilio

$ git ls-files servo/*.rs | xargs rustup run nightly rustfmt

Differential Revision: https://phabricator.services.mozilla.com/D194020
This commit is contained in:
Zach Hoffman 2023-11-20 15:17:57 +00:00
parent 34bd197686
commit 2d02e6d74f
90 changed files with 2441 additions and 1313 deletions

View file

@ -714,7 +714,8 @@ impl MallocSizeOf for selectors::parser::AncestorHashes {
}
}
impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf for selectors::parser::Selector<Impl>
impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf
for selectors::parser::Selector<Impl>
where
Impl::NonTSPseudoClass: MallocSizeOf,
Impl::PseudoElement: MallocSizeOf,
@ -734,7 +735,8 @@ where
}
}
impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf for selectors::parser::SelectorList<Impl>
impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf
for selectors::parser::SelectorList<Impl>
where
Impl::NonTSPseudoClass: MallocSizeOf,
Impl::PseudoElement: MallocSizeOf,
@ -754,7 +756,8 @@ where
}
}
impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf for selectors::parser::Component<Impl>
impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf
for selectors::parser::Component<Impl>
where
Impl::NonTSPseudoClass: MallocSizeOf,
Impl::PseudoElement: MallocSizeOf,

View file

@ -66,11 +66,7 @@ impl<AttrValue> AttrSelectorOperation<AttrValue> {
operator,
case_sensitivity,
ref value,
} => operator.eval_str(
element_attr_value,
value.as_ref(),
case_sensitivity,
),
} => operator.eval_str(element_attr_value, value.as_ref(), case_sensitivity),
}
}
}

View file

@ -168,7 +168,7 @@ fn split_from_end<T>(s: &[T], at: usize) -> (&[T], &[T]) {
/// Flags that indicate at which point of parsing a selector are we.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, ToShmem)]
pub (crate) struct SelectorFlags(u8);
pub(crate) struct SelectorFlags(u8);
bitflags! {
impl SelectorFlags: u8 {
@ -188,7 +188,7 @@ impl SelectorFlags {
///
/// It is not supposed to work, because :is(::before) is invalid. We can't propagate the
/// pseudo-flags from inner to outer selectors, to avoid breaking our invariants.
pub (crate) fn for_nesting() -> Self {
pub(crate) fn for_nesting() -> Self {
Self::all() - (Self::HAS_PSEUDO | Self::HAS_SLOTTED | Self::HAS_PART)
}
}
@ -268,7 +268,9 @@ where
specificity.element_selectors += 1
},
Component::Slotted(ref selector) => {
flags.insert(SelectorFlags::HAS_SLOTTED | SelectorFlags::HAS_NON_FEATURELESS_COMPONENT);
flags.insert(
SelectorFlags::HAS_SLOTTED | SelectorFlags::HAS_NON_FEATURELESS_COMPONENT,
);
specificity.element_selectors += 1;
// Note that due to the way ::slotted works we only compete with
// other ::slotted rules, so the above rule doesn't really

View file

@ -508,11 +508,7 @@ fn relative_selector_match_early<E: Element>(
if context
.selector_caches
.relative_selector_filter_map
.fast_reject(
element,
selector,
context.quirks_mode(),
)
.fast_reject(element, selector, context.quirks_mode())
{
// Alright, add as unmatched to cache.
context.selector_caches.relative_selector.add(
@ -691,7 +687,9 @@ fn assigned_slot<E>(element: &E, context: &MatchingContext<E::Impl>) -> Option<E
where
E: Element,
{
debug_assert!(element.assigned_slot().map_or(true, |s| s.is_html_slot_element()));
debug_assert!(element
.assigned_slot()
.map_or(true, |s| s.is_html_slot_element()));
let scope = context.current_host?;
let mut current_slot = element.assigned_slot()?;
while current_slot.containing_shadow_host().unwrap().opaque() != scope {

View file

@ -7,9 +7,7 @@ use fxhash::FxHashMap;
use crate::bloom::BloomFilter;
use crate::context::QuirksMode;
use crate::parser::{
collect_selector_hashes, RelativeSelector, RelativeSelectorMatchHint,
};
use crate::parser::{collect_selector_hashes, RelativeSelector, RelativeSelectorMatchHint};
use crate::tree::{Element, OpaqueElement};
use crate::SelectorImpl;
@ -121,7 +119,10 @@ impl RelativeSelectorFilterMap {
selector: &RelativeSelector<Impl>,
quirks_mode: QuirksMode,
) -> bool {
if matches!(selector.match_hint, RelativeSelectorMatchHint::InNextSibling) {
if matches!(
selector.match_hint,
RelativeSelectorMatchHint::InNextSibling
) {
// Don't bother.
return false;
}

View file

@ -892,11 +892,7 @@ impl<H, T> UniqueArc<HeaderSlice<H, T>> {
}
#[inline]
pub fn from_header_and_iter_with_size<I>(
header: H,
items: I,
num_items: usize,
) -> Self
pub fn from_header_and_iter_with_size<I>(header: H, items: I, num_items: usize) -> Self
where
I: Iterator<Item = T>,
{

View file

@ -312,12 +312,8 @@ impl ElementData {
return InvalidationResult::empty();
}
let mut processor = StateAndAttrInvalidationProcessor::new(
shared_context,
element,
self,
selector_caches,
);
let mut processor =
StateAndAttrInvalidationProcessor::new(shared_context, element, self, selector_caches);
let invalidator = TreeStyleInvalidator::new(element, stack_limit_checker, &mut processor);

View file

@ -15,11 +15,11 @@ use crate::invalidation::element::invalidator::{InvalidationProcessor, Invalidat
use crate::selector_parser::SelectorImpl;
use crate::values::AtomIdent;
use selectors::attr::CaseSensitivity;
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
use selectors::matching::{
self, MatchingForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags,
self, MatchingContext, MatchingForInvalidation, MatchingMode, NeedsSelectorFlags,
SelectorCaches,
};
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
use selectors::parser::{Combinator, Component, LocalName};
use selectors::{Element, SelectorList};
use smallvec::SmallVec;
@ -461,11 +461,13 @@ where
Component::AttributeInNoNamespaceExists {
ref local_name,
ref local_name_lower,
} => {
collect_all_elements::<E, Q, _>(root, results, |element| {
element.has_attr_in_no_namespace(matching::select_name(&element, local_name, local_name_lower))
})
},
} => collect_all_elements::<E, Q, _>(root, results, |element| {
element.has_attr_in_no_namespace(matching::select_name(
&element,
local_name,
local_name_lower,
))
}),
Component::AttributeInNoNamespace {
ref local_name,
ref value,
@ -480,7 +482,10 @@ where
local_name,
&AttrSelectorOperation::WithValue {
operator,
case_sensitivity: matching::to_unconditional_case_sensitivity(case_sensitivity, &element),
case_sensitivity: matching::to_unconditional_case_sensitivity(
case_sensitivity,
&element,
),
value,
},
)

View file

@ -54,9 +54,8 @@ fn with_pool_in_place_scope<'scope, R>(
if work_unit_max == 0 || pool.is_none() {
closure(None)
} else {
pool.unwrap().in_place_scope_fifo(|scope| {
closure(Some(scope))
})
pool.unwrap()
.in_place_scope_fifo(|scope| closure(Some(scope)))
}
}
@ -116,7 +115,11 @@ where
thread_local: &mut tlc,
};
debug_assert_eq!(scoped_tls.current_thread_index(), 0, "Main thread should be the first thread");
debug_assert_eq!(
scoped_tls.current_thread_index(),
0,
"Main thread should be the first thread"
);
let mut discovered = VecDeque::with_capacity(work_unit_max * 2);
discovered.push_back(unsafe { SendNode::new(root.as_node()) });
@ -125,7 +128,9 @@ where
discovered,
root.as_node().opaque(),
work_unit_max,
PerLevelTraversalData { current_dom_depth: root.depth() },
PerLevelTraversalData {
current_dom_depth: root.depth(),
},
maybe_scope,
traversal,
&scoped_tls,

View file

@ -19,11 +19,7 @@ use style_traits::ParseError;
#[derive(Debug)]
pub enum ContextualParseError<'a> {
/// A property declaration was not recognized.
UnsupportedPropertyDeclaration(
&'a str,
ParseError<'a>,
&'a [SelectorList<SelectorImpl>],
),
UnsupportedPropertyDeclaration(&'a str, ParseError<'a>, &'a [SelectorList<SelectorImpl>]),
/// A property descriptor was not recognized.
UnsupportedPropertyDescriptor(&'a str, ParseError<'a>),
/// A font face descriptor was not recognized.

View file

@ -8,9 +8,9 @@ use crate::gecko_bindings::bindings;
use crate::gecko_bindings::structs;
use crate::gecko_bindings::structs::ScreenColorGamut;
use crate::media_queries::{Device, MediaType};
use crate::queries::condition::KleeneValue;
use crate::queries::feature::{AllowsRanges, Evaluator, FeatureFlags, QueryFeatureDescription};
use crate::queries::values::Orientation;
use crate::queries::condition::KleeneValue;
use crate::values::computed::{CSSPixelLength, Context, Ratio, Resolution};
use crate::values::AtomString;
use app_units::Au;
@ -615,10 +615,10 @@ fn eval_moz_overlay_scrollbars(context: &Context) -> bool {
}
fn eval_moz_bool_pref(_: &Context, pref: Option<&AtomString>) -> KleeneValue {
let Some(pref) = pref else { return KleeneValue::False };
KleeneValue::from(unsafe {
bindings::Gecko_ComputeBoolPrefMediaQuery(pref.as_ptr())
})
let Some(pref) = pref else {
return KleeneValue::False;
};
KleeneValue::from(unsafe { bindings::Gecko_ComputeBoolPrefMediaQuery(pref.as_ptr()) })
}
fn get_lnf_int(int_id: i32) -> i32 {

View file

@ -168,10 +168,12 @@ impl PseudoElement {
pub fn enabled_in_content(&self) -> bool {
match *self {
Self::Highlight(..) => pref!("dom.customHighlightAPI.enabled"),
Self::SliderFill | Self::SliderTrack | Self::SliderThumb => pref!("layout.css.modern-range-pseudos.enabled"),
Self::SliderFill | Self::SliderTrack | Self::SliderThumb => {
pref!("layout.css.modern-range-pseudos.enabled")
},
// If it's not explicitly enabled in UA sheets or chrome, then we're enabled for
// content.
_ => (self.flags() & structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME) == 0
_ => (self.flags() & structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME) == 0,
}
}

View file

@ -13,7 +13,9 @@ use crate::selector_parser::{AttrValue, SnapshotMap};
use crate::string_cache::WeakAtom;
use crate::values::AtomIdent;
use crate::{Atom, CaseSensitivityExt, LocalName, Namespace};
use selectors::attr::{CaseSensitivity, NamespaceConstraint, AttrSelectorOperation, AttrSelectorOperator};
use selectors::attr::{
AttrSelectorOperation, AttrSelectorOperator, CaseSensitivity, NamespaceConstraint,
};
use smallvec::SmallVec;
/// A function that, given an element of type `T`, allows you to get a single
@ -291,36 +293,24 @@ fn attr_matches_checked_name(
let value = value.as_ptr();
unsafe {
match operator {
AttrSelectorOperator::Equal => bindings::Gecko_AttrEquals(
&attr.mValue,
value,
ignore_case,
),
AttrSelectorOperator::Includes => bindings::Gecko_AttrIncludes(
&attr.mValue,
value,
ignore_case,
),
AttrSelectorOperator::DashMatch => bindings::Gecko_AttrDashEquals(
&attr.mValue,
value,
ignore_case,
),
AttrSelectorOperator::Prefix => bindings::Gecko_AttrHasPrefix(
&attr.mValue,
value,
ignore_case,
),
AttrSelectorOperator::Suffix => bindings::Gecko_AttrHasSuffix(
&attr.mValue,
value,
ignore_case,
),
AttrSelectorOperator::Substring => bindings::Gecko_AttrHasSubstring(
&attr.mValue,
value,
ignore_case,
),
AttrSelectorOperator::Equal => {
bindings::Gecko_AttrEquals(&attr.mValue, value, ignore_case)
},
AttrSelectorOperator::Includes => {
bindings::Gecko_AttrIncludes(&attr.mValue, value, ignore_case)
},
AttrSelectorOperator::DashMatch => {
bindings::Gecko_AttrDashEquals(&attr.mValue, value, ignore_case)
},
AttrSelectorOperator::Prefix => {
bindings::Gecko_AttrHasPrefix(&attr.mValue, value, ignore_case)
},
AttrSelectorOperator::Suffix => {
bindings::Gecko_AttrHasSuffix(&attr.mValue, value, ignore_case)
},
AttrSelectorOperator::Substring => {
bindings::Gecko_AttrHasSubstring(&attr.mValue, value, ignore_case)
},
}
}
}

View file

@ -304,7 +304,8 @@ impl<'ln> GeckoNode<'ln> {
#[inline]
fn set_selector_flags(&self, flags: u32) {
self.selector_flags_atomic().fetch_or(flags, Ordering::Relaxed);
self.selector_flags_atomic()
.fetch_or(flags, Ordering::Relaxed);
}
#[inline]
@ -1250,9 +1251,7 @@ impl<'le> TElement for GeckoElement<'le> {
F: FnMut(&AtomIdent),
{
for attr in self.attrs() {
unsafe {
AtomIdent::with(attr.mName.name(), |a| callback(a))
}
unsafe { AtomIdent::with(attr.mName.name(), |a| callback(a)) }
}
}
@ -1366,7 +1365,10 @@ impl<'le> TElement for GeckoElement<'le> {
return None;
}
PseudoElement::from_pseudo_type(unsafe { bindings::Gecko_GetImplementedPseudo(self.0) }, None)
PseudoElement::from_pseudo_type(
unsafe { bindings::Gecko_GetImplementedPseudo(self.0) },
None,
)
}
#[inline]
@ -1889,7 +1891,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
// Handle flags that apply to the element.
let self_flags = flags.for_self();
if !self_flags.is_empty() {
self.as_node().set_selector_flags(selector_flags_to_node_flags(flags))
self.as_node()
.set_selector_flags(selector_flags_to_node_flags(flags))
}
// Handle flags that apply to the parent.
@ -2016,7 +2019,9 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::MozRevealed |
NonTSPseudoClass::MozValueEmpty => self.state().intersects(pseudo_class.state_flag()),
// TODO: This applying only to HTML elements is weird.
NonTSPseudoClass::Dir(ref dir) => self.is_html_element() && self.state().intersects(dir.element_state()),
NonTSPseudoClass::Dir(ref dir) => {
self.is_html_element() && self.state().intersects(dir.element_state())
},
NonTSPseudoClass::AnyLink => self.is_link(),
NonTSPseudoClass::Link => {
self.is_link() && context.visited_handling().matches_unvisited()

View file

@ -13,11 +13,11 @@ use crate::thread_state;
use gecko_profiler;
use parking_lot::{Mutex, RwLock, RwLockReadGuard};
use rayon;
use std::{io, thread};
#[cfg(unix)]
use std::os::unix::thread::{JoinHandleExt, RawPthread};
#[cfg(windows)]
use std::os::windows::{io::AsRawHandle, prelude::RawHandle};
use std::{io, thread};
use thin_vec::ThinVec;
/// Platform-specific handle to a thread.

View file

@ -14,7 +14,7 @@ use crate::invalidation::element::state_and_attributes;
use crate::stylist::CascadeData;
use dom::DocumentState;
use selectors::matching::{
MatchingForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags, QuirksMode,
MatchingContext, MatchingForInvalidation, MatchingMode, NeedsSelectorFlags, QuirksMode,
SelectorCaches, VisitedHandlingMode,
};

View file

@ -163,7 +163,10 @@ impl Dependency {
/// The kind of normal invalidation that this would generate. The dependency
/// in question must be a normal dependency.
pub fn normal_invalidation_kind(&self) -> NormalDependencyInvalidationKind {
debug_assert!(self.relative_kind.is_none(), "Querying normal invalidation kind on relative dependency.");
debug_assert!(
self.relative_kind.is_none(),
"Querying normal invalidation kind on relative dependency."
);
match self.combinator() {
None => NormalDependencyInvalidationKind::Element,
Some(Combinator::Child) | Some(Combinator::Descendant) => {
@ -174,7 +177,9 @@ impl Dependency {
},
// TODO(emilio): We could look at the selector itself to see if it's
// an eager pseudo, and return only Descendants here if not.
Some(Combinator::PseudoElement) => NormalDependencyInvalidationKind::ElementAndDescendants,
Some(Combinator::PseudoElement) => {
NormalDependencyInvalidationKind::ElementAndDescendants
},
Some(Combinator::SlotAssignment) => NormalDependencyInvalidationKind::SlottedElements,
Some(Combinator::Part) => NormalDependencyInvalidationKind::Parts,
}
@ -197,7 +202,8 @@ impl Dependency {
return false;
}
matches!(
self.selector.combinator_at_match_order(self.selector_offset - 1),
self.selector
.combinator_at_match_order(self.selector_offset - 1),
Combinator::NextSibling
)
}
@ -209,8 +215,9 @@ impl Dependency {
pub fn dependency_is_relative_with_single_next_sibling(&self) -> bool {
match self.invalidation_kind() {
DependencyInvalidationKind::Normal(_) => false,
DependencyInvalidationKind::Relative(kind) =>
kind == RelativeDependencyInvalidationKind::PrevSibling,
DependencyInvalidationKind::Relative(kind) => {
kind == RelativeDependencyInvalidationKind::PrevSibling
},
}
}
}
@ -1030,7 +1037,9 @@ impl<'a> Collector for RelativeSelectorDependencyCollector<'a> {
selector_offset: self.compound_state.state.offset,
relative_kind: Some(match self.combinator_count.get_match_hint() {
RelativeSelectorMatchHint::InChild => RelativeDependencyInvalidationKind::Parent,
RelativeSelectorMatchHint::InSubtree => RelativeDependencyInvalidationKind::Ancestors,
RelativeSelectorMatchHint::InSubtree => {
RelativeDependencyInvalidationKind::Ancestors
},
RelativeSelectorMatchHint::InNextSibling => {
RelativeDependencyInvalidationKind::PrevSibling
},

View file

@ -8,7 +8,8 @@
use crate::context::StackLimitChecker;
use crate::dom::{TElement, TNode, TShadowRoot};
use crate::invalidation::element::invalidation_map::{
Dependency, NormalDependencyInvalidationKind, DependencyInvalidationKind, RelativeDependencyInvalidationKind
Dependency, DependencyInvalidationKind, NormalDependencyInvalidationKind,
RelativeDependencyInvalidationKind,
};
use selectors::matching::matches_compound_selector_from;
use selectors::matching::{CompoundSelectorMatchingResult, MatchingContext};
@ -272,7 +273,8 @@ impl<'a> Invalidation<'a> {
pub fn new(dependency: &'a Dependency, scope: Option<OpaqueElement>) -> Self {
debug_assert!(
dependency.selector_offset == dependency.selector.len() + 1 ||
dependency.normal_invalidation_kind() != NormalDependencyInvalidationKind::Element,
dependency.normal_invalidation_kind() !=
NormalDependencyInvalidationKind::Element,
"No point to this, if the dependency matched the element we should just invalidate it"
);
Self {
@ -936,8 +938,11 @@ where
match invalidation_kind {
DependencyInvalidationKind::Normal(_) => &**p,
DependencyInvalidationKind::Relative(kind) => {
self.processor
.found_relative_selector_invalidation(self.element, kind, &**p);
self.processor.found_relative_selector_invalidation(
self.element,
kind,
&**p,
);
return SingleInvalidationResult {
invalidated_self: false,
matched: true,
@ -962,7 +967,9 @@ where
};
}
if cur_dependency.normal_invalidation_kind() == NormalDependencyInvalidationKind::Element {
if cur_dependency.normal_invalidation_kind() ==
NormalDependencyInvalidationKind::Element
{
continue;
}

View file

@ -8,6 +8,6 @@ pub mod document_state;
pub mod element_wrapper;
pub mod invalidation_map;
pub mod invalidator;
pub mod relative_selector;
pub mod restyle_hints;
pub mod state_and_attributes;
pub mod relative_selector;

View file

@ -348,7 +348,11 @@ where
dependency: &'a Dependency,
host: Option<OpaqueElement>,
) {
match self.invalidations.iter_mut().find(|(_, _, d)| dependency_selectors_match(dependency, d)) {
match self
.invalidations
.iter_mut()
.find(|(_, _, d)| dependency_selectors_match(dependency, d))
{
Some((e, h, d)) => {
// Just keep one.
if d.selector_offset > dependency.selector_offset {
@ -357,7 +361,7 @@ where
},
None => {
self.invalidations.push((element, host, dependency));
}
},
}
}
@ -392,11 +396,7 @@ where
{
return;
}
self.insert_invalidation(
element,
dependency,
host,
);
self.insert_invalidation(element, dependency, host);
},
};
}
@ -411,12 +411,7 @@ where
},
DependencyInvalidationKind::Relative(kind) => {
if let Some(context) = self.optimization_context.as_ref() {
if context.can_be_ignored(
element != self.top,
element,
host,
dependency,
) {
if context.can_be_ignored(element != self.top, element, host, dependency) {
continue;
}
}

View file

@ -22,8 +22,8 @@ use crate::{Atom, WeakAtom};
use dom::ElementState;
use selectors::attr::CaseSensitivity;
use selectors::matching::{
matches_selector, MatchingForInvalidation, MatchingContext, MatchingMode,
NeedsSelectorFlags, SelectorCaches, VisitedHandlingMode,
matches_selector, MatchingContext, MatchingForInvalidation, MatchingMode, NeedsSelectorFlags,
SelectorCaches, VisitedHandlingMode,
};
use smallvec::SmallVec;
@ -239,7 +239,9 @@ where
let wrapper = ElementWrapper::new(element, &*self.shared_context.snapshot_map);
let state_changes = wrapper.state_changes();
let Some(snapshot) = wrapper.snapshot() else { return false };
let Some(snapshot) = wrapper.snapshot() else {
return false;
};
if !snapshot.has_attrs() && state_changes.is_empty() {
return false;
@ -485,8 +487,12 @@ where
fn scan_dependency(&mut self, dependency: &'selectors Dependency) {
debug_assert!(
matches!(dependency.invalidation_kind(), DependencyInvalidationKind::Normal(_)),
"Found relative selector dependency");
matches!(
dependency.invalidation_kind(),
DependencyInvalidationKind::Normal(_)
),
"Found relative selector dependency"
);
debug!(
"TreeStyleInvalidator::scan_dependency({:?}, {:?})",
self.element, dependency
@ -535,7 +541,9 @@ where
fn dependency_may_be_relevant(&self, dependency: &Dependency) -> bool {
match dependency.normal_invalidation_kind() {
NormalDependencyInvalidationKind::Element => !self.invalidates_self,
NormalDependencyInvalidationKind::SlottedElements => self.element.is_html_slot_element(),
NormalDependencyInvalidationKind::SlottedElements => {
self.element.is_html_slot_element()
},
NormalDependencyInvalidationKind::Parts => self.element.shadow_root().is_some(),
NormalDependencyInvalidationKind::ElementAndDescendants |
NormalDependencyInvalidationKind::Siblings |

View file

@ -152,7 +152,13 @@ impl StylesheetInvalidationSet {
let quirks_mode = device.quirks_mode();
for rule in stylesheet.effective_rules(device, guard) {
self.collect_invalidations_for_rule(rule, guard, device, quirks_mode, /* is_generic_change = */ false);
self.collect_invalidations_for_rule(
rule,
guard,
device,
quirks_mode,
/* is_generic_change = */ false,
);
if self.fully_invalid {
break;
}
@ -549,16 +555,19 @@ impl StylesheetInvalidationSet {
return;
}
if !is_generic_change &&
!EffectiveRules::is_effective(guard, device, quirks_mode, rule)
{
if !is_generic_change && !EffectiveRules::is_effective(guard, device, quirks_mode, rule) {
return;
}
let rules =
EffectiveRulesIterator::effective_children(device, quirks_mode, guard, rule);
let rules = EffectiveRulesIterator::effective_children(device, quirks_mode, guard, rule);
for rule in rules {
self.collect_invalidations_for_rule(rule, guard, device, quirks_mode, /* is_generic_change = */ false);
self.collect_invalidations_for_rule(
rule,
guard,
device,
quirks_mode,
/* is_generic_change = */ false,
);
if self.fully_invalid {
break;
}
@ -606,8 +615,8 @@ impl StylesheetInvalidationSet {
// invalidate fully.
return self.invalidate_fully();
},
Document(..) | Import(..) | Media(..) | Supports(..) |
Container(..) | LayerBlock(..) => {
Document(..) | Import(..) | Media(..) | Supports(..) | Container(..) |
LayerBlock(..) => {
// Do nothing, relevant nested rules are visited as part of rule iteration.
},
FontFace(..) => {
@ -633,10 +642,7 @@ impl StylesheetInvalidationSet {
// Do nothing, this animation can't affect the style of existing elements.
}
},
CounterStyle(..) |
Property(..) |
FontFeatureValues(..) |
FontPaletteValues(..) => {
CounterStyle(..) | Property(..) | FontFeatureValues(..) | FontPaletteValues(..) => {
debug!(" > Found unsupported rule, marking the whole subtree invalid.");
self.invalidate_fully();
},

View file

@ -1478,10 +1478,10 @@ impl LogicalSide {
pub fn to_physical(self, wm: WritingMode) -> PhysicalSide {
// Block mapping depends only on vertical+vertical-lr
static BLOCK_MAPPING: [[PhysicalSide; 2]; 4] = [
[PhysicalSide::Top, PhysicalSide::Bottom], // horizontal-tb
[PhysicalSide::Right, PhysicalSide::Left], // vertical-rl
[PhysicalSide::Bottom, PhysicalSide::Top], // (horizontal-bt)
[PhysicalSide::Left, PhysicalSide::Right], // vertical-lr
[PhysicalSide::Top, PhysicalSide::Bottom], // horizontal-tb
[PhysicalSide::Right, PhysicalSide::Left], // vertical-rl
[PhysicalSide::Bottom, PhysicalSide::Top], // (horizontal-bt)
[PhysicalSide::Left, PhysicalSide::Right], // vertical-lr
];
if self.is_block() {
@ -1506,34 +1506,35 @@ impl LogicalSide {
// text. (The former 'sideways-left' value, no longer in the spec, would have produced
// this in vertical-rl mode.)
static INLINE_MAPPING: [[PhysicalSide; 2]; 16] = [
[PhysicalSide::Left, PhysicalSide::Right], // horizontal-tb ltr
[PhysicalSide::Top, PhysicalSide::Bottom], // vertical-rl ltr
[PhysicalSide::Right, PhysicalSide::Left], // horizontal-tb rtl
[PhysicalSide::Bottom, PhysicalSide::Top], // vertical-rl rtl
[PhysicalSide::Right, PhysicalSide::Left], // (horizontal-bt) (inverted) ltr
[PhysicalSide::Top, PhysicalSide::Bottom], // sideways-lr rtl
[PhysicalSide::Left, PhysicalSide::Right], // (horizontal-bt) (inverted) rtl
[PhysicalSide::Bottom, PhysicalSide::Top], // sideways-lr ltr
[PhysicalSide::Left, PhysicalSide::Right], // horizontal-tb (inverted) rtl
[PhysicalSide::Top, PhysicalSide::Bottom], // vertical-rl (inverted) rtl
[PhysicalSide::Right, PhysicalSide::Left], // horizontal-tb (inverted) ltr
[PhysicalSide::Bottom, PhysicalSide::Top], // vertical-rl (inverted) ltr
[PhysicalSide::Left, PhysicalSide::Right], // (horizontal-bt) ltr
[PhysicalSide::Top, PhysicalSide::Bottom], // vertical-lr ltr
[PhysicalSide::Right, PhysicalSide::Left], // (horizontal-bt) rtl
[PhysicalSide::Bottom, PhysicalSide::Top], // vertical-lr rtl
[PhysicalSide::Left, PhysicalSide::Right], // horizontal-tb ltr
[PhysicalSide::Top, PhysicalSide::Bottom], // vertical-rl ltr
[PhysicalSide::Right, PhysicalSide::Left], // horizontal-tb rtl
[PhysicalSide::Bottom, PhysicalSide::Top], // vertical-rl rtl
[PhysicalSide::Right, PhysicalSide::Left], // (horizontal-bt) (inverted) ltr
[PhysicalSide::Top, PhysicalSide::Bottom], // sideways-lr rtl
[PhysicalSide::Left, PhysicalSide::Right], // (horizontal-bt) (inverted) rtl
[PhysicalSide::Bottom, PhysicalSide::Top], // sideways-lr ltr
[PhysicalSide::Left, PhysicalSide::Right], // horizontal-tb (inverted) rtl
[PhysicalSide::Top, PhysicalSide::Bottom], // vertical-rl (inverted) rtl
[PhysicalSide::Right, PhysicalSide::Left], // horizontal-tb (inverted) ltr
[PhysicalSide::Bottom, PhysicalSide::Top], // vertical-rl (inverted) ltr
[PhysicalSide::Left, PhysicalSide::Right], // (horizontal-bt) ltr
[PhysicalSide::Top, PhysicalSide::Bottom], // vertical-lr ltr
[PhysicalSide::Right, PhysicalSide::Left], // (horizontal-bt) rtl
[PhysicalSide::Bottom, PhysicalSide::Top], // vertical-lr rtl
];
debug_assert!(WritingMode::VERTICAL.bits() == 0x01 &&
WritingMode::INLINE_REVERSED.bits() == 0x02 &&
WritingMode::VERTICAL_LR.bits() == 0x04 &&
WritingMode::LINE_INVERTED.bits() == 0x08);
debug_assert!(
WritingMode::VERTICAL.bits() == 0x01 &&
WritingMode::INLINE_REVERSED.bits() == 0x02 &&
WritingMode::VERTICAL_LR.bits() == 0x04 &&
WritingMode::LINE_INVERTED.bits() == 0x08
);
let index = (wm.bits() & 0xF) as usize;
INLINE_MAPPING[index][edge]
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u8)]
pub enum LogicalCorner {
@ -1598,10 +1599,30 @@ impl PhysicalCorner {
// sides were to be parallel, we fall back to returning TopLeft.
const IMPOSSIBLE: PhysicalCorner = PhysicalCorner::TopLeft;
static SIDES_TO_CORNER: [[PhysicalCorner; 4]; 4] = [
[IMPOSSIBLE, PhysicalCorner::TopRight, IMPOSSIBLE, PhysicalCorner::TopLeft ],
[PhysicalCorner::TopRight, IMPOSSIBLE, PhysicalCorner::BottomRight, IMPOSSIBLE ],
[IMPOSSIBLE, PhysicalCorner::BottomRight, IMPOSSIBLE, PhysicalCorner::BottomLeft ],
[PhysicalCorner::TopLeft, IMPOSSIBLE, PhysicalCorner::BottomLeft, IMPOSSIBLE ],
[
IMPOSSIBLE,
PhysicalCorner::TopRight,
IMPOSSIBLE,
PhysicalCorner::TopLeft,
],
[
PhysicalCorner::TopRight,
IMPOSSIBLE,
PhysicalCorner::BottomRight,
IMPOSSIBLE,
],
[
IMPOSSIBLE,
PhysicalCorner::BottomRight,
IMPOSSIBLE,
PhysicalCorner::BottomLeft,
],
[
PhysicalCorner::TopLeft,
IMPOSSIBLE,
PhysicalCorner::BottomLeft,
IMPOSSIBLE,
],
];
SIDES_TO_CORNER[a as usize][b as usize]
}

View file

@ -54,7 +54,7 @@ pub const STACK_SAFETY_MARGIN_KB: usize = 168;
/// out of line so we don't allocate stack space for the entire struct
/// in the caller.
#[inline(never)]
pub (crate) fn create_thread_local_context<'scope, E>(slot: &mut Option<ThreadLocalStyleContext<E>>)
pub(crate) fn create_thread_local_context<'scope, E>(slot: &mut Option<ThreadLocalStyleContext<E>>)
where
E: TElement + 'scope,
{

View file

@ -208,10 +208,12 @@ impl PiecewiseLinearFunctionBuilder {
if self.entries.len() == 1 {
// Don't bother resolving anything.
return PiecewiseLinearFunction {
entries: crate::ArcSlice::from_iter(std::iter::once(PiecewiseLinearFunctionEntry {
x: 0.,
y: self.entries[0].y,
})),
entries: crate::ArcSlice::from_iter(std::iter::once(
PiecewiseLinearFunctionEntry {
x: 0.,
y: self.entries[0].y,
},
)),
};
}
// Guaranteed at least two elements.

View file

@ -297,7 +297,8 @@ where
let mut shorthand_cache = ShorthandsWithPropertyReferencesCache::default();
let properties_to_apply = match cascade_mode {
CascadeMode::Visited { unvisited_context } => {
cascade.context.builder.custom_properties = unvisited_context.builder.custom_properties.clone();
cascade.context.builder.custom_properties =
unvisited_context.builder.custom_properties.clone();
cascade.context.builder.writing_mode = unvisited_context.builder.writing_mode;
// We never insert visited styles into the cache so we don't need to try looking it up.
// It also wouldn't be super-profitable, only a handful :visited properties are
@ -340,7 +341,11 @@ where
},
};
cascade.apply_non_prioritary_properties(&declarations.longhand_declarations, &mut shorthand_cache, &properties_to_apply);
cascade.apply_non_prioritary_properties(
&declarations.longhand_declarations,
&mut shorthand_cache,
&properties_to_apply,
);
cascade.finished_applying_properties();
@ -690,12 +695,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
);
loop {
let decl = decls.longhand_declarations[index as usize];
self.apply_one_longhand(
longhand_id,
decl.decl,
decl.priority,
cache,
);
self.apply_one_longhand(longhand_id, decl.decl, decl.priority, cache);
if self.seen.contains(longhand_id) {
return true; // Common case, we're done.
}
@ -717,15 +717,23 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
false
}
fn apply_prioritary_properties(&mut self, decls: &Declarations, cache: &mut ShorthandsWithPropertyReferencesCache) {
fn apply_prioritary_properties(
&mut self,
decls: &Declarations,
cache: &mut ShorthandsWithPropertyReferencesCache,
) {
if !decls.has_prioritary_properties {
return;
}
let has_writing_mode = self
.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::WritingMode) |
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::Direction) |
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::TextOrientation);
let has_writing_mode =
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::WritingMode) |
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::Direction) |
self.apply_one_prioritary_property(
decls,
cache,
PrioritaryPropertyId::TextOrientation,
);
if has_writing_mode {
self.compute_writing_mode();
}
@ -737,7 +745,8 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
// Compute font-family.
let has_font_family =
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::FontFamily);
let has_lang = self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::XLang);
let has_lang =
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::XLang);
if has_lang {
self.recompute_initial_font_family_if_needed();
}
@ -753,8 +762,11 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::FontSize);
let has_math_depth =
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::MathDepth);
let has_min_font_size_ratio =
self.apply_one_prioritary_property(decls, cache, PrioritaryPropertyId::MozMinFontSizeRatio);
let has_min_font_size_ratio = self.apply_one_prioritary_property(
decls,
cache,
PrioritaryPropertyId::MozMinFontSizeRatio,
);
if has_math_depth && has_font_size {
self.recompute_math_font_size_if_needed();
@ -796,7 +808,10 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
let is_logical = longhand_id.is_logical();
if is_logical {
let wm = self.context.builder.writing_mode;
self.context.rule_cache_conditions.borrow_mut().set_writing_mode_dependency(wm);
self.context
.rule_cache_conditions
.borrow_mut()
.set_writing_mode_dependency(wm);
longhand_id = longhand_id.to_physical(wm);
}
self.apply_one_longhand(
@ -834,9 +849,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
}
if self.reverted_set.contains(longhand_id) {
if let Some(&(reverted_priority, is_origin_revert)) =
self.reverted.get(&longhand_id)
{
if let Some(&(reverted_priority, is_origin_revert)) = self.reverted.get(&longhand_id) {
if !reverted_priority.allows_when_reverted(&priority, is_origin_revert) {
return;
}
@ -864,8 +877,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
// We intentionally don't want to insert it into `self.seen`, `reverted` takes
// care of rejecting other declarations as needed.
self.reverted_set.insert(longhand_id);
self.reverted
.insert(longhand_id, (priority, origin_revert));
self.reverted.insert(longhand_id, (priority, origin_revert));
return;
},
CSSWideKeyword::Unset => true,
@ -884,13 +896,15 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
return;
}
unsafe {
self.do_apply_declaration(longhand_id, &declaration)
}
unsafe { self.do_apply_declaration(longhand_id, &declaration) }
}
#[inline]
unsafe fn do_apply_declaration(&mut self, longhand_id: LonghandId, declaration: &PropertyDeclaration) {
unsafe fn do_apply_declaration(
&mut self,
longhand_id: LonghandId,
declaration: &PropertyDeclaration,
) {
debug_assert!(!longhand_id.is_logical());
// We could (and used to) use a pattern match here, but that bloats this
// function to over 100K of compiled code!
@ -945,7 +959,9 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
visited_parent!(parent_style),
visited_parent!(layout_parent_style),
self.first_line_reparenting,
CascadeMode::Visited { unvisited_context: &*self.context },
CascadeMode::Visited {
unvisited_context: &*self.context,
},
// Cascade input flags don't matter for the visited style, they are
// in the main (unvisited) style.
Default::default(),

View file

@ -4,12 +4,12 @@
//! Registered custom properties.
use crate::Atom;
use super::rule::{Inherits, InitialValue, PropertyRuleName};
use super::syntax::Descriptor;
use crate::selector_map::PrecomputedHashMap;
use crate::stylesheets::UrlExtraData;
use crate::Atom;
use cssparser::SourceLocation;
use super::syntax::Descriptor;
use super::rule::{InitialValue, Inherits, PropertyRuleName};
/// A computed, already-validated property registration.
/// <https://drafts.css-houdini.org/css-properties-values-api-1/#custom-property-registration>

View file

@ -7,8 +7,8 @@
//! https://drafts.css-houdini.org/css-properties-values-api-1/#at-property-rule
use super::{
syntax::Descriptor,
registry::PropertyRegistration,
syntax::Descriptor,
value::{AllowComputationallyDependent, SpecifiedValue as SpecifiedRegisteredValue},
};
use crate::custom_properties::{Name as CustomPropertyName, SpecifiedValue};
@ -71,15 +71,21 @@ pub fn parse_property_block<'i, 't>(
//
// The syntax descriptor is required for the @property rule to be valid; if its
// missing, the @property rule is invalid.
let Some(syntax) = descriptors.syntax else { return Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)) };
let Some(syntax) = descriptors.syntax else {
return Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid));
};
// https://drafts.css-houdini.org/css-properties-values-api-1/#inherits-descriptor:
//
// The inherits descriptor is required for the @property rule to be valid; if its
// missing, the @property rule is invalid.
let Some(inherits) = descriptors.inherits else { return Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)) };
let Some(inherits) = descriptors.inherits else {
return Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid));
};
if PropertyRegistration::validate_initial_value(&syntax, descriptors.initial_value.as_ref()).is_err() {
if PropertyRegistration::validate_initial_value(&syntax, descriptors.initial_value.as_ref())
.is_err()
{
return Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid));
}
@ -239,7 +245,7 @@ impl PropertyRegistration {
// initial-value descriptor is optional. If omitted, the initial value of the property is
// the guaranteed-invalid value.
if syntax.is_universal() && initial_value.is_none() {
return Ok(())
return Ok(());
}
// Otherwise, if the value of the syntax descriptor is not the universal syntax definition,
@ -247,7 +253,7 @@ impl PropertyRegistration {
// The initial-value descriptor must be present.
let Some(initial) = initial_value else {
return Err(PropertyRegistrationError::NoInitialValue)
return Err(PropertyRegistrationError::NoInitialValue);
};
// A value that references the environment or other variables is not computationally

View file

@ -90,25 +90,23 @@ impl ToCss for DataType {
W: Write,
{
dest.write_char('<')?;
dest.write_str(
match *self {
DataType::Length => "length",
DataType::Number => "number",
DataType::Percentage => "percentage",
DataType::LengthPercentage => "length-percentage",
DataType::Color => "color",
DataType::Image => "image",
DataType::Url => "url",
DataType::Integer => "integer",
DataType::Angle => "angle",
DataType::Time => "time",
DataType::Resolution => "resolution",
DataType::TransformFunction => "transform-function",
DataType::CustomIdent => "custom-ident",
DataType::TransformList => "transform-list",
DataType::String => "string",
}
)?;
dest.write_str(match *self {
DataType::Length => "length",
DataType::Number => "number",
DataType::Percentage => "percentage",
DataType::LengthPercentage => "length-percentage",
DataType::Color => "color",
DataType::Image => "image",
DataType::Url => "url",
DataType::Integer => "integer",
DataType::Angle => "angle",
DataType::Time => "time",
DataType::Resolution => "resolution",
DataType::TransformFunction => "transform-function",
DataType::CustomIdent => "custom-ident",
DataType::TransformList => "transform-list",
DataType::String => "string",
})?;
dest.write_char('>')
}
}

View file

@ -55,7 +55,11 @@ impl Descriptor {
return Err(ParseError::EmptyInput);
}
let specified = if save_specified { Some(Box::from(css)) } else { None };
let specified = if save_specified {
Some(Box::from(css))
} else {
None
};
// 3. If string's length is 1, and the only code point in string is U+002A
// ASTERISK (*), return the universal syntax descriptor.
@ -113,7 +117,10 @@ impl ToCss for Descriptor {
impl Parse for Descriptor {
/// Parse a syntax descriptor.
fn parse<'i>( _: &ParserContext, parser: &mut CSSParser<'i, '_>,) -> Result<Self, StyleParseError<'i>> {
fn parse<'i>(
_: &ParserContext,
parser: &mut CSSParser<'i, '_>,
) -> Result<Self, StyleParseError<'i>> {
let input = parser.expect_string()?;
Descriptor::from_str(input.as_ref(), /* save_specified = */ true)
.map_err(|err| parser.new_custom_error(StyleParseErrorKind::PropertySyntaxField(err)))
@ -134,12 +141,10 @@ impl ToCss for Multiplier {
where
W: Write,
{
dest.write_char(
match *self {
Multiplier::Space => '+',
Multiplier::Comma => '#',
}
)
dest.write_char(match *self {
Multiplier::Space => '+',
Multiplier::Comma => '#',
})
}
}

View file

@ -413,7 +413,9 @@ impl SpecifiedValue {
allow_computationally_dependent: AllowComputationallyDependent,
) -> Result<Self, StyleParseError<'i>> {
if syntax.is_universal() {
return Ok(Self::Universal(ComputedPropertyValue::parse(&mut input, url_data)?));
return Ok(Self::Universal(ComputedPropertyValue::parse(
&mut input, url_data,
)?));
}
let mut values = SmallComponentVec::new();

View file

@ -654,10 +654,7 @@ impl QueryFeatureExpression {
return evaluator(context, computed);
},
Evaluator::String(evaluator) => {
let string = self
.kind
.non_ranged_value()
.map(|v| expect!(String, v));
let string = self.kind.non_ranged_value().map(|v| expect!(String, v));
return evaluator(context, string);
},
Evaluator::BoolInteger(eval) => {

View file

@ -11,7 +11,7 @@ use crate::values::serialize_atom_identifier;
use crate::Atom;
use cssparser::{Parser as CssParser, ParserInput};
use dom::ElementState;
use selectors::parser::{SelectorList, ParseRelative};
use selectors::parser::{ParseRelative, SelectorList};
use std::fmt::{self, Debug, Write};
use style_traits::{CssWriter, ParseError, ToCss};

View file

@ -137,8 +137,7 @@ where
let for_element = target.revalidation_match_results(stylist, bloom, selector_caches);
let for_candidate =
candidate.revalidation_match_results(stylist, bloom, selector_caches);
let for_candidate = candidate.revalidation_match_results(stylist, bloom, selector_caches);
// This assert "ensures", to some extent, that the two candidates have
// matched the same rulehash buckets, and as such, that the bits we're

View file

@ -635,7 +635,8 @@ impl<E: TElement> StyleSharingCache<E> {
.style
.0
.flags
.intersects(ComputedValueFlags::ANCHORS_RELATIVE_SELECTOR) {
.intersects(ComputedValueFlags::ANCHORS_RELATIVE_SELECTOR)
{
debug!("Failing to insert to the cache: may anchor relative selector");
return;
}
@ -898,7 +899,11 @@ impl<E: TElement> StyleSharingCache<E> {
// RELEVANT_LINK_VISITED flag, so we can't share by rule node between visited and
// unvisited styles. We don't check for visitedness and just refuse to share for links
// entirely, so that visitedness doesn't affect timing.
debug_assert_eq!(target.is_link(), candidate.element.is_link(), "Linkness mismatch");
debug_assert_eq!(
target.is_link(),
candidate.element.is_link(),
"Linkness mismatch"
);
if target.is_link() {
return None;
}

View file

@ -17,7 +17,7 @@ use crate::selector_parser::{PseudoElement, SelectorImpl};
use crate::stylist::RuleInclusion;
use log::Level::Trace;
use selectors::matching::{
MatchingForInvalidation, MatchingContext, MatchingMode, NeedsSelectorFlags,
MatchingContext, MatchingForInvalidation, MatchingMode, NeedsSelectorFlags,
RelativeSelectorMatchingState, VisitedHandlingMode,
};
use servo_arc::Arc;

View file

@ -59,8 +59,8 @@ pub use self::loader::StylesheetLoader;
pub use self::media_rule::MediaRule;
pub use self::namespace_rule::NamespaceRule;
pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter};
pub use self::page_rule::{PagePseudoClassFlags, PageRule, PageSelector, PageSelectors};
pub use self::property_rule::PropertyRule;
pub use self::page_rule::{PageRule, PagePseudoClassFlags, PageSelector, PageSelectors};
pub use self::rule_list::{CssRules, CssRulesHelpers};
pub use self::rule_parser::{InsertRuleContext, State, TopLevelRuleParser};
pub use self::rules_iterator::{AllRules, EffectiveRules};

View file

@ -16,8 +16,8 @@ use cssparser::{Parser, SourceLocation, Token};
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use servo_arc::Arc;
use std::fmt::{self, Write};
use smallvec::SmallVec;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss};
macro_rules! page_pseudo_classes {
@ -123,7 +123,7 @@ type PagePseudoClasses = SmallVec<[PagePseudoClass; 4]>;
///
/// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors
#[derive(Clone, Debug, MallocSizeOf, ToShmem)]
pub struct PageSelector{
pub struct PageSelector {
/// Page name
///
/// https://drafts.csswg.org/css-page-3/#page-type-selector
@ -177,18 +177,20 @@ impl PageSelector {
let mut h: usize = 0;
for pc in self.pseudos.iter() {
if !flags.contains_class(pc) {
return None
return None;
}
match pc {
PagePseudoClass::First |
PagePseudoClass::Blank => g += 1,
PagePseudoClass::Left |
PagePseudoClass::Right => h += 1,
PagePseudoClass::First | PagePseudoClass::Blank => g += 1,
PagePseudoClass::Left | PagePseudoClass::Right => h += 1,
}
}
let h = h.min(0xFFFF) as u32;
let g = (g.min(0x7FFF) as u32) << 16;
let f = if self.name.0.is_empty() { 0 } else { 0x80000000 };
let f = if self.name.0.is_empty() {
0
} else {
0x80000000
};
Some(h + g + f)
}
}
@ -196,7 +198,7 @@ impl PageSelector {
impl ToCss for PageSelector {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write
W: Write,
{
self.name.to_css(dest)?;
for pc in self.pseudos.iter() {
@ -206,9 +208,7 @@ impl ToCss for PageSelector {
}
}
fn parse_page_name<'i, 't>(
input: &mut Parser<'i, 't>
) -> Result<AtomIdent, ParseError<'i>> {
fn parse_page_name<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AtomIdent, ParseError<'i>> {
let s = input.expect_ident()?;
Ok(AtomIdent::from(&**s))
}
@ -218,12 +218,14 @@ impl Parse for PageSelector {
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let name = input.try_parse(parse_page_name).unwrap_or(AtomIdent(atom!("")));
let name = input
.try_parse(parse_page_name)
.unwrap_or(AtomIdent(atom!("")));
let mut pseudos = PagePseudoClasses::default();
while let Ok(pc) = input.try_parse(PagePseudoClass::parse) {
pseudos.push(pc);
}
Ok(PageSelector{name, pseudos})
Ok(PageSelector { name, pseudos })
}
}

View file

@ -542,7 +542,8 @@ impl<'a, 'i> NestedRuleParser<'a, 'i> {
}
let declarations = if parse_declarations {
let top = &mut **parser;
top.declaration_parser_state.report_errors_if_needed(&top.context, &top.error_reporting_state);
top.declaration_parser_state
.report_errors_if_needed(&top.context, &top.error_reporting_state);
parser.declaration_parser_state.take_declarations()
} else {
PropertyDeclarationBlock::default()
@ -586,7 +587,9 @@ impl<'a, 'i> NestedRuleParser<'a, 'i> {
if found_host && found_non_host {
self.context.log_css_error(
start.source_location(),
ContextualParseError::NeverMatchingHostSelector(selector.to_css_string()),
ContextualParseError::NeverMatchingHostSelector(
selector.to_css_string(),
),
);
continue 'selector_loop;
}
@ -774,11 +777,8 @@ impl<'a, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'i> {
})))
},
AtRulePrelude::Property(name) => self.nest_for_rule(CssRuleType::Property, |p| {
let rule_data = parse_property_block(
&p.context,
input,
name,
start.source_location())?;
let rule_data =
parse_property_block(&p.context, input, name, start.source_location())?;
Ok::<CssRule, ParseError<'i>>(CssRule::Property(Arc::new(rule_data)))
})?,
AtRulePrelude::Document(condition) => {
@ -922,7 +922,9 @@ impl<'a, 'i> DeclarationParser<'i> for NestedRuleParser<'a, 'i> {
}
impl<'a, 'i> RuleBodyItemParser<'i, (), StyleParseErrorKind<'i>> for NestedRuleParser<'a, 'i> {
fn parse_qualified(&self) -> bool { true }
fn parse_qualified(&self) -> bool {
true
}
/// If nesting is disabled, we can't get there for a non-style-rule. If it's enabled, we parse
/// raw declarations there.

View file

@ -13,7 +13,9 @@ use crate::str::CssStringWriter;
use crate::stylesheets::CssRules;
use cssparser::SourceLocation;
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocUnconditionalShallowSizeOf, MallocUnconditionalSizeOf, MallocSizeOf, MallocSizeOfOps};
use malloc_size_of::{
MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf, MallocUnconditionalSizeOf,
};
use selectors::SelectorList;
use servo_arc::Arc;
use std::fmt::{self, Write};

View file

@ -8,7 +8,7 @@ use crate::applicable_declarations::{
ApplicableDeclarationBlock, ApplicableDeclarationList, CascadePriority,
};
use crate::context::{CascadeInputs, QuirksMode};
use crate::custom_properties::{CustomPropertiesMap, ComputedCustomProperties};
use crate::custom_properties::{ComputedCustomProperties, CustomPropertiesMap};
use crate::dom::TElement;
#[cfg(feature = "gecko")]
use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion};
@ -22,7 +22,9 @@ use crate::invalidation::stylesheets::RuleChangeKind;
use crate::media_queries::Device;
use crate::properties::{self, CascadeMode, ComputedValues, FirstLineReparenting};
use crate::properties::{AnimationDeclarations, PropertyDeclarationBlock};
use crate::properties_and_values::registry::{ScriptRegistry as CustomPropertyScriptRegistry, PropertyRegistration};
use crate::properties_and_values::registry::{
PropertyRegistration, ScriptRegistry as CustomPropertyScriptRegistry,
};
use crate::rule_cache::{RuleCache, RuleCacheConditions};
use crate::rule_collector::RuleCollector;
use crate::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
@ -40,8 +42,8 @@ use crate::stylesheets::{
CounterStyleRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule,
};
use crate::stylesheets::{
CssRule, EffectiveRulesIterator, Origin, OriginSet, PerOrigin, PerOriginIter,
PagePseudoClassFlags, PageRule,
CssRule, EffectiveRulesIterator, Origin, OriginSet, PagePseudoClassFlags, PageRule, PerOrigin,
PerOriginIter,
};
use crate::stylesheets::{StyleRule, StylesheetContents, StylesheetInDocument};
use crate::values::computed;
@ -1428,11 +1430,12 @@ impl Stylist {
// [1]: https://github.com/w3c/csswg-drafts/issues/1995
// [2]: https://bugzil.la/1458189
let mut animation = None;
let doc_rules_apply = element.each_applicable_non_document_style_rule_data(|data, _host| {
if animation.is_none() {
animation = data.animations.get(name);
}
});
let doc_rules_apply =
element.each_applicable_non_document_style_rule_data(|data, _host| {
if animation.is_none() {
animation = data.animations.get(name);
}
});
if animation.is_some() {
return animation;
@ -1743,16 +1746,22 @@ impl PageRuleMap {
let cascade_data = cascade_data.borrow_for_origin(origin);
let start = matched_rules.len();
self.match_and_add_rules(matched_rules, level, guards, cascade_data, &atom!(""), pseudos);
self.match_and_add_rules(
matched_rules,
level,
guards,
cascade_data,
&atom!(""),
pseudos,
);
if let Some(name) = name {
self.match_and_add_rules(matched_rules, level, guards, cascade_data, name, pseudos);
}
// Because page-rules do not have source location information stored,
// use stable sort to ensure source locations are preserved.
matched_rules[start..].sort_by_key(|block| {
(block.layer_order(), block.specificity, block.source_order())
});
matched_rules[start..]
.sort_by_key(|block| (block.layer_order(), block.specificity, block.source_order()));
}
fn match_and_add_rules(
@ -1856,7 +1865,10 @@ impl ExtraStyleData {
let page_rule = rule.read_with(guard);
let mut add_rule = |name| {
let vec = self.pages.rules.entry(name).or_default();
vec.push(PageRuleData{layer, rule: rule.clone()});
vec.push(PageRuleData {
layer,
rule: rule.clone(),
});
};
if page_rule.selectors.0.is_empty() {
add_rule(atom!(""));
@ -2047,7 +2059,7 @@ impl<'a> StylistSelectorVisitor<'a> {
fn visit_nested_selector(
&mut self,
in_selector_list_of: SelectorListKind,
selector: &Selector<SelectorImpl>
selector: &Selector<SelectorImpl>,
) {
let old_passed_rightmost_selector = self.passed_rightmost_selector;
let old_in_selector_list_of = self.in_selector_list_of;
@ -2777,9 +2789,11 @@ impl CascadeData {
self.num_declarations += style_rule.block.read_with(&guard).len();
let has_nested_rules = style_rule.rules.is_some();
let mut ancestor_selectors = containing_rule_state.ancestor_selector_lists.last_mut();
let mut ancestor_selectors =
containing_rule_state.ancestor_selector_lists.last_mut();
let mut replaced_selectors = SmallVec::<[Selector<SelectorImpl>; 4]>::new();
let collect_replaced_selectors = has_nested_rules && ancestor_selectors.is_some();
let collect_replaced_selectors =
has_nested_rules && ancestor_selectors.is_some();
for selector in style_rule.selectors.slice() {
self.num_selectors += 1;

View file

@ -352,7 +352,11 @@ impl Quaternion {
// direction: [-360, 0]. And quaternions between the range [720*k, 720*(k+1)] will be
// treated as rotations [0, 720]. So it does not make sense to use quaternions to rotate
// the element more than ±360deg. Therefore, we have to make sure its range is (-360, 360).
let half_angle = angle.abs().rem_euclid(std::f64::consts::TAU).copysign(angle) / 2.;
let half_angle = angle
.abs()
.rem_euclid(std::f64::consts::TAU)
.copysign(angle) /
2.;
// Reference:
// https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
@ -393,7 +397,12 @@ impl Add for Quaternion {
type Output = Self;
fn add(self, other: Self) -> Self {
Self(self.0 + other.0, self.1 + other.1, self.2 + other.2, self.3 + other.3)
Self(
self.0 + other.0,
self.1 + other.1,
self.2 + other.2,
self.3 + other.3,
)
}
}

View file

@ -4,13 +4,13 @@
//! Computed color values.
use crate::color::parsing::Color as CSSParserColor;
use crate::color::AbsoluteColor;
use crate::values::animated::ToAnimatedZero;
use crate::values::computed::percentage::Percentage;
use crate::values::generics::color::{
GenericCaretColor, GenericColor, GenericColorMix, GenericColorOrAuto,
};
use crate::color::parsing::Color as CSSParserColor;
use std::fmt;
use style_traits::{CssWriter, ToCss};

View file

@ -26,8 +26,7 @@ pub use specified::ImageRendering;
/// Computed values for an image according to CSS-IMAGES.
/// <https://drafts.csswg.org/css-images/#image-values>
pub type Image =
generic::GenericImage<Gradient, ComputedImageUrl, Color, Percentage, Resolution>;
pub type Image = generic::GenericImage<Gradient, ComputedImageUrl, Color, Percentage, Resolution>;
// Images should remain small, see https://github.com/servo/servo/pull/18430
size_of_test!(Image, 16);
@ -87,7 +86,10 @@ impl ToComputedValue for specified::ImageSet {
}
let candidate_resolution = item.resolution.dppx();
debug_assert!(candidate_resolution >= 0.0, "Resolutions should be non-negative");
debug_assert!(
candidate_resolution >= 0.0,
"Resolutions should be non-negative"
);
if candidate_resolution == 0.0 {
// If the resolution is 0, we also treat it as an invalid image.
continue;

View file

@ -23,10 +23,10 @@ use crate::media_queries::Device;
use crate::properties;
use crate::properties::{ComputedValues, StyleBuilder};
use crate::rule_cache::RuleCacheConditions;
use crate::stylist::Stylist;
use crate::stylesheets::container_rule::{
ContainerInfo, ContainerSizeQuery, ContainerSizeQueryResult,
};
use crate::stylist::Stylist;
use crate::values::specified::length::FontBaseSize;
use crate::{ArcSlice, Atom, One};
use euclid::{default, Point2D, Rect, Size2D};

View file

@ -9,7 +9,7 @@ use crate::values::computed::image::Image;
use crate::values::computed::Number;
use crate::values::generics::ui as generics;
pub use crate::values::specified::ui::{CursorKind, BoolInteger, UserSelect, MozTheme};
pub use crate::values::specified::ui::{BoolInteger, CursorKind, MozTheme, UserSelect};
/// A computed value for the `cursor` property.
pub type Cursor = generics::GenericCursor<CursorImage>;

View file

@ -60,8 +60,8 @@ impl Default for ShapeGeometryBox {
fn is_default_box_for_clip_path(b: &ShapeGeometryBox) -> bool {
// Note: for clip-path, ElementDependent is always border-box, so we have to check both of them
// for serialization.
matches!(b, ShapeGeometryBox::ElementDependent)
|| matches!(b, ShapeGeometryBox::ShapeBox(ShapeBox::BorderBox))
matches!(b, ShapeGeometryBox::ElementDependent) ||
matches!(b, ShapeGeometryBox::ShapeBox(ShapeBox::BorderBox))
}
/// https://drafts.csswg.org/css-shapes-1/#typedef-shape-box

View file

@ -5,8 +5,8 @@
//! Generic types for font stuff.
use crate::parser::{Parse, ParserContext};
use crate::One;
use crate::values::animated::ToAnimatedZero;
use crate::One;
use byteorder::{BigEndian, ReadBytesExt};
use cssparser::Parser;
use std::fmt::{self, Write};

View file

@ -777,7 +777,7 @@ impl<I: ToCss> ToCss for LineNameListValue<I> {
ToShmem,
)]
#[repr(C)]
pub struct GenericLineNameList<I>{
pub struct GenericLineNameList<I> {
/// The pre-computed length of line_names, without the length of repeat(auto-fill, ...).
// We precomputed this at parsing time, so we can avoid an extra loop when expanding
// repeat(auto-fill).

View file

@ -156,7 +156,9 @@ pub use self::GenericImageSet as ImageSet;
pub use self::GenericImageSetItem as ImageSetItem;
/// State flags stored on each variant of a Gradient.
#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
#[derive(
Clone, Copy, Debug, Default, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem,
)]
#[repr(C)]
pub struct GradientFlags(u8);
bitflags! {

View file

@ -120,7 +120,9 @@ where
{
use crate::serde::de::Error;
// Return Err() so the IPC will catch it and assert this as a fetal error.
Err(<D as Deserializer>::Error::custom("we don't support the deserializing for url"))
Err(<D as Deserializer>::Error::custom(
"we don't support the deserializing for url",
))
}
/// The <offset-path> value.

View file

@ -12,7 +12,9 @@ use std::fmt::{self, Write};
use style_traits::{CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss};
/// Constants shared by multiple CSS Box Alignment properties
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
#[derive(
Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem,
)]
#[repr(C)]
pub struct AlignFlags(u8);
bitflags! {

View file

@ -14,13 +14,13 @@ use crate::values::generics::border::BorderSpacing as GenericBorderSpacing;
use crate::values::generics::rect::Rect;
use crate::values::generics::size::Size2D;
use crate::values::specified::length::{Length, NonNegativeLength, NonNegativeLengthPercentage};
use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage};
use crate::values::specified::Color;
use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage};
use crate::Zero;
use app_units::Au;
use cssparser::Parser;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss, values::SequenceWriter};
use style_traits::{values::SequenceWriter, CssWriter, ParseError, ToCss};
/// A specified value for a single side of a `border-style` property.
///
@ -382,7 +382,7 @@ where
let has_color = *color != Color::CurrentColor;
let has_width = *width != BorderSideWidth::medium();
if !has_style && !has_color && !has_width {
return width.to_css(dest)
return width.to_css(dest);
}
let mut writer = SequenceWriter::new(dest, " ");
if has_width {

View file

@ -1022,7 +1022,19 @@ impl WillChange {
}
/// The change bits that we care about.
#[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
#[derive(
Clone,
Copy,
Debug,
Default,
Eq,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct WillChangeBits(u16);
bitflags! {
@ -1134,7 +1146,20 @@ impl Parse for WillChange {
}
/// Values for the `touch-action` property.
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
#[derive(
Clone,
Copy,
Debug,
Eq,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[css(bitflags(single = "none,auto,manipulation", mixed = "pan-x,pan-y,pinch-zoom"))]
#[repr(C)]
pub struct TouchAction(u8);
@ -1163,8 +1188,25 @@ impl TouchAction {
}
}
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
#[css(bitflags(single = "none,strict,content", mixed="size,layout,style,paint,inline-size", overlapping_bits))]
#[derive(
Clone,
Copy,
Debug,
Eq,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[css(bitflags(
single = "none,strict,content",
mixed = "size,layout,style,paint,inline-size",
overlapping_bits
))]
#[repr(C)]
/// Constants for contain: https://drafts.csswg.org/css-contain/#contain-property
pub struct Contain(u8);
@ -1844,9 +1886,26 @@ impl Overflow {
}
}
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
#[derive(
Clone,
Copy,
Debug,
Eq,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
#[css(bitflags(single = "auto", mixed = "stable,both-edges", validate_mixed="Self::has_stable"))]
#[css(bitflags(
single = "auto",
mixed = "stable,both-edges",
validate_mixed = "Self::has_stable"
))]
/// Values for scrollbar-gutter:
/// <https://drafts.csswg.org/css-overflow-3/#scrollbar-gutter-property>
pub struct ScrollbarGutter(u8);

View file

@ -6,6 +6,7 @@
//!
//! [calc]: https://drafts.csswg.org/css-values/#calc-notation
use crate::color::parsing::{AngleOrNumber, NumberOrPercentage};
use crate::parser::ParserContext;
use crate::values::generics::calc::{
self as generic, CalcNodeLeaf, CalcUnits, MinMaxOp, ModRemOp, PositivePercentageBasis,
@ -16,7 +17,6 @@ use crate::values::specified::length::{ContainerRelativeLength, ViewportPercenta
use crate::values::specified::{self, Angle, Resolution, Time};
use crate::values::{serialize_number, serialize_percentage, CSSFloat, CSSInteger};
use cssparser::{CowRcStr, Parser, Token};
use crate::color::parsing::{AngleOrNumber, NumberOrPercentage};
use smallvec::SmallVec;
use std::cmp;
use std::fmt::{self, Write};
@ -188,11 +188,9 @@ impl generic::CalcNodeLeaf for Leaf {
}
match (self, other) {
(&Percentage(ref one), &Percentage(ref other)) => {
match basis {
PositivePercentageBasis::Yes => one.partial_cmp(other),
PositivePercentageBasis::Unknown => None,
}
(&Percentage(ref one), &Percentage(ref other)) => match basis {
PositivePercentageBasis::Yes => one.partial_cmp(other),
PositivePercentageBasis::Unknown => None,
},
(&Length(ref one), &Length(ref other)) => one.partial_cmp(other),
(&Angle(ref one), &Angle(ref other)) => one.degrees().partial_cmp(&other.degrees()),

View file

@ -16,7 +16,10 @@ use crate::values::generics::font::{
use crate::values::generics::NonNegative;
use crate::values::specified::length::{FontBaseSize, LineHeightBase, PX_PER_PT};
use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage};
use crate::values::specified::{FontRelativeLength, NoCalcLength, NonNegativeNumber, NonNegativePercentage, NonNegativeLengthPercentage, Number};
use crate::values::specified::{
FontRelativeLength, NoCalcLength, NonNegativeLengthPercentage, NonNegativeNumber,
NonNegativePercentage, Number,
};
use crate::values::{serialize_atom_identifier, CustomIdent, SelectorParseErrorKind};
use crate::Atom;
use cssparser::{Parser, Token};

View file

@ -433,9 +433,9 @@ impl Parse for LineNameList<Integer> {
line_names.push(value);
}
Ok(LineNameList{
expanded_line_names_length,
line_names : line_names.into(),
Ok(LineNameList {
expanded_line_names_length,
line_names: line_names.into(),
})
}
}

View file

@ -42,8 +42,7 @@ fn gradient_color_interpolation_method_enabled() -> bool {
/// Specified values for an image according to CSS-IMAGES.
/// <https://drafts.csswg.org/css-images/#image-values>
pub type Image =
generic::Image<Gradient, SpecifiedImageUrl, Color, Percentage, Resolution>;
pub type Image = generic::Image<Gradient, SpecifiedImageUrl, Color, Percentage, Resolution>;
// Images should remain small, see https://github.com/servo/servo/pull/18430
size_of_test!(Image, 16);

View file

@ -17,7 +17,7 @@ use super::{CSSFloat, CSSInteger};
use crate::context::QuirksMode;
use crate::parser::{Parse, ParserContext};
use crate::values::specified::calc::CalcNode;
use crate::values::{AtomString, serialize_atom_identifier, serialize_number};
use crate::values::{serialize_atom_identifier, serialize_number, AtomString};
use crate::{Atom, Namespace, One, Prefix, Zero};
use cssparser::{Parser, Token};
use std::fmt::{self, Write};
@ -39,11 +39,11 @@ pub use self::border::{
BorderImageWidth, BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle, LineWidth,
};
pub use self::box_::{
Appearance, BreakBetween, BaselineSource, BreakWithin, Contain, ContainerName, ContainerType,
Clear, ContainIntrinsicSize, ContentVisibility, Display, Float, LineClamp, Overflow,
OverflowAnchor, OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollbarGutter,
ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType,
TouchAction, VerticalAlign, WillChange, Zoom
Appearance, BaselineSource, BreakBetween, BreakWithin, Clear, Contain, ContainIntrinsicSize,
ContainerName, ContainerType, ContentVisibility, Display, Float, LineClamp, Overflow,
OverflowAnchor, OverflowClipBox, OverscrollBehavior, Perspective, Resize, ScrollSnapAlign,
ScrollSnapAxis, ScrollSnapStop, ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter,
TouchAction, VerticalAlign, WillChange, Zoom,
};
pub use self::color::{
Color, ColorOrAuto, ColorPropertyValue, ColorScheme, ForcedColorAdjust, PrintColorAdjust,
@ -55,7 +55,9 @@ pub use self::effects::{BoxShadow, Filter, SimpleShadow};
pub use self::flex::FlexBasis;
pub use self::font::{FontFamily, FontLanguageOverride, FontPalette, FontStyle};
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
pub use self::font::{FontSize, FontSizeAdjust, FontSizeAdjustFactor, FontSizeKeyword, FontStretch, FontSynthesis};
pub use self::font::{
FontSize, FontSizeAdjust, FontSizeAdjustFactor, FontSizeKeyword, FontStretch, FontSynthesis,
};
pub use self::font::{FontVariantAlternates, FontWeight};
pub use self::font::{FontVariantEastAsian, FontVariationSettings, LineHeight};
pub use self::font::{MathDepth, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextScale};
@ -878,7 +880,7 @@ pub struct Attr {
/// Attribute name
pub attribute: Atom,
/// Fallback value
pub fallback: AtomString
pub fallback: AtomString,
}
impl Parse for Attr {
@ -897,7 +899,10 @@ fn get_namespace_for_prefix(prefix: &Prefix, context: &ParserContext) -> Option<
}
/// Try to parse a namespace and return it if parsed, or none if there was not one present
fn parse_namespace<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<(Prefix, Namespace), ParseError<'i>> {
fn parse_namespace<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<(Prefix, Namespace), ParseError<'i>> {
let ns_prefix = match input.next()? {
Token::Ident(ref prefix) => Some(Prefix::from(prefix.as_ref())),
Token::Delim('|') => None,
@ -927,7 +932,9 @@ impl Attr {
input: &mut Parser<'i, 't>,
) -> Result<Attr, ParseError<'i>> {
// Syntax is `[namespace? '|']? ident [',' fallback]?`
let namespace = input.try_parse(|input| parse_namespace(context, input)).ok();
let namespace = input
.try_parse(|input| parse_namespace(context, input))
.ok();
let namespace_is_some = namespace.is_some();
let (namespace_prefix, namespace_url) = namespace.unwrap_or_default();
@ -944,10 +951,12 @@ impl Attr {
// Fallback will always be a string value for now as we do not support
// attr() types yet.
let fallback = input.try_parse(|input| -> Result<AtomString, ParseError<'i>> {
input.expect_comma()?;
Ok(input.expect_string()?.as_ref().into())
}).unwrap_or_default();
let fallback = input
.try_parse(|input| -> Result<AtomString, ParseError<'i>> {
input.expect_comma()?;
Ok(input.expect_string()?.as_ref().into())
})
.unwrap_or_default();
Ok(Attr {
namespace_prefix,

View file

@ -197,8 +197,8 @@ impl Parse for OffsetPath {
.ok();
}
if static_prefs::pref!("layout.css.motion-path-coord-box.enabled")
&& coord_box.is_none()
if static_prefs::pref!("layout.css.motion-path-coord-box.enabled") &&
coord_box.is_none()
{
coord_box = input.try_parse(CoordBox::parse).ok();
if coord_box.is_some() {

View file

@ -372,7 +372,18 @@ impl Side for VerticalPositionKeyword {
/// Controls how the auto-placement algorithm works specifying exactly how auto-placed items
/// get flowed into the grid.
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
#[derive(
Clone,
Copy,
Debug,
Eq,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
#[value_info(other_values = "row,column,dense")]
#[repr(C)]
pub struct GridAutoFlow(u8);
@ -632,7 +643,10 @@ pub struct TemplateAreasParser {
impl TemplateAreasParser {
/// Parse a single string.
pub fn try_parse_string<'i>(&mut self, input: &mut Parser<'i, '_>) -> Result<(), ParseError<'i>> {
pub fn try_parse_string<'i>(
&mut self,
input: &mut Parser<'i, '_>,
) -> Result<(), ParseError<'i>> {
input.try_parse(|input| {
self.parse_string(input.expect_string()?)
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
@ -676,12 +690,14 @@ impl TemplateAreasParser {
match self.area_indices.entry(name) {
Entry::Occupied(ref e) => {
let index = *e.get();
if self.areas[index].columns.start != column || self.areas[index].rows.end != self.row {
if self.areas[index].columns.start != column ||
self.areas[index].rows.end != self.row
{
return Err(());
}
self.areas[index].rows.end += 1;
current_area_index = Some(index);
}
},
Entry::Vacant(v) => {
let index = self.areas.len();
let name = v.key().clone();
@ -698,7 +714,7 @@ impl TemplateAreasParser {
},
});
current_area_index = Some(index);
}
},
}
}
if column == 0 {
@ -725,7 +741,7 @@ impl TemplateAreasParser {
/// Return the parsed template areas.
pub fn finish(self) -> Result<TemplateAreas, ()> {
if self.strings.is_empty() {
return Err(())
return Err(());
}
Ok(TemplateAreas {
areas: self.areas.into(),
@ -744,7 +760,10 @@ impl TemplateAreas {
}
impl Parse for TemplateAreas {
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>,) -> Result<Self, ParseError<'i>> {
fn parse<'i, 't>(
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(input)
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}

View file

@ -248,7 +248,19 @@ impl ToCss for SVGPaintOrder {
}
/// The context properties we understand.
#[derive(Clone, Copy, Eq, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
#[derive(
Clone,
Copy,
Eq,
Debug,
Default,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct ContextPropertyBits(u8);
bitflags! {

View file

@ -119,7 +119,9 @@ impl<T> ArcSlice<T> {
#[allow(unsafe_code)]
pub fn forget(self) -> ForgottenArcSlicePtr<T> {
let ret = unsafe {
ForgottenArcSlicePtr(NonNull::new_unchecked(self.0.raw_ptr() as *const _ as *mut _))
ForgottenArcSlicePtr(NonNull::new_unchecked(
self.0.raw_ptr() as *const _ as *mut _
))
};
mem::forget(self);
ret

View file

@ -20,7 +20,7 @@ extern crate smallvec;
extern crate string_cache;
extern crate thin_vec;
use servo_arc::{Arc, ArcUnion, HeaderSlice, ArcUnionBorrow};
use servo_arc::{Arc, ArcUnion, ArcUnionBorrow, HeaderSlice};
use smallbitvec::{InternalStorage, SmallBitVec};
use smallvec::{Array, SmallVec};
use std::alloc::Layout;
@ -438,12 +438,12 @@ where
{
fn to_shmem(&self, builder: &mut SharedMemoryBuilder) -> Result<Self> {
Ok(ManuallyDrop::new(match self.borrow() {
ArcUnionBorrow::First(first) => Self::from_first(ManuallyDrop::into_inner(first.with_arc(|a| {
a.to_shmem(builder)
})?)),
ArcUnionBorrow::Second(second) => Self::from_second(ManuallyDrop::into_inner(second.with_arc(|a| {
a.to_shmem(builder)
})?)),
ArcUnionBorrow::First(first) => Self::from_first(ManuallyDrop::into_inner(
first.with_arc(|a| a.to_shmem(builder))?,
)),
ArcUnionBorrow::Second(second) => Self::from_second(ManuallyDrop::into_inner(
second.with_arc(|a| a.to_shmem(builder))?,
)),
}))
}
}

View file

@ -466,8 +466,9 @@ impl ErrorReporter {
Some(desugared.to_css_string())
},
};
let selector_list_ptr =
desugared_selector_list.as_ref().map_or(ptr::null(), |s| s.as_ptr()) as *const _;
let selector_list_ptr = desugared_selector_list
.as_ref()
.map_or(ptr::null(), |s| s.as_ptr()) as *const _;
let params = error.error_params();
let param = params.main_param;
let pre_param = params.prefix_param;
@ -491,7 +492,9 @@ impl ErrorReporter {
source.as_ptr() as *const _,
source.len() as u32,
selector_list_ptr,
desugared_selector_list.as_ref().map_or(0, |string| string.len()) as u32,
desugared_selector_list
.as_ref()
.map_or(0, |string| string.len()) as u32,
location.line,
location.column,
);

View file

@ -14,8 +14,6 @@ use selectors::matching::{ElementSelectorFlags, MatchingForInvalidation, Selecto
use selectors::{Element, OpaqueElement};
use servo_arc::{Arc, ArcBorrow};
use smallvec::SmallVec;
use style::invalidation::element::element_wrapper::{ElementWrapper, ElementSnapshot};
use style::values::generics::color::ColorMixFlags;
use std::collections::BTreeSet;
use std::fmt::Write;
use std::iter;
@ -45,7 +43,9 @@ use style::gecko::selector_parser::{NonTSPseudoClass, PseudoElement};
use style::gecko::snapshot_helpers::classes_changed;
use style::gecko::traversal::RecalcStyleOnly;
use style::gecko::url;
use style::gecko::wrapper::{GeckoElement, GeckoNode, slow_selector_flags_from_node_selector_flags};
use style::gecko::wrapper::{
slow_selector_flags_from_node_selector_flags, GeckoElement, GeckoNode,
};
use style::gecko_bindings::bindings;
use style::gecko_bindings::bindings::nsACString;
use style::gecko_bindings::bindings::nsAString;
@ -58,7 +58,6 @@ use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
use style::gecko_bindings::bindings::Gecko_HaveSeenPtr;
use style::gecko_bindings::structs;
use style::gecko_bindings::structs::GeckoFontMetrics;
use style::gecko_bindings::structs::gfx::FontPaletteValueSet;
use style::gecko_bindings::structs::gfxFontFeatureValueSet;
use style::gecko_bindings::structs::ipc::ByteBuf;
@ -74,6 +73,7 @@ use style::gecko_bindings::structs::nsresult;
use style::gecko_bindings::structs::CallerType;
use style::gecko_bindings::structs::CompositeOperation;
use style::gecko_bindings::structs::DeclarationBlockMutationClosure;
use style::gecko_bindings::structs::GeckoFontMetrics;
use style::gecko_bindings::structs::IterationCompositeOperation;
use style::gecko_bindings::structs::Loader;
use style::gecko_bindings::structs::LoaderReusableStyleSheets;
@ -97,7 +97,10 @@ use style::gecko_bindings::sugar::refptr::RefPtr;
use style::global_style_data::{
GlobalStyleData, PlatformThreadHandle, StyleThreadPool, GLOBAL_STYLE_DATA, STYLE_THREAD_POOL,
};
use style::invalidation::element::invalidation_map::{RelativeSelectorInvalidationMap, TSStateForInvalidation};
use style::invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
use style::invalidation::element::invalidation_map::{
RelativeSelectorInvalidationMap, TSStateForInvalidation,
};
use style::invalidation::element::invalidator::{InvalidationResult, SiblingTraversalMap};
use style::invalidation::element::relative_selector::{
DomMutationOperation, RelativeSelectorDependencyCollector, RelativeSelectorInvalidator,
@ -131,8 +134,8 @@ use style::stylesheets::{
CssRules, CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule,
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule, PropertyRule,
SanitizationData, SanitizationKind, StyleRule, StylesheetContents, StylesheetLoader as
StyleStylesheetLoader, SupportsRule, UrlExtraData,
SanitizationData, SanitizationKind, StyleRule, StylesheetContents,
StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData,
};
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
use style::thread_state;
@ -148,6 +151,7 @@ use style::values::computed::font::{
};
use style::values::computed::{self, Context, ToComputedValue};
use style::values::distance::ComputeSquaredDistance;
use style::values::generics::color::ColorMixFlags;
use style::values::generics::easing::BeforeFlag;
use style::values::specified::gecko::IntersectionObserverRootMargin;
use style::values::specified::source_size_list::SourceSizeList;
@ -876,9 +880,7 @@ pub unsafe extern "C" fn Servo_AnimationValue_GetOffsetPosition(
}
#[no_mangle]
pub unsafe extern "C" fn Servo_AnimationValue_IsOffsetPathUrl(
value: &AnimationValue,
) -> bool {
pub unsafe extern "C" fn Servo_AnimationValue_IsOffsetPathUrl(value: &AnimationValue) -> bool {
use style::values::generics::motion::{GenericOffsetPath, GenericOffsetPathFunction};
if let AnimationValue::OffsetPath(ref op) = value {
if let GenericOffsetPath::OffsetPath { path, coord_box: _ } = op {
@ -1196,22 +1198,28 @@ pub extern "C" fn Servo_ComputedValues_ShouldTransition(
start: &mut structs::RefPtr<AnimationValue>,
end: &mut structs::RefPtr<AnimationValue>,
) -> ShouldTransitionResult {
let Ok(prop) = LonghandId::from_nscsspropertyid(prop) else { return Default::default() };
let Ok(prop) = LonghandId::from_nscsspropertyid(prop) else {
return Default::default();
};
if prop.is_discrete_animatable() && prop != LonghandId::Visibility {
return Default::default();
}
let Some(new_value) = AnimationValue::from_computed_values(prop, new) else { return Default::default() };
let Some(new_value) = AnimationValue::from_computed_values(prop, new) else {
return Default::default();
};
if let Some(old_transition_value) = old_transition_value {
if *old_transition_value == new_value {
return ShouldTransitionResult {
should_animate: false,
old_transition_value_matches: true,
}
};
}
}
let Some(old_value) = AnimationValue::from_computed_values(prop, old) else { return Default::default() };
let Some(old_value) = AnimationValue::from_computed_values(prop, old) else {
return Default::default();
};
if old_value == new_value || !old_value.interpolable_with(&new_value) {
return Default::default();
}
@ -1231,11 +1239,15 @@ pub extern "C" fn Servo_ComputedValues_TransitionValueMatches(
prop: nsCSSPropertyID,
transition_value: &AnimationValue,
) -> bool {
let Ok(prop) = LonghandId::from_nscsspropertyid(prop) else { return false };
let Ok(prop) = LonghandId::from_nscsspropertyid(prop) else {
return false;
};
if prop.is_discrete_animatable() && prop != LonghandId::Visibility {
return false;
}
let Some(value) = AnimationValue::from_computed_values(prop, style) else { return false };
let Some(value) = AnimationValue::from_computed_values(prop, style) else {
return false;
};
value == *transition_value
}
@ -1631,7 +1643,9 @@ pub unsafe extern "C" fn Servo_ShutdownThreadPool() {
}
#[no_mangle]
pub unsafe extern "C" fn Servo_ThreadPool_GetThreadHandles(handles: &mut ThinVec<PlatformThreadHandle>) {
pub unsafe extern "C" fn Servo_ThreadPool_GetThreadHandles(
handles: &mut ThinVec<PlatformThreadHandle>,
) {
StyleThreadPool::get_thread_handles(handles);
}
@ -2291,7 +2305,10 @@ impl_basic_rule_funcs! { (Style, StyleRule, Locked<StyleRule>),
}
#[no_mangle]
pub extern "C" fn Servo_StyleRule_EnsureRules(rule: &LockedStyleRule, read_only: bool) -> Strong<LockedCssRules> {
pub extern "C" fn Servo_StyleRule_EnsureRules(
rule: &LockedStyleRule,
read_only: bool,
) -> Strong<LockedCssRules> {
let global_style_data = &*GLOBAL_STYLE_DATA;
let lock = &global_style_data.shared_lock;
if read_only {
@ -2465,7 +2482,9 @@ pub extern "C" fn Servo_StyleRule_GetSelectorDataAtIndex(
specificity: Option<&mut u64>,
) {
let selectors = desugared_selector_list(rules);
let Some(selector) = selectors.slice().get(index as usize) else { return };
let Some(selector) = selectors.slice().get(index as usize) else {
return;
};
if let Some(text) = text {
selector.to_css(text).unwrap();
}
@ -2492,7 +2511,9 @@ pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
matches_selector, MatchingContext, MatchingMode, NeedsSelectorFlags, VisitedHandlingMode,
};
let selectors = desugared_selector_list(rules);
let Some(selector) = selectors.slice().get(index as usize) else { return false };
let Some(selector) = selectors.slice().get(index as usize) else {
return false;
};
let mut matching_mode = MatchingMode::Normal;
match PseudoElement::from_pseudo_type(pseudo_type, None) {
Some(pseudo) => {
@ -2548,8 +2569,8 @@ pub extern "C" fn Servo_StyleRule_SetSelectorText(
let value_str = unsafe { text.as_str_unchecked() };
write_locked_arc(rule, |rule: &mut StyleRule| {
use style::selector_parser::SelectorParser;
use selectors::parser::ParseRelative;
use style::selector_parser::SelectorParser;
let namespaces = contents.namespaces.read();
let url_data = contents.url_data.read();
@ -2563,7 +2584,11 @@ pub extern "C" fn Servo_StyleRule_SetSelectorText(
// TODO: Maybe allow setting relative selectors from the OM, if we're in a nested style
// rule?
let mut parser_input = ParserInput::new(&value_str);
match SelectorList::parse(&parser, &mut Parser::new(&mut parser_input), ParseRelative::No) {
match SelectorList::parse(
&parser,
&mut Parser::new(&mut parser_input),
ParseRelative::No,
) {
Ok(selectors) => {
rule.selectors = selectors;
true
@ -4024,7 +4049,12 @@ pub extern "C" fn Servo_ResolvePseudoStyle(
inherited_style,
&doc_data.stylist,
is_probe,
/* matching_func = */ if pseudo_element.is_highlight() {Some(&matching_fn)} else {None},
/* matching_func = */
if pseudo_element.is_highlight() {
Some(&matching_fn)
} else {
None
},
);
match style {
@ -4198,8 +4228,13 @@ fn get_pseudo_style(
}
Some(style.unwrap_or_else(|| {
StyleBuilder::for_inheritance(stylist.device(), Some(stylist), Some(styles.primary()), Some(pseudo))
.build()
StyleBuilder::for_inheritance(
stylist.device(),
Some(stylist),
Some(styles.primary()),
Some(pseudo),
)
.build()
}))
}
@ -4216,8 +4251,12 @@ pub unsafe extern "C" fn Servo_ComputedValues_Inherit(
let pseudo = PseudoElement::from_pseudo_type(pseudo, None).unwrap();
debug_assert!(pseudo.is_anon_box());
let mut style =
StyleBuilder::for_inheritance(data.stylist.device(), Some(&data.stylist), parent_style_context, Some(&pseudo));
let mut style = StyleBuilder::for_inheritance(
data.stylist.device(),
Some(&data.stylist),
parent_style_context,
Some(&pseudo),
);
if for_text {
StyleAdjuster::new(&mut style).adjust_for_text();
@ -5207,7 +5246,8 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(
use style::values::generics::box_::{VerticalAlign, VerticalAlignKeyword};
use style::values::generics::font::FontStyle;
use style::values::specified::{
table::CaptionSide, BorderStyle, Clear, Display, Float, TextAlign, TextEmphasisPosition, TextTransform
table::CaptionSide, BorderStyle, Clear, Display, Float, TextAlign, TextEmphasisPosition,
TextTransform,
};
fn get_from_computed<T>(value: u32) -> T
@ -5407,7 +5447,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetLengthValue(
use style::properties::PropertyDeclaration;
use style::values::generics::length::{LengthPercentageOrAuto, Size};
use style::values::generics::NonNegative;
use style::values::specified::length::{FontRelativeLength, LengthPercentage, ViewportPercentageLength};
use style::values::specified::length::{
FontRelativeLength, LengthPercentage, ViewportPercentageLength,
};
use style::values::specified::FontSize;
let long = get_longhand_from_id!(property);
@ -6018,7 +6060,12 @@ fn create_context_for_animation<'a>(
container_size_query: ContainerSizeQuery<'a>,
) -> Context<'a> {
Context::new_for_animation(
StyleBuilder::for_animation(per_doc_data.stylist.device(), Some(&per_doc_data.stylist), style, parent_style),
StyleBuilder::for_animation(
per_doc_data.stylist.device(),
Some(&per_doc_data.stylist),
style,
parent_style,
),
for_smil_animation,
per_doc_data.stylist.quirks_mode(),
rule_cache_conditions,
@ -6196,7 +6243,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(
None
} else {
Some(&custom_properties)
}
},
);
for value in iter {
@ -6224,7 +6271,8 @@ pub extern "C" fn Servo_GetAnimationValues(
.map(|d| d.styles.primary())
.map(|x| &**x);
let container_size_query = ContainerSizeQuery::for_element(element, None, /* is_pseudo = */ false);
let container_size_query =
ContainerSizeQuery::for_element(element, None, /* is_pseudo = */ false);
let mut conditions = Default::default();
let mut context = create_context_for_animation(
&data,
@ -6270,7 +6318,8 @@ pub extern "C" fn Servo_AnimationValue_Compute(
.map(|d| d.styles.primary())
.map(|x| &**x);
let container_size_query = ContainerSizeQuery::for_element(element, None, /* is_pseudo = */ false);
let container_size_query =
ContainerSizeQuery::for_element(element, None, /* is_pseudo = */ false);
let mut conditions = Default::default();
let mut context = create_context_for_animation(
&data,
@ -6930,7 +6979,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorIDDependency(
scope,
quirks_mode,
&invalidation_map,
collector
collector,
);
add_relative_selector_attribute_dependency(
element,
@ -6972,7 +7021,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorClassDependency(
scope,
quirks_mode,
invalidation_map,
collector
collector,
);
add_relative_selector_attribute_dependency(
element,
@ -7185,11 +7234,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorNthDependencyFro
// Short of doing the actual matching, any of the siblings can match the selector, so we
// have to try invalidating against all of them.
while let Some(sibling) = element {
invalidate_relative_selector_ts_dependency(
raw_data,
sibling,
TSStateForInvalidation::NTH,
);
invalidate_relative_selector_ts_dependency(raw_data, sibling, TSStateForInvalidation::NTH);
element = sibling.next_sibling_element();
}
}
@ -7219,13 +7264,18 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForInsertion(
// Note that the previous sibling may be the anchor, and not part of the invalidation chain.
// Either way, there must be siblings to both sides of the element being inserted
// to consider it.
match (element.prev_sibling_element(), element.next_sibling_element()) {
match (
element.prev_sibling_element(),
element.next_sibling_element(),
) {
(Some(prev_sibling), Some(next_sibling)) => 'sibling: {
// If the prev sibling is not on the sibling search path, skip.
if prev_sibling
.relative_selector_search_direction()
.map_or(true, |direction| {
!direction.intersects(ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_SIBLING)
!direction.intersects(
ElementSelectorFlags::RELATIVE_SELECTOR_SEARCH_DIRECTION_SIBLING,
)
})
{
break 'sibling;
@ -7257,7 +7307,6 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForInsertion(
_ => (),
};
let invalidator = RelativeSelectorInvalidator {
element,
quirks_mode,
@ -7338,7 +7387,7 @@ pub extern "C" fn Servo_StyleSet_MaybeInvalidateRelativeSelectorForRemoval(
prev_sibling,
quirks_mode,
SiblingTraversalMap::default(),
&data.stylist
&data.stylist,
);
invalidate_relative_selector_next_sibling_side_effect(
next_sibling,
@ -7481,9 +7530,17 @@ pub unsafe extern "C" fn Servo_GetCustomPropertyValue(
let stylist = &doc_data.stylist;
let custom_registration = stylist.get_custom_property_registration(&name);
let computed_value = if custom_registration.map_or(true, |r| r.inherits()) {
computed_values.custom_properties.inherited.as_ref().and_then(|m| m.get(&name))
computed_values
.custom_properties
.inherited
.as_ref()
.and_then(|m| m.get(&name))
} else {
computed_values.custom_properties.non_inherited.as_ref().and_then(|m| m.get(&name))
computed_values
.custom_properties
.non_inherited
.as_ref()
.and_then(|m| m.get(&name))
};
if let Some(v) = computed_value {
@ -7508,7 +7565,10 @@ pub extern "C" fn Servo_GetCustomPropertyNameAt(
computed_values: &ComputedValues,
index: u32,
) -> *mut nsAtom {
match &computed_values.custom_properties.property_at(index as usize) {
match &computed_values
.custom_properties
.property_at(index as usize)
{
Some((name, _value)) => name.as_ptr(),
None => ptr::null_mut(),
}
@ -7528,8 +7588,10 @@ fn relative_selector_dependencies_for_id<'a>(
invalidation_map: &'a RelativeSelectorInvalidationMap,
collector: &mut RelativeSelectorDependencyCollector<'a, GeckoElement<'a>>,
) {
[old_id, new_id].iter().filter(|id| !id.is_null()).for_each(|id| {
unsafe {
[old_id, new_id]
.iter()
.filter(|id| !id.is_null())
.for_each(|id| unsafe {
AtomIdent::with(*id, |atom| {
match invalidation_map.map.id_to_selector.get(atom, quirks_mode) {
Some(v) => {
@ -7540,8 +7602,7 @@ fn relative_selector_dependencies_for_id<'a>(
None => (),
};
})
}
});
});
}
fn relative_selector_dependencies_for_class<'a>(
@ -7594,12 +7655,20 @@ fn process_relative_selector_invalidations(
&data.stylist,
|element, scope, data, quirks_mode, collector| {
let invalidation_map = data.relative_selector_invalidation_map();
let states = *states.get_or_insert_with(|| ElementWrapper::new(*element, snapshot_table).state_changes());
let states = *states.get_or_insert_with(|| {
ElementWrapper::new(*element, snapshot_table).state_changes()
});
let classes = classes.get_or_insert_with(|| classes_changed(element, snapshot_table));
if snapshot.id_changed() {
relative_selector_dependencies_for_id(
element.id().map(|id| id.as_ptr().cast_const()).unwrap_or(ptr::null()),
snapshot.id_attr().map(|id| id.as_ptr().cast_const()).unwrap_or(ptr::null()),
element
.id()
.map(|id| id.as_ptr().cast_const())
.unwrap_or(ptr::null()),
snapshot
.id_attr()
.map(|id| id.as_ptr().cast_const())
.unwrap_or(ptr::null()),
element,
scope,
quirks_mode,
@ -7607,8 +7676,23 @@ fn process_relative_selector_invalidations(
collector,
);
}
relative_selector_dependencies_for_class(&classes, element, scope, quirks_mode, invalidation_map, collector);
snapshot.each_attr_changed(|attr| add_relative_selector_attribute_dependency(element, &scope, invalidation_map, attr, collector));
relative_selector_dependencies_for_class(
&classes,
element,
scope,
quirks_mode,
invalidation_map,
collector,
);
snapshot.each_attr_changed(|attr| {
add_relative_selector_attribute_dependency(
element,
&scope,
invalidation_map,
attr,
collector,
)
});
invalidation_map
.map
.state_affecting_selectors
@ -7960,7 +8044,10 @@ pub extern "C" fn Servo_ParseFilters(
let mut filters = vec![];
if parser.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
if parser
.try_parse(|i| i.expect_ident_matching("none"))
.is_ok()
{
return parser.expect_exhausted().is_ok();
}
@ -8070,9 +8157,9 @@ pub unsafe extern "C" fn Servo_ParseFontShorthandForMatching(
},
specified::FontSize::Keyword(info) => {
let keyword = if info.kw != specified::FontSizeKeyword::Math {
info.kw
info.kw
} else {
specified::FontSizeKeyword::Medium
specified::FontSizeKeyword::Medium
};
// Map absolute-size keywords to sizes.
// TODO: Maybe get a meaningful quirks / base size from the caller?
@ -8533,12 +8620,10 @@ pub extern "C" fn Servo_ParseLengthWithoutStyleContext(
len: &nsACString,
out: &mut f32,
get_font_metrics: Option<unsafe extern "C" fn(*mut c_void) -> GeckoFontMetrics>,
getter_context: *mut c_void
getter_context: *mut c_void,
) -> bool {
let metrics_getter = if let Some(getter) = get_font_metrics {
Some(move || -> GeckoFontMetrics {
unsafe { getter(getter_context) }
})
Some(move || -> GeckoFontMetrics { unsafe { getter(getter_context) } })
} else {
None
};
@ -8574,7 +8659,13 @@ pub extern "C" fn Servo_SlowRgbToColorName(r: u8, g: u8, b: u8, result: &mut nsA
pub extern "C" fn Servo_ColorNameToRgb(name: &nsACString, out: &mut structs::nscolor) -> bool {
match cssparser::color::parse_named_color(unsafe { name.as_str_unchecked() }) {
Ok((r, g, b)) => {
*out = style::gecko::values::convert_absolute_color_to_nscolor(&AbsoluteColor::new(ColorSpace::Srgb, r, g, b, 1.0));
*out = style::gecko::values::convert_absolute_color_to_nscolor(&AbsoluteColor::new(
ColorSpace::Srgb,
r,
g,
b,
1.0,
));
true
},
_ => false,
@ -8621,25 +8712,34 @@ pub extern "C" fn Servo_RegisterCustomProperty(
// If property set already contains an entry with name as its property name (compared
// codepoint-wise), throw an InvalidModificationError and exit this algorithm.
if per_doc_data.stylist.custom_property_script_registry().get(&name).is_some() {
return AlreadyRegistered
if per_doc_data
.stylist
.custom_property_script_registry()
.get(&name)
.is_some()
{
return AlreadyRegistered;
}
// Attempt to consume a syntax definition from syntax. If it returns failure, throw a
// SyntaxError. Otherwise, let syntax definition be the returned syntax definition.
let Ok(syntax) = Descriptor::from_str(syntax, /* preserve_specified = */ false) else { return InvalidSyntax };
let Ok(syntax) = Descriptor::from_str(syntax, /* preserve_specified = */ false) else {
return InvalidSyntax;
};
let initial_value = match initial_value {
Some(v) => {
let mut input = ParserInput::new(v);
let parsed = Parser::new(&mut input).parse_entirely(|input| {
input.skip_whitespace();
SpecifiedValue::parse(input, url_data)
}).ok();
let parsed = Parser::new(&mut input)
.parse_entirely(|input| {
input.skip_whitespace();
SpecifiedValue::parse(input, url_data)
})
.ok();
if parsed.is_none() {
return InvalidInitialValue
return InvalidInitialValue;
}
parsed
}
},
None => None,
};
@ -8647,27 +8747,33 @@ pub extern "C" fn Servo_RegisterCustomProperty(
PropertyRegistration::validate_initial_value(&syntax, initial_value.as_ref())
{
return match error {
PropertyRegistrationError::InitialValueNotComputationallyIndependent => InitialValueNotComputationallyIndependent,
PropertyRegistrationError::InitialValueNotComputationallyIndependent => {
InitialValueNotComputationallyIndependent
},
PropertyRegistrationError::InvalidInitialValue => InvalidInitialValue,
PropertyRegistrationError::NoInitialValue=> NoInitialValue,
}
PropertyRegistrationError::NoInitialValue => NoInitialValue,
};
}
per_doc_data
.stylist
.custom_property_script_registry_mut()
.register(
PropertyRegistration {
name: PropertyRuleName(name),
syntax,
inherits: if inherits { PropertyInherits::True } else { PropertyInherits::False },
initial_value,
url_data: url_data.clone(),
source_location: SourceLocation { line: 0, column: 0 },
.register(PropertyRegistration {
name: PropertyRuleName(name),
syntax,
inherits: if inherits {
PropertyInherits::True
} else {
PropertyInherits::False
},
);
initial_value,
url_data: url_data.clone(),
source_location: SourceLocation { line: 0, column: 0 },
});
per_doc_data.stylist.rebuild_initial_values_for_custom_properties();
per_doc_data
.stylist
.rebuild_initial_values_for_custom_properties();
SuccessfullyRegistered
}
@ -8686,21 +8792,19 @@ pub struct PropDef {
pub from_js: bool,
}
impl PropDef {
/// Creates a PropDef from a name and a PropertyRegistration.
pub fn new(
name: Atom,
property_registration: &PropertyRegistration,
from_js: bool
) -> Self {
pub fn new(name: Atom, property_registration: &PropertyRegistration, from_js: bool) -> Self {
let mut syntax = nsCString::new();
if let Some(spec) = property_registration.syntax.specified_string() {
syntax.assign(spec);
} else {
// FIXME: Descriptor::to_css should behave consistently (probably this shouldn't use
// the ToCss trait).
property_registration.syntax.to_css(&mut CssWriter::new(&mut syntax)).unwrap();
property_registration
.syntax
.to_css(&mut CssWriter::new(&mut syntax))
.unwrap();
};
let initial_value = property_registration.initial_value.to_css_nscstring();
@ -8710,7 +8814,7 @@ impl PropDef {
inherits: property_registration.inherits(),
has_initial_value: property_registration.initial_value.is_some(),
initial_value,
from_js
from_js,
}
}
}
@ -8727,31 +8831,23 @@ pub extern "C" fn Servo_GetRegisteredCustomProperties(
.custom_property_script_registry()
.get_all()
.iter()
.map(|(name, property_registration)|
.map(|(name, property_registration)| {
PropDef::new(name.clone(), property_registration, /* from_js */ true)
}),
);
for (cascade_data, _origin) in stylist.iter_origins() {
custom_properties.extend(cascade_data.custom_property_registrations().iter().map(
|(name, value)| {
let property_registration = &value.last().unwrap().0;
PropDef::new(
name.clone(),
property_registration,
/* from_js */
true
false,
)
)
);
for (cascade_data, _origin) in stylist.iter_origins() {
custom_properties.extend(
cascade_data
.custom_property_registrations()
.iter()
.map(|(name, value)| {
let property_registration = &value.last().unwrap().0;
PropDef::new(
name.clone(),
property_registration,
/* from_js */
false
)
})
)
},
))
}
}
@ -8768,14 +8864,11 @@ pub extern "C" fn Servo_GetSelectorWarnings(
rule: &LockedStyleRule,
warnings: &mut ThinVec<SelectorWarningData>,
) {
read_locked_arc(rule, |r|
read_locked_arc(rule, |r| {
for (i, selector) in r.selectors.slice().iter().enumerate() {
for k in SelectorWarningKind::from_selector(selector) {
warnings.push(SelectorWarningData {
index: i,
kind: k,
});
warnings.push(SelectorWarningData { index: i, kind: k });
}
}
);
});
}

View file

@ -35,7 +35,6 @@ pub mod does_not_impl_malloc_size_of {
*/
pub fn servo_arc() {}
/**
```compile_fail,E0277
extern crate malloc_size_of;
@ -49,7 +48,6 @@ pub mod does_not_impl_malloc_size_of {
*/
pub fn std_arc() {}
/**
```compile_fail,E0277
extern crate malloc_size_of;
@ -79,7 +77,6 @@ pub mod does_not_impl_malloc_shallow_size_of {
*/
pub fn servo_arc() {}
/**
```compile_fail,E0277
extern crate malloc_size_of;
@ -93,7 +90,6 @@ pub mod does_not_impl_malloc_shallow_size_of {
*/
pub fn std_arc() {}
/**
```compile_fail,E0277
extern crate malloc_size_of;

View file

@ -11,53 +11,76 @@ fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA {
let from = from.to_animated_value();
let to = to.to_animated_value();
RGBA::from_animated_value(
from.animate(&to, Procedure::Interpolate { progress }).unwrap(),
from.animate(&to, Procedure::Interpolate { progress })
.unwrap(),
)
}
// Color
#[test]
fn test_rgba_color_interepolation_preserves_transparent() {
assert_eq!(interpolate_rgba(RGBA::transparent(),
RGBA::transparent(), 0.5),
RGBA::transparent());
assert_eq!(
interpolate_rgba(RGBA::transparent(), RGBA::transparent(), 0.5),
RGBA::transparent()
);
}
#[test]
fn test_rgba_color_interepolation_alpha() {
assert_eq!(interpolate_rgba(RGBA::new(200, 0, 0, 100),
RGBA::new(0, 200, 0, 200), 0.5),
RGBA::new(67, 133, 0, 150));
assert_eq!(
interpolate_rgba(RGBA::new(200, 0, 0, 100), RGBA::new(0, 200, 0, 200), 0.5),
RGBA::new(67, 133, 0, 150)
);
}
#[test]
fn test_rgba_color_interepolation_out_of_range_1() {
// Some cubic-bezier functions produce values that are out of range [0, 1].
// Unclamped cases.
assert_eq!(interpolate_rgba(RGBA::from_floats(0.3, 0.0, 0.0, 0.4),
RGBA::from_floats(0.0, 1.0, 0.0, 0.6), -0.5),
RGBA::new(154, 0, 0, 77));
assert_eq!(
interpolate_rgba(
RGBA::from_floats(0.3, 0.0, 0.0, 0.4),
RGBA::from_floats(0.0, 1.0, 0.0, 0.6),
-0.5
),
RGBA::new(154, 0, 0, 77)
);
}
#[test]
fn test_rgba_color_interepolation_out_of_range_2() {
assert_eq!(interpolate_rgba(RGBA::from_floats(1.0, 0.0, 0.0, 0.6),
RGBA::from_floats(0.0, 0.3, 0.0, 0.4), 1.5),
RGBA::new(0, 154, 0, 77));
assert_eq!(
interpolate_rgba(
RGBA::from_floats(1.0, 0.0, 0.0, 0.6),
RGBA::from_floats(0.0, 0.3, 0.0, 0.4),
1.5
),
RGBA::new(0, 154, 0, 77)
);
}
#[test]
fn test_rgba_color_interepolation_out_of_range_clamped_1() {
assert_eq!(interpolate_rgba(RGBA::from_floats(1.0, 0.0, 0.0, 0.8),
RGBA::from_floats(0.0, 1.0, 0.0, 0.2), -0.5),
RGBA::from_floats(1.0, 0.0, 0.0, 1.0));
assert_eq!(
interpolate_rgba(
RGBA::from_floats(1.0, 0.0, 0.0, 0.8),
RGBA::from_floats(0.0, 1.0, 0.0, 0.2),
-0.5
),
RGBA::from_floats(1.0, 0.0, 0.0, 1.0)
);
}
#[test]
fn test_rgba_color_interepolation_out_of_range_clamped_2() {
assert_eq!(interpolate_rgba(RGBA::from_floats(1.0, 0.0, 0.0, 0.8),
RGBA::from_floats(0.0, 1.0, 0.0, 0.2), 1.5),
RGBA::from_floats(0.0, 0.0, 0.0, 0.0));
assert_eq!(
interpolate_rgba(
RGBA::from_floats(1.0, 0.0, 0.0, 0.8),
RGBA::from_floats(0.0, 1.0, 0.0, 0.2),
1.5
),
RGBA::from_floats(0.0, 0.0, 0.0, 0.0)
);
}
// Transform
@ -65,16 +88,19 @@ fn test_rgba_color_interepolation_out_of_range_clamped_2() {
fn test_transform_interpolation_on_translate() {
use style::values::computed::{CalcLengthPercentage, Length, LengthPercentage};
let from = Transform(vec![
TransformOperation::Translate3D(LengthPercentage::Length(Length::new(0.)),
LengthPercentage::Length(Length::new(100.)),
Length::new(25.))]);
let to = Transform(vec![
TransformOperation::Translate3D(LengthPercentage::Length(Length::new(100.)),
LengthPercentage::Length(Length::new(0.)),
Length::new(75.))]);
let from = Transform(vec![TransformOperation::Translate3D(
LengthPercentage::Length(Length::new(0.)),
LengthPercentage::Length(Length::new(100.)),
Length::new(25.),
)]);
let to = Transform(vec![TransformOperation::Translate3D(
LengthPercentage::Length(Length::new(100.)),
LengthPercentage::Length(Length::new(0.)),
Length::new(75.),
)]);
assert_eq!(
from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
from.animate(&to, Procedure::Interpolate { progress: 0.5 })
.unwrap(),
Transform(vec![TransformOperation::Translate3D(
LengthPercentage::Length(Length::new(50.)),
LengthPercentage::Length(Length::new(50.)),
@ -87,19 +113,25 @@ fn test_transform_interpolation_on_translate() {
LengthPercentage::Percentage(Percentage(1.0)),
Length::new(25.),
)]);
let to = Transform(vec![
TransformOperation::Translate3D(LengthPercentage::Length(Length::new(100.)),
LengthPercentage::Length(Length::new(50.)),
Length::new(75.))]);
let to = Transform(vec![TransformOperation::Translate3D(
LengthPercentage::Length(Length::new(100.)),
LengthPercentage::Length(Length::new(50.)),
Length::new(75.),
)]);
assert_eq!(
from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
from.animate(&to, Procedure::Interpolate { progress: 0.5 })
.unwrap(),
Transform(vec![TransformOperation::Translate3D(
// calc(50px + 25%)
LengthPercentage::Calc(CalcLengthPercentage::new(Length::new(50.),
Some(Percentage(0.25)))),
LengthPercentage::Calc(CalcLengthPercentage::new(
Length::new(50.),
Some(Percentage(0.25))
)),
// calc(25px + 50%)
LengthPercentage::Calc(CalcLengthPercentage::new(Length::new(25.),
Some(Percentage(0.5)))),
LengthPercentage::Calc(CalcLengthPercentage::new(
Length::new(25.),
Some(Percentage(0.5))
)),
Length::new(50.),
)])
);
@ -110,7 +142,8 @@ fn test_transform_interpolation_on_scale() {
let from = Transform(vec![TransformOperation::Scale3D(1.0, 2.0, 1.0)]);
let to = Transform(vec![TransformOperation::Scale3D(2.0, 4.0, 2.0)]);
assert_eq!(
from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
from.animate(&to, Procedure::Interpolate { progress: 0.5 })
.unwrap(),
Transform(vec![TransformOperation::Scale3D(1.5, 3.0, 1.5)])
);
}
@ -119,15 +152,27 @@ fn test_transform_interpolation_on_scale() {
fn test_transform_interpolation_on_rotate() {
use style::values::computed::Angle;
let from = Transform(vec![TransformOperation::Rotate3D(0.0, 0.0, 1.0,
Angle::from_radians(0.0))]);
let to = Transform(vec![TransformOperation::Rotate3D(0.0, 0.0, 1.0,
Angle::from_radians(100.0))]);
let from = Transform(vec![TransformOperation::Rotate3D(
0.0,
0.0,
1.0,
Angle::from_radians(0.0),
)]);
let to = Transform(vec![TransformOperation::Rotate3D(
0.0,
0.0,
1.0,
Angle::from_radians(100.0),
)]);
assert_eq!(
from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
Transform(vec![
TransformOperation::Rotate3D(0.0, 0.0, 1.0, Angle::from_radians(50.0)),
])
from.animate(&to, Procedure::Interpolate { progress: 0.5 })
.unwrap(),
Transform(vec![TransformOperation::Rotate3D(
0.0,
0.0,
1.0,
Angle::from_radians(50.0)
),])
);
}
@ -135,12 +180,17 @@ fn test_transform_interpolation_on_rotate() {
fn test_transform_interpolation_on_skew() {
use style::values::computed::Angle;
let from = Transform(vec![TransformOperation::Skew(Angle::from_radians(0.0),
Some(Angle::from_radians(100.0)))]);
let to = Transform(vec![TransformOperation::Skew(Angle::from_radians(100.0),
Some(Angle::from_radians(0.0)))]);
let from = Transform(vec![TransformOperation::Skew(
Angle::from_radians(0.0),
Some(Angle::from_radians(100.0)),
)]);
let to = Transform(vec![TransformOperation::Skew(
Angle::from_radians(100.0),
Some(Angle::from_radians(0.0)),
)]);
assert_eq!(
from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
from.animate(&to, Procedure::Interpolate { progress: 0.5 })
.unwrap(),
Transform(vec![TransformOperation::Skew(
Angle::from_radians(50.0),
Some(Angle::from_radians(50.0)),
@ -152,14 +202,20 @@ fn test_transform_interpolation_on_skew() {
fn test_transform_interpolation_on_mismatched_lists() {
use style::values::computed::{Angle, Length, LengthPercentage};
let from = Transform(vec![TransformOperation::Rotate3D(0.0, 0.0, 1.0,
Angle::from_radians(100.0))]);
let to = Transform(vec![
TransformOperation::Translate3D(LengthPercentage::Length(Length::new(100.)),
LengthPercentage::Length(Length::new(0.)),
Length::new(0.))]);
let from = Transform(vec![TransformOperation::Rotate3D(
0.0,
0.0,
1.0,
Angle::from_radians(100.0),
)]);
let to = Transform(vec![TransformOperation::Translate3D(
LengthPercentage::Length(Length::new(100.)),
LengthPercentage::Length(Length::new(0.)),
Length::new(0.),
)]);
assert_eq!(
from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
from.animate(&to, Procedure::Interpolate { progress: 0.5 })
.unwrap(),
Transform(vec![TransformOperation::InterpolateMatrix {
from_list: from.clone(),
to_list: to.clone(),

View file

@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use app_units::Au;
use style::attr::{AttrValue, LengthPercentageOrAuto, parse_length};
use style::attr::{parse_length, AttrValue, LengthPercentageOrAuto};
use style::values::computed::{CalcLengthPercentage, Percentage};
#[test]
@ -23,7 +23,7 @@ fn test_parse_double() {
let value = String::from("432.5e2");
match AttrValue::from_double(value, 0.0) {
AttrValue::Double(_, num) => assert_eq!(num, 43250f64),
_ => panic!("expected a double value")
_ => panic!("expected a double value"),
}
}
@ -32,7 +32,7 @@ fn test_parse_double_negative_prefix() {
let value = String::from("-5.6");
match AttrValue::from_double(value, 0.0) {
AttrValue::Double(_, num) => assert_eq!(num, -5.6f64),
_ => panic!("expected a double value")
_ => panic!("expected a double value"),
}
}
@ -41,7 +41,7 @@ fn test_parse_double_positive_prefix() {
let value = String::from("+5.6");
match AttrValue::from_double(value, 0.0) {
AttrValue::Double(_, num) => assert_eq!(num, 5.6f64),
_ => panic!("expected a double value")
_ => panic!("expected a double value"),
}
}
@ -50,7 +50,7 @@ fn test_from_limited_i32_should_be_default_when_less_than_0() {
let value = String::from("-1");
match AttrValue::from_limited_i32(value, 0) {
AttrValue::Int(_, 0) => (),
_ => panic!("expected an IndexSize error")
_ => panic!("expected an IndexSize error"),
}
}
@ -58,7 +58,7 @@ fn test_from_limited_i32_should_be_default_when_less_than_0() {
fn test_from_limited_i32_should_parse_a_uint_when_value_is_0_or_greater() {
match AttrValue::from_limited_i32(String::from("1"), 0) {
AttrValue::Int(_, 1) => (),
_ => panic!("expected an successful parsing")
_ => panic!("expected an successful parsing"),
}
}
@ -68,7 +68,7 @@ fn test_from_limited_i32_should_keep_parsed_value_when_not_an_int() {
AttrValue::Int(p, 0) => {
assert_eq!(p, String::from("parsed-value"))
},
_ => panic!("expected an successful parsing")
_ => panic!("expected an successful parsing"),
}
}
@ -82,7 +82,13 @@ pub fn test_parse_length() {
check("0", LengthPercentageOrAuto::Length(Au::from_px(0)));
check("0.000%", LengthPercentageOrAuto::Percentage(0.0));
check("+5.82%", LengthPercentageOrAuto::Percentage(0.0582));
check("5.82", LengthPercentageOrAuto::Length(Au::from_f64_px(5.82)));
check(
"5.82",
LengthPercentageOrAuto::Length(Au::from_f64_px(5.82)),
);
check("invalid", LengthPercentageOrAuto::Auto);
check("12 followed by invalid", LengthPercentageOrAuto::Length(Au::from_px(12)));
check(
"12 followed by invalid",
LengthPercentageOrAuto::Length(Au::from_px(12)),
);
}

View file

@ -4,7 +4,9 @@
use cssparser::{Parser, ParserInput};
use servo_arc::Arc;
use style::custom_properties::{Name, SpecifiedValue, CustomPropertiesMap, CustomPropertiesBuilder, CssEnvironment};
use style::custom_properties::{
CssEnvironment, CustomPropertiesBuilder, CustomPropertiesMap, Name, SpecifiedValue,
};
use style::properties::CustomDeclarationValue;
use test::{self, Bencher};
@ -12,11 +14,17 @@ fn cascade(
name_and_value: &[(&str, &str)],
inherited: Option<&Arc<CustomPropertiesMap>>,
) -> Option<Arc<CustomPropertiesMap>> {
let values = name_and_value.iter().map(|&(name, value)| {
let mut input = ParserInput::new(value);
let mut parser = Parser::new(&mut input);
(Name::from(name), SpecifiedValue::parse(&mut parser).unwrap())
}).collect::<Vec<_>>();
let values = name_and_value
.iter()
.map(|&(name, value)| {
let mut input = ParserInput::new(value);
let mut parser = Parser::new(&mut input);
(
Name::from(name),
SpecifiedValue::parse(&mut parser).unwrap(),
)
})
.collect::<Vec<_>>();
let env = CssEnvironment;
let mut builder = CustomPropertiesBuilder::new(inherited, &env);
@ -31,14 +39,11 @@ fn cascade(
#[bench]
fn cascade_custom_simple(b: &mut Bencher) {
b.iter(|| {
let parent = cascade(&[
("foo", "10px"),
("bar", "100px"),
], None);
let parent = cascade(&[("foo", "10px"), ("bar", "100px")], None);
test::black_box(cascade(&[
("baz", "calc(40em + 4px)"),
("bazz", "calc(30em + 4px)"),
], parent.as_ref()))
test::black_box(cascade(
&[("baz", "calc(40em + 4px)"), ("bazz", "calc(30em + 4px)")],
parent.as_ref(),
))
})
}

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use euclid::{Size2D, Point2D, SideOffsets2D, Rect};
use style::logical_geometry::{WritingMode, LogicalSize, LogicalPoint, LogicalMargin, LogicalRect};
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
#[cfg(test)]
fn modes() -> Vec<WritingMode> {
@ -19,8 +19,14 @@ fn modes() -> Vec<WritingMode> {
WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::VERTICAL_SIDEWAYS | WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::TEXT_SIDEWAYS | WritingMode::RTL,
WritingMode::VERTICAL |
WritingMode::VERTICAL_LR |
WritingMode::VERTICAL_SIDEWAYS |
WritingMode::RTL,
WritingMode::VERTICAL |
WritingMode::VERTICAL_LR |
WritingMode::TEXT_SIDEWAYS |
WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::UPRIGHT | WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::VERTICAL_SIDEWAYS | WritingMode::RTL,
WritingMode::VERTICAL | WritingMode::TEXT_SIDEWAYS | WritingMode::RTL,

View file

@ -7,13 +7,13 @@ use euclid::Size2D;
use servo_arc::Arc;
use servo_url::ServoUrl;
use std::borrow::ToOwned;
use style::Atom;
use style::context::QuirksMode;
use style::media_queries::*;
use style::servo::media_queries::*;
use style::shared_lock::SharedRwLock;
use style::stylesheets::{AllRules, Stylesheet, StylesheetInDocument, Origin, CssRule};
use style::values::{CustomIdent, specified};
use style::stylesheets::{AllRules, CssRule, Origin, Stylesheet, StylesheetInDocument};
use style::values::{specified, CustomIdent};
use style::Atom;
use style_traits::ToCss;
fn test_media_rule<F>(css: &str, callback: F)
@ -25,9 +25,21 @@ where
let lock = SharedRwLock::new();
let media_list = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock,
None, None, QuirksMode::NoQuirks, 0);
let dummy = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
css,
url,
Origin::Author,
media_list,
lock,
None,
None,
QuirksMode::NoQuirks,
0,
);
let dummy = Device::new(
MediaType::screen(),
Size2D::new(200.0, 100.0),
Scale::new(1.0),
);
let mut rule_count = 0;
let guard = stylesheet.shared_lock.read();
for rule in stylesheet.iter_rules::<AllRules>(&dummy, &guard) {
@ -44,8 +56,16 @@ fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) {
let lock = SharedRwLock::new();
let media_list = Arc::new(lock.wrap(MediaList::empty()));
let ss = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock,
None, None, QuirksMode::NoQuirks, 0);
css,
url,
Origin::Author,
media_list,
lock,
None,
None,
QuirksMode::NoQuirks,
0,
);
let mut rule_count = 0;
ss.effective_style_rules(device, &ss.shared_lock.read(), |_| rule_count += 1);
assert!(rule_count == expected_rule_count, css.to_owned());
@ -64,7 +84,10 @@ fn test_mq_screen() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::screen()),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -72,7 +95,10 @@ fn test_mq_screen() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Only), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::screen()),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -80,7 +106,10 @@ fn test_mq_screen() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::screen()),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
}
@ -91,7 +120,10 @@ fn test_mq_print() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::print()),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -99,7 +131,10 @@ fn test_mq_print() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Only), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::print()),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -107,7 +142,10 @@ fn test_mq_print() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::print()),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
}
@ -118,8 +156,10 @@ fn test_mq_unknown() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(
MediaType(CustomIdent(Atom::from("fridge")))), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType(CustomIdent(Atom::from("fridge")))),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -127,8 +167,10 @@ fn test_mq_unknown() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Only), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(
MediaType(CustomIdent(Atom::from("glass")))), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType(CustomIdent(Atom::from("glass")))),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -136,8 +178,10 @@ fn test_mq_unknown() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(
MediaType(CustomIdent(Atom::from("wood")))), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType(CustomIdent(Atom::from("wood")))),
css.to_owned()
);
assert!(q.expressions.len() == 0, css.to_owned());
});
}
@ -175,12 +219,18 @@ fn test_mq_or() {
assert!(list.media_queries.len() == 2, css.to_owned());
let q0 = &list.media_queries[0];
assert!(q0.qualifier == None, css.to_owned());
assert!(q0.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned());
assert!(
q0.media_type == MediaQueryType::Concrete(MediaType::screen()),
css.to_owned()
);
assert!(q0.expressions.len() == 0, css.to_owned());
let q1 = &list.media_queries[1];
assert!(q1.qualifier == None, css.to_owned());
assert!(q1.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned());
assert!(
q1.media_type == MediaQueryType::Concrete(MediaType::print()),
css.to_owned()
);
assert!(q1.expressions.len() == 0, css.to_owned());
});
}
@ -194,7 +244,9 @@ fn test_mq_default_expressions() {
assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)),
ExpressionKind::Width(Range::Min(ref w)) => {
assert!(*w == specified::Length::from_px(100.))
},
_ => panic!("wrong expression type"),
}
});
@ -206,7 +258,9 @@ fn test_mq_default_expressions() {
assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(43.)),
ExpressionKind::Width(Range::Max(ref w)) => {
assert!(*w == specified::Length::from_px(43.))
},
_ => panic!("wrong expression type"),
}
});
@ -218,10 +272,15 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::screen()),
css.to_owned()
);
assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)),
ExpressionKind::Width(Range::Min(ref w)) => {
assert!(*w == specified::Length::from_px(100.))
},
_ => panic!("wrong expression type"),
}
});
@ -230,10 +289,15 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::print()),
css.to_owned()
);
assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(43.)),
ExpressionKind::Width(Range::Max(ref w)) => {
assert!(*w == specified::Length::from_px(43.))
},
_ => panic!("wrong expression type"),
}
});
@ -242,10 +306,15 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::print()),
css.to_owned()
);
assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Eq(ref w)) => assert!(*w == specified::Length::from_px(43.)),
ExpressionKind::Width(Range::Eq(ref w)) => {
assert!(*w == specified::Length::from_px(43.))
},
_ => panic!("wrong expression type"),
}
});
@ -254,11 +323,15 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(
MediaType(CustomIdent(Atom::from("fridge")))), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType(CustomIdent(Atom::from("fridge")))),
css.to_owned()
);
assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(52.)),
ExpressionKind::Width(Range::Max(ref w)) => {
assert!(*w == specified::Length::from_px(52.))
},
_ => panic!("wrong expression type"),
}
});
@ -275,37 +348,54 @@ fn test_to_css() {
#[test]
fn test_mq_multiple_expressions() {
test_media_rule("@media (min-width: 100px) and (max-width: 200px) { }", |list, css| {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 2, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)),
_ => panic!("wrong expression type"),
}
match *q.expressions[1].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(200.)),
_ => panic!("wrong expression type"),
}
});
test_media_rule(
"@media (min-width: 100px) and (max-width: 200px) { }",
|list, css| {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 2, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(ref w)) => {
assert!(*w == specified::Length::from_px(100.))
},
_ => panic!("wrong expression type"),
}
match *q.expressions[1].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => {
assert!(*w == specified::Length::from_px(200.))
},
_ => panic!("wrong expression type"),
}
},
);
test_media_rule("@media not screen and (min-width: 100px) and (max-width: 200px) { }", |list, css| {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned());
assert!(q.expressions.len() == 2, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)),
_ => panic!("wrong expression type"),
}
match *q.expressions[1].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(200.)),
_ => panic!("wrong expression type"),
}
});
test_media_rule(
"@media not screen and (min-width: 100px) and (max-width: 200px) { }",
|list, css| {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(
q.media_type == MediaQueryType::Concrete(MediaType::screen()),
css.to_owned()
);
assert!(q.expressions.len() == 2, css.to_owned());
match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(ref w)) => {
assert!(*w == specified::Length::from_px(100.))
},
_ => panic!("wrong expression type"),
}
match *q.expressions[1].kind_for_testing() {
ExpressionKind::Width(Range::Max(ref w)) => {
assert!(*w == specified::Length::from_px(200.))
},
_ => panic!("wrong expression type"),
}
},
);
}
#[test]
@ -333,7 +423,11 @@ fn test_mq_malformed_expressions() {
#[test]
fn test_matching_simple() {
let device = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
let device = Device::new(
MediaType::screen(),
Size2D::new(200.0, 100.0),
Scale::new(1.0),
);
media_query_test(&device, "@media not all { a { color: red; } }", 0);
media_query_test(&device, "@media not screen { a { color: red; } }", 0);
@ -349,50 +443,136 @@ fn test_matching_simple() {
#[test]
fn test_matching_width() {
let device = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
let device = Device::new(
MediaType::screen(),
Size2D::new(200.0, 100.0),
Scale::new(1.0),
);
media_query_test(&device, "@media { a { color: red; } }", 1);
media_query_test(&device, "@media (min-width: 50px) { a { color: red; } }", 1);
media_query_test(&device, "@media (min-width: 150px) { a { color: red; } }", 1);
media_query_test(&device, "@media (min-width: 300px) { a { color: red; } }", 0);
media_query_test(
&device,
"@media (min-width: 150px) { a { color: red; } }",
1,
);
media_query_test(
&device,
"@media (min-width: 300px) { a { color: red; } }",
0,
);
media_query_test(&device, "@media screen and (min-width: 50px) { a { color: red; } }", 1);
media_query_test(&device, "@media screen and (min-width: 150px) { a { color: red; } }", 1);
media_query_test(&device, "@media screen and (min-width: 300px) { a { color: red; } }", 0);
media_query_test(
&device,
"@media screen and (min-width: 50px) { a { color: red; } }",
1,
);
media_query_test(
&device,
"@media screen and (min-width: 150px) { a { color: red; } }",
1,
);
media_query_test(
&device,
"@media screen and (min-width: 300px) { a { color: red; } }",
0,
);
media_query_test(&device, "@media not screen and (min-width: 50px) { a { color: red; } }", 0);
media_query_test(&device, "@media not screen and (min-width: 150px) { a { color: red; } }", 0);
media_query_test(&device, "@media not screen and (min-width: 300px) { a { color: red; } }", 1);
media_query_test(
&device,
"@media not screen and (min-width: 50px) { a { color: red; } }",
0,
);
media_query_test(
&device,
"@media not screen and (min-width: 150px) { a { color: red; } }",
0,
);
media_query_test(
&device,
"@media not screen and (min-width: 300px) { a { color: red; } }",
1,
);
media_query_test(&device, "@media (max-width: 50px) { a { color: red; } }", 0);
media_query_test(&device, "@media (max-width: 150px) { a { color: red; } }", 0);
media_query_test(&device, "@media (max-width: 300px) { a { color: red; } }", 1);
media_query_test(&device, "@media screen and (min-width: 50px) and (max-width: 100px) { a { color: red; } }", 0);
media_query_test(&device, "@media screen and (min-width: 250px) and (max-width: 300px) { a { color: red; } }", 0);
media_query_test(&device, "@media screen and (min-width: 50px) and (max-width: 250px) { a { color: red; } }", 1);
media_query_test(
&device,
"@media (max-width: 150px) { a { color: red; } }",
0,
);
media_query_test(
&device,
"@media (max-width: 300px) { a { color: red; } }",
1,
);
media_query_test(
&device, "@media not screen and (min-width: 50px) and (max-width: 100px) { a { color: red; } }", 1);
&device,
"@media screen and (min-width: 50px) and (max-width: 100px) { a { color: red; } }",
0,
);
media_query_test(
&device, "@media not screen and (min-width: 250px) and (max-width: 300px) { a { color: red; } }", 1);
&device,
"@media screen and (min-width: 250px) and (max-width: 300px) { a { color: red; } }",
0,
);
media_query_test(
&device, "@media not screen and (min-width: 50px) and (max-width: 250px) { a { color: red; } }", 0);
&device,
"@media screen and (min-width: 50px) and (max-width: 250px) { a { color: red; } }",
1,
);
media_query_test(
&device, "@media not screen and (min-width: 3.1em) and (max-width: 6em) { a { color: red; } }", 1);
&device,
"@media not screen and (min-width: 50px) and (max-width: 100px) { a { color: red; } }",
1,
);
media_query_test(
&device, "@media not screen and (min-width: 16em) and (max-width: 19.75em) { a { color: red; } }", 1);
&device,
"@media not screen and (min-width: 250px) and (max-width: 300px) { a { color: red; } }",
1,
);
media_query_test(
&device, "@media not screen and (min-width: 3em) and (max-width: 250px) { a { color: red; } }", 0);
&device,
"@media not screen and (min-width: 50px) and (max-width: 250px) { a { color: red; } }",
0,
);
media_query_test(
&device,
"@media not screen and (min-width: 3.1em) and (max-width: 6em) { a { color: red; } }",
1,
);
media_query_test(
&device,
"@media not screen and (min-width: 16em) and (max-width: 19.75em) { a { color: red; } }",
1,
);
media_query_test(
&device,
"@media not screen and (min-width: 3em) and (max-width: 250px) { a { color: red; } }",
0,
);
}
#[test]
fn test_matching_invalid() {
let device = Device::new(MediaType::screen(), Size2D::new(200.0, 100.0), Scale::new(1.0));
let device = Device::new(
MediaType::screen(),
Size2D::new(200.0, 100.0),
Scale::new(1.0),
);
media_query_test(&device, "@media fridge { a { color: red; } }", 0);
media_query_test(&device, "@media screen and (height: 100px) { a { color: red; } }", 0);
media_query_test(&device, "@media not print and (width: 100) { a { color: red; } }", 0);
media_query_test(
&device,
"@media screen and (height: 100px) { a { color: red; } }",
0,
);
media_query_test(
&device,
"@media not print and (width: 100) { a { color: red; } }",
0,
);
}

View file

@ -6,8 +6,8 @@ use parsing::parse;
use servo_atoms::Atom;
use style::parser::Parse;
use style::properties::longhands::animation_name;
use style::values::{KeyframesName, CustomIdent};
use style::values::specified::AnimationIterationCount;
use style::values::{CustomIdent, KeyframesName};
use style_traits::ToCss;
#[test]

View file

@ -3,9 +3,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use parsing::parse;
use style::properties::longhands::{background_attachment, background_clip, background_color, background_image};
use style::properties::longhands::{background_origin, background_position_x, background_position_y, background_repeat};
use style::properties::longhands::background_size;
use style::properties::longhands::{
background_attachment, background_clip, background_color, background_image,
};
use style::properties::longhands::{
background_origin, background_position_x, background_position_y, background_repeat,
};
use style::properties::shorthands::background;
#[test]
@ -13,72 +17,179 @@ fn background_shorthand_should_parse_all_available_properties_when_specified() {
let input = "url(\"http://servo/test.png\") top center / 200px 200px repeat-x fixed padding-box content-box red";
let result = parse(background::parse_value, input).unwrap();
assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\")"));
assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "center"));
assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "top"));
assert_eq!(result.background_size, parse_longhand!(background_size, "200px 200px"));
assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "repeat-x"));
assert_eq!(result.background_attachment, parse_longhand!(background_attachment, "fixed"));
assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box"));
assert_eq!(result.background_clip, parse_longhand!(background_clip, "content-box"));
assert_eq!(result.background_color, parse_longhand!(background_color, "red"));
assert_eq!(
result.background_image,
parse_longhand!(background_image, "url(\"http://servo/test.png\")")
);
assert_eq!(
result.background_position_x,
parse_longhand!(background_position_x, "center")
);
assert_eq!(
result.background_position_y,
parse_longhand!(background_position_y, "top")
);
assert_eq!(
result.background_size,
parse_longhand!(background_size, "200px 200px")
);
assert_eq!(
result.background_repeat,
parse_longhand!(background_repeat, "repeat-x")
);
assert_eq!(
result.background_attachment,
parse_longhand!(background_attachment, "fixed")
);
assert_eq!(
result.background_origin,
parse_longhand!(background_origin, "padding-box")
);
assert_eq!(
result.background_clip,
parse_longhand!(background_clip, "content-box")
);
assert_eq!(
result.background_color,
parse_longhand!(background_color, "red")
);
}
#[test]
fn background_shorthand_should_parse_when_some_fields_set() {
let result = parse(background::parse_value, "14px 40px repeat-y").unwrap();
assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "14px"));
assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "40px"));
assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "repeat-y"));
assert_eq!(
result.background_position_x,
parse_longhand!(background_position_x, "14px")
);
assert_eq!(
result.background_position_y,
parse_longhand!(background_position_y, "40px")
);
assert_eq!(
result.background_repeat,
parse_longhand!(background_repeat, "repeat-y")
);
let result = parse(background::parse_value, "url(\"http://servo/test.png\") repeat blue").unwrap();
let result = parse(
background::parse_value,
"url(\"http://servo/test.png\") repeat blue",
)
.unwrap();
assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\")"));
assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "repeat"));
assert_eq!(result.background_color, parse_longhand!(background_color, "blue"));
assert_eq!(
result.background_image,
parse_longhand!(background_image, "url(\"http://servo/test.png\")")
);
assert_eq!(
result.background_repeat,
parse_longhand!(background_repeat, "repeat")
);
assert_eq!(
result.background_color,
parse_longhand!(background_color, "blue")
);
let result = parse(background::parse_value, "padding-box").unwrap();
assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box"));
assert_eq!(result.background_clip, parse_longhand!(background_clip, "padding-box"));
assert_eq!(
result.background_origin,
parse_longhand!(background_origin, "padding-box")
);
assert_eq!(
result.background_clip,
parse_longhand!(background_clip, "padding-box")
);
let result = parse(background::parse_value, "url(\"http://servo/test.png\")").unwrap();
assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\")"));
assert_eq!(
result.background_image,
parse_longhand!(background_image, "url(\"http://servo/test.png\")")
);
}
#[test]
fn background_shorthand_should_parse_comma_separated_declarations() {
let input = "url(\"http://servo/test.png\") top left no-repeat, url(\"http://servo/test.png\") \
let input =
"url(\"http://servo/test.png\") top left no-repeat, url(\"http://servo/test.png\") \
center / 100% 100% no-repeat, white";
let result = parse(background::parse_value, input).unwrap();
assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\"), \
url(\"http://servo/test.png\"), none"));
assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "left, center, 0%"));
assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "top, center, 0%"));
assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "no-repeat, no-repeat, repeat"));
assert_eq!(result.background_clip, parse_longhand!(background_clip, "border-box, border-box, border-box"));
assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box, padding-box, \
padding-box"));
assert_eq!(result.background_size, parse_longhand!(background_size, "auto auto, 100% 100%, auto auto"));
assert_eq!(result.background_attachment, parse_longhand!(background_attachment, "scroll, scroll, scroll"));
assert_eq!(result.background_color, parse_longhand!(background_color, "white"));
assert_eq!(
result.background_image,
parse_longhand!(
background_image,
"url(\"http://servo/test.png\"), \
url(\"http://servo/test.png\"), none"
)
);
assert_eq!(
result.background_position_x,
parse_longhand!(background_position_x, "left, center, 0%")
);
assert_eq!(
result.background_position_y,
parse_longhand!(background_position_y, "top, center, 0%")
);
assert_eq!(
result.background_repeat,
parse_longhand!(background_repeat, "no-repeat, no-repeat, repeat")
);
assert_eq!(
result.background_clip,
parse_longhand!(background_clip, "border-box, border-box, border-box")
);
assert_eq!(
result.background_origin,
parse_longhand!(
background_origin,
"padding-box, padding-box, \
padding-box"
)
);
assert_eq!(
result.background_size,
parse_longhand!(background_size, "auto auto, 100% 100%, auto auto")
);
assert_eq!(
result.background_attachment,
parse_longhand!(background_attachment, "scroll, scroll, scroll")
);
assert_eq!(
result.background_color,
parse_longhand!(background_color, "white")
);
}
#[test]
fn background_shorthand_should_parse_position_and_size_correctly() {
let result = parse(background::parse_value, "7px 4px").unwrap();
assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "7px"));
assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "4px"));
assert_eq!(
result.background_position_x,
parse_longhand!(background_position_x, "7px")
);
assert_eq!(
result.background_position_y,
parse_longhand!(background_position_y, "4px")
);
let result = parse(background::parse_value, "7px 4px / 30px 20px").unwrap();
assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "7px"));
assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "4px"));
assert_eq!(result.background_size, parse_longhand!(background_size, "30px 20px"));
assert_eq!(
result.background_position_x,
parse_longhand!(background_position_x, "7px")
);
assert_eq!(
result.background_position_y,
parse_longhand!(background_position_y, "4px")
);
assert_eq!(
result.background_size,
parse_longhand!(background_size, "30px 20px")
);
assert!(parse(background::parse_value, "/ 30px 20px").is_err());
@ -89,16 +200,34 @@ fn background_shorthand_should_parse_position_and_size_correctly() {
fn background_shorthand_should_parse_origin_and_clip_correctly() {
let result = parse(background::parse_value, "padding-box content-box").unwrap();
assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box"));
assert_eq!(result.background_clip, parse_longhand!(background_clip, "content-box"));
assert_eq!(
result.background_origin,
parse_longhand!(background_origin, "padding-box")
);
assert_eq!(
result.background_clip,
parse_longhand!(background_clip, "content-box")
);
let result = parse(background::parse_value, "padding-box padding-box").unwrap();
assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box"));
assert_eq!(result.background_clip, parse_longhand!(background_clip, "padding-box"));
assert_eq!(
result.background_origin,
parse_longhand!(background_origin, "padding-box")
);
assert_eq!(
result.background_clip,
parse_longhand!(background_clip, "padding-box")
);
let result = parse(background::parse_value, "padding-box").unwrap();
assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box"));
assert_eq!(result.background_clip, parse_longhand!(background_clip, "padding-box"));
assert_eq!(
result.background_origin,
parse_longhand!(background_origin, "padding-box")
);
assert_eq!(
result.background_clip,
parse_longhand!(background_clip, "padding-box")
);
}

View file

@ -4,40 +4,69 @@
use parsing::parse;
use style::parser::Parse;
use style::properties::MaybeBoxed;
use style::properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
use style::properties::longhands::{border_image_source, border_image_width};
use style::properties::shorthands::border_image;
use style::properties::MaybeBoxed;
use style::values::specified::BorderRadius;
use style_traits::ToCss;
macro_rules! assert_longhand {
($parsed_shorthand: expr, $prop: ident, $value_string: expr) => {
assert_eq!($parsed_shorthand.$prop, parse_longhand!($prop, $value_string).maybe_boxed())
}
assert_eq!(
$parsed_shorthand.$prop,
parse_longhand!($prop, $value_string).maybe_boxed()
)
};
}
macro_rules! assert_initial {
($parsed_shorthand: expr, $prop: ident) => {
assert_eq!($parsed_shorthand.$prop, $prop::get_initial_specified_value().maybe_boxed())
}
assert_eq!(
$parsed_shorthand.$prop,
$prop::get_initial_specified_value().maybe_boxed()
)
};
}
macro_rules! assert_border_radius_values {
($input:expr; $tlw:expr, $trw:expr, $brw:expr, $blw:expr ;
$tlh:expr, $trh:expr, $brh:expr, $blh:expr) => {
let input = parse(BorderRadius::parse, $input)
.expect(&format!("Failed parsing {} as border radius",
$input));
assert_eq!(::style_traits::ToCss::to_css_string(&input.top_left.0.width()), $tlw);
assert_eq!(::style_traits::ToCss::to_css_string(&input.top_right.0.width()), $trw);
assert_eq!(::style_traits::ToCss::to_css_string(&input.bottom_right.0.width()), $brw);
assert_eq!(::style_traits::ToCss::to_css_string(&input.bottom_left.0.width()), $blw);
assert_eq!(::style_traits::ToCss::to_css_string(&input.top_left.0.height()), $tlh);
assert_eq!(::style_traits::ToCss::to_css_string(&input.top_right.0.height()), $trh);
assert_eq!(::style_traits::ToCss::to_css_string(&input.bottom_right.0.height()), $brh);
assert_eq!(::style_traits::ToCss::to_css_string(&input.bottom_left.0.height()), $blh);
}
.expect(&format!("Failed parsing {} as border radius", $input));
assert_eq!(
::style_traits::ToCss::to_css_string(&input.top_left.0.width()),
$tlw
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.top_right.0.width()),
$trw
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.bottom_right.0.width()),
$brw
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.bottom_left.0.width()),
$blw
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.top_left.0.height()),
$tlh
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.top_right.0.height()),
$trh
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.bottom_right.0.height()),
$brh
);
assert_eq!(
::style_traits::ToCss::to_css_string(&input.bottom_left.0.height()),
$blh
);
};
}
#[test]

View file

@ -16,18 +16,26 @@ fn test_clip() {
assert_roundtrip_with_context!(clip::parse, "rect(auto, auto, auto, auto)");
// Non-standard syntax
assert_roundtrip_with_context!(clip::parse,
"rect(1px 2px 3px 4px)",
"rect(1px, 2px, 3px, 4px)");
assert_roundtrip_with_context!(clip::parse,
"rect(auto 2px 3px auto)",
"rect(auto, 2px, 3px, auto)");
assert_roundtrip_with_context!(clip::parse,
"rect(1px auto auto 4px)",
"rect(1px, auto, auto, 4px)");
assert_roundtrip_with_context!(clip::parse,
"rect(auto auto auto auto)",
"rect(auto, auto, auto, auto)");
assert_roundtrip_with_context!(
clip::parse,
"rect(1px 2px 3px 4px)",
"rect(1px, 2px, 3px, 4px)"
);
assert_roundtrip_with_context!(
clip::parse,
"rect(auto 2px 3px auto)",
"rect(auto, 2px, 3px, auto)"
);
assert_roundtrip_with_context!(
clip::parse,
"rect(1px auto auto 4px)",
"rect(1px, auto, auto, 4px)"
);
assert_roundtrip_with_context!(
clip::parse,
"rect(auto auto auto auto)",
"rect(auto, auto, auto, auto)"
);
}
#[test]
@ -85,7 +93,7 @@ fn test_parse_factor() {
#[test]
fn blur_radius_should_not_accept_negavite_values() {
use style::properties::longhands::box_shadow;
assert!(parse(box_shadow::parse, "1px 1px -1px").is_err());// for -ve values
assert!(parse(box_shadow::parse, "1px 1px 0").is_ok());// for zero
assert!(parse(box_shadow::parse, "1px 1px 1px").is_ok());// for +ve value
assert!(parse(box_shadow::parse, "1px 1px -1px").is_err()); // for -ve values
assert!(parse(box_shadow::parse, "1px 1px 0").is_ok()); // for zero
assert!(parse(box_shadow::parse, "1px 1px 1px").is_ok()); // for +ve value
}

View file

@ -33,72 +33,122 @@ fn test_linear_gradient() {
#[test]
fn test_radial_gradient() {
// Parsing with all values
assert_roundtrip_with_context!(Image::parse, "radial-gradient(circle closest-side at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse, "radial-gradient(ellipse closest-side at 20px 30px, red, green)",
"radial-gradient(closest-side at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse, "radial-gradient(closest-side circle at 20px 30px, red, green)",
"radial-gradient(circle closest-side at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse, "radial-gradient(closest-side ellipse at 20px 30px, red, green)",
"radial-gradient(closest-side at 20px 30px, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(circle closest-side at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(ellipse closest-side at 20px 30px, red, green)",
"radial-gradient(closest-side at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(closest-side circle at 20px 30px, red, green)",
"radial-gradient(circle closest-side at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(closest-side ellipse at 20px 30px, red, green)",
"radial-gradient(closest-side at 20px 30px, red, green)"
);
// Parsing with <shape-keyword> and <size> reversed
assert_roundtrip_with_context!(Image::parse, "radial-gradient(closest-side circle at 20px 30px, red, green)",
"radial-gradient(circle closest-side at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse, "radial-gradient(closest-corner ellipse at 20px 30px, red, green)",
"radial-gradient(closest-corner at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse, "radial-gradient(30px circle, red, green)",
"radial-gradient(30px at center center, red, green)");
assert_roundtrip_with_context!(Image::parse, "radial-gradient(30px 40px ellipse, red, green)",
"radial-gradient(30px 40px at center center, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(closest-side circle at 20px 30px, red, green)",
"radial-gradient(circle closest-side at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(closest-corner ellipse at 20px 30px, red, green)",
"radial-gradient(closest-corner at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(30px circle, red, green)",
"radial-gradient(30px at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(30px 40px ellipse, red, green)",
"radial-gradient(30px 40px at center center, red, green)"
);
// Parsing without <size>
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(circle, red, green)",
"radial-gradient(circle at center center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(ellipse, red, green)",
"radial-gradient(at center center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(circle at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(ellipse at 20px 30px, red, green)",
"radial-gradient(at 20px 30px, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(circle, red, green)",
"radial-gradient(circle at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(ellipse, red, green)",
"radial-gradient(at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(circle at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(ellipse at 20px 30px, red, green)",
"radial-gradient(at 20px 30px, red, green)"
);
// Parsing without <shape-keyword>
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(20px at 20px 30px, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(20px 30px at left center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(closest-side at center, red, green)",
"radial-gradient(closest-side at center center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(20px, red, green)",
"radial-gradient(20px at center center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(20px 30px, red, green)",
"radial-gradient(20px 30px at center center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(closest-side, red, green)",
"radial-gradient(closest-side at center center, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(20px at 20px 30px, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(20px 30px at left center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(closest-side at center, red, green)",
"radial-gradient(closest-side at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(20px, red, green)",
"radial-gradient(20px at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(20px 30px, red, green)",
"radial-gradient(20px 30px at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(closest-side, red, green)",
"radial-gradient(closest-side at center center, red, green)"
);
// Parsing without <shape-keyword> and <size>
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(at center, red, green)",
"radial-gradient(at center center, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(at center bottom, red, green)");
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(at 40px 50px, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(at center, red, green)",
"radial-gradient(at center center, red, green)"
);
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(at center bottom, red, green)"
);
assert_roundtrip_with_context!(Image::parse, "radial-gradient(at 40px 50px, red, green)");
// Parsing with just color stops
assert_roundtrip_with_context!(Image::parse,
"radial-gradient(red, green)",
"radial-gradient(at center center, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"radial-gradient(red, green)",
"radial-gradient(at center center, red, green)"
);
// Parsing repeating radial gradient
assert_roundtrip_with_context!(Image::parse,
"repeating-radial-gradient(red, green)",
"repeating-radial-gradient(at center center, red, green)");
assert_roundtrip_with_context!(
Image::parse,
"repeating-radial-gradient(red, green)",
"repeating-radial-gradient(at center center, red, green)"
);
}

View file

@ -8,22 +8,24 @@ use style::values::generics::text::Spacing;
#[test]
fn negative_letter_spacing_should_parse_properly() {
use style::properties::longhands::letter_spacing;
use style::values::specified::length::{Length, NoCalcLength, FontRelativeLength};
use style::values::specified::length::{FontRelativeLength, Length, NoCalcLength};
let negative_value = parse_longhand!(letter_spacing, "-0.5em");
let expected = Spacing::Value(Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(-0.5))));
let expected = Spacing::Value(Length::NoCalc(NoCalcLength::FontRelative(
FontRelativeLength::Em(-0.5),
)));
assert_eq!(negative_value, expected);
}
#[test]
fn negative_word_spacing_should_parse_properly() {
use style::properties::longhands::word_spacing;
use style::values::specified::length::{NoCalcLength, LengthPercentage, FontRelativeLength};
use style::values::specified::length::{FontRelativeLength, LengthPercentage, NoCalcLength};
let negative_value = parse_longhand!(word_spacing, "-0.5em");
let expected = Spacing::Value(LengthPercentage::Length(
NoCalcLength::FontRelative(FontRelativeLength::Em(-0.5))
));
let expected = Spacing::Value(LengthPercentage::Length(NoCalcLength::FontRelative(
FontRelativeLength::Em(-0.5),
)));
assert_eq!(negative_value, expected);
}

View file

@ -8,16 +8,20 @@ use cssparser::{Parser, ParserInput};
use style::context::QuirksMode;
use style::parser::ParserContext;
use style::stylesheets::{CssRuleType, Origin};
use style_traits::{ParsingMode, ParseError};
use style_traits::{ParseError, ParsingMode};
fn parse<T, F>(f: F, s: &'static str) -> Result<T, ParseError<'static>>
where F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>> {
where
F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>>,
{
let mut input = ParserInput::new(s);
parse_input(f, &mut input)
}
fn parse_input<'i: 't, 't, T, F>(f: F, input: &'t mut ParserInput<'i>) -> Result<T, ParseError<'i>>
where F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>> {
where
F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>>,
{
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let context = ParserContext::new(
Origin::Author,
@ -33,14 +37,24 @@ where F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>> {
}
fn parse_entirely<T, F>(f: F, s: &'static str) -> Result<T, ParseError<'static>>
where F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>> {
where
F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>>,
{
let mut input = ParserInput::new(s);
parse_entirely_input(f, &mut input)
}
fn parse_entirely_input<'i: 't, 't, T, F>(f: F, input: &'t mut ParserInput<'i>) -> Result<T, ParseError<'i>>
where F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>> {
parse_input(|context, parser| parser.parse_entirely(|p| f(context, p)), input)
fn parse_entirely_input<'i: 't, 't, T, F>(
f: F,
input: &'t mut ParserInput<'i>,
) -> Result<T, ParseError<'i>>
where
F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>>,
{
parse_input(
|context, parser| parser.parse_entirely(|p| f(context, p)),
input,
)
}
// This is a macro so that the file/line information
@ -51,24 +65,31 @@ macro_rules! assert_roundtrip_with_context {
};
($fun:expr, $input:expr, $output:expr) => {{
let mut input = ::cssparser::ParserInput::new($input);
let serialized = super::parse_input(|context, i| {
let parsed = $fun(context, i)
.expect(&format!("Failed to parse {}", $input));
let serialized = ToCss::to_css_string(&parsed);
assert_eq!(serialized, $output);
Ok(serialized)
}, &mut input).unwrap();
let serialized = super::parse_input(
|context, i| {
let parsed = $fun(context, i).expect(&format!("Failed to parse {}", $input));
let serialized = ToCss::to_css_string(&parsed);
assert_eq!(serialized, $output);
Ok(serialized)
},
&mut input,
)
.unwrap();
let mut input = ::cssparser::ParserInput::new(&serialized);
let unwrapped = super::parse_input(|context, i| {
let re_parsed = $fun(context, i)
.expect(&format!("Failed to parse serialization {}", $input));
let re_serialized = ToCss::to_css_string(&re_parsed);
assert_eq!(serialized, re_serialized);
Ok(())
}, &mut input).unwrap();
let unwrapped = super::parse_input(
|context, i| {
let re_parsed =
$fun(context, i).expect(&format!("Failed to parse serialization {}", $input));
let re_serialized = ToCss::to_css_string(&re_parsed);
assert_eq!(serialized, re_serialized);
Ok(())
},
&mut input,
)
.unwrap();
unwrapped
}}
}};
}
macro_rules! assert_roundtrip {
@ -78,34 +99,37 @@ macro_rules! assert_roundtrip {
($fun:expr, $input:expr, $output:expr) => {
let mut input = ParserInput::new($input);
let mut parser = Parser::new(&mut input);
let parsed = $fun(&mut parser)
.expect(&format!("Failed to parse {}", $input));
let parsed = $fun(&mut parser).expect(&format!("Failed to parse {}", $input));
let serialized = ToCss::to_css_string(&parsed);
assert_eq!(serialized, $output);
let mut input = ParserInput::new(&serialized);
let mut parser = Parser::new(&mut input);
let re_parsed = $fun(&mut parser)
.expect(&format!("Failed to parse serialization {}", $input));
let re_parsed =
$fun(&mut parser).expect(&format!("Failed to parse serialization {}", $input));
let re_serialized = ToCss::to_css_string(&re_parsed);
assert_eq!(serialized, re_serialized)
}
};
}
macro_rules! assert_parser_exhausted {
($fun:expr, $string:expr, $should_exhausted:expr) => {{
parse(|context, input| {
let parsed = $fun(context, input);
assert_eq!(parsed.is_ok(), true);
assert_eq!(input.is_exhausted(), $should_exhausted);
Ok(())
}, $string).unwrap()
}}
parse(
|context, input| {
let parsed = $fun(context, input);
assert_eq!(parsed.is_ok(), true);
assert_eq!(input.is_exhausted(), $should_exhausted);
Ok(())
},
$string,
)
.unwrap()
}};
}
macro_rules! parse_longhand {
($name:ident, $s:expr) => {
parse($name::parse, $s).unwrap()
parse($name::parse, $s).unwrap()
};
}

View file

@ -5,10 +5,12 @@
use cssparser::{Parser, ParserInput, ToCss};
use selectors::parser::SelectorList;
use style::selector_parser::{SelectorImpl, SelectorParser};
use style::stylesheets::{Origin, Namespaces};
use style::stylesheets::{Namespaces, Origin};
use style_traits::ParseError;
fn parse_selector<'i, 't>(input: &mut Parser<'i, 't>) -> Result<SelectorList<SelectorImpl>, ParseError<'i>> {
fn parse_selector<'i, 't>(
input: &mut Parser<'i, 't>,
) -> Result<SelectorList<SelectorImpl>, ParseError<'i>> {
let mut ns = Namespaces::default();
ns.prefixes.insert("svg".into(), ns!(svg));
let parser = SelectorParser {
@ -24,7 +26,10 @@ fn test_selectors() {
assert_roundtrip!(parse_selector, "div");
assert_roundtrip!(parse_selector, "svg|circle");
assert_roundtrip!(parse_selector, "p:before", "p::before");
assert_roundtrip!(parse_selector, "[border=\"0\"]:-servo-nonzero-border ~ ::-servo-details-summary");
assert_roundtrip!(
parse_selector,
"[border=\"0\"]:-servo-nonzero-border ~ ::-servo-details-summary"
);
assert_roundtrip!(parse_selector, "* > *");
assert_roundtrip!(parse_selector, "*|* + *", "* + *");
}

View file

@ -10,7 +10,10 @@ use style_traits::ToCss;
fn test_supports_condition() {
assert_roundtrip!(SupportsCondition::parse, "(margin: 1px)");
assert_roundtrip!(SupportsCondition::parse, "not (--be: to be)");
assert_roundtrip!(SupportsCondition::parse, "(color: blue) and future-extension(4)");
assert_roundtrip!(
SupportsCondition::parse,
"(color: blue) and future-extension(4)"
);
assert_roundtrip!(SupportsCondition::parse, "future-\\1 extension(4)");
assert_roundtrip!(SupportsCondition::parse, "((test))");
}

View file

@ -8,14 +8,35 @@ use style_traits::ToCss;
#[test]
fn test_cubic_bezier() {
assert_roundtrip_with_context!(transition_timing_function::parse, "cubic-bezier(0, 0, 0, 0)");
assert_roundtrip_with_context!(transition_timing_function::parse, "cubic-bezier(0.25, 0, 0.5, 0)");
assert_roundtrip_with_context!(transition_timing_function::parse, "cubic-bezier(1, 1, 1, 1)");
assert_roundtrip_with_context!(
transition_timing_function::parse,
"cubic-bezier(0, 0, 0, 0)"
);
assert_roundtrip_with_context!(
transition_timing_function::parse,
"cubic-bezier(0.25, 0, 0.5, 0)"
);
assert_roundtrip_with_context!(
transition_timing_function::parse,
"cubic-bezier(1, 1, 1, 1)"
);
// p1x and p2x values must be in range [0, 1]
assert!(parse(transition_timing_function::parse, "cubic-bezier(-1, 0, 0, 0").is_err());
assert!(parse(transition_timing_function::parse, "cubic-bezier(0, 0, -1, 0").is_err());
assert!(parse(transition_timing_function::parse, "cubic-bezier(-1, 0, -1, 0").is_err());
assert!(parse(
transition_timing_function::parse,
"cubic-bezier(-1, 0, 0, 0"
)
.is_err());
assert!(parse(
transition_timing_function::parse,
"cubic-bezier(0, 0, -1, 0"
)
.is_err());
assert!(parse(
transition_timing_function::parse,
"cubic-bezier(-1, 0, -1, 0"
)
.is_err());
assert!(parse(transition_timing_function::parse, "cubic-bezier(2, 0, 0, 0").is_err());
assert!(parse(transition_timing_function::parse, "cubic-bezier(0, 0, 2, 0").is_err());
@ -27,7 +48,11 @@ fn test_steps() {
assert_roundtrip_with_context!(transition_timing_function::parse, "steps(1)");
assert_roundtrip_with_context!(transition_timing_function::parse, "steps( 1)", "steps(1)");
assert_roundtrip_with_context!(transition_timing_function::parse, "steps(1, start)");
assert_roundtrip_with_context!(transition_timing_function::parse, "steps(2, end) ", "steps(2)");
assert_roundtrip_with_context!(
transition_timing_function::parse,
"steps(2, end) ",
"steps(2)"
);
// Step interval value must be an integer greater than 0
assert!(parse(transition_timing_function::parse, "steps(0)").is_err());

View file

@ -6,14 +6,11 @@ use cssparser::{Parser, ParserInput};
use style::context::QuirksMode;
use style::parser::ParserContext;
use style::stylesheets::{CssRuleType, Origin};
use style_traits::{ParsingMode, ParseError};
use style_traits::{ParseError, ParsingMode};
fn parse<T, F>(f: F, s: &'static str) -> Result<T, ParseError<'static>>
where
F: for<'t> Fn(
&ParserContext,
&mut Parser<'static, 't>,
) -> Result<T, ParseError<'static>>
F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>>,
{
let mut input = ParserInput::new(s);
parse_input(f, &mut input)
@ -42,24 +39,31 @@ macro_rules! assert_roundtrip_with_context {
assert_roundtrip_with_context!($fun, $string, $string);
};
($fun:expr, $input:expr, $output:expr) => {{
let serialized = parse(|context, i| {
let parsed = $fun(context, i)
.expect(&format!("Failed to parse {}", $input));
let serialized = ToCss::to_css_string(&parsed);
assert_eq!(serialized, $output);
Ok(serialized)
}, $input).unwrap();
let serialized = parse(
|context, i| {
let parsed = $fun(context, i).expect(&format!("Failed to parse {}", $input));
let serialized = ToCss::to_css_string(&parsed);
assert_eq!(serialized, $output);
Ok(serialized)
},
$input,
)
.unwrap();
let mut input = ::cssparser::ParserInput::new(&serialized);
let unwrapped = parse_input(|context, i| {
let re_parsed = $fun(context, i)
.expect(&format!("Failed to parse serialization {}", $input));
let re_serialized = ToCss::to_css_string(&re_parsed);
assert_eq!(serialized, re_serialized);
Ok(())
}, &mut input).unwrap();
let unwrapped = parse_input(
|context, i| {
let re_parsed =
$fun(context, i).expect(&format!("Failed to parse serialization {}", $input));
let re_serialized = ToCss::to_css_string(&re_parsed);
assert_eq!(serialized, re_serialized);
Ok(())
},
&mut input,
)
.unwrap();
unwrapped
}}
}};
}
mod scaffolding;

View file

@ -4,19 +4,30 @@
use serde_json::{self, Value};
use std::env;
use std::fs::{File, remove_file};
use std::fs::{remove_file, File};
use std::path::Path;
use std::process::Command;
#[test]
fn properties_list_json() {
let top = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join("..").join("..").join("..");
let json = top.join("target").join("doc").join("servo").join("css-properties.json");
let top = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap())
.join("..")
.join("..")
.join("..");
let json = top
.join("target")
.join("doc")
.join("servo")
.join("css-properties.json");
if json.exists() {
remove_file(&json).unwrap()
}
let python = env::var("PYTHON").ok().unwrap_or_else(find_python);
let script = top.join("components").join("style").join("properties").join("build.py");
let script = top
.join("components")
.join("style")
.join("properties")
.join("build.py");
let status = Command::new(python)
.arg(&script)
.arg("servo")
@ -34,11 +45,19 @@ fn properties_list_json() {
#[cfg(windows)]
fn find_python() -> String {
if Command::new("python2.7.exe").arg("--version").output().is_ok() {
if Command::new("python2.7.exe")
.arg("--version")
.output()
.is_ok()
{
return "python2.7.exe".to_owned();
}
if Command::new("python27.exe").arg("--version").output().is_ok() {
if Command::new("python27.exe")
.arg("--version")
.output()
.is_ok()
{
return "python27.exe".to_owned();
}
@ -51,9 +70,16 @@ fn find_python() -> String {
#[cfg(not(windows))]
fn find_python() -> String {
if Command::new("python2.7").arg("--version").output().unwrap().status.success() {
if Command::new("python2.7")
.arg("--version")
.output()
.unwrap()
.status
.success()
{
"python2.7"
} else {
"python"
}.to_owned()
}
.to_owned()
}

View file

@ -4,14 +4,14 @@
use properties::{parse, parse_input};
use style::computed_values::display::T as Display;
use style::properties::{PropertyDeclaration, Importance};
use style::properties::declaration_block::PropertyDeclarationBlock;
use style::properties::parse_property_declaration_list;
use style::values::RGBA;
use style::values::specified::{BorderStyle, BorderSideWidth, Color};
use style::values::specified::{Length, LengthPercentage, LengthPercentageOrAuto};
use style::values::specified::NoCalcLength;
use style::properties::{Importance, PropertyDeclaration};
use style::values::specified::url::SpecifiedUrl;
use style::values::specified::NoCalcLength;
use style::values::specified::{BorderSideWidth, BorderStyle, Color};
use style::values::specified::{Length, LengthPercentage, LengthPercentageOrAuto};
use style::values::RGBA;
use style_traits::ToCss;
use stylesheets::block_from;
@ -32,28 +32,34 @@ fn property_declaration_block_should_serialize_correctly() {
use style::properties::longhands::overflow_x::SpecifiedValue as OverflowValue;
let declarations = vec![
(PropertyDeclaration::Width(
LengthPercentageOrAuto::Length(NoCalcLength::from_px(70f32))),
Importance::Normal),
(PropertyDeclaration::MinHeight(
LengthPercentage::Length(NoCalcLength::from_px(20f32))),
Importance::Normal),
(PropertyDeclaration::Height(
LengthPercentageOrAuto::Length(NoCalcLength::from_px(20f32))),
Importance::Important),
(PropertyDeclaration::Display(Display::InlineBlock),
Importance::Normal),
(PropertyDeclaration::OverflowX(
OverflowValue::Auto),
Importance::Normal),
(PropertyDeclaration::OverflowY(
OverflowValue::Auto),
Importance::Normal),
(
PropertyDeclaration::Width(LengthPercentageOrAuto::Length(NoCalcLength::from_px(
70f32,
))),
Importance::Normal,
),
(
PropertyDeclaration::MinHeight(LengthPercentage::Length(NoCalcLength::from_px(20f32))),
Importance::Normal,
),
(
PropertyDeclaration::Height(LengthPercentageOrAuto::Length(NoCalcLength::from_px(
20f32,
))),
Importance::Important,
),
(
PropertyDeclaration::Display(Display::InlineBlock),
Importance::Normal,
),
(
PropertyDeclaration::OverflowX(OverflowValue::Auto),
Importance::Normal,
),
(
PropertyDeclaration::OverflowY(OverflowValue::Auto),
Importance::Normal,
),
];
let block = block_from(declarations);
@ -147,62 +153,65 @@ mod shorthand_serialization {
#[test]
fn different_longhands_should_serialize_to_long_form() {
let mut properties = Vec::new();
let mut properties = Vec::new();
let solid = BorderStyle::Solid;
let solid = BorderStyle::Solid;
properties.push(PropertyDeclaration::BorderTopStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderRightStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderBottomStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderLeftStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderTopStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderRightStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderBottomStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderLeftStyle(solid.clone()));
let px_30 = BorderSideWidth::Length(Length::from_px(30f32));
let px_10 = BorderSideWidth::Length(Length::from_px(10f32));
let px_30 = BorderSideWidth::Length(Length::from_px(30f32));
let px_10 = BorderSideWidth::Length(Length::from_px(10f32));
properties.push(PropertyDeclaration::BorderTopWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderRightWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderBottomWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderLeftWidth(px_10.clone()));
properties.push(PropertyDeclaration::BorderTopWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderRightWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderBottomWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderLeftWidth(px_10.clone()));
let blue = Color::rgba(RGBA::new(0, 0, 255, 255));
let blue = Color::rgba(RGBA::new(0, 0, 255, 255));
properties.push(PropertyDeclaration::BorderTopColor(blue.clone()));
properties.push(PropertyDeclaration::BorderRightColor(blue.clone()));
properties.push(PropertyDeclaration::BorderBottomColor(blue.clone()));
properties.push(PropertyDeclaration::BorderLeftColor(blue.clone()));
properties.push(PropertyDeclaration::BorderTopColor(blue.clone()));
properties.push(PropertyDeclaration::BorderRightColor(blue.clone()));
properties.push(PropertyDeclaration::BorderBottomColor(blue.clone()));
properties.push(PropertyDeclaration::BorderLeftColor(blue.clone()));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization,
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization,
"border-style: solid; border-width: 30px 30px 30px 10px; border-color: rgb(0, 0, 255);");
}
#[test]
fn same_longhands_should_serialize_correctly() {
let mut properties = Vec::new();
let mut properties = Vec::new();
let solid = BorderStyle::Solid;
let solid = BorderStyle::Solid;
properties.push(PropertyDeclaration::BorderTopStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderRightStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderBottomStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderLeftStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderTopStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderRightStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderBottomStyle(solid.clone()));
properties.push(PropertyDeclaration::BorderLeftStyle(solid.clone()));
let px_30 = BorderSideWidth::Length(Length::from_px(30f32));
let px_30 = BorderSideWidth::Length(Length::from_px(30f32));
properties.push(PropertyDeclaration::BorderTopWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderRightWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderBottomWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderLeftWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderTopWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderRightWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderBottomWidth(px_30.clone()));
properties.push(PropertyDeclaration::BorderLeftWidth(px_30.clone()));
let blue = Color::rgba(RGBA::new(0, 0, 255, 255));
let blue = Color::rgba(RGBA::new(0, 0, 255, 255));
properties.push(PropertyDeclaration::BorderTopColor(blue.clone()));
properties.push(PropertyDeclaration::BorderRightColor(blue.clone()));
properties.push(PropertyDeclaration::BorderBottomColor(blue.clone()));
properties.push(PropertyDeclaration::BorderLeftColor(blue.clone()));
properties.push(PropertyDeclaration::BorderTopColor(blue.clone()));
properties.push(PropertyDeclaration::BorderRightColor(blue.clone()));
properties.push(PropertyDeclaration::BorderBottomColor(blue.clone()));
properties.push(PropertyDeclaration::BorderLeftColor(blue.clone()));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization, "border-style: solid; border-width: 30px; border-color: rgb(0, 0, 255);");
let serialization = shorthand_properties_to_string(properties);
assert_eq!(
serialization,
"border-style: solid; border-width: 30px; border-color: rgb(0, 0, 255);"
);
}
#[test]
@ -274,7 +283,10 @@ mod shorthand_serialization {
let serialization = shorthand_properties_to_string(properties);
// TODO: Make the rgb test show border-color as blue red instead of below tuples
assert_eq!(serialization, "border-color: rgb(0, 0, 255) rgb(255, 0, 0);");
assert_eq!(
serialization,
"border-color: rgb(0, 0, 255) rgb(255, 0, 0);"
);
}
#[test]
@ -297,41 +309,42 @@ mod shorthand_serialization {
#[test]
fn border_radius_should_serialize_correctly() {
let mut properties = Vec::new();
properties.push(PropertyDeclaration::BorderTopLeftRadius(Box::new(BorderCornerRadius::new(
Percentage::new(0.01).into(), Percentage::new(0.05).into()
))));
properties.push(PropertyDeclaration::BorderTopRightRadius(Box::new(BorderCornerRadius::new(
Percentage::new(0.02).into(), Percentage::new(0.06).into()
))));
properties.push(PropertyDeclaration::BorderBottomRightRadius(Box::new(BorderCornerRadius::new(
Percentage::new(0.03).into(), Percentage::new(0.07).into()
))));
properties.push(PropertyDeclaration::BorderBottomLeftRadius(Box::new(BorderCornerRadius::new(
Percentage::new(0.04).into(), Percentage::new(0.08).into()
))));
properties.push(PropertyDeclaration::BorderTopLeftRadius(Box::new(
BorderCornerRadius::new(Percentage::new(0.01).into(), Percentage::new(0.05).into()),
)));
properties.push(PropertyDeclaration::BorderTopRightRadius(Box::new(
BorderCornerRadius::new(Percentage::new(0.02).into(), Percentage::new(0.06).into()),
)));
properties.push(PropertyDeclaration::BorderBottomRightRadius(Box::new(
BorderCornerRadius::new(Percentage::new(0.03).into(), Percentage::new(0.07).into()),
)));
properties.push(PropertyDeclaration::BorderBottomLeftRadius(Box::new(
BorderCornerRadius::new(Percentage::new(0.04).into(), Percentage::new(0.08).into()),
)));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization, "border-radius: 1% 2% 3% 4% / 5% 6% 7% 8%;");
}
}
mod border_shorthands {
use super::*;
#[test]
fn border_top_and_color() {
let mut properties = Vec::new();
properties.push(PropertyDeclaration::BorderTopWidth(BorderSideWidth::Length(Length::from_px(1.))));
properties.push(PropertyDeclaration::BorderTopWidth(
BorderSideWidth::Length(Length::from_px(1.)),
));
properties.push(PropertyDeclaration::BorderTopStyle(BorderStyle::Solid));
let c = Color::Numeric {
parsed: RGBA::new(255, 0, 0, 255),
authored: Some("green".to_string().into_boxed_str())
authored: Some("green".to_string().into_boxed_str()),
};
properties.push(PropertyDeclaration::BorderTopColor(c));
let c = Color::Numeric {
parsed: RGBA::new(0, 255, 0, 255),
authored: Some("red".to_string().into_boxed_str())
authored: Some("red".to_string().into_boxed_str()),
};
properties.push(PropertyDeclaration::BorderTopColor(c.clone()));
properties.push(PropertyDeclaration::BorderBottomColor(c.clone()));
@ -339,31 +352,39 @@ mod shorthand_serialization {
properties.push(PropertyDeclaration::BorderRightColor(c.clone()));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization, "border-top: 1px solid red; border-color: red;");
assert_eq!(
serialization,
"border-top: 1px solid red; border-color: red;"
);
}
#[test]
fn border_color_and_top() {
let mut properties = Vec::new();
let c = Color::Numeric {
let c = Color::Numeric {
parsed: RGBA::new(0, 255, 0, 255),
authored: Some("red".to_string().into_boxed_str())
authored: Some("red".to_string().into_boxed_str()),
};
properties.push(PropertyDeclaration::BorderTopColor(c.clone()));
properties.push(PropertyDeclaration::BorderBottomColor(c.clone()));
properties.push(PropertyDeclaration::BorderLeftColor(c.clone()));
properties.push(PropertyDeclaration::BorderRightColor(c.clone()));
properties.push(PropertyDeclaration::BorderTopWidth(BorderSideWidth::Length(Length::from_px(1.))));
properties.push(PropertyDeclaration::BorderTopWidth(
BorderSideWidth::Length(Length::from_px(1.)),
));
properties.push(PropertyDeclaration::BorderTopStyle(BorderStyle::Solid));
let c = Color::Numeric {
parsed: RGBA::new(255, 0, 0, 255),
authored: Some("green".to_string().into_boxed_str())
authored: Some("green".to_string().into_boxed_str()),
};
properties.push(PropertyDeclaration::BorderTopColor(c));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization, "border-color: green red red; border-top: 1px solid green;");
assert_eq!(
serialization,
"border-color: green red red; border-top: 1px solid green;"
);
}
// we can use border-top as a base to test out the different combinations
@ -386,9 +407,11 @@ mod shorthand_serialization {
}
fn get_border_property_values() -> (BorderSideWidth, BorderStyle, Color) {
(BorderSideWidth::Length(Length::from_px(4f32)),
BorderStyle::Solid,
Color::currentcolor())
(
BorderSideWidth::Length(Length::from_px(4f32)),
BorderStyle::Solid,
Color::currentcolor(),
)
}
#[test]
@ -451,7 +474,8 @@ mod shorthand_serialization {
border-left: 4px solid; \
border-image: none;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -475,7 +499,8 @@ mod shorthand_serialization {
background-origin: border-box; \
background-clip: padding-box;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -499,7 +524,8 @@ mod shorthand_serialization {
background-origin: padding-box; \
background-clip: padding-box;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -523,7 +549,8 @@ mod shorthand_serialization {
background-origin: border-box, padding-box; \
background-clip: padding-box, padding-box;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -554,7 +581,8 @@ mod shorthand_serialization {
background-origin: border-box; \
background-clip: padding-box, padding-box;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -568,7 +596,8 @@ mod shorthand_serialization {
let block_text = "\
background-position-x: 30px;\
background-position-y: bottom 20px;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
assert_eq!(serialization, "background-position: left 30px bottom 20px;");
@ -577,7 +606,8 @@ mod shorthand_serialization {
let block_text = "\
background-position-x: center;\
background-position-y: 20px;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
assert_eq!(serialization, "background-position: center 20px;");
}
@ -609,11 +639,15 @@ mod shorthand_serialization {
animation-iteration-count: infinite;\
animation-play-state: paused;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
assert_eq!(serialization, "animation: 1s ease-in 0s infinite normal forwards paused bounce;")
assert_eq!(
serialization,
"animation: 1s ease-in 0s infinite normal forwards paused bounce;"
)
}
#[test]
@ -628,13 +662,16 @@ mod shorthand_serialization {
animation-iteration-count: infinite, 2;\
animation-play-state: paused, running;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
assert_eq!(serialization,
"animation: 1s ease-in 0s infinite normal forwards paused bounce, \
0.2s linear 1s 2 reverse backwards running roll;");
assert_eq!(
serialization,
"animation: 1s ease-in 0s infinite normal forwards paused bounce, \
0.2s linear 1s 2 reverse backwards running roll;"
);
}
#[test]
@ -654,7 +691,8 @@ mod shorthand_serialization {
animation-iteration-count: infinite, 2; \
animation-play-state: paused, running;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -671,7 +709,8 @@ mod shorthand_serialization {
animation-iteration-count: infinite, 2; \
animation-play-state: paused, running;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
@ -684,7 +723,8 @@ mod shorthand_serialization {
#[test]
fn css_wide_keywords_should_be_parsed() {
let block_text = "--a:inherit;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
assert_eq!(serialization, "--a: inherit;");
@ -693,7 +733,8 @@ mod shorthand_serialization {
#[test]
fn non_keyword_custom_property_should_be_unparsed() {
let block_text = "--main-color: #06c;";
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let block =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string();
assert_eq!(serialization, block_text);
@ -723,7 +764,8 @@ mod shorthand_serialization {
let shadow_decl = BoxShadowList(vec![shadow_val]);
properties.push(PropertyDeclaration::BoxShadow(shadow_decl));
let shadow_css = "box-shadow: 1px 2px 3px 4px;";
let shadow = parse(|c, i| Ok(parse_property_declaration_list(c, i)), shadow_css).unwrap();
let shadow =
parse(|c, i| Ok(parse_property_declaration_list(c, i)), shadow_css).unwrap();
assert_eq!(shadow.to_css_string(), shadow_css);
}

View file

@ -7,22 +7,25 @@ use rayon;
use servo_arc::Arc;
use servo_url::ServoUrl;
use style::context::QuirksMode;
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
use style::error_reporting::{ContextualParseError, ParseErrorReporter};
use style::media_queries::MediaList;
use style::properties::{longhands, Importance, PropertyDeclaration, PropertyDeclarationBlock};
use style::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
use style::shared_lock::SharedRwLock;
use style::stylesheets::{Origin, Stylesheet, CssRule};
use style::stylesheets::{CssRule, Origin, Stylesheet};
use style::thread_state::{self, ThreadState};
use test::{self, Bencher};
struct ErrorringErrorReporter;
impl ParseErrorReporter for ErrorringErrorReporter {
fn report_error(&self,
url: &ServoUrl,
location: SourceLocation,
error: ContextualParseError) {
panic!("CSS error: {}\t\n{}:{} {}", url.as_str(), location.line, location.column, error);
fn report_error(&self, url: &ServoUrl, location: SourceLocation, error: ContextualParseError) {
panic!(
"CSS error: {}\t\n{}:{} {}",
url.as_str(),
location.line,
location.column,
error
);
}
}
@ -38,9 +41,10 @@ impl<'a> Drop for AutoGCRuleTree<'a> {
fn drop(&mut self) {
unsafe {
self.0.gc();
assert!(::std::thread::panicking() ||
!self.0.root().has_children_for_testing(),
"No rule nodes other than the root shall remain!");
assert!(
::std::thread::panicking() || !self.0.root().has_children_for_testing(),
"No rule nodes other than the root shall remain!"
);
}
}
}
@ -49,41 +53,51 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
let s = Stylesheet::from_str(css,
ServoUrl::parse("http://localhost").unwrap(),
Origin::Author,
media,
lock,
None,
Some(&ErrorringErrorReporter),
QuirksMode::NoQuirks,
0);
let s = Stylesheet::from_str(
css,
ServoUrl::parse("http://localhost").unwrap(),
Origin::Author,
media,
lock,
None,
Some(&ErrorringErrorReporter),
QuirksMode::NoQuirks,
0,
);
let guard = s.shared_lock.read();
let rules = s.contents.rules.read_with(&guard);
rules.0.iter().filter_map(|rule| {
match *rule {
rules
.0
.iter()
.filter_map(|rule| match *rule {
CssRule::Style(ref style_rule) => Some((
StyleSource::from_rule(style_rule.clone()),
CascadeLevel::UserNormal,
)),
_ => None,
}
}).collect()
})
.collect()
}
fn test_insertion(rule_tree: &RuleTree, rules: Vec<(StyleSource, CascadeLevel)>) -> StrongRuleNode {
rule_tree.insert_ordered_rules(rules.into_iter())
}
fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, CascadeLevel)],
shared_lock: &SharedRwLock)
-> StrongRuleNode {
fn test_insertion_style_attribute(
rule_tree: &RuleTree,
rules: &[(StyleSource, CascadeLevel)],
shared_lock: &SharedRwLock,
) -> StrongRuleNode {
let mut rules = rules.to_vec();
rules.push((StyleSource::from_declarations(Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
PropertyDeclaration::Display(
longhands::display::SpecifiedValue::Block),
Importance::Normal
)))), CascadeLevel::UserNormal));
rules.push((
StyleSource::from_declarations(Arc::new(shared_lock.wrap(
PropertyDeclarationBlock::with_one(
PropertyDeclaration::Display(longhands::display::SpecifiedValue::Block),
Importance::Normal,
),
))),
CascadeLevel::UserNormal,
));
test_insertion(rule_tree, rules)
}
@ -95,7 +109,8 @@ fn bench_insertion_basic(b: &mut Bencher) {
let rules_matched = parse_rules(
".foo { width: 200px; } \
.bar { height: 500px; } \
.baz { display: block; }");
.baz { display: block; }",
);
b.iter(|| {
let _gc = AutoGCRuleTree::new(&r);
@ -114,7 +129,8 @@ fn bench_insertion_basic_per_element(b: &mut Bencher) {
let rules_matched = parse_rules(
".foo { width: 200px; } \
.bar { height: 500px; } \
.baz { display: block; }");
.baz { display: block; }",
);
b.iter(|| {
let _gc = AutoGCRuleTree::new(&r);
@ -134,14 +150,19 @@ fn bench_expensive_insertion(b: &mut Bencher) {
let rules_matched = parse_rules(
".foo { width: 200px; } \
.bar { height: 500px; } \
.baz { display: block; }");
.baz { display: block; }",
);
let shared_lock = SharedRwLock::new();
b.iter(|| {
let _gc = AutoGCRuleTree::new(&r);
for _ in 0..(4000 + 400) {
test::black_box(test_insertion_style_attribute(&r, &rules_matched, &shared_lock));
test::black_box(test_insertion_style_attribute(
&r,
&rules_matched,
&shared_lock,
));
}
});
}
@ -154,7 +175,8 @@ fn bench_insertion_basic_parallel(b: &mut Bencher) {
let rules_matched = parse_rules(
".foo { width: 200px; } \
.bar { height: 500px; } \
.baz { display: block; }");
.baz { display: block; }",
);
b.iter(|| {
let _gc = AutoGCRuleTree::new(&r);
@ -163,13 +185,11 @@ fn bench_insertion_basic_parallel(b: &mut Bencher) {
for _ in 0..4 {
s.spawn(|s| {
for _ in 0..1000 {
test::black_box(test_insertion(&r,
rules_matched.clone()));
test::black_box(test_insertion(&r, rules_matched.clone()));
}
s.spawn(|_| {
for _ in 0..100 {
test::black_box(test_insertion(&r,
rules_matched.clone()));
test::black_box(test_insertion(&r, rules_matched.clone()));
}
})
})
@ -186,7 +206,8 @@ fn bench_expensive_insertion_parallel(b: &mut Bencher) {
let rules_matched = parse_rules(
".foo { width: 200px; } \
.bar { height: 500px; } \
.baz { display: block; }");
.baz { display: block; }",
);
let shared_lock = SharedRwLock::new();
b.iter(|| {
@ -196,15 +217,19 @@ fn bench_expensive_insertion_parallel(b: &mut Bencher) {
for _ in 0..4 {
s.spawn(|s| {
for _ in 0..1000 {
test::black_box(test_insertion_style_attribute(&r,
&rules_matched,
&shared_lock));
test::black_box(test_insertion_style_attribute(
&r,
&rules_matched,
&shared_lock,
));
}
s.spawn(|_| {
for _ in 0..100 {
test::black_box(test_insertion_style_attribute(&r,
&rules_matched,
&shared_lock));
test::black_box(test_insertion_style_attribute(
&r,
&rules_matched,
&shared_lock,
));
}
})
})

View file

@ -8,16 +8,44 @@ use style::properties;
size_of_test!(test_size_of_dependency, Dependency, 16);
size_of_test!(test_size_of_property_declaration, properties::PropertyDeclaration, 32);
size_of_test!(
test_size_of_property_declaration,
properties::PropertyDeclaration,
32
);
// This is huge, but we allocate it on the stack and then never move it,
// we only pass `&mut SourcePropertyDeclaration` references around.
size_of_test!(test_size_of_parsed_declaration, properties::SourcePropertyDeclaration, 568);
size_of_test!(
test_size_of_parsed_declaration,
properties::SourcePropertyDeclaration,
568
);
size_of_test!(test_size_of_selector_parse_error_kind, SelectorParseErrorKind, 40);
size_of_test!(test_size_of_style_parse_error_kind, ::style_traits::StyleParseErrorKind, 56);
size_of_test!(test_size_of_value_parse_error_kind, ::style_traits::ValueParseErrorKind, 40);
size_of_test!(
test_size_of_selector_parse_error_kind,
SelectorParseErrorKind,
40
);
size_of_test!(
test_size_of_style_parse_error_kind,
::style_traits::StyleParseErrorKind,
56
);
size_of_test!(
test_size_of_value_parse_error_kind,
::style_traits::ValueParseErrorKind,
40
);
size_of_test!(test_size_of_selector_parse_error, SelectorParseError, 56);
size_of_test!(test_size_of_style_traits_parse_error, ::style_traits::ParseError, 72);
size_of_test!(test_size_of_value_parse_error, ::style_traits::ValueParseError, 56);
size_of_test!(
test_size_of_style_traits_parse_error,
::style_traits::ParseError,
72
);
size_of_test!(
test_size_of_value_parse_error,
::style_traits::ValueParseError,
56
);

View file

@ -2,12 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use style::str::{split_html_space_chars, str_join, starts_with_ignore_ascii_case};
use style::str::{split_html_space_chars, starts_with_ignore_ascii_case, str_join};
#[test]
pub fn split_html_space_chars_whitespace() {
assert!(split_html_space_chars("").collect::<Vec<_>>().is_empty());
assert!(split_html_space_chars("\u{0020}\u{0009}\u{000a}\u{000c}\u{000d}").collect::<Vec<_>>().is_empty());
assert!(
split_html_space_chars("\u{0020}\u{0009}\u{000a}\u{000c}\u{000d}")
.collect::<Vec<_>>()
.is_empty()
);
}
#[test]

View file

@ -3,35 +3,39 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use cssparser::{self, SourceLocation};
use html5ever::{Namespace as NsAtom};
use html5ever::Namespace as NsAtom;
use parking_lot::RwLock;
use selectors::attr::*;
use selectors::parser::*;
use servo_arc::Arc;
use servo_atoms::Atom;
use servo_config::prefs::{PREFS, PrefValue};
use servo_config::prefs::{PrefValue, PREFS};
use servo_url::ServoUrl;
use std::borrow::ToOwned;
use std::cell::RefCell;
use std::sync::atomic::AtomicBool;
use style::context::QuirksMode;
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
use style::error_reporting::{ContextualParseError, ParseErrorReporter};
use style::media_queries::MediaList;
use style::properties::longhands::{self, animation_timing_function};
use style::properties::{CSSWideKeyword, CustomDeclaration};
use style::properties::{CustomDeclarationValue, Importance};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::properties::longhands::{self, animation_timing_function};
use style::shared_lock::SharedRwLock;
use style::stylesheets::{Origin, Namespaces};
use style::stylesheets::{Stylesheet, StylesheetContents, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule};
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframePercentage};
use style::values::{KeyframesName, CustomIdent};
use style::stylesheets::keyframes_rule::{Keyframe, KeyframePercentage, KeyframeSelector};
use style::stylesheets::{
CssRule, CssRules, KeyframesRule, NamespaceRule, StyleRule, Stylesheet, StylesheetContents,
};
use style::stylesheets::{Namespaces, Origin};
use style::values::computed::Percentage;
use style::values::specified::{LengthPercentageOrAuto, PositionComponent};
use style::values::specified::TimingFunction;
use style::values::specified::{LengthPercentageOrAuto, PositionComponent};
use style::values::{CustomIdent, KeyframesName};
pub fn block_from<I>(iterable: I) -> PropertyDeclarationBlock
where I: IntoIterator<Item=(PropertyDeclaration, Importance)> {
where
I: IntoIterator<Item = (PropertyDeclaration, Importance)>,
{
let mut block = PropertyDeclarationBlock::new();
for (d, i) in iterable {
block.push(d, i);
@ -69,8 +73,17 @@ fn test_parse_stylesheet() {
let url = ServoUrl::parse("about::test").unwrap();
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
None, None, QuirksMode::NoQuirks, 0);
let stylesheet = Stylesheet::from_str(
css,
url.clone(),
Origin::UserAgent,
media,
lock,
None,
None,
QuirksMode::NoQuirks,
0,
);
let mut namespaces = Namespaces::default();
namespaces.default = Some(ns!(html));
let expected = Stylesheet {
@ -79,180 +92,245 @@ fn test_parse_stylesheet() {
namespaces: RwLock::new(namespaces),
url_data: RwLock::new(url),
quirks_mode: QuirksMode::NoQuirks,
rules: CssRules::new(vec![
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml"),
source_location: SourceLocation {
line: 1,
column: 19,
},
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec!(
Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::LocalName(LocalName {
name: local_name!("input"),
lower_name: local_name!("input"),
}),
Component::AttributeInNoNamespace {
local_name: local_name!("type"),
operator: AttrSelectorOperator::Equal,
value: "hidden".to_owned(),
case_sensitivity: ParsedCaseSensitivity::AsciiCaseInsensitive,
never_matches: false,
}
), (0 << 20) + (1 << 10) + (1 << 0))
)),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(
PropertyDeclaration::Display(longhands::display::SpecifiedValue::None),
Importance::Important,
),
(
PropertyDeclaration::Custom(CustomDeclaration {
name: Atom::from("a"),
value: CustomDeclarationValue::CSSWideKeyword(CSSWideKeyword::Inherit),
}),
Importance::Important,
),
]))),
source_location: SourceLocation {
line: 3,
column: 9,
},
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec!(
Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
rules: CssRules::new(
vec![
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml"),
source_location: SourceLocation {
line: 1,
column: 19,
},
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec![Selector::from_vec(
vec![
Component::DefaultNamespace(NsAtom::from(
"http://www.w3.org/1999/xhtml",
)),
Component::LocalName(LocalName {
name: local_name!("html"),
lower_name: local_name!("html"),
name: local_name!("input"),
lower_name: local_name!("input"),
}),
), (0 << 20) + (0 << 10) + (1 << 0)),
Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::LocalName(LocalName {
name: local_name!("body"),
lower_name: local_name!("body"),
})
), (0 << 20) + (0 << 10) + (1 << 0)
),
)),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::Block),
Importance::Normal),
]))),
source_location: SourceLocation {
line: 11,
column: 9,
},
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec!(
Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::ID(Atom::from("d1")),
Component::Combinator(Combinator::Child),
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::Class(Atom::from("ok"))
), (1 << 20) + (1 << 10) + (0 << 0))
)),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::BackgroundColor(
longhands::background_color::SpecifiedValue::Numeric {
authored: Some("blue".to_owned().into_boxed_str()),
parsed: cssparser::RGBA::new(0, 0, 255, 255),
}
),
Importance::Normal),
(PropertyDeclaration::BackgroundPositionX(
longhands::background_position_x::SpecifiedValue(
vec![PositionComponent::zero()])),
Importance::Normal),
(PropertyDeclaration::BackgroundPositionY(
longhands::background_position_y::SpecifiedValue(
vec![PositionComponent::zero()])),
Importance::Normal),
(PropertyDeclaration::BackgroundRepeat(
longhands::background_repeat::SpecifiedValue(
vec![longhands::background_repeat::single_value
::get_initial_specified_value()])),
Importance::Normal),
(PropertyDeclaration::BackgroundAttachment(
longhands::background_attachment::SpecifiedValue(
vec![longhands::background_attachment::single_value
::get_initial_specified_value()])),
Importance::Normal),
(PropertyDeclaration::BackgroundImage(
longhands::background_image::SpecifiedValue(
vec![longhands::background_image::single_value
::get_initial_specified_value()])),
Importance::Normal),
(PropertyDeclaration::BackgroundSize(
longhands::background_size::SpecifiedValue(
vec![longhands::background_size::single_value
::get_initial_specified_value()])),
Importance::Normal),
(PropertyDeclaration::BackgroundOrigin(
longhands::background_origin::SpecifiedValue(
vec![longhands::background_origin::single_value
::get_initial_specified_value()])),
Importance::Normal),
(PropertyDeclaration::BackgroundClip(
longhands::background_clip::SpecifiedValue(
vec![longhands::background_clip::single_value
::get_initial_specified_value()])),
Importance::Normal),
]))),
source_location: SourceLocation {
line: 15,
column: 9,
},
}))),
CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule {
name: KeyframesName::Ident(CustomIdent("foo".into())),
keyframes: vec![
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(
vec![KeyframePercentage::new(0.)]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Width(
LengthPercentageOrAuto::Percentage(Percentage(0.))),
Importance::Normal),
]))),
source_location: SourceLocation {
line: 17,
column: 13,
},
})),
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(
vec![KeyframePercentage::new(1.)]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Width(
LengthPercentageOrAuto::Percentage(Percentage(1.))),
Importance::Normal),
(PropertyDeclaration::AnimationTimingFunction(
animation_timing_function::SpecifiedValue(
vec![TimingFunction::ease()])),
Importance::Normal),
]))),
source_location: SourceLocation {
line: 18,
column: 13,
},
})),
],
vendor_prefix: None,
source_location: SourceLocation {
line: 16,
column: 19,
},
})))
], &stylesheet.shared_lock),
Component::AttributeInNoNamespace {
local_name: local_name!("type"),
operator: AttrSelectorOperator::Equal,
value: "hidden".to_owned(),
case_sensitivity: ParsedCaseSensitivity::AsciiCaseInsensitive,
never_matches: false,
},
],
(0 << 20) + (1 << 10) + (1 << 0),
)]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(
PropertyDeclaration::Display(
longhands::display::SpecifiedValue::None,
),
Importance::Important,
),
(
PropertyDeclaration::Custom(CustomDeclaration {
name: Atom::from("a"),
value: CustomDeclarationValue::CSSWideKeyword(
CSSWideKeyword::Inherit,
),
}),
Importance::Important,
),
]))),
source_location: SourceLocation { line: 3, column: 9 },
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec![
Selector::from_vec(
vec![
Component::DefaultNamespace(NsAtom::from(
"http://www.w3.org/1999/xhtml",
)),
Component::LocalName(LocalName {
name: local_name!("html"),
lower_name: local_name!("html"),
}),
],
(0 << 20) + (0 << 10) + (1 << 0),
),
Selector::from_vec(
vec![
Component::DefaultNamespace(NsAtom::from(
"http://www.w3.org/1999/xhtml",
)),
Component::LocalName(LocalName {
name: local_name!("body"),
lower_name: local_name!("body"),
}),
],
(0 << 20) + (0 << 10) + (1 << 0),
),
]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![(
PropertyDeclaration::Display(longhands::display::SpecifiedValue::Block),
Importance::Normal,
)]))),
source_location: SourceLocation {
line: 11,
column: 9,
},
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec![Selector::from_vec(
vec![
Component::DefaultNamespace(NsAtom::from(
"http://www.w3.org/1999/xhtml",
)),
Component::ID(Atom::from("d1")),
Component::Combinator(Combinator::Child),
Component::DefaultNamespace(NsAtom::from(
"http://www.w3.org/1999/xhtml",
)),
Component::Class(Atom::from("ok")),
],
(1 << 20) + (1 << 10) + (0 << 0),
)]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(
PropertyDeclaration::BackgroundColor(
longhands::background_color::SpecifiedValue::Numeric {
authored: Some("blue".to_owned().into_boxed_str()),
parsed: cssparser::RGBA::new(0, 0, 255, 255),
},
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundPositionX(
longhands::background_position_x::SpecifiedValue(vec![
PositionComponent::zero(),
]),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundPositionY(
longhands::background_position_y::SpecifiedValue(vec![
PositionComponent::zero(),
]),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundRepeat(
longhands::background_repeat::SpecifiedValue(
vec![longhands::background_repeat::single_value
::get_initial_specified_value()],
),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundAttachment(
longhands::background_attachment::SpecifiedValue(
vec![longhands::background_attachment::single_value
::get_initial_specified_value()],
),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundImage(
longhands::background_image::SpecifiedValue(
vec![longhands::background_image::single_value
::get_initial_specified_value()],
),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundSize(
longhands::background_size::SpecifiedValue(
vec![longhands::background_size::single_value
::get_initial_specified_value()],
),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundOrigin(
longhands::background_origin::SpecifiedValue(
vec![longhands::background_origin::single_value
::get_initial_specified_value()],
),
),
Importance::Normal,
),
(
PropertyDeclaration::BackgroundClip(
longhands::background_clip::SpecifiedValue(
vec![longhands::background_clip::single_value
::get_initial_specified_value()],
),
),
Importance::Normal,
),
]))),
source_location: SourceLocation {
line: 15,
column: 9,
},
}))),
CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule {
name: KeyframesName::Ident(CustomIdent("foo".into())),
keyframes: vec![
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![
KeyframePercentage::new(0.),
]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![(
PropertyDeclaration::Width(LengthPercentageOrAuto::Percentage(
Percentage(0.),
)),
Importance::Normal,
)]))),
source_location: SourceLocation {
line: 17,
column: 13,
},
})),
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![
KeyframePercentage::new(1.),
]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(
PropertyDeclaration::Width(
LengthPercentageOrAuto::Percentage(Percentage(1.)),
),
Importance::Normal,
),
(
PropertyDeclaration::AnimationTimingFunction(
animation_timing_function::SpecifiedValue(vec![
TimingFunction::ease(),
]),
),
Importance::Normal,
),
]))),
source_location: SourceLocation {
line: 18,
column: 13,
},
})),
],
vendor_prefix: None,
source_location: SourceLocation {
line: 16,
column: 19,
},
}))),
],
&stylesheet.shared_lock,
),
source_map_url: RwLock::new(None),
source_url: RwLock::new(None),
},
@ -266,10 +344,10 @@ fn test_parse_stylesheet() {
#[derive(Debug)]
struct CSSError {
pub url : ServoUrl,
pub url: ServoUrl,
pub line: u32,
pub column: u32,
pub message: String
pub message: String,
}
struct TestingErrorReporter {
@ -285,11 +363,21 @@ impl TestingErrorReporter {
fn assert_messages_contain(&self, expected_errors: &[(u32, u32, &str)]) {
let errors = self.errors.borrow();
for (i, (error, &(line, column, message))) in errors.iter().zip(expected_errors).enumerate() {
assert_eq!((error.line, error.column), (line, column),
"line/column numbers of the {}th error: {:?}", i + 1, error.message);
assert!(error.message.contains(message),
"{:?} does not contain {:?}", error.message, message);
for (i, (error, &(line, column, message))) in errors.iter().zip(expected_errors).enumerate()
{
assert_eq!(
(error.line, error.column),
(line, column),
"line/column numbers of the {}th error: {:?}",
i + 1,
error.message
);
assert!(
error.message.contains(message),
"{:?} does not contain {:?}",
error.message,
message
);
}
if errors.len() < expected_errors.len() {
panic!("Missing errors: {:#?}", &expected_errors[errors.len()..]);
@ -301,22 +389,16 @@ impl TestingErrorReporter {
}
impl ParseErrorReporter for TestingErrorReporter {
fn report_error(&self,
url: &ServoUrl,
location: SourceLocation,
error: ContextualParseError) {
self.errors.borrow_mut().push(
CSSError{
url: url.clone(),
line: location.line,
column: location.column,
message: error.to_string(),
}
)
fn report_error(&self, url: &ServoUrl, location: SourceLocation, error: ContextualParseError) {
self.errors.borrow_mut().push(CSSError {
url: url.clone(),
line: location.line,
column: location.column,
message: error.to_string(),
})
}
}
#[test]
fn test_report_error_stylesheet() {
PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true));
@ -342,29 +424,50 @@ fn test_report_error_stylesheet() {
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
None, Some(&error_reporter), QuirksMode::NoQuirks, 5);
Stylesheet::from_str(
css,
url.clone(),
Origin::UserAgent,
media,
lock,
None,
Some(&error_reporter),
QuirksMode::NoQuirks,
5,
);
error_reporter.assert_messages_contain(&[
(8, 18, "Unsupported property declaration: 'display: invalid;'"),
(9, 27, "Unsupported property declaration: 'background-image:"), // FIXME: column should be around 56
(
8,
18,
"Unsupported property declaration: 'display: invalid;'",
),
(
9,
27,
"Unsupported property declaration: 'background-image:",
), // FIXME: column should be around 56
(10, 17, "Unsupported property declaration: 'invalid: true;'"),
(12, 28, "Invalid media rule"),
(13, 30, "Unsupported @font-face descriptor declaration"),
// When @counter-style is supported, this should be replaced with two errors
(14, 19, "Invalid rule: '@counter-style "),
// When @font-feature-values is supported, this should be replaced with two errors
(15, 25, "Invalid rule: '@font-feature-values "),
(16, 13, "Invalid rule: '@invalid'"),
(17, 29, "Invalid rule: '@invalid'"),
(18, 34, "Invalid rule: '@supports "),
(19, 26, "Invalid keyframe rule: 'from invalid '"),
(19, 52, "Unsupported keyframe property declaration: 'margin: 0 invalid 0;'"),
(20, 29, "Unsupported @viewport descriptor declaration: 'width: 320px invalid auto;'"),
(
19,
52,
"Unsupported keyframe property declaration: 'margin: 0 invalid 0;'",
),
(
20,
29,
"Unsupported @viewport descriptor declaration: 'width: 320px invalid auto;'",
),
]);
assert_eq!(error_reporter.errors.borrow()[0].url, url);
@ -384,28 +487,50 @@ fn test_no_report_unrecognized_vendor_properties() {
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
Stylesheet::from_str(css, url, Origin::UserAgent, media, lock,
None, Some(&error_reporter), QuirksMode::NoQuirks, 0);
Stylesheet::from_str(
css,
url,
Origin::UserAgent,
media,
lock,
None,
Some(&error_reporter),
QuirksMode::NoQuirks,
0,
);
error_reporter.assert_messages_contain(&[
(4, 31, "Unsupported property declaration: '-moz-background-color: red;'"),
]);
error_reporter.assert_messages_contain(&[(
4,
31,
"Unsupported property declaration: '-moz-background-color: red;'",
)]);
}
#[test]
fn test_source_map_url() {
let tests = vec![
("", None),
("/*# sourceMappingURL=something */", Some("something".to_string())),
(
"/*# sourceMappingURL=something */",
Some("something".to_string()),
),
];
for test in tests {
let url = ServoUrl::parse("about::test").unwrap();
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock,
None, None, QuirksMode::NoQuirks,
0);
let stylesheet = Stylesheet::from_str(
test.0,
url.clone(),
Origin::UserAgent,
media,
lock,
None,
None,
QuirksMode::NoQuirks,
0,
);
let url_opt = stylesheet.contents.source_map_url.read();
assert_eq!(*url_opt, test.1);
}
@ -422,9 +547,17 @@ fn test_source_url() {
let url = ServoUrl::parse("about::test").unwrap();
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock,
None, None, QuirksMode::NoQuirks,
0);
let stylesheet = Stylesheet::from_str(
test.0,
url.clone(),
Origin::UserAgent,
media,
lock,
None,
None,
QuirksMode::NoQuirks,
0,
);
let url_opt = stylesheet.contents.source_url.read();
assert_eq!(*url_opt, test.1);
}

View file

@ -10,51 +10,69 @@ use servo_arc::Arc;
use servo_atoms::Atom;
use style::context::QuirksMode;
use style::media_queries::{Device, MediaType};
use style::properties::{PropertyDeclarationBlock, PropertyDeclaration};
use style::properties::{longhands, Importance};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::selector_map::SelectorMap;
use style::selector_parser::{SelectorImpl, SelectorParser};
use style::shared_lock::SharedRwLock;
use style::stylesheets::StyleRule;
use style::stylist::{Stylist, Rule};
use style::stylist::needs_revalidation_for_testing;
use style::stylist::{Rule, Stylist};
use style::thread_state::{self, ThreadState};
/// Helper method to get some Rules from selector strings.
/// Each sublist of the result contains the Rules for one StyleRule.
fn get_mock_rules(css_selectors: &[&str]) -> (Vec<Vec<Rule>>, SharedRwLock) {
let shared_lock = SharedRwLock::new();
(css_selectors.iter().enumerate().map(|(i, selectors)| {
let selectors = SelectorParser::parse_author_origin_no_namespace(selectors).unwrap();
(
css_selectors
.iter()
.enumerate()
.map(|(i, selectors)| {
let selectors =
SelectorParser::parse_author_origin_no_namespace(selectors).unwrap();
let locked = Arc::new(shared_lock.wrap(StyleRule {
selectors: selectors,
block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
PropertyDeclaration::Display(
longhands::display::SpecifiedValue::Block),
Importance::Normal
))),
source_location: SourceLocation {
line: 0,
column: 0,
},
}));
let locked = Arc::new(shared_lock.wrap(StyleRule {
selectors: selectors,
block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one(
PropertyDeclaration::Display(longhands::display::SpecifiedValue::Block),
Importance::Normal,
))),
source_location: SourceLocation { line: 0, column: 0 },
}));
let guard = shared_lock.read();
let rule = locked.read_with(&guard);
rule.selectors.0.iter().map(|s| {
Rule::new(s.clone(), AncestorHashes::new(s, QuirksMode::NoQuirks), locked.clone(), i as u32)
}).collect()
}).collect(), shared_lock)
let guard = shared_lock.read();
let rule = locked.read_with(&guard);
rule.selectors
.0
.iter()
.map(|s| {
Rule::new(
s.clone(),
AncestorHashes::new(s, QuirksMode::NoQuirks),
locked.clone(),
i as u32,
)
})
.collect()
})
.collect(),
shared_lock,
)
}
fn parse_selectors(selectors: &[&str]) -> Vec<Selector<SelectorImpl>> {
selectors.iter()
.map(|x| SelectorParser::parse_author_origin_no_namespace(x).unwrap().0
.into_iter()
.nth(0)
.unwrap())
.collect()
selectors
.iter()
.map(|x| {
SelectorParser::parse_author_origin_no_namespace(x)
.unwrap()
.0
.into_iter()
.nth(0)
.unwrap()
})
.collect()
}
#[test]
@ -65,14 +83,13 @@ fn test_revalidation_selectors() {
"div:not(.foo)",
"div span",
"div > span",
// ID selectors.
"#foo1",
"#foo2::before",
"#foo3 > span",
"#foo1 > span", // FIXME(bz): This one should not be a
// revalidation selector, since #foo1 should be in the
// rule hash.
// revalidation selector, since #foo1 should be in the
// rule hash.
// Attribute selectors.
"div[foo]",
@ -84,7 +101,6 @@ fn test_revalidation_selectors() {
"div[foo $= \"bar\"]",
"div[foo *= \"bar\"]",
"*|div[foo][bar = \"baz\"]",
// Non-state-based pseudo-classes.
"div:empty",
"div:first-child",
@ -97,7 +113,6 @@ fn test_revalidation_selectors() {
"div:first-of-type",
"div:last-of-type",
"div:only-of-type",
// Note: it would be nice to test :moz-any and the various other non-TS
// pseudo classes supported by gecko, but we don't have access to those
// in these unit tests. :-(
@ -105,18 +120,17 @@ fn test_revalidation_selectors() {
// Sibling combinators.
"span + div",
"span ~ div",
// Selectors in the ancestor chain (needed for cousin sharing).
"p:first-child span",
]).into_iter()
.filter(|s| needs_revalidation_for_testing(&s))
.collect::<Vec<_>>();
])
.into_iter()
.filter(|s| needs_revalidation_for_testing(&s))
.collect::<Vec<_>>();
let reference = parse_selectors(&[
// ID selectors.
"#foo3 > span",
"#foo1 > span",
// Attribute selectors.
"div[foo]",
"div:not([foo])",
@ -127,7 +141,6 @@ fn test_revalidation_selectors() {
"div[foo $= \"bar\"]",
"div[foo *= \"bar\"]",
"*|div[foo][bar = \"baz\"]",
// Non-state-based pseudo-classes.
"div:empty",
"div:first-child",
@ -140,15 +153,14 @@ fn test_revalidation_selectors() {
"div:first-of-type",
"div:last-of-type",
"div:only-of-type",
// Sibling combinators.
"span + div",
"span ~ div",
// Selectors in the ancestor chain (needed for cousin sharing).
"p:first-child span",
]).into_iter()
.collect::<Vec<_>>();
])
.into_iter()
.collect::<Vec<_>>();
assert_eq!(test.len(), reference.len());
for (t, r) in test.into_iter().zip(reference.into_iter()) {
@ -161,25 +173,50 @@ fn test_rule_ordering_same_specificity() {
let (rules_list, _) = get_mock_rules(&["a.intro", "img.sidebar"]);
let a = &rules_list[0][0];
let b = &rules_list[1][0];
assert!((a.specificity(), a.source_order) < ((b.specificity(), b.source_order)),
"The rule that comes later should win.");
assert!(
(a.specificity(), a.source_order) < ((b.specificity(), b.source_order)),
"The rule that comes later should win."
);
}
#[test]
fn test_insert() {
let (rules_list, _) = get_mock_rules(&[".intro.foo", "#top"]);
let mut selector_map = SelectorMap::new();
selector_map.insert(rules_list[1][0].clone(), QuirksMode::NoQuirks)
.expect("OOM");
assert_eq!(1, selector_map.id_hash.get(&Atom::from("top"), QuirksMode::NoQuirks).unwrap()[0].source_order);
selector_map.insert(rules_list[0][0].clone(), QuirksMode::NoQuirks)
.expect("OOM");
assert_eq!(0, selector_map.class_hash.get(&Atom::from("foo"), QuirksMode::NoQuirks).unwrap()[0].source_order);
assert!(selector_map.class_hash.get(&Atom::from("intro"), QuirksMode::NoQuirks).is_none());
selector_map
.insert(rules_list[1][0].clone(), QuirksMode::NoQuirks)
.expect("OOM");
assert_eq!(
1,
selector_map
.id_hash
.get(&Atom::from("top"), QuirksMode::NoQuirks)
.unwrap()[0]
.source_order
);
selector_map
.insert(rules_list[0][0].clone(), QuirksMode::NoQuirks)
.expect("OOM");
assert_eq!(
0,
selector_map
.class_hash
.get(&Atom::from("foo"), QuirksMode::NoQuirks)
.unwrap()[0]
.source_order
);
assert!(selector_map
.class_hash
.get(&Atom::from("intro"), QuirksMode::NoQuirks)
.is_none());
}
fn mock_stylist() -> Stylist {
let device = Device::new(MediaType::screen(), Size2D::new(0f32, 0f32), Scale::new(1.0));
let device = Device::new(
MediaType::screen(),
Size2D::new(0f32, 0f32),
Scale::new(1.0),
);
Stylist::new(device, QuirksMode::NoQuirks)
}