aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/animation.rs6
-rw-r--r--components/layout/generated_content.rs16
-rw-r--r--components/selectors/bloom.rs2
-rw-r--r--components/style/animation.rs57
-rw-r--r--components/style/gecko/data.rs24
-rw-r--r--components/style/gecko/media_queries.rs6
-rw-r--r--components/style/lib.rs1
-rw-r--r--components/style/matching.rs1
-rw-r--r--components/style/properties/gecko.mako.rs12
-rw-r--r--components/style/properties/helpers/animated_properties.mako.rs37
-rw-r--r--components/style/properties/properties.mako.rs6
-rw-r--r--components/style/shared_lock.rs2
-rw-r--r--components/style/stylesheets/keyframes_rule.rs6
-rw-r--r--components/style/stylist.rs83
-rw-r--r--components/style/values/computed/transform.rs6
-rw-r--r--components/style/values/generics/border.rs21
-rw-r--r--components/style/values/generics/counters.rs52
-rw-r--r--components/style/values/generics/effects.rs30
-rw-r--r--components/style/values/specified/counters.rs9
-rw-r--r--components/style/values/specified/font.rs4
-rw-r--r--components/style/values/specified/position.rs18
-rw-r--r--components/style_derive/specified_value_info.rs5
-rw-r--r--components/style_derive/to_css.rs12
-rw-r--r--components/style_traits/specified_value_info.rs2
-rw-r--r--components/style_traits/values.rs18
-rw-r--r--ports/geckolib/error_reporter.rs10
-rw-r--r--ports/geckolib/glue.rs86
-rw-r--r--ports/geckolib/stylesheet_loader.rs14
-rw-r--r--tests/unit/style/properties/serialization.rs29
29 files changed, 247 insertions, 328 deletions
diff --git a/components/layout/animation.rs b/components/layout/animation.rs
index 3ea59e7b972..05718dda00a 100644
--- a/components/layout/animation.rs
+++ b/components/layout/animation.rs
@@ -39,14 +39,14 @@ where
let mut new_running_animations = vec![];
while let Ok(animation) = new_animations_receiver.try_recv() {
let mut should_push = true;
- if let Animation::Keyframes(ref node, ref name, ref state) = animation {
+ if let Animation::Keyframes(ref node, _, ref name, ref state) = animation {
// If the animation was already present in the list for the
// node, just update its state, else push the new animation to
// run.
if let Some(ref mut animations) = running_animations.get_mut(node) {
// TODO: This being linear is probably not optimal.
for anim in animations.iter_mut() {
- if let Animation::Keyframes(_, ref anim_name, ref mut anim_state) = *anim {
+ if let Animation::Keyframes(_, _, ref anim_name, ref mut anim_state) = *anim {
if *name == *anim_name {
debug!("update_animation_state: Found other animation {}", name);
anim_state.update_from_other(&state, timer);
@@ -83,7 +83,7 @@ where
Animation::Transition(_, started_at, ref frame, _expired) => {
now < started_at + frame.duration
}
- Animation::Keyframes(_, _, ref mut state) => {
+ Animation::Keyframes(_, _, _, ref mut state) => {
// This animation is still running, or we need to keep
// iterating.
now < state.started_at + state.duration || state.tick()
diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs
index 700e9bc9ddd..da390cc9cec 100644
--- a/components/layout/generated_content.rs
+++ b/components/layout/generated_content.rs
@@ -272,27 +272,27 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
}
self.traversal.list_item.truncate_to_level(self.level);
- for &(ref counter_name, value) in &*fragment.style().get_counters().counter_reset {
- let counter_name = &*counter_name.0;
+ for pair in &*fragment.style().get_counters().counter_reset {
+ let counter_name = &*pair.name.0;
if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
- counter.reset(self.level, value);
+ counter.reset(self.level, pair.value);
continue
}
let mut counter = Counter::new();
- counter.reset(self.level, value);
+ counter.reset(self.level, pair.value);
self.traversal.counters.insert(counter_name.to_owned(), counter);
}
- for &(ref counter_name, value) in &*fragment.style().get_counters().counter_increment {
- let counter_name = &*counter_name.0;
+ for pair in &*fragment.style().get_counters().counter_increment {
+ let counter_name = &*pair.name.0;
if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
- counter.increment(self.level, value);
+ counter.increment(self.level, pair.value);
continue
}
let mut counter = Counter::new();
- counter.increment(self.level, value);
+ counter.increment(self.level, pair.value);
self.traversal.counters.insert(counter_name.to_owned(), counter);
}
diff --git a/components/selectors/bloom.rs b/components/selectors/bloom.rs
index e06649d73bf..e4cd0a77f98 100644
--- a/components/selectors/bloom.rs
+++ b/components/selectors/bloom.rs
@@ -335,7 +335,7 @@ fn create_and_insert_some_stuff() {
let false_positives = (1001_usize..2000).filter(|i| bf.might_contain(i)).count();
- assert!(false_positives < 150, "{} is not < 150", false_positives); // 15%.
+ assert!(false_positives < 160, "{} is not < 160", false_positives); // 16%.
for i in 0_usize..100 {
bf.remove(&i);
diff --git a/components/style/animation.rs b/components/style/animation.rs
index 9fc93a6cd5b..bbf847d7f14 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! CSS transitions and animations.
-#![deny(missing_docs)]
use Atom;
use bezier::Bezier;
@@ -16,8 +15,9 @@ use properties::longhands::animation_direction::computed_value::single_value::T
use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState;
use rule_tree::CascadeLevel;
use servo_arc::Arc;
+use std::fmt;
use std::sync::mpsc::Sender;
-use stylesheets::keyframes_rule::{KeyframesStep, KeyframesStepValue};
+use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue};
use timer::Timer;
use values::computed::Time;
use values::computed::transform::TimingFunction;
@@ -52,7 +52,7 @@ pub enum KeyframesRunningState {
/// duration, the current and maximum iteration count, and the state (either
/// playing or paused).
// TODO: unify the use of f32/f64 in this file.
-#[derive(Clone, Debug)]
+#[derive(Clone)]
pub struct KeyframesAnimationState {
/// The time this animation started at.
pub started_at: f64,
@@ -183,6 +183,22 @@ impl KeyframesAnimationState {
}
}
+impl fmt::Debug for KeyframesAnimationState {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("KeyframesAnimationState")
+ .field("started_at", &self.started_at)
+ .field("duration", &self.duration)
+ .field("delay", &self.delay)
+ .field("iteration_state", &self.iteration_state)
+ .field("running_state", &self.running_state)
+ .field("direction", &self.direction)
+ .field("current_direction", &self.current_direction)
+ .field("expired", &self.expired)
+ .field("cascade_style", &())
+ .finish()
+ }
+}
+
/// State relating to an animation.
#[derive(Clone, Debug)]
pub enum Animation {
@@ -194,7 +210,9 @@ pub enum Animation {
Transition(OpaqueNode, f64, AnimationFrame, bool),
/// A keyframes animation is identified by a name, and can have a
/// node-dependent state (i.e. iteration count, etc.).
- Keyframes(OpaqueNode, Atom, KeyframesAnimationState),
+ ///
+ /// TODO(emilio): The animation object could be refcounted.
+ Keyframes(OpaqueNode, KeyframesAnimation, Atom, KeyframesAnimationState),
}
impl Animation {
@@ -204,7 +222,7 @@ impl Animation {
debug_assert!(!self.is_expired());
match *self {
Animation::Transition(_, _, _, ref mut expired) => *expired = true,
- Animation::Keyframes(_, _, ref mut state) => state.expired = true,
+ Animation::Keyframes(_, _, _, ref mut state) => state.expired = true,
}
}
@@ -213,7 +231,7 @@ impl Animation {
pub fn is_expired(&self) -> bool {
match *self {
Animation::Transition(_, _, _, expired) => expired,
- Animation::Keyframes(_, _, ref state) => state.expired,
+ Animation::Keyframes(_, _, _, ref state) => state.expired,
}
}
@@ -222,7 +240,7 @@ impl Animation {
pub fn node(&self) -> &OpaqueNode {
match *self {
Animation::Transition(ref node, _, _, _) => node,
- Animation::Keyframes(ref node, _, _) => node,
+ Animation::Keyframes(ref node, _, _, _) => node,
}
}
@@ -231,7 +249,7 @@ impl Animation {
pub fn is_paused(&self) -> bool {
match *self {
Animation::Transition(..) => false,
- Animation::Keyframes(_, _, ref state) => state.is_paused(),
+ Animation::Keyframes(_, _, _, ref state) => state.is_paused(),
}
}
@@ -390,7 +408,6 @@ impl PropertyAnimation {
/// Inserts transitions into the queue of running animations as applicable for
/// the given style difference. This is called from the layout worker threads.
/// Returns true if any animations were kicked off and false otherwise.
-#[cfg(feature = "servo")]
pub fn start_transitions_if_applicable(
new_animations_sender: &Sender<Animation>,
opaque_node: OpaqueNode,
@@ -500,12 +517,16 @@ where
/// Triggers animations for a given node looking at the animation property
/// values.
-pub fn maybe_start_animations(
+pub fn maybe_start_animations<E>(
+ element: E,
context: &SharedStyleContext,
new_animations_sender: &Sender<Animation>,
node: OpaqueNode,
new_style: &Arc<ComputedValues>,
-) -> bool {
+) -> bool
+where
+ E: TElement,
+{
let mut had_animations = false;
let box_style = new_style.get_box();
@@ -522,7 +543,7 @@ pub fn maybe_start_animations(
continue;
}
- if let Some(ref anim) = context.stylist.get_animation(name) {
+ if let Some(anim) = context.stylist.get_animation(name, element) {
debug!("maybe_start_animations: animation {} found", name);
// If this animation doesn't have any keyframe, we can just continue
@@ -561,6 +582,7 @@ pub fn maybe_start_animations(
new_animations_sender
.send(Animation::Keyframes(
node,
+ anim.clone(),
name.clone(),
KeyframesAnimationState {
started_at: animation_start,
@@ -605,6 +627,7 @@ pub fn update_style_for_animation_frame(
true
}
+
/// Updates a single animation and associated style based on the current time.
pub fn update_style_for_animation<E>(
context: &SharedStyleContext,
@@ -628,7 +651,7 @@ pub fn update_style_for_animation<E>(
*style = new_style
}
},
- Animation::Keyframes(_, ref name, ref state) => {
+ Animation::Keyframes(_, ref animation, ref name, ref state) => {
debug!(
"update_style_for_animation: animation found: \"{}\", {:?}",
name, state
@@ -641,14 +664,6 @@ pub fn update_style_for_animation<E>(
KeyframesRunningState::Paused(progress) => started_at + duration * progress,
};
- let animation = match context.stylist.get_animation(name) {
- None => {
- warn!("update_style_for_animation: Animation {:?} not found", name);
- return;
- },
- Some(animation) => animation,
- };
-
debug_assert!(!animation.steps.is_empty());
let maybe_index = style
diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs
index 567a9b7f6ca..a4ed8294ac2 100644
--- a/components/style/gecko/data.rs
+++ b/components/style/gecko/data.rs
@@ -8,8 +8,8 @@ use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use context::QuirksMode;
use dom::TElement;
use gecko_bindings::bindings::{self, RawServoStyleSet};
-use gecko_bindings::structs::{self, RawGeckoPresContextOwned, ServoStyleSetSizes, ServoStyleSheet};
-use gecko_bindings::structs::{ServoStyleSheetInner, StyleSheetInfo, nsIDocument};
+use gecko_bindings::structs::{self, RawGeckoPresContextOwned, ServoStyleSetSizes, StyleSheet as DomStyleSheet};
+use gecko_bindings::structs::{StyleSheetInfo, nsIDocument};
use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI};
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use malloc_size_of::MallocSizeOfOps;
@@ -23,7 +23,7 @@ use stylist::Stylist;
/// Little wrapper to a Gecko style sheet.
#[derive(Debug, Eq, PartialEq)]
-pub struct GeckoStyleSheet(*const ServoStyleSheet);
+pub struct GeckoStyleSheet(*const DomStyleSheet);
impl ToMediaListKey for ::gecko::data::GeckoStyleSheet {
fn to_media_list_key(&self) -> MediaListKey {
@@ -33,30 +33,30 @@ impl ToMediaListKey for ::gecko::data::GeckoStyleSheet {
}
impl GeckoStyleSheet {
- /// Create a `GeckoStyleSheet` from a raw `ServoStyleSheet` pointer.
+ /// Create a `GeckoStyleSheet` from a raw `DomStyleSheet` pointer.
#[inline]
- pub unsafe fn new(s: *const ServoStyleSheet) -> Self {
+ pub unsafe fn new(s: *const DomStyleSheet) -> Self {
debug_assert!(!s.is_null());
bindings::Gecko_StyleSheet_AddRef(s);
Self::from_addrefed(s)
}
- /// Create a `GeckoStyleSheet` from a raw `ServoStyleSheet` pointer that
+ /// Create a `GeckoStyleSheet` from a raw `DomStyleSheet` pointer that
/// already holds a strong reference.
#[inline]
- pub unsafe fn from_addrefed(s: *const ServoStyleSheet) -> Self {
+ pub unsafe fn from_addrefed(s: *const DomStyleSheet) -> Self {
debug_assert!(!s.is_null());
GeckoStyleSheet(s)
}
- /// Get the raw `ServoStyleSheet` that we're wrapping.
- pub fn raw(&self) -> &ServoStyleSheet {
+ /// Get the raw `StyleSheet` that we're wrapping.
+ pub fn raw(&self) -> &DomStyleSheet {
unsafe { &*self.0 }
}
- fn inner(&self) -> &ServoStyleSheetInner {
+ fn inner(&self) -> &StyleSheetInfo {
unsafe {
- &*(self.raw()._base.mInner as *const StyleSheetInfo as *const ServoStyleSheetInner)
+ &*(self.raw().mInner as *const StyleSheetInfo)
}
}
@@ -98,7 +98,7 @@ impl StylesheetInDocument for GeckoStyleSheet {
use std::mem;
unsafe {
- let dom_media_list = self.raw()._base.mMedia.mRawPtr as *const DomMediaList;
+ let dom_media_list = self.raw().mMedia.mRawPtr as *const DomMediaList;
if dom_media_list.is_null() {
return None;
}
diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs
index e488fdfa00a..7d9724cc6c5 100644
--- a/components/style/gecko/media_queries.rs
+++ b/components/style/gecko/media_queries.rs
@@ -13,7 +13,7 @@ use euclid::TypedScale;
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
use gecko_bindings::bindings;
use gecko_bindings::structs;
-use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSUnit, nsCSSValue};
+use gecko_bindings::structs::{nsCSSKTableEntry, nsCSSKeyword, nsCSSUnit, nsCSSValue};
use gecko_bindings::structs::{nsMediaFeature, nsMediaFeature_RangeType};
use gecko_bindings::structs::{nsMediaFeature_ValueType, nsPresContext};
use gecko_bindings::structs::RawGeckoPresContextOwned;
@@ -479,7 +479,7 @@ where
}
unsafe fn find_in_table<F>(
- mut current_entry: *const nsCSSProps_KTableEntry,
+ mut current_entry: *const nsCSSKTableEntry,
mut f: F,
) -> Option<(nsCSSKeyword, i16)>
where
@@ -544,7 +544,7 @@ fn parse_feature_value<'i, 't>(
bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(), keyword.len() as u32)
};
- let first_table_entry: *const nsCSSProps_KTableEntry =
+ let first_table_entry: *const nsCSSKTableEntry =
unsafe { *feature.mData.mKeywordTable.as_ref() };
let value = match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } {
diff --git a/components/style/lib.rs b/components/style/lib.rs
index 538dce92b87..20a54c62680 100644
--- a/components/style/lib.rs
+++ b/components/style/lib.rs
@@ -103,7 +103,6 @@ extern crate void;
#[macro_use]
mod macros;
-#[cfg(feature = "servo")]
pub mod animation;
pub mod applicable_declarations;
#[allow(missing_docs)] // TODO.
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 97b31f4f6b0..1d5cbf8d375 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -425,6 +425,7 @@ trait PrivateMatchMethods: TElement {
let this_opaque = self.as_node().opaque();
// Trigger any present animations if necessary.
animation::maybe_start_animations(
+ *self,
&shared_context,
new_animations_sender,
this_opaque,
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index a3d316df321..4479d040564 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -5697,9 +5697,9 @@ clip-path
) {
unsafe {
bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut self.gecko, v.len() as u32);
- for (i, &(ref name, value)) in v.iter().enumerate() {
- self.gecko.m${counter_property}s[i].mCounter.assign(name.0.as_slice());
- self.gecko.m${counter_property}s[i].mValue = value;
+ for (i, ref pair) in v.iter().enumerate() {
+ self.gecko.m${counter_property}s[i].mCounter.assign(pair.name.0.as_slice());
+ self.gecko.m${counter_property}s[i].mValue = pair.value;
}
}
}
@@ -5717,12 +5717,16 @@ clip-path
pub fn clone_counter_${counter_property.lower()}(
&self
) -> longhands::counter_${counter_property.lower()}::computed_value::T {
+ use values::generics::counters::CounterPair;
use values::CustomIdent;
use gecko_string_cache::Atom;
longhands::counter_${counter_property.lower()}::computed_value::T::new(
self.gecko.m${counter_property}s.iter().map(|ref gecko_counter| {
- (CustomIdent(Atom::from(gecko_counter.mCounter.to_string())), gecko_counter.mValue)
+ CounterPair {
+ name: CustomIdent(Atom::from(gecko_counter.mCounter.to_string())),
+ value: gecko_counter.mValue,
+ }
}).collect()
)
}
diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs
index 57a8ed99880..fa6166e17ae 100644
--- a/components/style/properties/helpers/animated_properties.mako.rs
+++ b/components/style/properties/helpers/animated_properties.mako.rs
@@ -196,7 +196,6 @@ pub fn nscsspropertyid_is_transitionable(property: nsCSSPropertyID) -> bool {
/// An animated property interpolation between two computed values for that
/// property.
-#[cfg(feature = "servo")]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
pub enum AnimatedProperty {
@@ -213,7 +212,6 @@ pub enum AnimatedProperty {
% endfor
}
-#[cfg(feature = "servo")]
impl AnimatedProperty {
/// Get the name of this property.
pub fn name(&self) -> &'static str {
@@ -255,9 +253,12 @@ impl AnimatedProperty {
/// Update `style` with the proper computed style corresponding to this
/// animation at `progress`.
+ #[cfg_attr(feature = "gecko", allow(unused))]
pub fn update(&self, style: &mut ComputedValues, progress: f64) {
- match *self {
- % for prop in data.longhands:
+ #[cfg(feature = "servo")]
+ {
+ match *self {
+ % for prop in data.longhands:
% if prop.animatable:
AnimatedProperty::${prop.camel_case}(ref from, ref to) => {
// https://drafts.csswg.org/web-animations/#discrete-animation-type
@@ -276,7 +277,8 @@ impl AnimatedProperty {
style.mutate_${prop.style_struct.name_lower}().set_${prop.ident}(value);
}
% endif
- % endfor
+ % endfor
+ }
}
}
@@ -1291,16 +1293,8 @@ impl Animate for ComputedTransformOperation {
&TransformOperation::Perspective(ref fd),
&TransformOperation::Perspective(ref td),
) => {
- let mut fd_matrix = Matrix3D::identity();
- let mut td_matrix = Matrix3D::identity();
- if fd.px() > 0. {
- fd_matrix.m34 = -1. / fd.px();
- }
- if td.px() > 0. {
- td_matrix.m34 = -1. / td.px();
- }
- Ok(TransformOperation::Matrix3D(
- fd_matrix.animate(&td_matrix, procedure)?,
+ Ok(TransformOperation::Perspective(
+ fd.animate(td, procedure)?
))
},
_ if self.is_translate() && other.is_translate() => {
@@ -2640,16 +2634,7 @@ impl ComputeSquaredDistance for ComputedTransformOperation {
&TransformOperation::Perspective(ref fd),
&TransformOperation::Perspective(ref td),
) => {
- let mut fd_matrix = Matrix3D::identity();
- let mut td_matrix = Matrix3D::identity();
- if fd.px() > 0. {
- fd_matrix.m34 = -1. / fd.px();
- }
-
- if td.px() > 0. {
- td_matrix.m34 = -1. / td.px();
- }
- fd_matrix.compute_squared_distance(&td_matrix)
+ fd.compute_squared_distance(td)
}
(
&TransformOperation::Perspective(ref p),
@@ -2658,6 +2643,8 @@ impl ComputeSquaredDistance for ComputedTransformOperation {
&TransformOperation::Matrix3D(ref m),
&TransformOperation::Perspective(ref p),
) => {
+ // FIXME(emilio): Is this right? Why interpolating this with
+ // Perspective but not with anything else?
let mut p_matrix = Matrix3D::identity();
if p.px() > 0. {
p_matrix.m34 = -1. / p.px();
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index a1d2ee9d085..5e3d8eaeaaf 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -56,12 +56,6 @@ use style_adjuster::StyleAdjuster;
pub use self::declaration_block::*;
-#[cfg(feature = "gecko")]
-#[macro_export]
-macro_rules! property_name {
- ($s: tt) => { atom!($s) }
-}
-
<%!
from data import Method, Keyword, to_rust_ident, to_camel_case, SYSTEM_FONT_LONGHANDS
import os.path
diff --git a/components/style/shared_lock.rs b/components/style/shared_lock.rs
index 9bb54a274c6..e79f684a7bb 100644
--- a/components/style/shared_lock.rs
+++ b/components/style/shared_lock.rs
@@ -237,7 +237,7 @@ pub trait ToCssWithGuard {
#[cfg(feature = "gecko")]
pub struct DeepCloneParams {
/// The new sheet we're cloning rules into.
- pub reference_sheet: *const ::gecko_bindings::structs::ServoStyleSheet,
+ pub reference_sheet: *const ::gecko_bindings::structs::StyleSheet,
}
/// Parameters needed for deep clones.
diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs
index c4649dc135f..4de3acbaff5 100644
--- a/components/style/stylesheets/keyframes_rule.rs
+++ b/components/style/stylesheets/keyframes_rule.rs
@@ -259,7 +259,7 @@ impl DeepCloneWithLock for Keyframe {
/// declarations to apply.
///
/// TODO: Find a better name for this?
-#[derive(Debug, MallocSizeOf)]
+#[derive(Clone, Debug, MallocSizeOf)]
pub enum KeyframesStepValue {
/// A step formed by a declaration block specified by the CSS.
Declarations {
@@ -275,7 +275,7 @@ pub enum KeyframesStepValue {
}
/// A single step from a keyframe animation.
-#[derive(Debug, MallocSizeOf)]
+#[derive(Clone, Debug, MallocSizeOf)]
pub struct KeyframesStep {
/// The percentage of the animation duration when this step starts.
pub start_percentage: KeyframePercentage,
@@ -352,7 +352,7 @@ impl KeyframesStep {
/// of keyframes, in order.
///
/// It only takes into account animable properties.
-#[derive(Debug, MallocSizeOf)]
+#[derive(Clone, Debug, MallocSizeOf)]
pub struct KeyframesAnimation {
/// The difference steps of the animation.
pub steps: Vec<KeyframesStep>,
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index a76a461b73f..34f187e483a 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -1421,14 +1421,53 @@ impl Stylist {
}
/// Returns the registered `@keyframes` animation for the specified name.
- ///
- /// FIXME(emilio): This needs to account for the element rules.
#[inline]
- pub fn get_animation(&self, name: &Atom) -> Option<&KeyframesAnimation> {
- self.cascade_data
- .iter_origins()
- .filter_map(|(d, _)| d.animations.get(name))
- .next()
+ pub fn get_animation<'a, E>(
+ &'a self,
+ name: &Atom,
+ element: E,
+ ) -> Option<&'a KeyframesAnimation>
+ where
+ E: TElement + 'a,
+ {
+ macro_rules! try_find_in {
+ ($data:expr) => {
+ if let Some(animation) = $data.animations.get(name) {
+ return Some(animation);
+ }
+ }
+ }
+
+ // NOTE(emilio): We implement basically what Blink does for this case,
+ // which is [1] as of this writing.
+ //
+ // See [2] for the spec discussion about what to do about this. WebKit's
+ // behavior makes a bit more sense off-hand, but it's way more complex
+ // to implement, and it makes value computation having to thread around
+ // the cascade level, which is not great. Also, it breaks if you inherit
+ // animation-name from an element in a different tree.
+ //
+ // See [3] for the bug to implement whatever gets resolved, and related
+ // bugs for a bit more context.
+ //
+ // [1]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/
+ // core/css/resolver/style_resolver.cc?l=1267&rcl=90f9f8680ebb4a87d177f3b0833372ae4e0c88d8
+ // [2]: https://github.com/w3c/csswg-drafts/issues/1995
+ // [3]: https://bugzil.la/1458189
+ if let Some(shadow) = element.shadow_root() {
+ try_find_in!(shadow.style_data());
+ }
+
+ if let Some(shadow) = element.containing_shadow() {
+ try_find_in!(shadow.style_data());
+ } else {
+ try_find_in!(self.cascade_data.author);
+ }
+
+ try_find_in!(self.cascade_data.user);
+ try_find_in!(self.cascade_data.user_agent.cascade_data);
+
+ None
}
/// Computes the match results of a given element against the set of
@@ -1517,27 +1556,25 @@ impl Stylist {
E: TElement,
{
use font_metrics::get_metrics_provider_for_product;
- use std::iter;
-
- // FIXME(emilio): Why do we even need the rule node? We should probably
- // just avoid allocating it and calling `apply_declarations` directly,
- // maybe...
- let rule_node = self.rule_tree.insert_ordered_rules(iter::once((
- StyleSource::from_declarations(declarations),
- CascadeLevel::StyleAttributeNormal,
- )));
-
- // This currently ignores visited styles. It appears to be used for
- // font styles in <canvas> via Servo_StyleSet_ResolveForDeclarations.
- // It is unclear if visited styles are meaningful for this case.
+
+ let block = declarations.read_with(guards.author);
+ let iter_declarations = || {
+ block.declaration_importance_iter().map(|(declaration, importance)| {
+ debug_assert!(!importance.important());
+ (declaration, CascadeLevel::StyleAttributeNormal)
+ })
+ };
+
let metrics = get_metrics_provider_for_product();
- // FIXME(emilio): the pseudo bit looks quite dubious!
- properties::cascade::<E>(
+ // We don't bother inserting these declarations in the rule tree, since
+ // it'd be quite useless and slow.
+ properties::apply_declarations::<E, _, _>(
&self.device,
/* pseudo = */ None,
- &rule_node,
+ self.rule_tree.root(),
guards,
+ iter_declarations,
Some(parent_style),
Some(parent_style),
Some(parent_style),
diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs
index 38b45f83669..fd7a7cf5c2d 100644
--- a/components/style/values/computed/transform.rs
+++ b/components/style/values/computed/transform.rs
@@ -251,11 +251,11 @@ impl ToAnimatedZero for TransformOperation {
generic::TransformOperation::Rotate(_) => {
Ok(generic::TransformOperation::Rotate(Angle::zero()))
},
- generic::TransformOperation::Perspective(..) |
+ generic::TransformOperation::Perspective(ref l) => {
+ Ok(generic::TransformOperation::Perspective(l.to_animated_zero()?))
+ },
generic::TransformOperation::AccumulateMatrix { .. } |
generic::TransformOperation::InterpolateMatrix { .. } => {
- // Perspective: We convert a perspective function into an equivalent
- // ComputedMatrix, and then decompose/interpolate/recompose these matrices.
// AccumulateMatrix/InterpolateMatrix: We do interpolation on
// AccumulateMatrix/InterpolateMatrix by reading it as a ComputedMatrix
// (with layout information), and then do matrix interpolation.
diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs
index 6230a1cf36a..c25560ed0f1 100644
--- a/components/style/values/generics/border.rs
+++ b/components/style/values/generics/border.rs
@@ -23,12 +23,13 @@ pub enum BorderImageSideWidth<LengthOrPercentage, Number> {
/// A generic value for the `border-image-slice` property.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
- ToComputedValue)]
+ ToComputedValue, ToCss)]
pub struct BorderImageSlice<NumberOrPercentage> {
/// The offsets.
+ #[css(field_bound)]
pub offsets: Rect<NumberOrPercentage>,
/// Whether to fill the middle part.
- #[value_info(represents_keyword)]
+ #[css(represents_keyword)]
pub fill: bool,
}
@@ -86,22 +87,6 @@ where
}
}
-impl<N> ToCss for BorderImageSlice<N>
-where
- N: PartialEq + ToCss,
-{
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
- where
- W: Write,
- {
- self.offsets.to_css(dest)?;
- if self.fill {
- dest.write_str(" fill")?;
- }
- Ok(())
- }
-}
-
impl<L> BorderRadius<L> {
/// Returns a new `BorderRadius<L>`.
#[inline]
diff --git a/components/style/values/generics/counters.rs b/components/style/values/generics/counters.rs
index 7373cd8e947..9f50ab1e2b0 100644
--- a/components/style/values/generics/counters.rs
+++ b/components/style/values/generics/counters.rs
@@ -4,12 +4,19 @@
//! Generic types for counters-related CSS values.
-use std::fmt;
-use std::fmt::Write;
use std::ops::Deref;
-use style_traits::{CssWriter, ToCss};
use values::CustomIdent;
+/// A name / value pair for counters.
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
+ ToComputedValue, ToCss)]
+pub struct CounterPair<Integer> {
+ /// The name of the counter.
+ pub name: CustomIdent,
+ /// The value of the counter / increment / etc.
+ pub value: Integer,
+}
+
/// A generic value for the `counter-increment` property.
#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo,
ToComputedValue, ToCss)]
@@ -18,13 +25,13 @@ pub struct CounterIncrement<I>(Counters<I>);
impl<I> CounterIncrement<I> {
/// Returns a new value for `counter-increment`.
#[inline]
- pub fn new(counters: Vec<(CustomIdent, I)>) -> Self {
+ pub fn new(counters: Vec<CounterPair<I>>) -> Self {
CounterIncrement(Counters(counters.into_boxed_slice()))
}
}
impl<I> Deref for CounterIncrement<I> {
- type Target = [(CustomIdent, I)];
+ type Target = [CounterPair<I>];
#[inline]
fn deref(&self) -> &Self::Target {
@@ -40,13 +47,13 @@ pub struct CounterReset<I>(Counters<I>);
impl<I> CounterReset<I> {
/// Returns a new value for `counter-reset`.
#[inline]
- pub fn new(counters: Vec<(CustomIdent, I)>) -> Self {
+ pub fn new(counters: Vec<CounterPair<I>>) -> Self {
CounterReset(Counters(counters.into_boxed_slice()))
}
}
impl<I> Deref for CounterReset<I> {
- type Target = [(CustomIdent, I)];
+ type Target = [CounterPair<I>];
#[inline]
fn deref(&self) -> &Self::Target {
@@ -58,8 +65,8 @@ impl<I> Deref for CounterReset<I> {
///
/// Keyword `none` is represented by an empty vector.
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
- ToComputedValue)]
-pub struct Counters<I>(#[css(if_empty = "none")] Box<[(CustomIdent, I)]>);
+ ToComputedValue, ToCss)]
+pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);
impl<I> Default for Counters<I> {
#[inline]
@@ -67,30 +74,3 @@ impl<I> Default for Counters<I> {
Counters(vec![].into_boxed_slice())
}
}
-
-impl<I> ToCss for Counters<I>
-where
- I: ToCss,
-{
- #[inline]
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
- where
- W: fmt::Write,
- {
- if self.0.is_empty() {
- return dest.write_str("none");
- }
-
- let mut first = true;
- for &(ref name, ref value) in &*self.0 {
- if !first {
- dest.write_str(" ")?;
- }
- first = false;
- name.to_css(dest)?;
- dest.write_str(" ")?;
- value.to_css(dest)?;
- }
- Ok(())
- }
-}
diff --git a/components/style/values/generics/effects.rs b/components/style/values/generics/effects.rs
index 7a76cdeb7bc..e5ee10fcada 100644
--- a/components/style/values/generics/effects.rs
+++ b/components/style/values/generics/effects.rs
@@ -4,14 +4,12 @@
//! Generic types for CSS values related to effects.
-use std::fmt::{self, Write};
-use style_traits::values::{CssWriter, SequenceWriter, ToCss};
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
/// A generic value for a single `box-shadow`.
#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
- ToAnimatedValue, ToAnimatedZero)]
+ ToAnimatedValue, ToAnimatedZero, ToCss)]
pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
/// The base shadow.
pub base: SimpleShadow<Color, SizeLength, BlurShapeLength>,
@@ -19,7 +17,7 @@ pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
pub spread: ShapeLength,
/// Whether this is an inset box shadow.
#[animation(constant)]
- #[value_info(represents_keyword)]
+ #[css(represents_keyword)]
pub inset: bool,
}
@@ -80,27 +78,3 @@ pub struct SimpleShadow<Color, SizeLength, ShapeLength> {
/// Blur radius.
pub blur: ShapeLength,
}
-
-impl<Color, SizeLength, BlurShapeLength, ShapeLength> ToCss
- for BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength>
-where
- Color: ToCss,
- SizeLength: ToCss,
- BlurShapeLength: ToCss,
- ShapeLength: ToCss,
-{
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
- where
- W: Write,
- {
- {
- let mut writer = SequenceWriter::new(&mut *dest, " ");
- writer.item(&self.base)?;
- writer.item(&self.spread)?;
- }
- if self.inset {
- dest.write_str(" inset")?;
- }
- Ok(())
- }
-}
diff --git a/components/style/values/specified/counters.rs b/components/style/values/specified/counters.rs
index 8a8e25ab065..3daf8ee56a0 100644
--- a/components/style/values/specified/counters.rs
+++ b/components/style/values/specified/counters.rs
@@ -13,6 +13,7 @@ use values::CustomIdent;
#[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone;
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
+use values::generics::counters::CounterPair;
use values::generics::counters::CounterReset as GenericCounterReset;
#[cfg(feature = "gecko")]
use values::specified::Attr;
@@ -48,7 +49,7 @@ fn parse_counters<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
default_value: i32,
-) -> Result<Vec<(CustomIdent, Integer)>, ParseError<'i>> {
+) -> Result<Vec<CounterPair<Integer>>, ParseError<'i>> {
if input
.try(|input| input.expect_ident_matching("none"))
.is_ok()
@@ -59,16 +60,16 @@ fn parse_counters<'i, 't>(
let mut counters = Vec::new();
loop {
let location = input.current_source_location();
- let counter_name = match input.next() {
+ let name = match input.next() {
Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?,
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
Err(_) => break,
};
- let counter_delta = input
+ let value = input
.try(|input| Integer::parse(context, input))
.unwrap_or(Integer::new(default_value));
- counters.push((counter_name, counter_delta))
+ counters.push(CounterPair { name, value });
}
if !counters.is_empty() {
diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs
index 8ec4354ab7a..266d7c52c09 100644
--- a/components/style/values/specified/font.rs
+++ b/components/style/values/specified/font.rs
@@ -1947,11 +1947,11 @@ pub struct FontSynthesis {
/// If a `font-weight` is requested that the font family does not contain,
/// the user agent may synthesize the requested weight from the weights
/// that do exist in the font family.
- #[value_info(represents_keyword)]
+ #[css(represents_keyword)]
pub weight: bool,
/// If a font-style is requested that the font family does not contain,
/// the user agent may synthesize the requested style from the normal face in the font family.
- #[value_info(represents_keyword)]
+ #[css(represents_keyword)]
pub style: bool,
}
diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs
index 0f2669f0a02..17a5db17bcb 100644
--- a/components/style/values/specified/position.rs
+++ b/components/style/values/specified/position.rs
@@ -424,14 +424,14 @@ pub enum AutoFlow {
}
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
- ToComputedValue)]
+ ToComputedValue, ToCss)]
/// Controls how the auto-placement algorithm works
/// specifying exactly how auto-placed items get flowed into the grid
pub struct GridAutoFlow {
/// Specifiy how auto-placement algorithm fills each `row` or `column` in turn
pub autoflow: AutoFlow,
/// Specify use `dense` packing algorithm or not
- #[value_info(represents_keyword)]
+ #[css(represents_keyword)]
pub dense: bool,
}
@@ -446,20 +446,6 @@ impl GridAutoFlow {
}
}
-impl ToCss for GridAutoFlow {
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
- where
- W: Write,
- {
- self.autoflow.to_css(dest)?;
-
- if self.dense {
- dest.write_str(" dense")?;
- }
- Ok(())
- }
-}
-
impl Parse for GridAutoFlow {
/// [ row | column ] || dense
fn parse<'i, 't>(
diff --git a/components/style_derive/specified_value_info.rs b/components/style_derive/specified_value_info.rs
index 11ad7a0d1b4..7aae081641d 100644
--- a/components/style_derive/specified_value_info.rs
+++ b/components/style_derive/specified_value_info.rs
@@ -140,13 +140,13 @@ fn derive_struct_fields<'a>(
values.push(value.to_string());
}
}
- if info_attrs.represents_keyword {
+ let css_attrs = cg::parse_field_attrs::<CssFieldAttrs>(field);
+ if css_attrs.represents_keyword {
let ident = field.ident.as_ref()
.expect("only named field should use represents_keyword");
values.push(cg::to_css_identifier(ident.as_ref()));
return None;
}
- let css_attrs = cg::parse_field_attrs::<CssFieldAttrs>(field);
if let Some(if_empty) = css_attrs.if_empty {
values.push(if_empty);
}
@@ -176,6 +176,5 @@ struct ValueInfoVariantAttrs {
#[darling(attributes(value_info), default)]
#[derive(Default, FromField)]
struct ValueInfoFieldAttrs {
- represents_keyword: bool,
other_values: Option<String>,
}
diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs
index 722107da0cd..0caef8b01a7 100644
--- a/components/style_derive/to_css.rs
+++ b/components/style_derive/to_css.rs
@@ -175,7 +175,7 @@ fn derive_single_field_expr(
{
let mut iter = #field.iter().peekable();
if iter.peek().is_none() {
- writer.item(&::style_traits::values::Verbatim(#if_empty))?;
+ writer.raw_item(#if_empty)?;
} else {
for item in iter {
writer.item(&item)?;
@@ -189,6 +189,15 @@ fn derive_single_field_expr(
writer.item(&item)?;
}
}
+ } else if attrs.represents_keyword {
+ let ident =
+ field.ast().ident.as_ref().expect("Unnamed field with represents_keyword?");
+ let ident = cg::to_css_identifier(ident.as_ref());
+ quote! {
+ if *#field {
+ writer.raw_item(#ident)?;
+ }
+ }
} else {
if attrs.field_bound {
let ty = &field.ast().ty;
@@ -236,5 +245,6 @@ pub struct CssFieldAttrs {
pub field_bound: bool,
pub iterable: bool,
pub skip: bool,
+ pub represents_keyword: bool,
pub skip_if: Option<Path>,
}
diff --git a/components/style_traits/specified_value_info.rs b/components/style_traits/specified_value_info.rs
index 28e1eef25e6..d9f4578b1a8 100644
--- a/components/style_traits/specified_value_info.rs
+++ b/components/style_traits/specified_value_info.rs
@@ -56,8 +56,6 @@ pub type KeywordsCollectFn<'a> = &'a mut FnMut(&[&'static str]);
/// * `#[value_info(starts_with_keyword)]` can be used on variants to
/// add the name of a non-unit variant (serialized like `ToCss`) into
/// `collect_completion_keywords`.
-/// * `#[value_info(represents_keyword)]` can be used on fields into
-/// `collect_completion_keywords`.
pub trait SpecifiedValueInfo {
/// Supported CssTypes by the given value type.
///
diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs
index 481eb1aff6d..29b8eee58ea 100644
--- a/components/style_traits/values.rs
+++ b/components/style_traits/values.rs
@@ -37,6 +37,9 @@ use std::fmt::{self, Write};
/// * if `#[css(skip_if = "function")]` is found on a field, the `ToCss` call
/// for that field is skipped if `function` returns true. This function is
/// provided the field as an argument;
+/// * `#[css(represents_keyword)]` can be used on bool fields in order to
+/// serialize the field name if the field is true, or nothing otherwise. It
+/// also collects those keywords for `SpecifiedValueInfo`.
/// * finally, one can put `#[css(derive_debug)]` on the whole type, to
/// implement `Debug` by a single call to `ToCss::to_css`.
pub trait ToCss {
@@ -232,21 +235,6 @@ where
}
}
-/// A wrapper type that implements `ToCss` by printing its inner field.
-pub struct Verbatim<'a, T>(pub &'a T)
-where
- T: ?Sized + 'a;
-
-impl<'a, T> ToCss for Verbatim<'a, T>
-where
- T: AsRef<str> + ?Sized + 'a,
-{
- #[inline]
- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write {
- dest.write_str(self.0.as_ref())
- }
-}
-
/// Type used as the associated type in the `OneOrMoreSeparated` trait on a
/// type to indicate that a serialized list of elements of this type is
/// separated by commas.
diff --git a/ports/geckolib/error_reporter.rs b/ports/geckolib/error_reporter.rs
index 7e59f416ff2..3faddf7dcd2 100644
--- a/ports/geckolib/error_reporter.rs
+++ b/ports/geckolib/error_reporter.rs
@@ -14,7 +14,7 @@ use std::ptr;
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
use style::gecko_bindings::bindings::{Gecko_CreateCSSErrorReporter, Gecko_DestroyCSSErrorReporter};
use style::gecko_bindings::bindings::Gecko_ReportUnexpectedCSSError;
-use style::gecko_bindings::structs::{Loader, ServoStyleSheet, nsIURI};
+use style::gecko_bindings::structs::{Loader, StyleSheet as DomStyleSheet, nsIURI};
use style::gecko_bindings::structs::ErrorReporter as GeckoErrorReporter;
use style::gecko_bindings::structs::URLExtraData as RawUrlExtraData;
use style::stylesheets::UrlExtraData;
@@ -27,9 +27,11 @@ pub struct ErrorReporter(*mut GeckoErrorReporter);
impl ErrorReporter {
/// Create a new instance of the Gecko error reporter.
- pub fn new(sheet: *mut ServoStyleSheet,
- loader: *mut Loader,
- extra_data: *mut RawUrlExtraData) -> ErrorReporter {
+ pub fn new(
+ sheet: *mut DomStyleSheet,
+ loader: *mut Loader,
+ extra_data: *mut RawUrlExtraData,
+ ) -> Self {
unsafe {
let url = extra_data.as_ref()
.map(|d| d.mBaseURI.raw::<nsIURI>())
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index e602401c954..3b341cadbb5 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -73,7 +73,6 @@ use style::gecko_bindings::bindings::RawGeckoCSSPropertyIDListBorrowed;
use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoComputedTimingBorrowed;
use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut;
-use style::gecko_bindings::bindings::RawGeckoServoAnimationValueListBorrowed;
use style::gecko_bindings::bindings::RawGeckoServoAnimationValueListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoServoStyleRuleListBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
@@ -92,8 +91,8 @@ use style::gecko_bindings::structs;
use style::gecko_bindings::structs::{CallerType, CSSPseudoElementType, CompositeOperation};
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
use style::gecko_bindings::structs::{RawServoStyleRule, ComputedStyleStrong, RustString};
-use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder};
use style::gecko_bindings::structs::{SheetParsingMode, nsAtom, nsCSSPropertyID};
+use style::gecko_bindings::structs::{StyleSheet as DomStyleSheet, SheetLoadData, SheetLoadDataHolder};
use style::gecko_bindings::structs::{nsCSSFontDesc, nsCSSCounterDesc};
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair};
use style::gecko_bindings::structs::AtomArray;
@@ -129,7 +128,7 @@ use style::invalidation::element::restyle_hints;
use style::media_queries::{MediaList, parse_media_query_list};
use style::parser::{Parse, ParserContext, self};
use style::properties::{ComputedValues, DeclarationSource, Importance};
-use style::properties::{LonghandId, LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
+use style::properties::{LonghandId, LonghandIdSet, PropertyDeclarationBlock, PropertyId};
use style::properties::{PropertyDeclarationId, ShorthandId};
use style::properties::{SourcePropertyDeclaration, StyleBuilder};
use style::properties::{parse_one_declaration_into, parse_style_attribute};
@@ -709,31 +708,6 @@ pub extern "C" fn Servo_AnimationValue_Serialize(
}
#[no_mangle]
-pub unsafe extern "C" fn Servo_Shorthand_AnimationValues_Serialize(
- shorthand_property: nsCSSPropertyID,
- values: RawGeckoServoAnimationValueListBorrowed,
- buffer: *mut nsAString,
-) {
- let property_id = get_property_id_from_nscsspropertyid!(shorthand_property, ());
- let shorthand = match property_id.as_shorthand() {
- Ok(shorthand) => shorthand,
- _ => return,
- };
-
- // Convert RawServoAnimationValue(s) into a vector of PropertyDeclaration
- // so that we can use reference of the PropertyDeclaration without worrying
- // about its lifetime. (longhands_to_css() expects &PropertyDeclaration
- // iterator.)
- let declarations: Vec<PropertyDeclaration> =
- values.iter().map(|v| AnimationValue::as_arc(&&*v.mRawPtr).uncompute()).collect();
-
- let _ = shorthand.longhands_to_css(
- declarations.iter(),
- &mut CssWriter::new(&mut *buffer),
- );
-}
-
-#[no_mangle]
pub extern "C" fn Servo_AnimationValue_GetOpacity(
value: RawServoAnimationValueBorrowed,
) -> f32 {
@@ -1194,7 +1168,7 @@ fn mode_to_origin(mode: SheetParsingMode) -> Origin {
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
loader: *mut Loader,
- stylesheet: *mut ServoStyleSheet,
+ stylesheet: *mut DomStyleSheet,
load_data: *mut SheetLoadData,
bytes: *const nsACString,
mode: SheetParsingMode,
@@ -1263,7 +1237,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync(
#[no_mangle]
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(
raw_data: RawServoStyleSetBorrowed,
- sheet: *const ServoStyleSheet,
+ sheet: *const DomStyleSheet,
) {
let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
@@ -1288,7 +1262,7 @@ pub extern "C" fn Servo_AuthorStyles_Drop(
#[no_mangle]
pub unsafe extern "C" fn Servo_AuthorStyles_AppendStyleSheet(
styles: RawServoAuthorStylesBorrowedMut,
- sheet: *const ServoStyleSheet,
+ sheet: *const DomStyleSheet,
) {
let styles = AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(styles);
@@ -1301,8 +1275,8 @@ pub unsafe extern "C" fn Servo_AuthorStyles_AppendStyleSheet(
#[no_mangle]
pub unsafe extern "C" fn Servo_AuthorStyles_InsertStyleSheetBefore(
styles: RawServoAuthorStylesBorrowedMut,
- sheet: *const ServoStyleSheet,
- before_sheet: *const ServoStyleSheet,
+ sheet: *const DomStyleSheet,
+ before_sheet: *const DomStyleSheet,
) {
let styles = AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(styles);
@@ -1319,7 +1293,7 @@ pub unsafe extern "C" fn Servo_AuthorStyles_InsertStyleSheetBefore(
#[no_mangle]
pub unsafe extern "C" fn Servo_AuthorStyles_RemoveStyleSheet(
styles: RawServoAuthorStylesBorrowedMut,
- sheet: *const ServoStyleSheet,
+ sheet: *const DomStyleSheet,
) {
let styles = AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(styles);
@@ -1454,7 +1428,7 @@ pub unsafe extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
#[no_mangle]
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(
raw_data: RawServoStyleSetBorrowed,
- sheet: *const ServoStyleSheet,
+ sheet: *const DomStyleSheet,
) {
let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
@@ -1467,8 +1441,8 @@ pub extern "C" fn Servo_StyleSet_PrependStyleSheet(
#[no_mangle]
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(
raw_data: RawServoStyleSetBorrowed,
- sheet: *const ServoStyleSheet,
- before_sheet: *const ServoStyleSheet
+ sheet: *const DomStyleSheet,
+ before_sheet: *const DomStyleSheet
) {
let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
@@ -1485,7 +1459,7 @@ pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(
#[no_mangle]
pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(
raw_data: RawServoStyleSetBorrowed,
- sheet: *const ServoStyleSheet
+ sheet: *const DomStyleSheet
) {
let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
@@ -1560,7 +1534,7 @@ pub extern "C" fn Servo_StyleSheet_GetRules(
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_Clone(
raw_sheet: RawServoStyleSheetContentsBorrowed,
- reference_sheet: *const ServoStyleSheet,
+ reference_sheet: *const DomStyleSheet,
) -> RawServoStyleSheetContentsStrong {
use style::shared_lock::{DeepCloneParams, DeepCloneWithLock};
let global_style_data = &*GLOBAL_STYLE_DATA;
@@ -1681,7 +1655,7 @@ pub extern "C" fn Servo_CssRules_InsertRule(
index: u32,
nested: bool,
loader: *mut Loader,
- gecko_stylesheet: *mut ServoStyleSheet,
+ gecko_stylesheet: *mut DomStyleSheet,
rule_type: *mut u16,
) -> nsresult {
let loader = if loader.is_null() {
@@ -2136,16 +2110,16 @@ pub extern "C" fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, res
#[no_mangle]
pub extern "C" fn Servo_ImportRule_GetSheet(
rule: RawServoImportRuleBorrowed,
-) -> *const ServoStyleSheet {
+) -> *const DomStyleSheet {
read_locked_arc(rule, |rule: &ImportRule| {
- rule.stylesheet.as_sheet().unwrap().raw() as *const ServoStyleSheet
+ rule.stylesheet.as_sheet().unwrap().raw() as *const DomStyleSheet
})
}
#[no_mangle]
pub extern "C" fn Servo_ImportRule_SetSheet(
rule: RawServoImportRuleBorrowed,
- sheet: *mut ServoStyleSheet,
+ sheet: *mut DomStyleSheet,
) {
write_locked_arc(rule, |rule: &mut ImportRule| {
let sheet = unsafe { GeckoStyleSheet::new(sheet) };
@@ -3610,6 +3584,20 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_SetProperty(
}
#[no_mangle]
+pub unsafe extern "C" fn Servo_DeclarationBlock_SetPropertyToAnimationValue(
+ declarations: RawServoDeclarationBlockBorrowed,
+ animation_value: RawServoAnimationValueBorrowed,
+) -> bool {
+ write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
+ decls.push(
+ AnimationValue::as_arc(&animation_value).uncompute(),
+ Importance::Normal,
+ DeclarationSource::CssOm,
+ )
+ })
+}
+
+#[no_mangle]
pub unsafe extern "C" fn Servo_DeclarationBlock_SetPropertyById(
declarations: RawServoDeclarationBlockBorrowed,
property: nsCSSPropertyID,
@@ -4506,7 +4494,6 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(
raw_data: RawServoStyleSetBorrowed,
computed_keyframes: RawGeckoComputedKeyframeValuesListBorrowedMut
) {
- use std::mem;
use style::properties::LonghandIdSet;
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
@@ -4567,10 +4554,6 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(
// This is safe since we immediately write to the uninitialized values.
unsafe { animation_values.set_len((property_index + 1) as u32) };
animation_values[property_index].mProperty = property.to_nscsspropertyid();
- // We only make sure we have enough space for this variable,
- // but didn't construct a default value for StyleAnimationValue,
- // so we should zero it to avoid getting undefined behaviors.
- animation_values[property_index].mValue.mGecko = unsafe { mem::zeroed() };
match value {
Some(v) => {
animation_values[property_index].mValue.mServo.set_arc_leaky(Arc::new(v));
@@ -4768,17 +4751,18 @@ fn fill_in_missing_keyframe_values(
#[no_mangle]
pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
raw_data: RawServoStyleSetBorrowed,
+ element: RawGeckoElementBorrowed,
name: *mut nsAtom,
inherited_timing_function: nsTimingFunctionBorrowed,
keyframes: RawGeckoKeyframeListBorrowedMut,
) -> bool {
- debug_assert!(keyframes.len() == 0,
- "keyframes should be initially empty");
+ debug_assert!(keyframes.len() == 0, "keyframes should be initially empty");
+ let element = GeckoElement(element);
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let name = Atom::from_raw(name);
- let animation = match data.stylist.get_animation(&name) {
+ let animation = match data.stylist.get_animation(&name, element) {
Some(animation) => animation,
None => return false,
};
diff --git a/ports/geckolib/stylesheet_loader.rs b/ports/geckolib/stylesheet_loader.rs
index 0c320fee897..7ed1db57bc3 100644
--- a/ports/geckolib/stylesheet_loader.rs
+++ b/ports/geckolib/stylesheet_loader.rs
@@ -12,7 +12,7 @@ use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
use style::gecko_bindings::bindings;
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
-use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder};
+use style::gecko_bindings::structs::{StyleSheet as DomStyleSheet, SheetLoadData, SheetLoadDataHolder};
use style::gecko_bindings::structs::URLExtraData;
use style::gecko_bindings::sugar::ownership::FFIArcHelpers;
use style::gecko_bindings::sugar::refptr::RefPtr;
@@ -24,13 +24,15 @@ use style::stylesheets::StylesheetContents;
use style::stylesheets::import_rule::ImportSheet;
use style::values::CssUrl;
-pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet, *mut SheetLoadData, *mut LoaderReusableStyleSheets);
+pub struct StylesheetLoader(*mut Loader, *mut DomStyleSheet, *mut SheetLoadData, *mut LoaderReusableStyleSheets);
impl StylesheetLoader {
- pub fn new(loader: *mut Loader,
- parent: *mut ServoStyleSheet,
- parent_load_data: *mut SheetLoadData,
- reusable_sheets: *mut LoaderReusableStyleSheets) -> Self {
+ pub fn new(
+ loader: *mut Loader,
+ parent: *mut DomStyleSheet,
+ parent_load_data: *mut SheetLoadData,
+ reusable_sheets: *mut LoaderReusableStyleSheets,
+ ) -> Self {
StylesheetLoader(loader, parent, parent_load_data, reusable_sheets)
}
}
diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs
index e274d8a2a6a..e7b5689e05f 100644
--- a/tests/unit/style/properties/serialization.rs
+++ b/tests/unit/style/properties/serialization.rs
@@ -7,7 +7,7 @@ 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::{CustomIdent, RGBA};
+use style::values::RGBA;
use style::values::specified::{BorderStyle, BorderSideWidth, Color};
use style::values::specified::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::specified::NoCalcLength;
@@ -890,31 +890,4 @@ mod shorthand_serialization {
assert_eq!(shadow.to_css_string(), shadow_css);
}
}
-
- mod counter_increment {
- pub use super::*;
- pub use style::properties::longhands::counter_increment::SpecifiedValue as CounterIncrement;
- use style::values::specified::Integer;
-
- #[test]
- fn counter_increment_with_properties_should_serialize_correctly() {
- let mut properties = Vec::new();
-
- properties.push((CustomIdent("counter1".into()), Integer::new(1)));
- properties.push((CustomIdent("counter2".into()), Integer::new(-4)));
-
- let counter_increment = CounterIncrement::new(properties);
- let counter_increment_css = "counter1 1 counter2 -4";
-
- assert_eq!(counter_increment.to_css_string(), counter_increment_css);
- }
-
- #[test]
- fn counter_increment_without_properties_should_serialize_correctly() {
- let counter_increment = CounterIncrement::new(Vec::new());
- let counter_increment_css = "none";
-
- assert_eq!(counter_increment.to_css_string(), counter_increment_css);
- }
- }
}