aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko_bindings/nsstring_vendor/src/lib.rs14
-rw-r--r--components/style/gecko_bindings/sugar/ns_style_auto_array.rs14
-rw-r--r--components/style/properties/gecko.mako.rs44
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") %>