Auto merge of #22466 - emilio:gecko-sync, r=emilio

style: Sync changes from mozilla-central.

See each individual commit for details.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22466)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-12-16 07:35:48 -05:00 committed by GitHub
commit ee48b679d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 246 additions and 2145 deletions

View file

@ -436,126 +436,89 @@ where
}
}
impl<T, S> MallocShallowSizeOf for std::collections::HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
if ops.has_malloc_enclosing_size_of() {
// The first value from the iterator gives us an interior pointer.
// `ops.malloc_enclosing_size_of()` then gives us the storage size.
// This assumes that the `HashSet`'s contents (values and hashes)
// are all stored in a single contiguous heap allocation.
self.iter()
.next()
.map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) })
} else {
// An estimate.
self.capacity() * (size_of::<T>() + size_of::<usize>())
macro_rules! malloc_size_of_hash_set {
($ty:ty) => {
impl<T, S> MallocShallowSizeOf for $ty
where
T: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
if ops.has_malloc_enclosing_size_of() {
// The first value from the iterator gives us an interior pointer.
// `ops.malloc_enclosing_size_of()` then gives us the storage size.
// This assumes that the `HashSet`'s contents (values and hashes)
// are all stored in a single contiguous heap allocation.
self.iter()
.next()
.map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) })
} else {
// An estimate.
self.capacity() * (size_of::<T>() + size_of::<usize>())
}
}
}
}
}
impl<T, S> MallocSizeOf for std::collections::HashSet<T, S>
where
T: Eq + Hash + MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for t in self.iter() {
n += t.size_of(ops);
impl<T, S> MallocSizeOf for $ty
where
T: Eq + Hash + MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for t in self.iter() {
n += t.size_of(ops);
}
n
}
}
n
}
};
}
impl<T, S> MallocShallowSizeOf for hashglobe::hash_set::HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
// See the implementation for std::collections::HashSet for details.
if ops.has_malloc_enclosing_size_of() {
self.iter()
.next()
.map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) })
} else {
self.capacity() * (size_of::<T>() + size_of::<usize>())
malloc_size_of_hash_set!(std::collections::HashSet<T, S>);
malloc_size_of_hash_set!(hashglobe::hash_set::HashSet<T, S>);
malloc_size_of_hash_set!(hashglobe::fake::HashSet<T, S>);
macro_rules! malloc_size_of_hash_map {
($ty:ty) => {
impl<K, V, S> MallocShallowSizeOf for $ty
where
K: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
// See the implementation for std::collections::HashSet for details.
if ops.has_malloc_enclosing_size_of() {
self.values()
.next()
.map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
} else {
self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
}
}
}
}
}
impl<T, S> MallocSizeOf for hashglobe::hash_set::HashSet<T, S>
where
T: Eq + Hash + MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for t in self.iter() {
n += t.size_of(ops);
impl<K, V, S> MallocSizeOf for $ty
where
K: Eq + Hash + MallocSizeOf,
V: MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for (k, v) in self.iter() {
n += k.size_of(ops);
n += v.size_of(ops);
}
n
}
}
n
}
};
}
impl<T, S> MallocShallowSizeOf for hashglobe::fake::HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
use std::ops::Deref;
self.deref().shallow_size_of(ops)
}
}
impl<T, S> MallocSizeOf for hashglobe::fake::HashSet<T, S>
where
T: Eq + Hash + MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
use std::ops::Deref;
self.deref().size_of(ops)
}
}
impl<K, V, S> MallocShallowSizeOf for std::collections::HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
// See the implementation for std::collections::HashSet for details.
if ops.has_malloc_enclosing_size_of() {
self.values()
.next()
.map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
} else {
self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
}
}
}
impl<K, V, S> MallocSizeOf for std::collections::HashMap<K, V, S>
where
K: Eq + Hash + MallocSizeOf,
V: MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for (k, v) in self.iter() {
n += k.size_of(ops);
n += v.size_of(ops);
}
n
}
}
malloc_size_of_hash_map!(std::collections::HashMap<K, V, S>);
malloc_size_of_hash_map!(hashglobe::hash_map::HashMap<K, V, S>);
malloc_size_of_hash_map!(hashglobe::fake::HashMap<K, V, S>);
impl<K, V> MallocShallowSizeOf for std::collections::BTreeMap<K, V>
where
@ -587,62 +550,6 @@ where
}
}
impl<K, V, S> MallocShallowSizeOf for hashglobe::hash_map::HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
// See the implementation for std::collections::HashSet for details.
if ops.has_malloc_enclosing_size_of() {
self.values()
.next()
.map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
} else {
self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
}
}
}
impl<K, V, S> MallocSizeOf for hashglobe::hash_map::HashMap<K, V, S>
where
K: Eq + Hash + MallocSizeOf,
V: MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let mut n = self.shallow_size_of(ops);
for (k, v) in self.iter() {
n += k.size_of(ops);
n += v.size_of(ops);
}
n
}
}
impl<K, V, S> MallocShallowSizeOf for hashglobe::fake::HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
use std::ops::Deref;
self.deref().shallow_size_of(ops)
}
}
impl<K, V, S> MallocSizeOf for hashglobe::fake::HashMap<K, V, S>
where
K: Eq + Hash + MallocSizeOf,
V: MallocSizeOf,
S: BuildHasher,
{
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
use std::ops::Deref;
self.deref().size_of(ops)
}
}
// PhantomData is always 0.
impl<T> MallocSizeOf for std::marker::PhantomData<T> {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {

View file

@ -134,8 +134,13 @@ pub static SELECTOR_WHITESPACE: &'static [char] = &[' ', '\t', '\n', '\r', '\x0C
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ParsedCaseSensitivity {
CaseSensitive,
// 's' was specified.
ExplicitCaseSensitive,
// 'i' was specified.
AsciiCaseInsensitive,
// No flags were specified and HTML says this is a case-sensitive attribute.
CaseSensitive,
// No flags were specified and HTML says this is a case-insensitive attribute.
AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument,
}
@ -150,7 +155,9 @@ impl ParsedCaseSensitivity {
ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {
CaseSensitivity::CaseSensitive
},
ParsedCaseSensitivity::CaseSensitive => CaseSensitivity::CaseSensitive,
ParsedCaseSensitivity::CaseSensitive | ParsedCaseSensitivity::ExplicitCaseSensitive => {
CaseSensitivity::CaseSensitive
},
ParsedCaseSensitivity::AsciiCaseInsensitive => CaseSensitivity::AsciiCaseInsensitive,
}
}

View file

@ -410,6 +410,7 @@ fn next_element_for_combinator<E>(
element: &E,
combinator: Combinator,
selector: &SelectorIter<E::Impl>,
context: &MatchingContext<E::Impl>,
) -> Option<E>
where
E: Element,
@ -449,12 +450,21 @@ where
element.containing_shadow_host()
},
Combinator::SlotAssignment => {
debug_assert!(
context.current_host.is_some(),
"Should not be trying to match slotted rules in a non-shadow-tree context"
);
debug_assert!(
element
.assigned_slot()
.map_or(true, |s| s.is_html_slot_element())
);
element.assigned_slot()
let scope = context.current_host?;
let mut current_slot = element.assigned_slot()?;
while current_slot.containing_shadow_host().unwrap().opaque() != scope {
current_slot = current_slot.assigned_slot()?;
}
Some(current_slot)
},
Combinator::PseudoElement => element.pseudo_element_originating_element(),
}
@ -511,7 +521,8 @@ where
Combinator::PseudoElement => SelectorMatchingResult::NotMatchedGlobally,
};
let mut next_element = next_element_for_combinator(element, combinator, &selector_iter);
let mut next_element =
next_element_for_combinator(element, combinator, &selector_iter, &context);
// Stop matching :visited as soon as we find a link, or a combinator for
// something that isn't an ancestor.
@ -575,7 +586,7 @@ where
visited_handling = VisitedHandlingMode::AllLinksUnvisited;
}
next_element = next_element_for_combinator(&element, combinator, &selector_iter);
next_element = next_element_for_combinator(&element, combinator, &selector_iter, &context);
}
}

View file

@ -1223,6 +1223,7 @@ impl<Impl: SelectorImpl> ToCss for Component<Impl> {
ParsedCaseSensitivity::CaseSensitive |
ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {},
ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?,
ParsedCaseSensitivity::ExplicitCaseSensitive => dest.write_str(" s")?,
}
dest.write_char(']')
},
@ -1301,6 +1302,7 @@ impl<Impl: SelectorImpl> ToCss for AttrSelectorWithOptionalNamespace<Impl> {
ParsedCaseSensitivity::CaseSensitive |
ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {},
ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?,
ParsedCaseSensitivity::ExplicitCaseSensitive => dest.write_str(" s")?,
}
},
}
@ -1711,24 +1713,16 @@ where
AttrSelectorOperator::Suffix => value.is_empty(),
};
let mut case_sensitivity = parse_attribute_flags(input)?;
let attribute_flags = parse_attribute_flags(input)?;
let value = value.as_ref().into();
let local_name_lower;
let local_name_is_ascii_lowercase;
let case_sensitivity;
{
let local_name_lower_cow = to_ascii_lowercase(&local_name);
if let ParsedCaseSensitivity::CaseSensitive = case_sensitivity {
if namespace.is_none() && include!(concat!(
env!("OUT_DIR"),
"/ascii_case_insensitive_html_attributes.rs"
))
.contains(&*local_name_lower_cow)
{
case_sensitivity =
ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument
}
}
case_sensitivity =
attribute_flags.to_case_sensitivity(local_name_lower_cow.as_ref(), namespace.is_some());
local_name_lower = local_name_lower_cow.as_ref().into();
local_name_is_ascii_lowercase = matches!(local_name_lower_cow, Cow::Borrowed(..));
}
@ -1758,20 +1752,61 @@ where
}
}
/// An attribute selector can have 's' or 'i' as flags, or no flags at all.
enum AttributeFlags {
// Matching should be case-sensitive ('s' flag).
CaseSensitive,
// Matching should be case-insensitive ('i' flag).
AsciiCaseInsensitive,
// No flags. Matching behavior depends on the name of the attribute.
CaseSensitivityDependsOnName,
}
impl AttributeFlags {
fn to_case_sensitivity(self, local_name: &str, have_namespace: bool) -> ParsedCaseSensitivity {
match self {
AttributeFlags::CaseSensitive => ParsedCaseSensitivity::ExplicitCaseSensitive,
AttributeFlags::AsciiCaseInsensitive => ParsedCaseSensitivity::AsciiCaseInsensitive,
AttributeFlags::CaseSensitivityDependsOnName => {
if !have_namespace && include!(concat!(
env!("OUT_DIR"),
"/ascii_case_insensitive_html_attributes.rs"
))
.contains(local_name)
{
ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument
} else {
ParsedCaseSensitivity::CaseSensitive
}
},
}
}
}
fn parse_attribute_flags<'i, 't>(
input: &mut CssParser<'i, 't>,
) -> Result<ParsedCaseSensitivity, BasicParseError<'i>> {
) -> Result<AttributeFlags, BasicParseError<'i>> {
let location = input.current_source_location();
match input.next() {
Err(_) => {
// Selectors spec says language-defined, but HTML says sensitive.
Ok(ParsedCaseSensitivity::CaseSensitive)
let token = match input.next() {
Ok(t) => t,
Err(..) => {
// Selectors spec says language-defined; HTML says it depends on the
// exact attribute name.
return Ok(AttributeFlags::CaseSensitivityDependsOnName);
},
Ok(&Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => {
Ok(ParsedCaseSensitivity::AsciiCaseInsensitive)
},
Ok(t) => Err(location.new_basic_unexpected_token_error(t.clone())),
}
};
let ident = match *token {
Token::Ident(ref i) => i,
ref other => return Err(location.new_basic_unexpected_token_error(other.clone())),
};
Ok(match_ignore_ascii_case! {
ident,
"i" => AttributeFlags::AsciiCaseInsensitive,
"s" => AttributeFlags::CaseSensitive,
_ => return Err(location.new_basic_unexpected_token_error(token.clone())),
})
}
/// Level 3: Parse **one** simple_selector. (Though we might insert a second

View file

@ -11,9 +11,8 @@ use crate::parser::SelectorImpl;
use std::fmt::Debug;
use std::ptr::NonNull;
/// Opaque representation of an Element, for identity comparisons. We use
/// NonZeroPtrMut to get the NonZero optimization.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
/// Opaque representation of an Element, for identity comparisons.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct OpaqueElement(NonNull<()>);
unsafe impl Send for OpaqueElement {}

View file

@ -25,6 +25,7 @@ use crate::values::computed::TimingFunction;
use crate::values::generics::box_::AnimationIterationCount;
use crate::values::generics::easing::{StepPosition, TimingFunction as GenericTimingFunction};
use crate::Atom;
#[cfg(feature = "servo")]
use crossbeam_channel::Sender;
use servo_arc::Arc;
use std::fmt;

View file

@ -59,5 +59,11 @@ include = [
"PathCommand",
"UnicodeRange",
"UserSelect",
"Float",
"OverscrollBehavior",
"ScrollSnapType",
"OverflowClipBox",
"Resize",
"Overflow",
]
item_types = ["enums", "structs", "typedefs"]

View file

@ -581,7 +581,7 @@ impl<'le> GeckoElement<'le> {
#[inline(always)]
fn attrs(&self) -> &[structs::AttrArray_InternalAttr] {
unsafe {
let attrs = match self.0._base.mAttrs.mImpl.mPtr.as_ref() {
let attrs = match self.0.mAttrs.mImpl.mPtr.as_ref() {
Some(attrs) => attrs,
None => return &[],
};

View file

@ -471,25 +471,34 @@ where
return false;
}
let slot = self.element;
self.invalidate_slotted_elements_in_slot(slot, invalidations)
}
fn invalidate_slotted_elements_in_slot(
&mut self,
slot: E,
invalidations: &[Invalidation<'b>],
) -> bool {
let mut any = false;
let mut sibling_invalidations = InvalidationVector::new();
let element = self.element;
for node in element.slotted_nodes() {
for node in slot.slotted_nodes() {
let element = match node.as_element() {
Some(e) => e,
None => continue,
};
any |= self.invalidate_child(
element,
invalidations,
&mut sibling_invalidations,
DescendantInvalidationKind::Slotted,
);
// FIXME(emilio): Need to handle nested slotted nodes if `element`
// is itself a <slot>.
if element.is_html_slot_element() {
any |= self.invalidate_slotted_elements_in_slot(element, invalidations);
} else {
any |= self.invalidate_child(
element,
invalidations,
&mut sibling_invalidations,
DescendantInvalidationKind::Slotted,
);
}
debug_assert!(
sibling_invalidations.is_empty(),

View file

@ -325,6 +325,7 @@ class Longhand(object):
"NonNegativeNumber",
"Opacity",
"OutlineStyle",
"Overflow",
"OverflowClipBox",
"OverflowWrap",
"OverscrollBehavior",

View file

@ -1389,8 +1389,15 @@ impl Clone for ${style_struct.gecko_struct_name} {
# Types used with predefined_type()-defined properties that we can auto-generate.
predefined_types = {
"Appearance": impl_simple,
"OverscrollBehavior": impl_simple,
"OverflowClipBox": impl_simple,
"ScrollSnapType": impl_simple,
"Float": impl_simple,
"Overflow": impl_simple,
"BreakBetween": impl_simple,
"BreakWithin": impl_simple,
"Resize": impl_simple,
"Color": impl_color,
"ColorOrAuto": impl_color,
"GreaterThanOrEqualToOneNumber": impl_simple,
@ -3005,20 +3012,18 @@ fn static_assert() {
}
</%def>
<% skip_box_longhands= """display -moz-appearance overflow-y vertical-align
<% skip_box_longhands= """display vertical-align
animation-name animation-delay animation-duration
animation-direction animation-fill-mode animation-play-state
animation-iteration-count animation-timing-function
transition-duration transition-delay
clear transition-duration transition-delay
transition-timing-function transition-property
rotate scroll-snap-points-x scroll-snap-points-y
scroll-snap-type-x scroll-snap-type-y scroll-snap-coordinate
scroll-snap-coordinate
perspective-origin -moz-binding will-change
offset-path overscroll-behavior-x overscroll-behavior-y
overflow-clip-box-inline overflow-clip-box-block
perspective-origin -moz-binding will-change
shape-outside contain touch-action translate
scale""" %>
offset-path perspective-origin -moz-binding
will-change shape-outside contain touch-action
translate scale""" %>
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
#[inline]
pub fn set_display(&mut self, v: longhands::display::computed_value::T) {
@ -3051,11 +3056,6 @@ fn static_assert() {
self.gecko.mDisplay
}
${impl_simple('_moz_appearance', 'mAppearance')}
<% float_keyword = Keyword("float", "Left Right None", gecko_enum_prefix="StyleFloat") %>
${impl_keyword('float', 'mFloat', float_keyword)}
<% clear_keyword = Keyword(
"clear",
"Left Right None Both",
@ -3064,31 +3064,6 @@ fn static_assert() {
) %>
${impl_keyword('clear', 'mBreakType', clear_keyword)}
<% resize_keyword = Keyword("resize", "None Both Horizontal Vertical") %>
${impl_keyword('resize', 'mResize', resize_keyword)}
<% overflow_x = data.longhands_by_name["overflow-x"] %>
pub fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) {
use crate::properties::longhands::overflow_x::computed_value::T as BaseType;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
self.gecko.mOverflowY = match v {
% for value in overflow_x.keyword.values_for('gecko'):
BaseType::${to_camel_case(value)} => structs::${overflow_x.keyword.gecko_constant(value)} as u8,
% endfor
};
}
${impl_simple_copy('overflow_y', 'mOverflowY')}
pub fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
use crate::properties::longhands::overflow_x::computed_value::T as BaseType;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
match self.gecko.mOverflowY as u32 {
% for value in overflow_x.keyword.values_for('gecko'):
structs::${overflow_x.keyword.gecko_constant(value)} => BaseType::${to_camel_case(value)},
% endfor
x => panic!("Found unexpected value in style struct for overflow_y property: {}", x),
}
}
pub fn set_vertical_align(&mut self, v: longhands::vertical_align::computed_value::T) {
use crate::values::generics::box_::VerticalAlign;
let value = match v {
@ -3398,19 +3373,6 @@ fn static_assert() {
${impl_animation_timing_function()}
<% scroll_snap_type_keyword = Keyword("scroll-snap-type", "None Mandatory Proximity") %>
${impl_keyword('scroll_snap_type_y', 'mScrollSnapTypeY', scroll_snap_type_keyword)}
${impl_keyword('scroll_snap_type_x', 'mScrollSnapTypeX', scroll_snap_type_keyword)}
<% overscroll_behavior_keyword = Keyword("overscroll-behavior", "Auto Contain None",
gecko_enum_prefix="StyleOverscrollBehavior") %>
${impl_keyword('overscroll_behavior_x', 'mOverscrollBehaviorX', overscroll_behavior_keyword)}
${impl_keyword('overscroll_behavior_y', 'mOverscrollBehaviorY', overscroll_behavior_keyword)}
<% overflow_clip_box_keyword = Keyword("overflow-clip-box", "padding-box content-box") %>
${impl_keyword('overflow_clip_box_inline', 'mOverflowClipBoxInline', overflow_clip_box_keyword)}
${impl_keyword('overflow_clip_box_block', 'mOverflowClipBoxBlock', overflow_clip_box_keyword)}
pub fn set_perspective_origin(&mut self, v: longhands::perspective_origin::computed_value::T) {
self.gecko.mPerspectiveOrigin[0].set(v.horizontal);
self.gecko.mPerspectiveOrigin[1].set(v.vertical);

View file

@ -100,34 +100,30 @@ ${helpers.single_keyword("-servo-overflow-clip-box", "padding-box content-box",
)}
% endfor
<%
overflow_custom_consts = { "-moz-hidden-unscrollable": "CLIP" }
%>
// FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
//
// We allow it to apply to placeholders for UA sheets, which set it !important.
${helpers.single_keyword(
${helpers.predefined_type(
"overflow-x",
"visible hidden scroll auto",
"Overflow",
"computed::Overflow::Visible",
animation_value_type="discrete",
extra_gecko_values="-moz-hidden-unscrollable",
custom_consts=overflow_custom_consts,
gecko_constant_prefix="NS_STYLE_OVERFLOW",
flags="APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-x",
needs_context=False,
servo_restyle_damage = "reflow",
)}
// FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
//
// We allow it to apply to placeholders for UA sheets, which set it !important.
<%helpers:longhand name="overflow-y" animation_value_type="discrete"
flags="APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-y"
servo_restyle_damage = "reflow">
pub use super::overflow_x::{SpecifiedValue, parse, get_initial_value, computed_value};
</%helpers:longhand>
${helpers.predefined_type(
"overflow-y",
"Overflow",
"computed::Overflow::Visible",
animation_value_type="discrete",
flags="APPLIES_TO_PLACEHOLDER",
spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-y",
needs_context=False,
servo_restyle_damage = "reflow",
)}
<% transition_extra_prefixes = "moz:layout.css.prefixes.transitions webkit" %>
@ -574,6 +570,7 @@ ${helpers.predefined_type(
alias="-webkit-appearance:layout.css.webkit-appearance.enabled",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-appearance)",
animation_value_type="discrete",
gecko_ffi_name="mAppearance",
)}
${helpers.predefined_type(

View file

@ -13,7 +13,7 @@ use crate::values::specified::box_ as specified;
pub use crate::values::specified::box_::{AnimationName, Appearance, BreakBetween, BreakWithin};
pub use crate::values::specified::box_::{Clear as SpecifiedClear, Float as SpecifiedFloat};
pub use crate::values::specified::box_::{Contain, Display, OverflowClipBox};
pub use crate::values::specified::box_::{Contain, Display, Overflow, OverflowClipBox};
pub use crate::values::specified::box_::{OverscrollBehavior, ScrollSnapType};
pub use crate::values::specified::box_::{TouchAction, TransitionProperty, WillChange};
@ -39,6 +39,7 @@ pub type Perspective = GenericPerspective<NonNegativeLength>;
#[derive(
Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss,
)]
#[repr(u8)]
/// A computed value for the `float` property.
pub enum Float {
Left,
@ -157,6 +158,7 @@ impl ToComputedValue for SpecifiedClear {
#[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss)]
#[repr(u8)]
pub enum Resize {
None,
Both,

View file

@ -43,7 +43,7 @@ pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
pub use self::border::{BorderImageSlice, BorderImageWidth};
pub use self::box_::{AnimationIterationCount, AnimationName, Contain};
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
pub use self::box_::{Display, TransitionProperty};
pub use self::box_::{Display, Overflow, TransitionProperty};
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor};

View file

@ -92,8 +92,7 @@ impl ToCss for AlignFlags {
dest.write_char(' ')?;
},
AlignFlags::SAFE => dest.write_str("safe ")?,
// Don't serialize "unsafe", since it's the default.
AlignFlags::UNSAFE => {},
AlignFlags::UNSAFE => dest.write_str("unsafe ")?,
_ => {
debug_assert_eq!(extra_flags, AlignFlags::empty());
},

View file

@ -389,6 +389,7 @@ impl Parse for AnimationName {
ToComputedValue,
ToCss,
)]
#[repr(u8)]
pub enum ScrollSnapType {
None,
Mandatory,
@ -409,6 +410,7 @@ pub enum ScrollSnapType {
ToComputedValue,
ToCss,
)]
#[repr(u8)]
pub enum OverscrollBehavior {
Auto,
Contain,
@ -429,6 +431,7 @@ pub enum OverscrollBehavior {
ToComputedValue,
ToCss,
)]
#[repr(u8)]
pub enum OverflowClipBox {
PaddingBox,
ContentBox,
@ -1360,3 +1363,28 @@ pub enum BreakWithin {
Auto,
Avoid,
}
/// The value for the `overflow-x` / `overflow-y` properties.
#[allow(missing_docs)]
#[derive(
Clone,
Copy,
Debug,
Eq,
Hash,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToCss,
ToComputedValue,
)]
#[repr(u8)]
pub enum Overflow {
Visible,
Hidden,
Scroll,
Auto,
#[cfg(feature = "gecko")]
MozHiddenUnscrollable,
}

View file

@ -36,7 +36,7 @@ pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle};
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float, Overflow};
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange};
pub use self::color::{Color, ColorPropertyValue, RGBAColor};

View file

@ -1,97 +0,0 @@
[cssom.html]
[[foo="bar" s\] getting CSSStyleRule#selectorText]
expected: FAIL
[[foo="bar" /**/ s\] setting CSSStyleRule#selectorText]
expected: FAIL
[[foo="bar" s\] getting CSSStyleRule#selectorText in @media]
expected: FAIL
[[foo="bar" s\] getting CSSRule#cssText]
expected: FAIL
[[foo="bar" /**/ s\] getting CSSStyleRule#selectorText in @media]
expected: FAIL
[[foo="bar" s\] insertRule in @media]
expected: FAIL
[[foo="bar"/**/s\] insertRule in @media]
expected: FAIL
[[foo="bar"/**/s\] getting CSSStyleRule#selectorText]
expected: FAIL
[[foo="bar"/**/s\] getting CSSRule#cssText]
expected: FAIL
[[foo="bar" /**/ s\] setting CSSStyleRule#selectorText in @media]
expected: FAIL
[[foo="bar"/**/s\] setting CSSStyleRule#selectorText]
expected: FAIL
[[foo="bar" /**/ s\] getting CSSStyleRule#selectorText]
expected: FAIL
[[foo="bar" /**/ s\] getting CSSRule#cssText]
expected: FAIL
[[foo="bar" s\] setting CSSStyleRule#selectorText in @media]
expected: FAIL
[[foo="bar" s\] setting CSSStyleRule#selectorText]
expected: FAIL
[[foo="bar" s\] insertRule]
expected: FAIL
[[foo="bar" /**/ s\] getting CSSRule#cssText in @media]
expected: FAIL
[[foo="bar" /**/ s\] insertRule]
expected: FAIL
[[foo="bar"/**/s\] getting CSSRule#cssText in @media]
expected: FAIL
[[foo="bar" s\] getting CSSRule#cssText in @media]
expected: FAIL
[[foo="bar"/**/s\] insertRule]
expected: FAIL
[[foo="bar" /**/ s\] insertRule in @media]
expected: FAIL
[[foo="bar"/**/s\] getting CSSStyleRule#selectorText in @media]
expected: FAIL
[[foo="bar"/**/s\] setting CSSStyleRule#selectorText in @media]
expected: FAIL
[[*|foo="bar" s\] getting CSSStyleRule#selectorText]
expected: FAIL
[[*|foo="bar" s\] getting CSSRule#cssText in @media]
expected: FAIL
[[*|foo="bar" s\] insertRule in @media]
expected: FAIL
[[*|foo="bar" s\] getting CSSRule#cssText]
expected: FAIL
[[*|foo="bar" s\] insertRule]
expected: FAIL
[[*|foo="bar" s\] getting CSSStyleRule#selectorText in @media]
expected: FAIL
[[*|foo="bar" s\] setting CSSStyleRule#selectorText]
expected: FAIL
[[*|foo="bar" s\] setting CSSStyleRule#selectorText in @media]
expected: FAIL

View file

@ -1,433 +0,0 @@
[syntax.html]
[[baz='quux' s \] with querySelector in XML]
expected: FAIL
[[baz='quux' \\s\] in XML]
expected: FAIL
[[baz='quux' s\] in quirks mode]
expected: FAIL
[[baz='quux' \\73\] with querySelector in XML]
expected: FAIL
[[baz$='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux's\] with querySelector in quirks mode]
expected: FAIL
[[baz=quux s\] in quirks mode]
expected: FAIL
[[baz*='quux' s\] in XML]
expected: FAIL
[[baz="quux" s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' s \] in XML]
expected: FAIL
[[baz='quux's \] with querySelector in standards mode]
expected: FAIL
[[baz*='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz|='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux' \\s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' \\73\] in standards mode]
expected: FAIL
[[baz='quux' /**/ s\] with querySelector in XML]
expected: FAIL
[[baz='quux' /**/ s\] in XML]
expected: FAIL
[[baz='quux' s\] with querySelector in XML]
expected: FAIL
[[baz~='quux' s\] in XML]
expected: FAIL
[[baz='quux'/**/s/**/\] with querySelector in XML]
expected: FAIL
[[baz='quux'/**/s/**/\] in XML]
expected: FAIL
[[baz=quux s\] with querySelector in XML]
expected: FAIL
[[baz='quux' \\53\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' \\73\] in XML]
expected: FAIL
[[baz$='quux' s\] in standards mode]
expected: FAIL
[[baz~='quux' s\] with querySelector in XML]
expected: FAIL
[[baz~='quux' s\] in standards mode]
expected: FAIL
[[baz='quux' S\] in standards mode]
expected: FAIL
[[baz='quux' s\] in XML]
expected: FAIL
[[baz='quux'\ns\n\] /* \\n */ in standards mode]
expected: FAIL
[[baz='quux's \] in quirks mode]
expected: FAIL
[[baz="quux" s\] with querySelector in standards mode]
expected: FAIL
[[*|baz='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux's \] in standards mode]
expected: FAIL
[[baz|='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux's \] with querySelector in XML]
expected: FAIL
[[baz=quux/**/s\] with querySelector in XML]
expected: FAIL
[[baz='quux'\ts\t\] /* \\t */ with querySelector in standards mode]
expected: FAIL
[[baz=quux s\] with querySelector in quirks mode]
expected: FAIL
[[baz$='quux' s\] in quirks mode]
expected: FAIL
[[baz*='quux' s\] in standards mode]
expected: FAIL
[[*|baz='quux' s\] in standards mode]
expected: FAIL
[[baz='quux's \] in XML]
expected: FAIL
[[baz^='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux'/**/s/**/\] with querySelector in standards mode]
expected: FAIL
[[baz='quux'\ts\t\] /* \\t */ in XML]
expected: FAIL
[[*|baz='quux' s\] with querySelector in XML]
expected: FAIL
[[baz="quux" s\] with querySelector in XML]
expected: FAIL
[[baz*='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz|='quux' s\] in XML]
expected: FAIL
[[baz='quux' \\s\] with querySelector in XML]
expected: FAIL
[[baz^='quux' s\] in quirks mode]
expected: FAIL
[[|baz='quux' s\] with querySelector in XML]
expected: FAIL
[[baz='quux' s\] in standards mode]
expected: FAIL
[[baz='quux' /**/ s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux' s \] with querySelector in quirks mode]
expected: FAIL
[[|baz='quux' s\] with querySelector in standards mode]
expected: FAIL
[[|baz='quux' s\] in quirks mode]
expected: FAIL
[[baz='quux' \\53\] in quirks mode]
expected: FAIL
[[baz$='quux' s\] in XML]
expected: FAIL
[[baz='quux' /**/ s\] in quirks mode]
expected: FAIL
[[baz=quux s\] with querySelector in standards mode]
expected: FAIL
[[baz=quux s\] in XML]
expected: FAIL
[[baz='quux' s /**/ \] with querySelector in XML]
expected: FAIL
[[baz='quux' \\s\] in standards mode]
expected: FAIL
[[baz|='quux' s\] with querySelector in XML]
expected: FAIL
[[baz='quux' S\] in quirks mode]
expected: FAIL
[[baz='quux's\] with querySelector in XML]
expected: FAIL
[[baz='quux'\ns\n\] /* \\n */ with querySelector in XML]
expected: FAIL
[[baz=quux/**/s\] in XML]
expected: FAIL
[[baz='quux' s \] in quirks mode]
expected: FAIL
[[baz='quux' s /**/ \] in quirks mode]
expected: FAIL
[[baz="quux" s\] in quirks mode]
expected: FAIL
[[baz='quux'\rs\r\] /* \\r */ with querySelector in quirks mode]
expected: FAIL
[[baz='quux' s /**/ \] in XML]
expected: FAIL
[[baz='quux'/**/s/**/\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' s \] in standards mode]
expected: FAIL
[[baz='quux's\] with querySelector in standards mode]
expected: FAIL
[[baz='quux'\ts\t\] /* \\t */ in standards mode]
expected: FAIL
[[baz^='quux' s\] with querySelector in XML]
expected: FAIL
[[baz='quux' \\73\] with querySelector in quirks mode]
expected: FAIL
[[baz|='quux' s\] in standards mode]
expected: FAIL
[[baz='quux'\ts\t\] /* \\t */ with querySelector in quirks mode]
expected: FAIL
[[baz='quux' \\53\] in standards mode]
expected: FAIL
[[baz=quux/**/s\] in standards mode]
expected: FAIL
[[baz$='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' /**/ s\] in standards mode]
expected: FAIL
[[baz|='quux' s\] in quirks mode]
expected: FAIL
[[baz~='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz^='quux' s\] in XML]
expected: FAIL
[[baz='quux's\] in XML]
expected: FAIL
[[baz=quux s\] in standards mode]
expected: FAIL
[[baz="quux" s\] in XML]
expected: FAIL
[[baz='quux'/**/s/**/\] in standards mode]
expected: FAIL
[[baz='quux' \\s\] with querySelector in standards mode]
expected: FAIL
[[*|baz='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux'\rs\r\] /* \\r */ with querySelector in standards mode]
expected: FAIL
[[*|baz='quux' s\] in XML]
expected: FAIL
[[|baz='quux' s\] in XML]
expected: FAIL
[[baz='quux' \\s\] in quirks mode]
expected: FAIL
[[baz='quux' S\] with querySelector in quirks mode]
expected: FAIL
[[baz=quux/**/s\] in quirks mode]
expected: FAIL
[[baz='quux's\] in standards mode]
expected: FAIL
[[baz*='quux' s\] in quirks mode]
expected: FAIL
[[baz='quux' s \] with querySelector in standards mode]
expected: FAIL
[[baz*='quux' s\] with querySelector in XML]
expected: FAIL
[[baz='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux' \\53\] with querySelector in standards mode]
expected: FAIL
[[baz='quux' \\53\] in XML]
expected: FAIL
[[baz='quux'\ns\n\] /* \\n */ in quirks mode]
expected: FAIL
[[baz='quux'\ts\t\] /* \\t */ in quirks mode]
expected: FAIL
[[baz^='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz=quux/**/s\] with querySelector in standards mode]
expected: FAIL
[[baz='quux'\ts\t\] /* \\t */ with querySelector in XML]
expected: FAIL
[[baz='quux'\ns\n\] /* \\n */ in XML]
expected: FAIL
[[baz='quux'\ns\n\] /* \\n */ with querySelector in quirks mode]
expected: FAIL
[[baz='quux' s /**/ \] with querySelector in quirks mode]
expected: FAIL
[[baz='quux's \] with querySelector in quirks mode]
expected: FAIL
[[baz^='quux' s\] in standards mode]
expected: FAIL
[[baz~='quux' s\] in quirks mode]
expected: FAIL
[[*|baz='quux' s\] in quirks mode]
expected: FAIL
[[baz='quux' S\] with querySelector in XML]
expected: FAIL
[[baz~='quux' s\] with querySelector in standards mode]
expected: FAIL
[[baz$='quux' s\] with querySelector in XML]
expected: FAIL
[[baz='quux'\rs\r\] /* \\r */ in quirks mode]
expected: FAIL
[[baz="quux" s\] in standards mode]
expected: FAIL
[[baz='quux' \\73\] with querySelector in standards mode]
expected: FAIL
[[baz=quux/**/s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[baz='quux' s /**/ \] in standards mode]
expected: FAIL
[[baz='quux's\] in quirks mode]
expected: FAIL
[[baz='quux'\rs\r\] /* \\r */ in standards mode]
expected: FAIL
[[baz='quux' s /**/ \] with querySelector in standards mode]
expected: FAIL
[[baz='quux'\rs\r\] /* \\r */ in XML]
expected: FAIL
[[baz='quux'/**/s/**/\] in quirks mode]
expected: FAIL
[[baz='quux'\ns\n\] /* \\n */ with querySelector in standards mode]
expected: FAIL
[[baz='quux'\rs\r\] /* \\r */ with querySelector in XML]
expected: FAIL
[[baz='quux' S\] with querySelector in standards mode]
expected: FAIL
[[baz='quux' \\73\] in quirks mode]
expected: FAIL
[[baz='quux' S\] in XML]
expected: FAIL
[[baz='quux' \\53\] with querySelector in XML]
expected: FAIL
[[|baz='quux' s\] with querySelector in quirks mode]
expected: FAIL
[[|baz='quux' s\] in standards mode]
expected: FAIL
[[baz='quux' /**/ s\] with querySelector in quirks mode]
expected: FAIL