diff options
-rw-r--r-- | Cargo.lock | 15 | ||||
-rw-r--r-- | components/allocator/Cargo.toml | 5 | ||||
-rw-r--r-- | components/allocator/lib.rs | 17 | ||||
-rw-r--r-- | components/gfx/platform/freetype/font_context.rs | 50 | ||||
-rw-r--r-- | components/layout/inline.rs | 9 | ||||
-rw-r--r-- | components/style/invalidation/element/collector.rs | 4 | ||||
-rw-r--r-- | components/style/invalidation/element/element_wrapper.rs | 6 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 22 | ||||
-rw-r--r-- | components/style/properties/longhand/font.mako.rs | 59 | ||||
-rw-r--r-- | components/style/properties/longhand/text.mako.rs | 127 | ||||
-rw-r--r-- | components/style/selector_map.rs | 6 | ||||
-rw-r--r-- | components/style/stylist.rs | 4 | ||||
-rw-r--r-- | components/style/values/computed/font.rs | 29 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 4 | ||||
-rw-r--r-- | components/style/values/computed/text.rs | 46 | ||||
-rw-r--r-- | components/style/values/specified/font.rs | 27 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 4 | ||||
-rw-r--r-- | components/style/values/specified/text.rs | 90 |
18 files changed, 273 insertions, 251 deletions
diff --git a/Cargo.lock b/Cargo.lock index c25798f73a8..5f09f0bdcd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1447,7 +1447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jemalloc-sys" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1456,10 +1456,10 @@ dependencies = [ [[package]] name = "jemallocator" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2391,7 +2391,7 @@ dependencies = [ "heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "influent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "profile_traits 0.0.1", @@ -2956,8 +2956,9 @@ dependencies = [ name = "servo_allocator" version = "0.0.1" dependencies = [ - "jemallocator 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jemallocator 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3912,8 +3913,8 @@ dependencies = [ "checksum ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10ed089b1921b01ef342c736a37ee0788eeb9a5f373bb2df1ba88d01125064f" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" -"checksum jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94fb624d7e8345e5c42caab8d1db6ec925fdadff3fd0cb7dd781b41be8442828" -"checksum jemallocator 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1850725977c344d63af66e8fd00857646e3ec936c490cd63667860b7b03ab5c1" +"checksum jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "479294d130502fada93c7a957e8d059b632b03d6204aca37af557dee947f30a9" +"checksum jemallocator 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "28b211ca65c440322b6d4d9b5b850b01e8e298393b7ebcb8205b7cbb14ea6329" "checksum jpeg-decoder 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2805ccb10ffe4d10e06ef68a158ff94c255211ecbae848fbde2146b098f93ce7" "checksum js 0.1.6 (git+https://github.com/servo/rust-mozjs)" = "<none>" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" diff --git a/components/allocator/Cargo.toml b/components/allocator/Cargo.toml index fccec48a5e9..645815ba1f1 100644 --- a/components/allocator/Cargo.toml +++ b/components/allocator/Cargo.toml @@ -11,8 +11,11 @@ path = "lib.rs" [features] unstable = ["kernel32-sys", "jemallocator"] +[dependencies] +libc = "0.2" # Only used when 'unstable' is disabled, but looks like Cargo cannot express that. + [target.'cfg(not(windows))'.dependencies] -jemallocator = { version = "0.1.3", optional = true } +jemallocator = { version = "0.1.4", optional = true } [target.'cfg(windows)'.dependencies] kernel32-sys = { version = "0.2.1", optional = true } diff --git a/components/allocator/lib.rs b/components/allocator/lib.rs index e832e485575..6c248f08055 100644 --- a/components/allocator/lib.rs +++ b/components/allocator/lib.rs @@ -9,9 +9,9 @@ #[cfg(feature = "unstable")] #[global_allocator] -static ALLOC: platform::Allocator = platform::Allocator; +static ALLOC: Allocator = Allocator; -pub use platform::usable_size; +pub use platform::*; #[cfg(all(feature = "unstable", not(windows)))] @@ -25,6 +25,11 @@ mod platform { pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize { jemallocator::usable_size(ptr) } + + /// Memory allocation APIs compatible with libc + pub mod libc_compat { + pub use super::jemallocator::ffi::{malloc, realloc, free}; + } } #[cfg(all(feature = "unstable", windows))] @@ -57,6 +62,10 @@ mod platform { pub unsafe extern "C" fn usable_size(_ptr: *const c_void) -> usize { 0 } -} - + /// Memory allocation APIs compatible with libc + pub mod libc_compat { + extern crate libc; + pub use self::libc::{malloc, realloc, free}; + } +} diff --git a/components/gfx/platform/freetype/font_context.rs b/components/gfx/platform/freetype/font_context.rs index f4a0745eb2c..2238561ba9c 100644 --- a/components/gfx/platform/freetype/font_context.rs +++ b/components/gfx/platform/freetype/font_context.rs @@ -9,8 +9,8 @@ use freetype::freetype::FT_Memory; use freetype::freetype::FT_MemoryRec_; use freetype::freetype::FT_New_Library; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; +use servo_allocator::libc_compat::{malloc, realloc, free}; use servo_allocator::usable_size; -use std::mem; use std::os::raw::{c_long, c_void}; use std::ptr; use std::rc::Rc; @@ -22,64 +22,38 @@ pub struct User { size: usize, } -// FreeType doesn't require any particular alignment for allocations. -const FT_ALIGNMENT: usize = 1; - extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void { - assert!(FT_ALIGNMENT == 1); - let mut vec = Vec::<u8>::with_capacity(req_size as usize); - let ptr = vec.as_mut_ptr() as *mut c_void; - mem::forget(vec); - unsafe { - let actual_size = usable_size(ptr as *const _); + let ptr = malloc(req_size as usize); + let ptr = ptr as *mut c_void; // libc::c_void vs std::os::raw::c_void + let actual_size = usable_size(ptr); let user = (*mem).user as *mut User; (*user).size += actual_size; + ptr } - - ptr } extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) { unsafe { - let actual_size = usable_size(ptr as *const _); + let actual_size = usable_size(ptr); let user = (*mem).user as *mut User; (*user).size -= actual_size; - - assert!(FT_ALIGNMENT == 1); - mem::drop(Vec::<u8>::from_raw_parts(ptr as *mut u8, actual_size, 0)) + free(ptr as *mut _); } } extern fn ft_realloc(mem: FT_Memory, _old_size: c_long, new_req_size: c_long, old_ptr: *mut c_void) -> *mut c_void { - let old_actual_size; - let mut vec; - unsafe { - old_actual_size = usable_size(old_ptr as *const _); - let old_size = old_actual_size as usize; - vec = Vec::<u8>::from_raw_parts(old_ptr as *mut u8, old_size, old_size); - }; - - let new_req_size = new_req_size as usize; - if new_req_size > old_actual_size { - vec.reserve_exact(new_req_size - old_actual_size) - } else if new_req_size < old_actual_size { - vec.truncate(new_req_size); - vec.shrink_to_fit() - } - - let new_ptr = vec.as_mut_ptr() as *mut c_void; - mem::forget(vec); - unsafe { - let new_actual_size = usable_size(new_ptr as *const _); + let old_actual_size = usable_size(old_ptr); + let new_ptr = realloc(old_ptr as *mut _, new_req_size as usize); + let new_ptr = new_ptr as *mut c_void; + let new_actual_size = usable_size(new_ptr); let user = (*mem).user as *mut User; (*user).size += new_actual_size; (*user).size -= old_actual_size; + new_ptr } - - new_ptr } // A |*mut User| field in a struct triggers a "use of `#[derive]` with a raw pointer" warning from diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 429ee7fc14e..afe770f06bb 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -33,9 +33,10 @@ use std::sync::Arc; use style::computed_values::{display, overflow_x, position, text_align, text_justify}; use style::computed_values::{vertical_align, white_space}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; -use style::properties::{longhands, ComputedValues}; +use style::properties::ComputedValues; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT}; use style::values::generics::box_::VerticalAlign; +use style::values::specified::text::TextOverflowSide; use text; use traversal::PreorderFlowTraversal; use unicode_bidi as bidi; @@ -714,15 +715,15 @@ impl LineBreaker { let ellipsis = match (&fragment.style().get_text().text_overflow.second, fragment.style().get_box().overflow_x) { - (&longhands::text_overflow::Side::Clip, _) | (_, overflow_x::T::visible) => None, - (&longhands::text_overflow::Side::Ellipsis, _) => { + (&TextOverflowSide::Clip, _) | (_, overflow_x::T::visible) => None, + (&TextOverflowSide::Ellipsis, _) => { if fragment.margin_box_inline_size() > available_inline_size { Some("…".to_string()) } else { None } }, - (&longhands::text_overflow::Side::String(ref string), _) => { + (&TextOverflowSide::String(ref string), _) => { if fragment.margin_box_inline_size() > available_inline_size { Some(string.to_string()) } else { diff --git a/components/style/invalidation/element/collector.rs b/components/style/invalidation/element/collector.rs index 31b93f8c732..9b697b76868 100644 --- a/components/style/invalidation/element/collector.rs +++ b/components/style/invalidation/element/collector.rs @@ -341,7 +341,7 @@ where self.quirks_mode, self.removed_id, self.classes_removed, - &mut |dependency| { + |dependency| { self.scan_dependency(dependency, VisitedDependent::No); true }, @@ -358,7 +358,7 @@ where self.quirks_mode, self.removed_id, self.classes_removed, - &mut |dependency| { + |dependency| { if !dependency.state.intersects(state_changes) { return true; } diff --git a/components/style/invalidation/element/element_wrapper.rs b/components/style/invalidation/element/element_wrapper.rs index 5cedff38fa3..8b3fb0385bb 100644 --- a/components/style/invalidation/element/element_wrapper.rs +++ b/components/style/invalidation/element/element_wrapper.rs @@ -348,7 +348,11 @@ impl<'a, E> Element for ElementWrapper<'a, E> } fn pseudo_element_originating_element(&self) -> Option<Self> { - self.element.closest_non_native_anonymous_ancestor() + self.element.pseudo_element_originating_element() .map(|e| ElementWrapper::new(e, self.snapshot_map)) } + + fn blocks_ancestor_combinators(&self) -> bool { + self.element.blocks_ancestor_combinators() + } } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 16a55c72689..f66eaf21241 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1119,6 +1119,7 @@ impl Clone for ${style_struct.gecko_struct_name} { "LengthOrNormal": impl_style_coord, "MaxLength": impl_style_coord, "MozLength": impl_style_coord, + "MozScriptMinSize": impl_absolute_length, "NonNegativeLengthOrPercentage": impl_style_coord, "NonNegativeNumber": impl_simple, "Number": impl_simple, @@ -4772,13 +4773,13 @@ fn static_assert() { pub fn set_text_overflow(&mut self, v: longhands::text_overflow::computed_value::T) { use gecko_bindings::structs::nsStyleTextOverflowSide; - use properties::longhands::text_overflow::Side; + use values::specified::text::TextOverflowSide; - fn set(side: &mut nsStyleTextOverflowSide, value: &Side) { + fn set(side: &mut nsStyleTextOverflowSide, value: &TextOverflowSide) { let ty = match *value { - Side::Clip => structs::NS_STYLE_TEXT_OVERFLOW_CLIP, - Side::Ellipsis => structs::NS_STYLE_TEXT_OVERFLOW_ELLIPSIS, - Side::String(ref s) => { + TextOverflowSide::Clip => structs::NS_STYLE_TEXT_OVERFLOW_CLIP, + TextOverflowSide::Ellipsis => structs::NS_STYLE_TEXT_OVERFLOW_ELLIPSIS, + TextOverflowSide::String(ref s) => { side.mString.assign_utf8(s); structs::NS_STYLE_TEXT_OVERFLOW_STRING } @@ -4813,13 +4814,14 @@ fn static_assert() { pub fn clone_text_overflow(&self) -> longhands::text_overflow::computed_value::T { use gecko_bindings::structs::nsStyleTextOverflowSide; - use properties::longhands::text_overflow::Side; + use values::specified::text::TextOverflowSide; - fn to_servo(side: &nsStyleTextOverflowSide) -> Side { + fn to_servo(side: &nsStyleTextOverflowSide) -> TextOverflowSide { match side.mType as u32 { - structs::NS_STYLE_TEXT_OVERFLOW_CLIP => Side::Clip, - structs::NS_STYLE_TEXT_OVERFLOW_ELLIPSIS => Side::Ellipsis, - structs::NS_STYLE_TEXT_OVERFLOW_STRING => Side::String(side.mString.to_string().into_boxed_str()), + structs::NS_STYLE_TEXT_OVERFLOW_CLIP => TextOverflowSide::Clip, + structs::NS_STYLE_TEXT_OVERFLOW_ELLIPSIS => TextOverflowSide::Ellipsis, + structs::NS_STYLE_TEXT_OVERFLOW_STRING => + TextOverflowSide::String(side.mString.to_string().into_boxed_str()), x => panic!("Found unexpected value in style struct for text_overflow property: {:?}", x), } } diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 20c0097a685..41ff54cee18 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -2187,57 +2187,14 @@ ${helpers.single_keyword("-moz-math-variant", animation_value_type="none", needs_conversion=True)} -<%helpers:longhand name="-moz-script-min-size" products="gecko" animation_value_type="none" - predefined_type="Length" gecko_ffi_name="mScriptMinSize" - spec="Internal (not web-exposed)" - internal="True"> - use gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT; - use values::computed::Length; - use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize, NoCalcLength}; - - #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] - #[derive(Clone, Debug, PartialEq, ToCss)] - pub struct SpecifiedValue(pub NoCalcLength); - - pub mod computed_value { - pub type T = ::values::computed::Length; - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - fn to_computed_value(&self, cx: &Context) -> Length { - // this value is used in the computation of font-size, so - // we use the parent size - let base_size = FontBaseSize::InheritedStyle; - match self.0 { - NoCalcLength::FontRelative(value) => { - value.to_computed_value(cx, base_size) - } - NoCalcLength::ServoCharacterWidth(value) => { - value.to_computed_value(base_size.resolve(cx)) - } - ref l => { - l.to_computed_value(cx) - } - } - } - fn from_computed_value(other: &computed_value::T) -> Self { - SpecifiedValue(ToComputedValue::from_computed_value(other)) - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - Length::new(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * (AU_PER_PT / AU_PER_PX)) - } - - pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<SpecifiedValue, ParseError<'i>> { - debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } -</%helpers:longhand> +${helpers.predefined_type("-moz-script-min-size", + "MozScriptMinSize", + "specified::MozScriptMinSize::get_initial_value()", + animation_value_type="none", + products="gecko", + internal=True, + gecko_ffi_name="mScriptMinSize", + spec="Internal (not web-exposed)")} ${helpers.predefined_type("-x-text-zoom", "XTextZoom", diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index a88d5199797..798c098ea02 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -12,126 +12,13 @@ Method("has_overline", "bool"), Method("has_line_through", "bool")]) %> -<%helpers:longhand name="text-overflow" animation_value_type="discrete" boxed="True" - flags="APPLIES_TO_PLACEHOLDER" - spec="https://drafts.csswg.org/css-ui/#propdef-text-overflow"> - use std::fmt; - use style_traits::ToCss; - - - #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] - pub enum Side { - Clip, - Ellipsis, - String(Box<str>), - } - - #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] - pub struct SpecifiedValue { - pub first: Side, - pub second: Option<Side> - } - - pub mod computed_value { - pub use super::Side; - - #[derive(Clone, Debug, MallocSizeOf, PartialEq)] - pub struct T { - // When the specified value only has one side, that's the "second" - // side, and the sides are logical, so "second" means "end". The - // start side is Clip in that case. - // - // When the specified value has two sides, those are our "first" - // and "second" sides, and they are physical sides ("left" and - // "right"). - pub first: Side, - pub second: Side, - pub sides_are_logical: bool - } - } - - impl ToCss for computed_value::T { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - if self.sides_are_logical { - assert!(self.first == Side::Clip); - self.second.to_css(dest)?; - } else { - self.first.to_css(dest)?; - dest.write_str(" ")?; - self.second.to_css(dest)?; - } - Ok(()) - } - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue { - if let Some(ref second) = self.second { - Self::ComputedValue { first: self.first.clone(), - second: second.clone(), - sides_are_logical: false } - } else { - Self::ComputedValue { first: Side::Clip, - second: self.first.clone(), - sides_are_logical: true } - } - } - - #[inline] - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - if computed.sides_are_logical { - assert!(computed.first == Side::Clip); - SpecifiedValue { first: computed.second.clone(), - second: None } - } else { - SpecifiedValue { first: computed.first.clone(), - second: Some(computed.second.clone()) } - } - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T { - first: Side::Clip, - second: Side::Clip, - sides_are_logical: true, - } - } - pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<SpecifiedValue, ParseError<'i>> { - let first = Side::parse(context, input)?; - let second = input.try(|input| Side::parse(context, input)).ok(); - Ok(SpecifiedValue { - first: first, - second: second, - }) - } - impl Parse for Side { - fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<Side, ParseError<'i>> { - let location = input.current_source_location(); - match *input.next()? { - Token::Ident(ref ident) => { - match_ignore_ascii_case! { ident, - "clip" => Ok(Side::Clip), - "ellipsis" => Ok(Side::Ellipsis), - _ => Err(location.new_custom_error( - SelectorParseErrorKind::UnexpectedIdent(ident.clone()) - )) - } - } - Token::QuotedString(ref v) => { - Ok(Side::String(v.as_ref().to_owned().into_boxed_str())) - } - ref t => Err(location.new_unexpected_token_error(t.clone())), - } - } - } -</%helpers:longhand> +${helpers.predefined_type("text-overflow", + "TextOverflow", + "computed::TextOverflow::get_initial_value()", + animation_value_type="discrete", + boxed=True, + flags="APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-ui/#propdef-text-overflow")} ${helpers.single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext", diff --git a/components/style/selector_map.rs b/components/style/selector_map.rs index c86053e8186..e3acda567f2 100644 --- a/components/style/selector_map.rs +++ b/components/style/selector_map.rs @@ -294,7 +294,7 @@ impl<T: SelectorMapEntry> SelectorMap<T> { /// FIXME(bholley) This overlaps with SelectorMap<Rule>::get_all_matching_rules, /// but that function is extremely hot and I'd rather not rearrange it. #[inline] - pub fn lookup<'a, E, F>(&'a self, element: E, quirks_mode: QuirksMode, f: &mut F) -> bool + pub fn lookup<'a, E, F>(&'a self, element: E, quirks_mode: QuirksMode, mut f: F) -> bool where E: TElement, F: FnMut(&'a T) -> bool @@ -361,14 +361,14 @@ impl<T: SelectorMapEntry> SelectorMap<T> { quirks_mode: QuirksMode, additional_id: Option<&Atom>, additional_classes: &[Atom], - f: &mut F, + mut f: F, ) -> bool where E: TElement, F: FnMut(&'a T) -> bool { // Do the normal lookup. - if !self.lookup(element, quirks_mode, f) { + if !self.lookup(element, quirks_mode, |entry| f(entry)) { return false; } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index acdb19da98b..687a05036d2 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1475,7 +1475,7 @@ impl Stylist { data.selectors_for_cache_revalidation.lookup( element, self.quirks_mode, - &mut |selector_and_hashes| { + |selector_and_hashes| { results.push(matches_selector( &selector_and_hashes.selector, selector_and_hashes.selector_offset, @@ -1493,7 +1493,7 @@ impl Stylist { stylist.cascade_data.author.selectors_for_cache_revalidation.lookup( element, stylist.quirks_mode, - &mut |selector_and_hashes| { + |selector_and_hashes| { results.push(matches_selector( &selector_and_hashes.selector, selector_and_hashes.selector_offset, diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index 8114a98d790..03427594331 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -8,9 +8,11 @@ use app_units::Au; use std::fmt; use style_traits::ToCss; use values::animated::ToAnimatedValue; -use values::computed::NonNegativeLength; +use values::computed::{Context, NonNegativeLength, ToComputedValue}; use values::specified::font as specified; +use values::specified::length::{FontBaseSize, NoCalcLength}; +pub use values::computed::Length as MozScriptMinSize; pub use values::specified::font::XTextZoom; #[derive(Animate, ComputeSquaredDistance, MallocSizeOf, ToAnimatedZero)] @@ -94,3 +96,28 @@ impl ToAnimatedValue for FontSize { } } } + +impl ToComputedValue for specified::MozScriptMinSize { + type ComputedValue = MozScriptMinSize; + + fn to_computed_value(&self, cx: &Context) -> MozScriptMinSize { + // this value is used in the computation of font-size, so + // we use the parent size + let base_size = FontBaseSize::InheritedStyle; + match self.0 { + NoCalcLength::FontRelative(value) => { + value.to_computed_value(cx, base_size) + } + NoCalcLength::ServoCharacterWidth(value) => { + value.to_computed_value(base_size.resolve(cx)) + } + ref l => { + l.to_computed_value(cx) + } + } + } + + fn from_computed_value(other: &MozScriptMinSize) -> Self { + specified::MozScriptMinSize(ToComputedValue::from_computed_value(other)) + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 4a74cabf72c..558c084b64f 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -36,7 +36,7 @@ pub use self::angle::Angle; pub use self::background::{BackgroundSize, BackgroundRepeat}; pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderCornerRadius, BorderSpacing}; -pub use self::font::XTextZoom; +pub use self::font::{XTextZoom, MozScriptMinSize}; pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; @@ -54,7 +54,7 @@ pub use self::percentage::Percentage; pub use self::position::Position; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth}; pub use self::table::XSpan; -pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing}; +pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextOverflow, WordSpacing}; pub use self::time::Time; pub use self::transform::{TimingFunction, TransformOrigin}; diff --git a/components/style/values/computed/text.rs b/components/style/values/computed/text.rs index ec55d27399b..4c724f7e418 100644 --- a/components/style/values/computed/text.rs +++ b/components/style/values/computed/text.rs @@ -4,6 +4,8 @@ //! Computed types for text properties. +use std::fmt; +use style_traits::ToCss; use values::{CSSInteger, CSSFloat}; use values::animated::ToAnimatedZero; use values::computed::{NonNegativeLength, NonNegativeNumber}; @@ -11,6 +13,7 @@ use values::computed::length::{Length, LengthOrPercentage}; use values::generics::text::InitialLetter as GenericInitialLetter; use values::generics::text::LineHeight as GenericLineHeight; use values::generics::text::Spacing; +use values::specified::text::TextOverflowSide; /// A computed value for the `initial-letter` property. pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>; @@ -28,3 +31,46 @@ impl ToAnimatedZero for LineHeight { #[inline] fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) } } + +#[derive(Clone, Debug, MallocSizeOf, PartialEq)] +/// text-overflow. +/// When the specified value only has one side, that's the "second" +/// side, and the sides are logical, so "second" means "end". The +/// start side is Clip in that case. +/// +/// When the specified value has two sides, those are our "first" +/// and "second" sides, and they are physical sides ("left" and +/// "right"). +pub struct TextOverflow { + /// First side + pub first: TextOverflowSide, + /// Second side + pub second: TextOverflowSide, + /// True if the specified value only has one side. + pub sides_are_logical: bool, +} + +impl TextOverflow { + /// Returns the initial `text-overflow` value + pub fn get_initial_value() -> TextOverflow { + TextOverflow { + first: TextOverflowSide::Clip, + second: TextOverflowSide::Clip, + sides_are_logical: true, + } + } +} + +impl ToCss for TextOverflow { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + if self.sides_are_logical { + debug_assert!(self.first == TextOverflowSide::Clip); + self.second.to_css(dest)?; + } else { + self.first.to_css(dest)?; + dest.write_str(" ")?; + self.second.to_css(dest)?; + } + Ok(()) + } +} diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index a04dcd80c5e..e4d007fcafa 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -12,9 +12,11 @@ use parser::{Parse, ParserContext}; use properties::longhands::system_font::SystemFont; use std::fmt; use style_traits::{ToCss, StyleParseErrorKind, ParseError}; -use values::computed::{font as computed, Context, NonNegativeLength, ToComputedValue}; +use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue}; use values::specified::{LengthOrPercentage, NoCalcLength}; -use values::specified::length::FontBaseSize; +use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize}; + +const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8; #[derive(Clone, Debug, MallocSizeOf, PartialEq)] /// A specified font-size value @@ -391,3 +393,24 @@ impl ToCss for XTextZoom { Ok(()) } } + +#[cfg_attr(feature = "gecko", derive(MallocSizeOf))] +#[derive(Clone, Debug, PartialEq, ToCss)] +/// Specifies the minimum font size allowed due to changes in scriptlevel. +/// Ref: https://wiki.mozilla.org/MathML:mstyle +pub struct MozScriptMinSize(pub NoCalcLength); + +impl MozScriptMinSize { + #[inline] + /// Calculate initial value of -moz-script-min-size. + pub fn get_initial_value() -> Length { + Length::new(DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * (AU_PER_PT / AU_PER_PX)) + } +} + +impl Parse for MozScriptMinSize { + fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<MozScriptMinSize, ParseError<'i>> { + debug_assert!(false, "Should be set directly by presentation attributes only."); + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 2f01f66029e..1c9bc6122a6 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -30,7 +30,7 @@ pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, Justify pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing}; -pub use self::font::XTextZoom; +pub use self::font::{XTextZoom, MozScriptMinSize}; pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; @@ -50,7 +50,7 @@ pub use self::percentage::Percentage; pub use self::position::{Position, PositionComponent}; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth}; pub use self::table::XSpan; -pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing}; +pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextOverflow, WordSpacing}; pub use self::time::Time; pub use self::transform::{TimingFunction, TransformOrigin}; pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; diff --git a/components/style/values/specified/text.rs b/components/style/values/specified/text.rs index ee39060b959..355cbc18960 100644 --- a/components/style/values/specified/text.rs +++ b/components/style/values/specified/text.rs @@ -4,13 +4,14 @@ //! Specified types for text properties. -use cssparser::Parser; +use cssparser::{Parser, Token}; use parser::{Parse, ParserContext}; use selectors::parser::SelectorParseErrorKind; use std::ascii::AsciiExt; use style_traits::ParseError; use values::computed::{Context, ToComputedValue}; use values::computed::text::LineHeight as ComputedLineHeight; +use values::computed::text::TextOverflow as ComputedTextOverflow; use values::generics::text::InitialLetter as GenericInitialLetter; use values::generics::text::LineHeight as GenericLineHeight; use values::generics::text::Spacing; @@ -154,3 +155,90 @@ impl ToComputedValue for LineHeight { } } } + +/// A generic value for the `text-overflow` property. +#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] +pub enum TextOverflowSide { + /// Clip inline content. + Clip, + /// Render ellipsis to represent clipped inline content. + Ellipsis, + /// Render a given string to represent clipped inline content. + String(Box<str>), +} + +impl Parse for TextOverflowSide { + fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) + -> Result<TextOverflowSide, ParseError<'i>> { + let location = input.current_source_location(); + match *input.next()? { + Token::Ident(ref ident) => { + match_ignore_ascii_case! { ident, + "clip" => Ok(TextOverflowSide::Clip), + "ellipsis" => Ok(TextOverflowSide::Ellipsis), + _ => Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent(ident.clone()) + )) + } + } + Token::QuotedString(ref v) => { + Ok(TextOverflowSide::String(v.as_ref().to_owned().into_boxed_str())) + } + ref t => Err(location.new_unexpected_token_error(t.clone())), + } + } +} + +#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] +/// text-overflow. Specifies rendering when inline content overflows its line box edge. +pub struct TextOverflow { + /// First value. Applies to end line box edge if no second is supplied; line-left edge otherwise. + pub first: TextOverflowSide, + /// Second value. Applies to the line-right edge if supplied. + pub second: Option<TextOverflowSide>, +} + +impl Parse for TextOverflow { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<TextOverflow, ParseError<'i>> { + let first = TextOverflowSide::parse(context, input)?; + let second = input.try(|input| TextOverflowSide::parse(context, input)).ok(); + Ok(TextOverflow { first, second }) + } +} + +impl ToComputedValue for TextOverflow { + type ComputedValue = ComputedTextOverflow; + + #[inline] + fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue { + if let Some(ref second) = self.second { + Self::ComputedValue { + first: self.first.clone(), + second: second.clone(), + sides_are_logical: false, + } + } else { + Self::ComputedValue { + first: TextOverflowSide::Clip, + second: self.first.clone(), + sides_are_logical: true, + } + } + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + if computed.sides_are_logical { + assert!(computed.first == TextOverflowSide::Clip); + TextOverflow { + first: computed.second.clone(), + second: None, + } + } else { + TextOverflow { + first: computed.first.clone(), + second: Some(computed.second.clone()), + } + } + } +} |