diff options
-rw-r--r-- | components/style/gecko_bindings/nsstring_vendor/src/lib.rs | 14 | ||||
-rw-r--r-- | components/style/gecko_bindings/sugar/ns_style_auto_array.rs | 14 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 44 |
3 files changed, 57 insertions, 15 deletions
diff --git a/components/style/gecko_bindings/nsstring_vendor/src/lib.rs b/components/style/gecko_bindings/nsstring_vendor/src/lib.rs index af0ba1d1918..ef2f07e0642 100644 --- a/components/style/gecko_bindings/nsstring_vendor/src/lib.rs +++ b/components/style/gecko_bindings/nsstring_vendor/src/lib.rs @@ -574,6 +574,12 @@ impl nsACString { pub unsafe fn as_str_unchecked(&self) -> &str { str::from_utf8_unchecked(self) } + + pub fn truncate(&mut self) { + unsafe { + Gecko_TruncateCString(self); + } + } } impl<'a> From<&'a str> for nsCString<'a> { @@ -674,6 +680,12 @@ impl nsAString { Gecko_AppendUTF8toString(self as *mut _, other as *const _); } } + + pub fn truncate(&mut self) { + unsafe { + Gecko_TruncateString(self); + } + } } // NOTE: The From impl for a string slice for nsString produces a <'static> @@ -727,10 +739,12 @@ extern "C" { fn Gecko_FinalizeCString(this: *mut nsACString); fn Gecko_AssignCString(this: *mut nsACString, other: *const nsACString); fn Gecko_AppendCString(this: *mut nsACString, other: *const nsACString); + fn Gecko_TruncateCString(this: *mut nsACString); fn Gecko_FinalizeString(this: *mut nsAString); fn Gecko_AssignString(this: *mut nsAString, other: *const nsAString); fn Gecko_AppendString(this: *mut nsAString, other: *const nsAString); + fn Gecko_TruncateString(this: *mut nsAString); // Gecko implementation in nsReadableUtils.cpp fn Gecko_AppendUTF16toCString(this: *mut nsACString, other: *const nsAString); diff --git a/components/style/gecko_bindings/sugar/ns_style_auto_array.rs b/components/style/gecko_bindings/sugar/ns_style_auto_array.rs index 9c41a0b6ec4..b20ee735631 100644 --- a/components/style/gecko_bindings/sugar/ns_style_auto_array.rs +++ b/components/style/gecko_bindings/sugar/ns_style_auto_array.rs @@ -7,7 +7,7 @@ use gecko_bindings::bindings::Gecko_EnsureStyleAnimationArrayLength; use gecko_bindings::structs::nsStyleAutoArray; use std::iter::{once, Chain, Once, IntoIterator}; -use std::ops::Index; +use std::ops::{Index, IndexMut}; use std::slice::{Iter, IterMut}; impl<T> Index<usize> for nsStyleAutoArray<T> { @@ -23,6 +23,18 @@ impl<T> Index<usize> for nsStyleAutoArray<T> { } } +impl<T> IndexMut<usize> for nsStyleAutoArray<T> { + fn index_mut(&mut self, index: usize) -> &mut T { + if index > self.len() { + panic!("out of range") + } + match index { + 0 => &mut self.mFirstElement, + _ => &mut self.mOtherElements[index - 1], + } + } +} + impl<T> nsStyleAutoArray<T> { /// Mutably iterate over the array elements. pub fn iter_mut(&mut self) -> Chain<Once<&mut T>, IterMut<T>> { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 0488ed31479..6d5885473c4 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1021,8 +1021,13 @@ fn static_assert() { #[allow(non_snake_case)] pub fn copy_animation_${ident}_from(&mut self, other: &Self) { unsafe { self.gecko.mAnimations.ensure_len(other.gecko.mAnimations.len()) }; - self.gecko.mAnimation${gecko_ffi_name}Count = other.gecko.mAnimation${gecko_ffi_name}Count; - for (index, animation) in self.gecko.mAnimations.iter_mut().enumerate() { + + let count = other.gecko.mAnimation${gecko_ffi_name}Count; + self.gecko.mAnimation${gecko_ffi_name}Count = count; + + // The length of mAnimations is often greater than mAnimationXXCount, + // don't copy values over the count. + for (index, animation) in self.gecko.mAnimations.iter_mut().enumerate().take(count as usize) { animation.m${gecko_ffi_name} = other.gecko.mAnimations[index].m${gecko_ffi_name}; } } @@ -1038,7 +1043,9 @@ fn static_assert() { <%def name="impl_animation_time_value(ident, gecko_ffi_name)"> #[allow(non_snake_case)] pub fn set_animation_${ident}(&mut self, v: longhands::animation_${ident}::computed_value::T) { + assert!(v.0.len() > 0); unsafe { self.gecko.mAnimations.ensure_len(v.0.len()) }; + self.gecko.mAnimation${gecko_ffi_name}Count = v.0.len() as u32; for (servo, gecko) in v.0.into_iter().zip(self.gecko.mAnimations.iter_mut()) { gecko.m${gecko_ffi_name} = servo.seconds() * 1000.; @@ -1060,7 +1067,9 @@ fn static_assert() { use properties::longhands::animation_${ident}::single_value::computed_value::T as Keyword; use gecko_bindings::structs; + assert!(v.0.len() > 0); unsafe { self.gecko.mAnimations.ensure_len(v.0.len()) }; + self.gecko.mAnimation${gecko_ffi_name}Count = v.0.len() as u32; for (servo, gecko) in v.0.into_iter().zip(self.gecko.mAnimations.iter_mut()) { @@ -1365,9 +1374,14 @@ fn static_assert() { pub fn set_animation_name(&mut self, v: longhands::animation_name::computed_value::T) { use nsstring::nsCString; unsafe { self.gecko.mAnimations.ensure_len(v.0.len()) }; - self.gecko.mAnimationNameCount = v.0.len() as u32; - for (servo, gecko) in v.0.into_iter().zip(self.gecko.mAnimations.iter_mut()) { - gecko.mName.assign_utf8(&nsCString::from(servo.0.to_string())); + + if v.0.len() > 0 { + self.gecko.mAnimationNameCount = v.0.len() as u32; + for (servo, gecko) in v.0.into_iter().zip(self.gecko.mAnimations.iter_mut()) { + gecko.mName.assign_utf8(&nsCString::from(servo.0.to_string())); + } + } else { + unsafe { self.gecko.mAnimations[0].mName.truncate(); } } } pub fn animation_name_at(&self, index: usize) @@ -1379,8 +1393,13 @@ fn static_assert() { } pub fn copy_animation_name_from(&mut self, other: &Self) { unsafe { self.gecko.mAnimations.ensure_len(other.gecko.mAnimations.len()) }; - self.gecko.mAnimationNameCount = other.gecko.mAnimationNameCount; - for (index, animation) in self.gecko.mAnimations.iter_mut().enumerate() { + + let count = other.gecko.mAnimationNameCount; + self.gecko.mAnimationNameCount = count; + + // The length of mAnimations is often greater than mAnimationXXCount, + // don't copy values over the count. + for (index, animation) in self.gecko.mAnimations.iter_mut().enumerate().take(count as usize) { animation.mName.assign(&other.gecko.mAnimations[index].mName); } } @@ -1400,7 +1419,9 @@ fn static_assert() { use std::f32; use properties::longhands::animation_iteration_count::single_value::SpecifiedValue as AnimationIterationCount; + assert!(v.0.len() > 0); unsafe { self.gecko.mAnimations.ensure_len(v.0.len()) }; + self.gecko.mAnimationIterationCountCount = v.0.len() as u32; for (servo, gecko) in v.0.into_iter().zip(self.gecko.mAnimations.iter_mut()) { match servo { @@ -1424,6 +1445,7 @@ fn static_assert() { ${impl_copy_animation_value('iteration_count', 'IterationCount')} pub fn set_animation_timing_function(&mut self, v: longhands::animation_timing_function::computed_value::T) { + assert!(v.0.len() > 0); unsafe { self.gecko.mAnimations.ensure_len(v.0.len()) }; self.gecko.mAnimationTimingFunctionCount = v.0.len() as u32; @@ -1432,17 +1454,11 @@ fn static_assert() { } } ${impl_animation_count('timing_function', 'TimingFunction')} + ${impl_copy_animation_value('timing_function', 'TimingFunction')} pub fn animation_timing_function_at(&self, index: usize) -> longhands::animation_timing_function::computed_value::SingleComputedValue { self.gecko.mAnimations[index].mTimingFunction.into() } - pub fn copy_animation_timing_function_from(&mut self, other: &Self) { - unsafe { self.gecko.mAnimations.ensure_len(other.gecko.mAnimations.len()) }; - self.gecko.mAnimationTimingFunctionCount = other.gecko.mAnimationTimingFunctionCount; - for (index, animation) in self.gecko.mAnimations.iter_mut().enumerate() { - animation.mTimingFunction = other.gecko.mAnimations[index].mTimingFunction; - } - } <% scroll_snap_type_keyword = Keyword("scroll-snap-type", "none mandatory proximity") %> |