mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Auto merge of #11972 - emilio:style-thingies, r=bholley
Staticize CASCADE_PROPERTIES, (temporarily) fix stylo path for animations, and introduce the long-term path to follow <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because refactoring + geckolib <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> @bholley: I was going to do this "the good way", but that involves quite a few properties, so I thought I'd rather unlock stylo before :) r? @bholley <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11972) <!-- Reviewable:end -->
This commit is contained in:
commit
a77cc9950f
9 changed files with 452 additions and 226 deletions
|
@ -253,10 +253,10 @@ impl PropertyAnimation {
|
||||||
new_style: &mut C)
|
new_style: &mut C)
|
||||||
-> Vec<PropertyAnimation> {
|
-> Vec<PropertyAnimation> {
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
let box_style = new_style.as_servo().get_box();
|
let box_style = new_style.get_box();
|
||||||
let transition_property = box_style.transition_property.0[transition_index];
|
let transition_property = box_style.transition_property_at(transition_index);
|
||||||
let timing_function = *box_style.transition_timing_function.0.get_mod(transition_index);
|
let timing_function = box_style.transition_timing_function_mod(transition_index);
|
||||||
let duration = *box_style.transition_duration.0.get_mod(transition_index);
|
let duration = box_style.transition_duration_mod(transition_index);
|
||||||
|
|
||||||
|
|
||||||
if transition_property != TransitionProperty::All {
|
if transition_property != TransitionProperty::All {
|
||||||
|
@ -333,23 +333,6 @@ impl PropertyAnimation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accesses an element of an array, "wrapping around" using modular arithmetic. This is needed
|
|
||||||
/// to handle [repeatable lists][lists] of differing lengths.
|
|
||||||
///
|
|
||||||
/// [lists]: https://drafts.csswg.org/css-transitions/#animtype-repeatable-list
|
|
||||||
pub trait GetMod {
|
|
||||||
type Item;
|
|
||||||
fn get_mod(&self, i: usize) -> &Self::Item;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> GetMod for Vec<T> {
|
|
||||||
type Item = T;
|
|
||||||
#[inline]
|
|
||||||
fn get_mod(&self, i: usize) -> &T {
|
|
||||||
&(*self)[i % self.len()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inserts transitions into the queue of running animations as applicable for
|
/// Inserts transitions into the queue of running animations as applicable for
|
||||||
/// the given style difference. This is called from the layout worker threads.
|
/// the given style difference. This is called from the layout worker threads.
|
||||||
/// Returns true if any animations were kicked off and false otherwise.
|
/// Returns true if any animations were kicked off and false otherwise.
|
||||||
|
@ -362,7 +345,7 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen
|
||||||
new_style: &mut Arc<Impl::ComputedValues>)
|
new_style: &mut Arc<Impl::ComputedValues>)
|
||||||
-> bool {
|
-> bool {
|
||||||
let mut had_animations = false;
|
let mut had_animations = false;
|
||||||
for i in 0..new_style.get_box().transition_count() {
|
for i in 0..new_style.get_box().transition_property_count() {
|
||||||
// Create any property animations, if applicable.
|
// Create any property animations, if applicable.
|
||||||
let property_animations = PropertyAnimation::from_transition(i, old_style, Arc::make_mut(new_style));
|
let property_animations = PropertyAnimation::from_transition(i, old_style, Arc::make_mut(new_style));
|
||||||
for property_animation in property_animations {
|
for property_animation in property_animations {
|
||||||
|
@ -372,13 +355,13 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen
|
||||||
property_animation.update(Arc::get_mut(new_style).unwrap(), 0.0);
|
property_animation.update(Arc::get_mut(new_style).unwrap(), 0.0);
|
||||||
|
|
||||||
// Kick off the animation.
|
// Kick off the animation.
|
||||||
|
let box_style = new_style.get_box();
|
||||||
let now = time::precise_time_s();
|
let now = time::precise_time_s();
|
||||||
let box_style = new_style.as_servo().get_box();
|
|
||||||
let start_time =
|
let start_time =
|
||||||
now + (box_style.transition_delay.0.get_mod(i).seconds() as f64);
|
now + (box_style.transition_delay_mod(i).seconds() as f64);
|
||||||
new_animations_sender
|
new_animations_sender
|
||||||
.send(Animation::Transition(node, start_time, AnimationFrame {
|
.send(Animation::Transition(node, start_time, AnimationFrame {
|
||||||
duration: box_style.transition_duration.0.get_mod(i).seconds() as f64,
|
duration: box_style.transition_duration_mod(i).seconds() as f64,
|
||||||
property_animation: property_animation,
|
property_animation: property_animation,
|
||||||
}, /* is_expired = */ false)).unwrap();
|
}, /* is_expired = */ false)).unwrap();
|
||||||
|
|
||||||
|
@ -422,10 +405,10 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex
|
||||||
{
|
{
|
||||||
let mut had_animations = false;
|
let mut had_animations = false;
|
||||||
|
|
||||||
let box_style = new_style.as_servo().get_box();
|
let box_style = new_style.get_box();
|
||||||
for (i, name) in box_style.animation_name.0.iter().enumerate() {
|
for (i, name) in box_style.animation_name_iter().enumerate() {
|
||||||
debug!("maybe_start_animations: name={}", name);
|
debug!("maybe_start_animations: name={}", name);
|
||||||
let total_duration = box_style.animation_duration.0.get_mod(i).seconds();
|
let total_duration = box_style.animation_duration_mod(i).seconds();
|
||||||
if total_duration == 0. {
|
if total_duration == 0. {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -441,16 +424,16 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let delay = box_style.animation_delay.0.get_mod(i).seconds();
|
let delay = box_style.animation_delay_mod(i).seconds();
|
||||||
let now = time::precise_time_s();
|
let now = time::precise_time_s();
|
||||||
let animation_start = now + delay as f64;
|
let animation_start = now + delay as f64;
|
||||||
let duration = box_style.animation_duration.0.get_mod(i).seconds();
|
let duration = box_style.animation_duration_mod(i).seconds();
|
||||||
let iteration_state = match *box_style.animation_iteration_count.0.get_mod(i) {
|
let iteration_state = match box_style.animation_iteration_count_mod(i) {
|
||||||
AnimationIterationCount::Infinite => KeyframesIterationState::Infinite,
|
AnimationIterationCount::Infinite => KeyframesIterationState::Infinite,
|
||||||
AnimationIterationCount::Number(n) => KeyframesIterationState::Finite(0, n),
|
AnimationIterationCount::Number(n) => KeyframesIterationState::Finite(0, n),
|
||||||
};
|
};
|
||||||
|
|
||||||
let animation_direction = *box_style.animation_direction.0.get_mod(i);
|
let animation_direction = box_style.animation_direction_mod(i);
|
||||||
|
|
||||||
let initial_direction = match animation_direction {
|
let initial_direction = match animation_direction {
|
||||||
AnimationDirection::normal |
|
AnimationDirection::normal |
|
||||||
|
@ -459,7 +442,7 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex
|
||||||
AnimationDirection::alternate_reverse => AnimationDirection::reverse,
|
AnimationDirection::alternate_reverse => AnimationDirection::reverse,
|
||||||
};
|
};
|
||||||
|
|
||||||
let running_state = match *box_style.animation_play_state.0.get_mod(i) {
|
let running_state = match box_style.animation_play_state_mod(i) {
|
||||||
AnimationPlayState::paused => KeyframesRunningState::Paused(0.),
|
AnimationPlayState::paused => KeyframesRunningState::Paused(0.),
|
||||||
AnimationPlayState::running => KeyframesRunningState::Running,
|
AnimationPlayState::running => KeyframesRunningState::Running,
|
||||||
};
|
};
|
||||||
|
@ -550,9 +533,9 @@ where Impl: SelectorImplExt,
|
||||||
|
|
||||||
debug_assert!(!animation.steps.is_empty());
|
debug_assert!(!animation.steps.is_empty());
|
||||||
|
|
||||||
let maybe_index = style.as_servo()
|
let maybe_index = style.get_box()
|
||||||
.get_box().animation_name.0.iter()
|
.animation_name_iter()
|
||||||
.position(|animation_name| name == animation_name);
|
.position(|animation_name| *name == animation_name);
|
||||||
|
|
||||||
let index = match maybe_index {
|
let index = match maybe_index {
|
||||||
Some(index) => index,
|
Some(index) => index,
|
||||||
|
@ -562,7 +545,7 @@ where Impl: SelectorImplExt,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let total_duration = style.as_servo().get_box().animation_duration.0.get_mod(index).seconds() as f64;
|
let total_duration = style.get_box().animation_duration_mod(index).seconds() as f64;
|
||||||
if total_duration == 0. {
|
if total_duration == 0. {
|
||||||
debug!("update_style_for_animation: zero duration for animation {:?}", name);
|
debug!("update_style_for_animation: zero duration for animation {:?}", name);
|
||||||
return;
|
return;
|
||||||
|
@ -642,9 +625,9 @@ where Impl: SelectorImplExt,
|
||||||
|
|
||||||
// NB: The spec says that the timing function can be overwritten
|
// NB: The spec says that the timing function can be overwritten
|
||||||
// from the keyframe style.
|
// from the keyframe style.
|
||||||
let mut timing_function = *style.as_servo().get_box().animation_timing_function.0.get_mod(index);
|
let mut timing_function = style.get_box().animation_timing_function_mod(index);
|
||||||
if !from_style.as_servo().get_box().animation_timing_function.0.is_empty() {
|
if from_style.get_box().animation_timing_function_count() != 0 {
|
||||||
timing_function = from_style.as_servo().get_box().animation_timing_function.0[0];
|
timing_function = from_style.get_box().animation_timing_function_at(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_style = compute_style_for_animation_step(context,
|
let target_style = compute_style_for_animation_step(context,
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Keyword(object):
|
||||||
class Longhand(object):
|
class Longhand(object):
|
||||||
def __init__(self, style_struct, name, animatable=None, derived_from=None, keyword=None,
|
def __init__(self, style_struct, name, animatable=None, derived_from=None, keyword=None,
|
||||||
predefined_type=None, custom_cascade=False, experimental=False, internal=False,
|
predefined_type=None, custom_cascade=False, experimental=False, internal=False,
|
||||||
need_clone=False, gecko_ffi_name=None):
|
need_clone=False, need_index=False, gecko_ffi_name=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.keyword = keyword
|
self.keyword = keyword
|
||||||
self.predefined_type = predefined_type
|
self.predefined_type = predefined_type
|
||||||
|
@ -57,7 +57,7 @@ class Longhand(object):
|
||||||
self.experimental = ("layout.%s.enabled" % name) if experimental else None
|
self.experimental = ("layout.%s.enabled" % name) if experimental else None
|
||||||
self.custom_cascade = custom_cascade
|
self.custom_cascade = custom_cascade
|
||||||
self.internal = internal
|
self.internal = internal
|
||||||
self.need_clone = need_clone
|
self.need_index = need_index
|
||||||
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
|
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
|
||||||
self.derived_from = (derived_from or "").split()
|
self.derived_from = (derived_from or "").split()
|
||||||
|
|
||||||
|
@ -71,6 +71,12 @@ class Longhand(object):
|
||||||
assert animatable == "True" or animatable == "False"
|
assert animatable == "True" or animatable == "False"
|
||||||
self.animatable = animatable == "True"
|
self.animatable = animatable == "True"
|
||||||
|
|
||||||
|
# NB: Animatable implies clone because a property animation requires a
|
||||||
|
# copy of the computed value.
|
||||||
|
#
|
||||||
|
# See components/style/helpers/animated_properties.mako.rs.
|
||||||
|
self.need_clone = need_clone or self.animatable
|
||||||
|
|
||||||
|
|
||||||
class Shorthand(object):
|
class Shorthand(object):
|
||||||
def __init__(self, name, sub_properties, experimental=False, internal=False):
|
def __init__(self, name, sub_properties, experimental=False, internal=False):
|
||||||
|
|
|
@ -225,6 +225,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::${to_camel_case(name)} as SingleComputedValue;
|
||||||
|
|
||||||
define_css_keyword_enum! { ${to_camel_case(name)}:
|
define_css_keyword_enum! { ${to_camel_case(name)}:
|
||||||
% for value in data.longhands_by_name[name].keyword.values_for(product):
|
% for value in data.longhands_by_name[name].keyword.values_for(product):
|
||||||
"${value}" => ${to_rust_ident(value)},
|
"${value}" => ${to_rust_ident(value)},
|
||||||
|
|
|
@ -127,22 +127,17 @@ impl AnimatedProperty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: Transition properties need clone
|
|
||||||
pub fn from_transition_property<C: ComputedValues>(transition_property: &TransitionProperty,
|
pub fn from_transition_property<C: ComputedValues>(transition_property: &TransitionProperty,
|
||||||
old_style: &C,
|
old_style: &C,
|
||||||
new_style: &C) -> AnimatedProperty {
|
new_style: &C) -> AnimatedProperty {
|
||||||
// TODO: Generalise this for GeckoLib, adding clone_xxx to the
|
|
||||||
// appropiate longhands.
|
|
||||||
let old_style = old_style.as_servo();
|
|
||||||
let new_style = new_style.as_servo();
|
|
||||||
match *transition_property {
|
match *transition_property {
|
||||||
TransitionProperty::All => panic!("Can't use TransitionProperty::All here."),
|
TransitionProperty::All => panic!("Can't use TransitionProperty::All here."),
|
||||||
% for prop in data.longhands:
|
% for prop in data.longhands:
|
||||||
% if prop.animatable:
|
% if prop.animatable:
|
||||||
TransitionProperty::${prop.camel_case} => {
|
TransitionProperty::${prop.camel_case} => {
|
||||||
AnimatedProperty::${prop.camel_case}(
|
AnimatedProperty::${prop.camel_case}(
|
||||||
old_style.get_${prop.style_struct.ident.strip("_")}().${prop.ident}.clone(),
|
old_style.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}(),
|
||||||
new_style.get_${prop.style_struct.ident.strip("_")}().${prop.ident}.clone())
|
new_style.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}())
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
|
|
||||||
<% data.new_style_struct("Box",
|
<% data.new_style_struct("Box",
|
||||||
inherited=False,
|
inherited=False,
|
||||||
gecko_name="Display",
|
gecko_name="Display") %>
|
||||||
additional_methods=[Method("transition_count", "usize")]) %>
|
|
||||||
|
|
||||||
// TODO(SimonSapin): don't parse `inline-table`, since we don't support it
|
// TODO(SimonSapin): don't parse `inline-table`, since we don't support it
|
||||||
<%helpers:longhand name="display"
|
<%helpers:longhand name="display"
|
||||||
|
@ -285,7 +284,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
// TODO(pcwalton): Multiple transitions.
|
// TODO(pcwalton): Multiple transitions.
|
||||||
<%helpers:longhand name="transition-duration" animatable="False">
|
<%helpers:longhand name="transition-duration"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
use values::specified::Time;
|
use values::specified::Time;
|
||||||
|
|
||||||
|
@ -343,7 +344,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
|
|
||||||
// TODO(pcwalton): Lots more timing functions.
|
// TODO(pcwalton): Lots more timing functions.
|
||||||
// TODO(pcwalton): Multiple transitions.
|
// TODO(pcwalton): Multiple transitions.
|
||||||
<%helpers:longhand name="transition-timing-function" animatable="False">
|
<%helpers:longhand name="transition-timing-function"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
use self::computed_value::{StartEnd, TransitionTimingFunction};
|
use self::computed_value::{StartEnd, TransitionTimingFunction};
|
||||||
|
|
||||||
use euclid::point::Point2D;
|
use euclid::point::Point2D;
|
||||||
|
@ -541,7 +544,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="transition-property" animatable="False">
|
<%helpers:longhand name="transition-property"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
|
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
|
||||||
pub use self::computed_value::T as SpecifiedValue;
|
pub use self::computed_value::T as SpecifiedValue;
|
||||||
|
|
||||||
|
@ -592,14 +597,18 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="transition-delay" animatable="False">
|
<%helpers:longhand name="transition-delay"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
pub use properties::longhands::transition_duration::{SingleSpecifiedValue, SpecifiedValue};
|
pub use properties::longhands::transition_duration::{SingleSpecifiedValue, SpecifiedValue};
|
||||||
pub use properties::longhands::transition_duration::{computed_value};
|
pub use properties::longhands::transition_duration::{computed_value};
|
||||||
pub use properties::longhands::transition_duration::{get_initial_single_value};
|
pub use properties::longhands::transition_duration::{get_initial_single_value};
|
||||||
pub use properties::longhands::transition_duration::{get_initial_value, parse, parse_one};
|
pub use properties::longhands::transition_duration::{get_initial_value, parse, parse_one};
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="animation-name" animatable="False">
|
<%helpers:longhand name="animation-name"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
@ -607,6 +616,8 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
|
||||||
|
pub use string_cache::Atom as SingleComputedValue;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, HeapSizeOf)]
|
#[derive(Debug, Clone, PartialEq, HeapSizeOf)]
|
||||||
pub struct T(pub Vec<Atom>);
|
pub struct T(pub Vec<Atom>);
|
||||||
|
|
||||||
|
@ -645,25 +656,33 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="animation-duration" animatable="False">
|
<%helpers:longhand name="animation-duration"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
pub use super::transition_duration::computed_value;
|
pub use super::transition_duration::computed_value;
|
||||||
pub use super::transition_duration::{parse, get_initial_value};
|
pub use super::transition_duration::{parse, get_initial_value};
|
||||||
pub use super::transition_duration::SpecifiedValue;
|
pub use super::transition_duration::SpecifiedValue;
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="animation-timing-function" animatable="False">
|
<%helpers:longhand name="animation-timing-function"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
pub use super::transition_timing_function::computed_value;
|
pub use super::transition_timing_function::computed_value;
|
||||||
pub use super::transition_timing_function::{parse, get_initial_value};
|
pub use super::transition_timing_function::{parse, get_initial_value};
|
||||||
pub use super::transition_timing_function::SpecifiedValue;
|
pub use super::transition_timing_function::SpecifiedValue;
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="animation-iteration-count" animatable="False">
|
<%helpers:longhand name="animation-iteration-count"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use cssparser::ToCss;
|
use cssparser::ToCss;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
pub use self::AnimationIterationCount as SingleComputedValue;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, HeapSizeOf)]
|
#[derive(Debug, Clone, PartialEq, HeapSizeOf)]
|
||||||
pub enum AnimationIterationCount {
|
pub enum AnimationIterationCount {
|
||||||
Number(u32),
|
Number(u32),
|
||||||
|
@ -728,18 +747,23 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
|
|
||||||
${helpers.keyword_list("animation-direction",
|
${helpers.keyword_list("animation-direction",
|
||||||
"normal reverse alternate alternate-reverse",
|
"normal reverse alternate alternate-reverse",
|
||||||
|
need_index=True,
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
${helpers.keyword_list("animation-play-state",
|
${helpers.keyword_list("animation-play-state",
|
||||||
"running paused",
|
"running paused",
|
||||||
need_clone=True,
|
need_clone=True,
|
||||||
|
need_index=True,
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
${helpers.keyword_list("animation-fill-mode",
|
${helpers.keyword_list("animation-fill-mode",
|
||||||
"none forwards backwards both",
|
"none forwards backwards both",
|
||||||
|
need_index=True,
|
||||||
animatable=False)}
|
animatable=False)}
|
||||||
|
|
||||||
<%helpers:longhand name="animation-delay" animatable="False">
|
<%helpers:longhand name="animation-delay"
|
||||||
|
need_index="True"
|
||||||
|
animatable="False">
|
||||||
pub use super::transition_duration::computed_value;
|
pub use super::transition_duration::computed_value;
|
||||||
pub use super::transition_duration::{parse, get_initial_value};
|
pub use super::transition_duration::{parse, get_initial_value};
|
||||||
pub use super::transition_duration::SpecifiedValue;
|
pub use super::transition_duration::SpecifiedValue;
|
||||||
|
|
|
@ -1082,12 +1082,61 @@ pub mod style_struct_traits {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T;
|
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T;
|
||||||
% endif
|
% endif
|
||||||
|
% if longhand.need_index:
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn ${longhand.ident}_count(&self) -> usize;
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn ${longhand.ident}_at(&self, index: usize)
|
||||||
|
-> longhands::${longhand.ident}::computed_value::SingleComputedValue;
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[inline]
|
||||||
|
fn ${longhand.ident}_iter<'a>(&'a self)
|
||||||
|
-> ${longhand.camel_case}Iter<'a, Self> {
|
||||||
|
${longhand.camel_case}Iter {
|
||||||
|
style_struct: self,
|
||||||
|
current: 0,
|
||||||
|
max: self.${longhand.ident}_count(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[inline]
|
||||||
|
fn ${longhand.ident}_mod(&self, index: usize)
|
||||||
|
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
|
||||||
|
self.${longhand.ident}_at(index % self.${longhand.ident}_count())
|
||||||
|
}
|
||||||
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
% for additional in style_struct.additional_methods:
|
% for additional in style_struct.additional_methods:
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
${additional.declare()}
|
${additional.declare()}
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
% for longhand in style_struct.longhands:
|
||||||
|
% if longhand.need_index:
|
||||||
|
pub struct ${longhand.camel_case}Iter<'a, S: ${style_struct.trait_name} + 'static> {
|
||||||
|
style_struct: &'a S,
|
||||||
|
current: usize,
|
||||||
|
max: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, S: ${style_struct.trait_name} + 'static> Iterator for ${longhand.camel_case}Iter<'a, S> {
|
||||||
|
type Item = longhands::${longhand.ident}::computed_value::SingleComputedValue;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.current += 1;
|
||||||
|
if self.current <= self.max {
|
||||||
|
Some(self.style_struct.${longhand.ident}_at(self.current - 1))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,65 +1175,39 @@ pub mod style_structs {
|
||||||
|
|
||||||
impl super::style_struct_traits::${style_struct.trait_name} for ${style_struct.servo_struct_name} {
|
impl super::style_struct_traits::${style_struct.trait_name} for ${style_struct.servo_struct_name} {
|
||||||
% for longhand in style_struct.longhands:
|
% for longhand in style_struct.longhands:
|
||||||
|
#[inline]
|
||||||
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
|
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
|
||||||
self.${longhand.ident} = v;
|
self.${longhand.ident} = v;
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
fn copy_${longhand.ident}_from(&mut self, other: &Self) {
|
fn copy_${longhand.ident}_from(&mut self, other: &Self) {
|
||||||
self.${longhand.ident} = other.${longhand.ident}.clone();
|
self.${longhand.ident} = other.${longhand.ident}.clone();
|
||||||
}
|
}
|
||||||
|
% if longhand.need_clone:
|
||||||
|
#[inline]
|
||||||
|
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T {
|
||||||
|
self.${longhand.ident}.clone()
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% if longhand.need_index:
|
||||||
|
fn ${longhand.ident}_count(&self) -> usize {
|
||||||
|
self.${longhand.ident}.0.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ${longhand.ident}_at(&self, index: usize)
|
||||||
|
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
|
||||||
|
self.${longhand.ident}.0[index].clone()
|
||||||
|
}
|
||||||
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
% if style_struct.trait_name == "Border":
|
% if style_struct.trait_name == "Border":
|
||||||
% for side in ["top", "right", "bottom", "left"]:
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
fn clone_border_${side}_style(&self) -> longhands::border_${side}_style::computed_value::T {
|
|
||||||
self.border_${side}_style.clone()
|
|
||||||
}
|
|
||||||
fn border_${side}_has_nonzero_width(&self) -> bool {
|
fn border_${side}_has_nonzero_width(&self) -> bool {
|
||||||
self.border_${side}_width != ::app_units::Au(0)
|
self.border_${side}_width != ::app_units::Au(0)
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
% elif style_struct.trait_name == "Box":
|
|
||||||
#[inline]
|
|
||||||
fn clone_display(&self) -> longhands::display::computed_value::T {
|
|
||||||
self.display.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_position(&self) -> longhands::position::computed_value::T {
|
|
||||||
self.position.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_float(&self) -> longhands::float::computed_value::T {
|
|
||||||
self.float.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_overflow_x(&self) -> longhands::overflow_x::computed_value::T {
|
|
||||||
self.overflow_x.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
|
|
||||||
self.overflow_y.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_animation_play_state(&self) -> longhands::animation_play_state::computed_value::T {
|
|
||||||
self.animation_play_state.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn transition_count(&self) -> usize {
|
|
||||||
self.transition_property.0.len()
|
|
||||||
}
|
|
||||||
% elif style_struct.trait_name == "Color":
|
|
||||||
#[inline]
|
|
||||||
fn clone_color(&self) -> longhands::color::computed_value::T {
|
|
||||||
self.color.clone()
|
|
||||||
}
|
|
||||||
% elif style_struct.trait_name == "Font":
|
% elif style_struct.trait_name == "Font":
|
||||||
#[inline]
|
|
||||||
fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
|
|
||||||
self.font_size.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
|
|
||||||
self.font_weight.clone()
|
|
||||||
}
|
|
||||||
fn compute_font_hash(&mut self) {
|
fn compute_font_hash(&mut self) {
|
||||||
// Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`.
|
// Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`.
|
||||||
let mut hasher: FnvHasher = Default::default();
|
let mut hasher: FnvHasher = Default::default();
|
||||||
|
@ -1193,43 +1216,11 @@ pub mod style_structs {
|
||||||
self.font_family.hash(&mut hasher);
|
self.font_family.hash(&mut hasher);
|
||||||
self.hash = hasher.finish()
|
self.hash = hasher.finish()
|
||||||
}
|
}
|
||||||
% elif style_struct.trait_name == "InheritedBox":
|
|
||||||
#[inline]
|
|
||||||
fn clone_direction(&self) -> longhands::direction::computed_value::T {
|
|
||||||
self.direction.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_writing_mode(&self) -> longhands::writing_mode::computed_value::T {
|
|
||||||
self.writing_mode.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T {
|
|
||||||
self.text_orientation.clone()
|
|
||||||
}
|
|
||||||
% elif style_struct.trait_name == "InheritedText" and product == "servo":
|
|
||||||
#[inline]
|
|
||||||
fn clone__servo_text_decorations_in_effect(&self) ->
|
|
||||||
longhands::_servo_text_decorations_in_effect::computed_value::T {
|
|
||||||
self._servo_text_decorations_in_effect.clone()
|
|
||||||
}
|
|
||||||
% elif style_struct.trait_name == "Outline":
|
% elif style_struct.trait_name == "Outline":
|
||||||
#[inline]
|
|
||||||
fn clone_outline_style(&self) -> longhands::outline_style::computed_value::T {
|
|
||||||
self.outline_style.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn outline_has_nonzero_width(&self) -> bool {
|
fn outline_has_nonzero_width(&self) -> bool {
|
||||||
self.outline_width != ::app_units::Au(0)
|
self.outline_width != ::app_units::Au(0)
|
||||||
}
|
}
|
||||||
% elif style_struct.trait_name == "Position":
|
|
||||||
#[inline]
|
|
||||||
fn clone_align_items(&self) -> longhands::align_items::computed_value::T {
|
|
||||||
self.align_items.clone()
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn clone_align_self(&self) -> longhands::align_self::computed_value::T {
|
|
||||||
self.align_self.clone()
|
|
||||||
}
|
|
||||||
% elif style_struct.trait_name == "Text":
|
% elif style_struct.trait_name == "Text":
|
||||||
<% text_decoration_field = 'text_decoration' if product == 'servo' else 'text_decoration_line' %>
|
<% text_decoration_field = 'text_decoration' if product == 'servo' else 'text_decoration_line' %>
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1255,13 +1246,6 @@ pub trait ComputedValues : Debug + Clone + Send + Sync + 'static {
|
||||||
type Concrete${style_struct.trait_name}: style_struct_traits::${style_struct.trait_name};
|
type Concrete${style_struct.trait_name}: style_struct_traits::${style_struct.trait_name};
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
// Temporary bailout case for stuff we haven't made work with the trait
|
|
||||||
// yet - panics for non-Servo implementations.
|
|
||||||
//
|
|
||||||
// Used only for animations. Don't use it in other places.
|
|
||||||
fn as_servo<'a>(&'a self) -> &'a ServoComputedValues;
|
|
||||||
fn as_servo_mut<'a>(&'a mut self) -> &'a mut ServoComputedValues;
|
|
||||||
|
|
||||||
fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
|
fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
|
@ -1275,7 +1259,7 @@ pub trait ComputedValues : Debug + Clone + Send + Sync + 'static {
|
||||||
|
|
||||||
fn initial_values() -> &'static Self;
|
fn initial_values() -> &'static Self;
|
||||||
|
|
||||||
fn do_cascade_property<F: FnOnce(&Vec<CascadePropertyFn<Self>>)>(f: F);
|
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F);
|
||||||
|
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
fn clone_${style_struct.trait_name_lower}(&self) ->
|
fn clone_${style_struct.trait_name_lower}(&self) ->
|
||||||
|
@ -1310,9 +1294,6 @@ impl ComputedValues for ServoComputedValues {
|
||||||
type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_name};
|
type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_name};
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
fn as_servo<'a>(&'a self) -> &'a ServoComputedValues { self }
|
|
||||||
fn as_servo_mut<'a>(&'a mut self) -> &'a mut ServoComputedValues { self }
|
|
||||||
|
|
||||||
fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
|
fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
|
@ -1346,8 +1327,9 @@ impl ComputedValues for ServoComputedValues {
|
||||||
|
|
||||||
fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
|
fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
|
||||||
|
|
||||||
fn do_cascade_property<F: FnOnce(&Vec<CascadePropertyFn<Self>>)>(f: F) {
|
#[inline]
|
||||||
CASCADE_PROPERTY.with(|x| f(x));
|
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F) {
|
||||||
|
f(&CASCADE_PROPERTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
|
@ -1747,19 +1729,11 @@ pub type CascadePropertyFn<C /*: ComputedValues */> =
|
||||||
cacheable: &mut bool,
|
cacheable: &mut bool,
|
||||||
error_reporter: &mut StdBox<ParseErrorReporter + Send>);
|
error_reporter: &mut StdBox<ParseErrorReporter + Send>);
|
||||||
|
|
||||||
pub fn make_cascade_vec<C: ComputedValues>() -> Vec<CascadePropertyFn<C>> {
|
static CASCADE_PROPERTY: [CascadePropertyFn<ServoComputedValues>; ${len(data.longhands)}] = [
|
||||||
vec![
|
|
||||||
% for property in data.longhands:
|
% for property in data.longhands:
|
||||||
longhands::${property.ident}::cascade_property,
|
longhands::${property.ident}::cascade_property,
|
||||||
% endfor
|
% endfor
|
||||||
]
|
];
|
||||||
}
|
|
||||||
|
|
||||||
// This is a thread-local rather than a lazy static to avoid atomic operations when cascading
|
|
||||||
// properties.
|
|
||||||
thread_local!(static CASCADE_PROPERTY: Vec<CascadePropertyFn<ServoComputedValues>> = {
|
|
||||||
make_cascade_vec::<ServoComputedValues>()
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Performs the CSS cascade, computing new styles for an element from its parent style and
|
/// Performs the CSS cascade, computing new styles for an element from its parent style and
|
||||||
/// optionally a cached related style. The arguments are:
|
/// optionally a cached related style. The arguments are:
|
||||||
|
|
|
@ -1194,6 +1194,11 @@ pub mod specified {
|
||||||
pub fn radians(self) -> f32 {
|
pub fn radians(self) -> f32 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn from_radians(r: f32) -> Self {
|
||||||
|
Angle(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RAD_PER_DEG: CSSFloat = PI / 180.0;
|
const RAD_PER_DEG: CSSFloat = PI / 180.0;
|
||||||
|
|
|
@ -33,9 +33,8 @@ use style::custom_properties::ComputedValuesMap;
|
||||||
use style::logical_geometry::WritingMode;
|
use style::logical_geometry::WritingMode;
|
||||||
use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
|
use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
|
||||||
use style::properties::longhands;
|
use style::properties::longhands;
|
||||||
use style::properties::make_cascade_vec;
|
|
||||||
use style::properties::style_struct_traits::*;
|
use style::properties::style_struct_traits::*;
|
||||||
use values::{StyleCoordHelpers, ToGeckoStyleCoord, convert_nscolor_to_rgba};
|
use values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba};
|
||||||
use values::{convert_rgba_to_nscolor, debug_assert_unit_is_safe_to_copy};
|
use values::{convert_rgba_to_nscolor, debug_assert_unit_is_safe_to_copy};
|
||||||
use values::round_border_to_device_pixels;
|
use values::round_border_to_device_pixels;
|
||||||
|
|
||||||
|
@ -74,10 +73,6 @@ impl ComputedValues for GeckoComputedValues {
|
||||||
type Concrete${style_struct.trait_name} = ${style_struct.gecko_struct_name};
|
type Concrete${style_struct.trait_name} = ${style_struct.gecko_struct_name};
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
// These will go away, and we will never implement them.
|
|
||||||
fn as_servo<'a>(&'a self) -> &'a ServoComputedValues { unimplemented!() }
|
|
||||||
fn as_servo_mut<'a>(&'a mut self) -> &'a mut ServoComputedValues { unimplemented!() }
|
|
||||||
|
|
||||||
fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
|
fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
|
@ -106,8 +101,9 @@ impl ComputedValues for GeckoComputedValues {
|
||||||
|
|
||||||
fn initial_values() -> &'static Self { &*INITIAL_GECKO_VALUES }
|
fn initial_values() -> &'static Self { &*INITIAL_GECKO_VALUES }
|
||||||
|
|
||||||
fn do_cascade_property<F: FnOnce(&Vec<CascadePropertyFn<Self>>)>(f: F) {
|
#[inline]
|
||||||
CASCADE_PROPERTY.with(|x| f(x));
|
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F) {
|
||||||
|
f(&CASCADE_PROPERTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
% for style_struct in data.style_structs:
|
% for style_struct in data.style_structs:
|
||||||
|
@ -147,7 +143,13 @@ pub struct ${style_struct.gecko_struct_name} {
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_simple_copy(ident, gecko_ffi_name)">
|
<%def name="impl_simple_clone(ident, gecko_ffi_name)">
|
||||||
|
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||||
|
self.gecko.${gecko_ffi_name}
|
||||||
|
}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="impl_simple_copy(ident, gecko_ffi_name, *kwargs)">
|
||||||
fn copy_${ident}_from(&mut self, other: &Self) {
|
fn copy_${ident}_from(&mut self, other: &Self) {
|
||||||
self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
|
self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
|
||||||
}
|
}
|
||||||
|
@ -252,7 +254,19 @@ def set_gecko_property(ffi_name, expr):
|
||||||
${set_current_color_flag(color_flags_ffi_name)}
|
${set_current_color_flag(color_flags_ffi_name)}
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
|
self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name}
|
||||||
|
}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="impl_color_clone(ident, gecko_ffi_name, color_flags_ffi_name=None)">
|
||||||
|
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||||
|
use cssparser::Color;
|
||||||
|
% if color_flags_ffi_name:
|
||||||
|
if ${get_current_color_flag_from("self.gecko." + color_flags_ffi_name)} {
|
||||||
|
return Color::CurrentColor
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
Color::RGBA(convert_nscolor_to_rgba(${get_gecko_property(gecko_ffi_name)}))
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
@ -264,14 +278,20 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% endif
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_simple(ident, gecko_ffi_name)">
|
<%def name="impl_simple(ident, gecko_ffi_name, need_clone=False)">
|
||||||
<%call expr="impl_simple_setter(ident, gecko_ffi_name)"></%call>
|
<%call expr="impl_simple_setter(ident, gecko_ffi_name)"></%call>
|
||||||
<%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
|
<%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
|
||||||
|
% if need_clone:
|
||||||
|
<%call expr="impl_simple_clone(ident, gecko_ffi_name)"></%call>
|
||||||
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_color(ident, gecko_ffi_name, color_flags_ffi_name=None)">
|
<%def name="impl_color(ident, gecko_ffi_name, color_flags_ffi_name=None, need_clone=False)">
|
||||||
<%call expr="impl_color_setter(ident, gecko_ffi_name, color_flags_ffi_name)"></%call>
|
<%call expr="impl_color_setter(ident, gecko_ffi_name, color_flags_ffi_name)"></%call>
|
||||||
<%call expr="impl_color_copy(ident, gecko_ffi_name, color_flags_ffi_name)"></%call>
|
<%call expr="impl_color_copy(ident, gecko_ffi_name, color_flags_ffi_name)"></%call>
|
||||||
|
% if need_clone:
|
||||||
|
<%call expr="impl_color_clone(ident, gecko_ffi_name, color_flags_ffi_name)"></%call>
|
||||||
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
|
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
|
||||||
|
@ -291,7 +311,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% endif
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_split_style_coord(ident, unit_ffi_name, union_ffi_name)">
|
<%def name="impl_split_style_coord(ident, unit_ffi_name, union_ffi_name, need_clone=False)">
|
||||||
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
v.to_gecko_style_coord(&mut self.gecko.${unit_ffi_name},
|
v.to_gecko_style_coord(&mut self.gecko.${unit_ffi_name},
|
||||||
&mut self.gecko.${union_ffi_name});
|
&mut self.gecko.${union_ffi_name});
|
||||||
|
@ -301,13 +321,25 @@ def set_gecko_property(ffi_name, expr):
|
||||||
self.gecko.${unit_ffi_name} = other.gecko.${unit_ffi_name};
|
self.gecko.${unit_ffi_name} = other.gecko.${unit_ffi_name};
|
||||||
self.gecko.${union_ffi_name} = other.gecko.${union_ffi_name};
|
self.gecko.${union_ffi_name} = other.gecko.${union_ffi_name};
|
||||||
}
|
}
|
||||||
|
% if need_clone:
|
||||||
|
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||||
|
use style::properties::longhands::${ident}::computed_value::T;
|
||||||
|
T::from_gecko_style_coord(&self.gecko.${unit_ffi_name},
|
||||||
|
&self.gecko.${union_ffi_name})
|
||||||
|
.expect("clone for ${ident} failed")
|
||||||
|
}
|
||||||
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_style_coord(ident, gecko_ffi_name)">
|
<%def name="impl_style_coord(ident, gecko_ffi_name, need_clone=False)">
|
||||||
<%call expr="impl_split_style_coord(ident, '%s.mUnit' % gecko_ffi_name, '%s.mValue' % gecko_ffi_name)"></%call>
|
${impl_split_style_coord(ident,
|
||||||
|
"%s.mUnit" % gecko_ffi_name,
|
||||||
|
"%s.mValue" % gecko_ffi_name,
|
||||||
|
need_clone=need_clone)}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_corner_style_coord(ident, x_unit_ffi_name, x_union_ffi_name, y_unit_ffi_name, y_union_ffi_name)">
|
<%def name="impl_corner_style_coord(ident, x_unit_ffi_name, x_union_ffi_name, \
|
||||||
|
y_unit_ffi_name, y_union_ffi_name, need_clone=False)">
|
||||||
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
v.0.width.to_gecko_style_coord(&mut self.gecko.${x_unit_ffi_name},
|
v.0.width.to_gecko_style_coord(&mut self.gecko.${x_unit_ffi_name},
|
||||||
&mut self.gecko.${x_union_ffi_name});
|
&mut self.gecko.${x_union_ffi_name});
|
||||||
|
@ -322,6 +354,19 @@ def set_gecko_property(ffi_name, expr):
|
||||||
self.gecko.${y_unit_ffi_name} = other.gecko.${y_unit_ffi_name};
|
self.gecko.${y_unit_ffi_name} = other.gecko.${y_unit_ffi_name};
|
||||||
self.gecko.${y_union_ffi_name} = other.gecko.${y_union_ffi_name};
|
self.gecko.${y_union_ffi_name} = other.gecko.${y_union_ffi_name};
|
||||||
}
|
}
|
||||||
|
% if need_clone:
|
||||||
|
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||||
|
use style::properties::longhands::${ident}::computed_value::T;
|
||||||
|
use euclid::Size2D;
|
||||||
|
let width = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${x_unit_ffi_name},
|
||||||
|
&self.gecko.${x_union_ffi_name})
|
||||||
|
.expect("Failed to clone ${ident}");
|
||||||
|
let height = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${y_unit_ffi_name},
|
||||||
|
&self.gecko.${y_union_ffi_name})
|
||||||
|
.expect("Failed to clone ${ident}");
|
||||||
|
T(Size2D::new(width, height))
|
||||||
|
}
|
||||||
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_style_struct(style_struct)">
|
<%def name="impl_style_struct(style_struct)">
|
||||||
|
@ -424,7 +469,7 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
|
||||||
impl_keyword(longhand.ident, longhand.gecko_ffi_name, longhand.keyword, longhand.need_clone)
|
impl_keyword(longhand.ident, longhand.gecko_ffi_name, longhand.keyword, longhand.need_clone)
|
||||||
for longhand in predefined_longhands:
|
for longhand in predefined_longhands:
|
||||||
impl_fn = predefined_types[longhand.predefined_type]
|
impl_fn = predefined_types[longhand.predefined_type]
|
||||||
impl_fn(longhand.ident, longhand.gecko_ffi_name)
|
impl_fn(longhand.ident, longhand.gecko_ffi_name, need_clone=longhand.need_clone)
|
||||||
%>
|
%>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -446,6 +491,12 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
% if longhand.need_index:
|
||||||
|
fn ${longhand.ident}_count(&self) -> usize { 0 }
|
||||||
|
fn ${longhand.ident}_at(&self, _index: usize) -> longhands::${longhand.ident}::computed_value::SingleComputedValue {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
<% additionals = [x for x in style_struct.additional_methods
|
<% additionals = [x for x in style_struct.additional_methods
|
||||||
if skip_additionals != "*" and not x.name in skip_additionals.split()] %>
|
if skip_additionals != "*" and not x.name in skip_additionals.split()] %>
|
||||||
|
@ -515,9 +566,9 @@ fn static_assert() {
|
||||||
need_clone=True) %>
|
need_clone=True) %>
|
||||||
|
|
||||||
<% impl_color("border_%s_color" % side.ident, "mBorderColor[%s]" % side.index,
|
<% impl_color("border_%s_color" % side.ident, "mBorderColor[%s]" % side.index,
|
||||||
color_flags_ffi_name="mBorderStyle[%s]" % side.index) %>
|
color_flags_ffi_name="mBorderStyle[%s]" % side.index, need_clone=True) %>
|
||||||
|
|
||||||
<% impl_app_units("border_%s_width" % side.ident, "mComputedBorder.%s" % side.ident, need_clone=False,
|
<% impl_app_units("border_%s_width" % side.ident, "mComputedBorder.%s" % side.ident, need_clone=True,
|
||||||
round_to_pixels=True) %>
|
round_to_pixels=True) %>
|
||||||
|
|
||||||
fn border_${side.ident}_has_nonzero_width(&self) -> bool {
|
fn border_${side.ident}_has_nonzero_width(&self) -> bool {
|
||||||
|
@ -530,7 +581,8 @@ fn static_assert() {
|
||||||
"mBorderRadius.mUnits[%s]" % corner.x_index,
|
"mBorderRadius.mUnits[%s]" % corner.x_index,
|
||||||
"mBorderRadius.mValues[%s]" % corner.x_index,
|
"mBorderRadius.mValues[%s]" % corner.x_index,
|
||||||
"mBorderRadius.mUnits[%s]" % corner.y_index,
|
"mBorderRadius.mUnits[%s]" % corner.y_index,
|
||||||
"mBorderRadius.mValues[%s]" % corner.y_index) %>
|
"mBorderRadius.mValues[%s]" % corner.y_index,
|
||||||
|
need_clone=True) %>
|
||||||
% endfor
|
% endfor
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
|
@ -541,7 +593,8 @@ fn static_assert() {
|
||||||
% for side in SIDES:
|
% for side in SIDES:
|
||||||
<% impl_split_style_coord("margin_%s" % side.ident,
|
<% impl_split_style_coord("margin_%s" % side.ident,
|
||||||
"mMargin.mUnits[%s]" % side.index,
|
"mMargin.mUnits[%s]" % side.index,
|
||||||
"mMargin.mValues[%s]" % side.index) %>
|
"mMargin.mValues[%s]" % side.index,
|
||||||
|
need_clone=True) %>
|
||||||
% endfor
|
% endfor
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
|
@ -552,7 +605,8 @@ fn static_assert() {
|
||||||
% for side in SIDES:
|
% for side in SIDES:
|
||||||
<% impl_split_style_coord("padding_%s" % side.ident,
|
<% impl_split_style_coord("padding_%s" % side.ident,
|
||||||
"mPadding.mUnits[%s]" % side.index,
|
"mPadding.mUnits[%s]" % side.index,
|
||||||
"mPadding.mValues[%s]" % side.index) %>
|
"mPadding.mValues[%s]" % side.index,
|
||||||
|
need_clone=True) %>
|
||||||
% endfor
|
% endfor
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
|
@ -563,7 +617,8 @@ fn static_assert() {
|
||||||
% for side in SIDES:
|
% for side in SIDES:
|
||||||
<% impl_split_style_coord("%s" % side.ident,
|
<% impl_split_style_coord("%s" % side.ident,
|
||||||
"mOffset.mUnits[%s]" % side.index,
|
"mOffset.mUnits[%s]" % side.index,
|
||||||
"mOffset.mValues[%s]" % side.index) %>
|
"mOffset.mValues[%s]" % side.index,
|
||||||
|
need_clone=True) %>
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
|
fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
|
||||||
|
@ -580,6 +635,17 @@ fn static_assert() {
|
||||||
self.gecko.mZIndex.mValue = other.gecko.mZIndex.mValue;
|
self.gecko.mZIndex.mValue = other.gecko.mZIndex.mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
|
||||||
|
use style::properties::longhands::z_index::computed_value::T;
|
||||||
|
|
||||||
|
if self.gecko.mZIndex.is_auto() {
|
||||||
|
return T::Auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert!(self.gecko.mZIndex.is_int());
|
||||||
|
T::Number(self.gecko.mZIndex.get_int())
|
||||||
|
}
|
||||||
|
|
||||||
fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) {
|
fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) {
|
||||||
use style::computed_values::box_sizing::T;
|
use style::computed_values::box_sizing::T;
|
||||||
use gecko_bindings::structs::StyleBoxSizing;
|
use gecko_bindings::structs::StyleBoxSizing;
|
||||||
|
@ -602,9 +668,9 @@ fn static_assert() {
|
||||||
|
|
||||||
<% impl_keyword("outline_style", "mOutlineStyle", border_style_keyword, need_clone=True) %>
|
<% impl_keyword("outline_style", "mOutlineStyle", border_style_keyword, need_clone=True) %>
|
||||||
|
|
||||||
<% impl_color("outline_color", "mOutlineColor", color_flags_ffi_name="mOutlineStyle") %>
|
<% impl_color("outline_color", "mOutlineColor", color_flags_ffi_name="mOutlineStyle", need_clone=True) %>
|
||||||
|
|
||||||
<% impl_app_units("outline_width", "mActualOutlineWidth", need_clone=False,
|
<% impl_app_units("outline_width", "mActualOutlineWidth", need_clone=True,
|
||||||
round_to_pixels=True) %>
|
round_to_pixels=True) %>
|
||||||
|
|
||||||
% for corner in CORNERS:
|
% for corner in CORNERS:
|
||||||
|
@ -675,7 +741,7 @@ fn static_assert() {
|
||||||
fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) {
|
fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) {
|
||||||
self.gecko.mFont.weight = v as u16;
|
self.gecko.mFont.weight = v as u16;
|
||||||
}
|
}
|
||||||
<%call expr="impl_simple_copy('font_weight', 'mFont.weight')"></%call>
|
${impl_simple_copy('font_weight', 'mFont.weight')}
|
||||||
|
|
||||||
fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
|
fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
|
||||||
debug_assert!(self.gecko.mFont.weight >= 100);
|
debug_assert!(self.gecko.mFont.weight >= 100);
|
||||||
|
@ -697,7 +763,7 @@ fn static_assert() {
|
||||||
"table-header-group table-footer-group table-row table-column-group " +
|
"table-header-group table-footer-group table-row table-column-group " +
|
||||||
"table-column table-cell table-caption list-item flex none " +
|
"table-column table-cell table-caption list-item flex none " +
|
||||||
"-moz-box -moz-inline-box") %>
|
"-moz-box -moz-inline-box") %>
|
||||||
<%call expr="impl_keyword('display', 'mDisplay', display_keyword, True)"></%call>
|
${impl_keyword('display', 'mDisplay', display_keyword, True)}
|
||||||
|
|
||||||
// overflow-y is implemented as a newtype of overflow-x, so we need special handling.
|
// overflow-y is implemented as a newtype of overflow-x, so we need special handling.
|
||||||
// We could generalize this if we run into other newtype keywords.
|
// We could generalize this if we run into other newtype keywords.
|
||||||
|
@ -711,7 +777,7 @@ fn static_assert() {
|
||||||
% endfor
|
% endfor
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
<%call expr="impl_simple_copy('overflow_y', 'mOverflowY')"></%call>
|
${impl_simple_copy('overflow_y', 'mOverflowY')}
|
||||||
fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
|
fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
|
||||||
use style::properties::longhands::overflow_x::computed_value::T as BaseType;
|
use style::properties::longhands::overflow_x::computed_value::T as BaseType;
|
||||||
use style::properties::longhands::overflow_y::computed_value::T as NewType;
|
use style::properties::longhands::overflow_y::computed_value::T as NewType;
|
||||||
|
@ -737,6 +803,26 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_vertical_align(&self) -> longhands::vertical_align::computed_value::T {
|
||||||
|
use style::properties::longhands::vertical_align::computed_value::T;
|
||||||
|
use style::values::computed::LengthOrPercentage;
|
||||||
|
|
||||||
|
if self.gecko.mVerticalAlign.is_enum() {
|
||||||
|
match self.gecko.mVerticalAlign.get_enum() as u32 {
|
||||||
|
% for value in keyword.values_for('gecko'):
|
||||||
|
structs::${keyword.gecko_constant(value)}
|
||||||
|
=> T::${to_rust_ident(value)},
|
||||||
|
% endfor
|
||||||
|
_ => panic!("Unexpected enum variant for vertical-align"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let v = LengthOrPercentage::from_gecko_style_coord(&self.gecko.mVerticalAlign.mUnit,
|
||||||
|
&self.gecko.mVerticalAlign.mValue)
|
||||||
|
.expect("Expected length or percentage for vertical-align");
|
||||||
|
T::LengthOrPercentage(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
|
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
|
||||||
|
|
||||||
fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
|
fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
|
||||||
|
@ -770,7 +856,7 @@ fn static_assert() {
|
||||||
skip_longhands="${skip_background_longhands}"
|
skip_longhands="${skip_background_longhands}"
|
||||||
skip_additionals="*">
|
skip_additionals="*">
|
||||||
|
|
||||||
<% impl_color("background_color", "mBackgroundColor") %>
|
<% impl_color("background_color", "mBackgroundColor", need_clone=True) %>
|
||||||
|
|
||||||
fn copy_background_repeat_from(&mut self, other: &Self) {
|
fn copy_background_repeat_from(&mut self, other: &Self) {
|
||||||
self.gecko.mImage.mRepeatCount = cmp::min(1, other.gecko.mImage.mRepeatCount);
|
self.gecko.mImage.mRepeatCount = cmp::min(1, other.gecko.mImage.mRepeatCount);
|
||||||
|
@ -945,8 +1031,8 @@ fn static_assert() {
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="List" skip_longhands="list-style-type" skip_additionals="*">
|
<%self:impl_trait style_struct_name="List" skip_longhands="list-style-type" skip_additionals="*">
|
||||||
|
|
||||||
<% impl_keyword_setter("list_style_type", "__LIST_STYLE_TYPE__",
|
${impl_keyword_setter("list_style_type", "__LIST_STYLE_TYPE__",
|
||||||
data.longhands_by_name["list-style-type"].keyword) %>
|
data.longhands_by_name["list-style-type"].keyword)}
|
||||||
fn copy_list_style_type_from(&mut self, other: &Self) {
|
fn copy_list_style_type_from(&mut self, other: &Self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko);
|
Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko);
|
||||||
|
@ -960,7 +1046,7 @@ fn static_assert() {
|
||||||
|
|
||||||
<% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " +
|
<% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " +
|
||||||
"-moz-right match-parent") %>
|
"-moz-right match-parent") %>
|
||||||
<%call expr="impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)"></%call>
|
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
|
||||||
|
|
||||||
fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
|
fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
|
||||||
use style::properties::longhands::line_height::computed_value::T;
|
use style::properties::longhands::line_height::computed_value::T;
|
||||||
|
@ -974,6 +1060,22 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
|
||||||
|
use style::properties::longhands::line_height::computed_value::T;
|
||||||
|
if self.gecko.mLineHeight.is_normal() {
|
||||||
|
return T::Normal;
|
||||||
|
}
|
||||||
|
if self.gecko.mLineHeight.is_coord() {
|
||||||
|
return T::Length(self.gecko.mLineHeight.get_coord());
|
||||||
|
}
|
||||||
|
if self.gecko.mLineHeight.is_factor() {
|
||||||
|
return T::Number(self.gecko.mLineHeight.get_factor());
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert!(self.gecko.mLineHeight.get_enum() == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT as i32);
|
||||||
|
T::MozBlockHeight
|
||||||
|
}
|
||||||
|
|
||||||
<%call expr="impl_coord_copy('line_height', 'mLineHeight')"></%call>
|
<%call expr="impl_coord_copy('line_height', 'mLineHeight')"></%call>
|
||||||
|
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
@ -982,8 +1084,8 @@ fn static_assert() {
|
||||||
skip_longhands="text-decoration-color text-decoration-line"
|
skip_longhands="text-decoration-color text-decoration-line"
|
||||||
skip_additionals="*">
|
skip_additionals="*">
|
||||||
|
|
||||||
<% impl_color("text_decoration_color", "mTextDecorationColor",
|
${impl_color("text_decoration_color", "mTextDecorationColor",
|
||||||
color_flags_ffi_name="mTextDecorationStyle") %>
|
color_flags_ffi_name="mTextDecorationStyle", need_clone=True)}
|
||||||
|
|
||||||
fn set_text_decoration_line(&mut self, v: longhands::text_decoration_line::computed_value::T) {
|
fn set_text_decoration_line(&mut self, v: longhands::text_decoration_line::computed_value::T) {
|
||||||
let mut bits: u8 = 0;
|
let mut bits: u8 = 0;
|
||||||
|
@ -999,14 +1101,19 @@ fn static_assert() {
|
||||||
self.gecko.mTextDecorationLine = bits;
|
self.gecko.mTextDecorationLine = bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
<%call expr="impl_simple_copy('text_decoration_line', 'mTextDecorationLine')"></%call>
|
${impl_simple_copy('text_decoration_line', 'mTextDecorationLine')}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn has_underline(&self) -> bool {
|
fn has_underline(&self) -> bool {
|
||||||
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0
|
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn has_overline(&self) -> bool {
|
fn has_overline(&self) -> bool {
|
||||||
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0
|
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn has_line_through(&self) -> bool {
|
fn has_line_through(&self) -> bool {
|
||||||
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0
|
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0
|
||||||
}
|
}
|
||||||
|
@ -1026,7 +1133,6 @@ fn static_assert() {
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Color"
|
<%self:impl_trait style_struct_name="Color"
|
||||||
skip_longhands="*">
|
skip_longhands="*">
|
||||||
|
|
||||||
fn set_color(&mut self, v: longhands::color::computed_value::T) {
|
fn set_color(&mut self, v: longhands::color::computed_value::T) {
|
||||||
let result = convert_rgba_to_nscolor(&v);
|
let result = convert_rgba_to_nscolor(&v);
|
||||||
${set_gecko_property("mColor", "result")}
|
${set_gecko_property("mColor", "result")}
|
||||||
|
@ -1042,7 +1148,6 @@ fn static_assert() {
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Pointing"
|
<%self:impl_trait style_struct_name="Pointing"
|
||||||
skip_longhands="cursor">
|
skip_longhands="cursor">
|
||||||
|
|
||||||
fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
|
fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
|
||||||
use style::properties::longhands::cursor::computed_value::T;
|
use style::properties::longhands::cursor::computed_value::T;
|
||||||
use style_traits::cursor::Cursor;
|
use style_traits::cursor::Cursor;
|
||||||
|
@ -1090,7 +1195,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
${impl_simple_copy('cursor', 'mCursor')}
|
${impl_simple_copy('cursor', 'mCursor')}
|
||||||
|
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Column"
|
<%self:impl_trait style_struct_name="Column"
|
||||||
|
@ -1104,7 +1208,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
${impl_coord_copy('column_width', 'mColumnWidth')}
|
${impl_coord_copy('column_width', 'mColumnWidth')}
|
||||||
|
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%def name="define_ffi_struct_accessor(style_struct)">
|
<%def name="define_ffi_struct_accessor(style_struct)">
|
||||||
|
@ -1139,8 +1242,8 @@ lazy_static! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a thread-local rather than a lazy static to avoid atomic operations when cascading
|
static CASCADE_PROPERTY: [CascadePropertyFn<GeckoComputedValues>; ${len(data.longhands)}] = [
|
||||||
// properties.
|
% for property in data.longhands:
|
||||||
thread_local!(static CASCADE_PROPERTY: Vec<CascadePropertyFn<GeckoComputedValues>> = {
|
longhands::${property.ident}::cascade_property,
|
||||||
make_cascade_vec::<GeckoComputedValues>()
|
% endfor
|
||||||
});
|
];
|
||||||
|
|
|
@ -11,17 +11,37 @@ use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, Leng
|
||||||
|
|
||||||
pub trait StyleCoordHelpers {
|
pub trait StyleCoordHelpers {
|
||||||
fn copy_from(&mut self, other: &Self);
|
fn copy_from(&mut self, other: &Self);
|
||||||
fn set<T: ToGeckoStyleCoord>(&mut self, val: T);
|
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T);
|
||||||
|
|
||||||
fn set_auto(&mut self);
|
fn set_auto(&mut self);
|
||||||
|
fn is_auto(&self) -> bool;
|
||||||
|
|
||||||
fn set_normal(&mut self);
|
fn set_normal(&mut self);
|
||||||
|
fn is_normal(&self) -> bool;
|
||||||
|
|
||||||
fn set_coord(&mut self, val: Au);
|
fn set_coord(&mut self, val: Au);
|
||||||
|
fn is_coord(&self) -> bool;
|
||||||
|
fn get_coord(&self) -> Au;
|
||||||
|
|
||||||
fn set_int(&mut self, val: i32);
|
fn set_int(&mut self, val: i32);
|
||||||
|
fn is_int(&self) -> bool;
|
||||||
|
fn get_int(&self) -> i32;
|
||||||
|
|
||||||
fn set_enum(&mut self, val: i32);
|
fn set_enum(&mut self, val: i32);
|
||||||
|
fn is_enum(&self) -> bool;
|
||||||
|
fn get_enum(&self) -> i32;
|
||||||
|
|
||||||
fn set_percent(&mut self, val: f32);
|
fn set_percent(&mut self, val: f32);
|
||||||
|
fn is_percent(&self) -> bool;
|
||||||
|
fn get_percent(&self) -> f32;
|
||||||
|
|
||||||
fn set_factor(&mut self, val: f32);
|
fn set_factor(&mut self, val: f32);
|
||||||
|
fn is_factor(&self) -> bool;
|
||||||
|
fn get_factor(&self) -> f32;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StyleCoordHelpers for nsStyleCoord {
|
impl StyleCoordHelpers for nsStyleCoord {
|
||||||
|
#[inline]
|
||||||
fn copy_from(&mut self, other: &Self) {
|
fn copy_from(&mut self, other: &Self) {
|
||||||
debug_assert_unit_is_safe_to_copy(self.mUnit);
|
debug_assert_unit_is_safe_to_copy(self.mUnit);
|
||||||
debug_assert_unit_is_safe_to_copy(other.mUnit);
|
debug_assert_unit_is_safe_to_copy(other.mUnit);
|
||||||
|
@ -29,51 +49,113 @@ impl StyleCoordHelpers for nsStyleCoord {
|
||||||
self.mValue = other.mValue;
|
self.mValue = other.mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set<T: ToGeckoStyleCoord>(&mut self, val: T) {
|
#[inline]
|
||||||
|
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
|
||||||
val.to_gecko_style_coord(&mut self.mUnit, &mut self.mValue);
|
val.to_gecko_style_coord(&mut self.mUnit, &mut self.mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_auto(&mut self) {
|
fn set_auto(&mut self) {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Auto;
|
self.mUnit = nsStyleUnit::eStyleUnit_Auto;
|
||||||
unsafe { *self.mValue.mInt.as_mut() = 0; }
|
unsafe { *self.mValue.mInt.as_mut() = 0; }
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn is_auto(&self) -> bool {
|
||||||
|
self.mUnit == nsStyleUnit::eStyleUnit_Auto
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_normal(&mut self) {
|
fn set_normal(&mut self) {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Normal;
|
self.mUnit = nsStyleUnit::eStyleUnit_Normal;
|
||||||
unsafe { *self.mValue.mInt.as_mut() = 0; }
|
unsafe { *self.mValue.mInt.as_mut() = 0; }
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn is_normal(&self) -> bool {
|
||||||
|
self.mUnit == nsStyleUnit::eStyleUnit_Normal
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_coord(&mut self, val: Au) {
|
fn set_coord(&mut self, val: Au) {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Coord;
|
self.mUnit = nsStyleUnit::eStyleUnit_Coord;
|
||||||
unsafe { *self.mValue.mInt.as_mut() = val.0; }
|
unsafe { *self.mValue.mInt.as_mut() = val.0; }
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
fn set_percent(&mut self, val: f32) {
|
fn is_coord(&self) -> bool {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Percent;
|
self.mUnit == nsStyleUnit::eStyleUnit_Coord
|
||||||
unsafe { *self.mValue.mFloat.as_mut() = val; }
|
}
|
||||||
|
#[inline]
|
||||||
|
fn get_coord(&self) -> Au {
|
||||||
|
debug_assert!(self.is_coord());
|
||||||
|
Au(unsafe { *self.mValue.mInt.as_ref() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_int(&mut self, val: i32) {
|
fn set_int(&mut self, val: i32) {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Integer;
|
self.mUnit = nsStyleUnit::eStyleUnit_Integer;
|
||||||
unsafe { *self.mValue.mInt.as_mut() = val; }
|
unsafe { *self.mValue.mInt.as_mut() = val; }
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn is_int(&self) -> bool {
|
||||||
|
self.mUnit == nsStyleUnit::eStyleUnit_Integer
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn get_int(&self) -> i32 {
|
||||||
|
debug_assert!(self.is_int());
|
||||||
|
unsafe { *self.mValue.mInt.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_enum(&mut self, val: i32) {
|
fn set_enum(&mut self, val: i32) {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Enumerated;
|
self.mUnit = nsStyleUnit::eStyleUnit_Enumerated;
|
||||||
unsafe { *self.mValue.mInt.as_mut() = val; }
|
unsafe { *self.mValue.mInt.as_mut() = val; }
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn is_enum(&self) -> bool {
|
||||||
|
self.mUnit == nsStyleUnit::eStyleUnit_Enumerated
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn get_enum(&self) -> i32 {
|
||||||
|
debug_assert!(self.is_enum());
|
||||||
|
unsafe { *self.mValue.mInt.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn set_percent(&mut self, val: f32) {
|
||||||
|
self.mUnit = nsStyleUnit::eStyleUnit_Percent;
|
||||||
|
unsafe { *self.mValue.mFloat.as_mut() = val; }
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn is_percent(&self) -> bool {
|
||||||
|
self.mUnit == nsStyleUnit::eStyleUnit_Percent
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn get_percent(&self) -> f32 {
|
||||||
|
debug_assert!(self.is_percent());
|
||||||
|
unsafe { *self.mValue.mFloat.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn set_factor(&mut self, val: f32) {
|
fn set_factor(&mut self, val: f32) {
|
||||||
self.mUnit = nsStyleUnit::eStyleUnit_Factor;
|
self.mUnit = nsStyleUnit::eStyleUnit_Factor;
|
||||||
unsafe { *self.mValue.mFloat.as_mut() = val; }
|
unsafe { *self.mValue.mFloat.as_mut() = val; }
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn is_factor(&self) -> bool {
|
||||||
|
self.mUnit == nsStyleUnit::eStyleUnit_Factor
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn get_factor(&self) -> f32 {
|
||||||
|
debug_assert!(self.is_factor());
|
||||||
|
unsafe { *self.mValue.mFloat.as_ref() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToGeckoStyleCoord {
|
pub trait GeckoStyleCoordConvertible : Sized {
|
||||||
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion);
|
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion);
|
||||||
|
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToGeckoStyleCoord for LengthOrPercentage {
|
impl GeckoStyleCoordConvertible for LengthOrPercentage {
|
||||||
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
||||||
match *self {
|
match *self {
|
||||||
LengthOrPercentage::Length(au) => {
|
LengthOrPercentage::Length(au) => {
|
||||||
|
@ -87,9 +169,21 @@ impl ToGeckoStyleCoord for LengthOrPercentage {
|
||||||
LengthOrPercentage::Calc(_) => unimplemented!(),
|
LengthOrPercentage::Calc(_) => unimplemented!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
|
||||||
|
match *unit {
|
||||||
|
nsStyleUnit::eStyleUnit_Coord
|
||||||
|
=> Some(LengthOrPercentage::Length(Au(unsafe { *union.mInt.as_ref() }))),
|
||||||
|
nsStyleUnit::eStyleUnit_Percent
|
||||||
|
=> Some(LengthOrPercentage::Percentage(unsafe { *union.mFloat.as_ref() })),
|
||||||
|
nsStyleUnit::eStyleUnit_Calc
|
||||||
|
=> unimplemented!(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToGeckoStyleCoord for LengthOrPercentageOrAuto {
|
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
|
||||||
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
||||||
match *self {
|
match *self {
|
||||||
LengthOrPercentageOrAuto::Length(au) => {
|
LengthOrPercentageOrAuto::Length(au) => {
|
||||||
|
@ -107,9 +201,23 @@ impl ToGeckoStyleCoord for LengthOrPercentageOrAuto {
|
||||||
LengthOrPercentageOrAuto::Calc(_) => unimplemented!(),
|
LengthOrPercentageOrAuto::Calc(_) => unimplemented!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
|
||||||
|
match *unit {
|
||||||
|
nsStyleUnit::eStyleUnit_Auto
|
||||||
|
=> Some(LengthOrPercentageOrAuto::Auto),
|
||||||
|
nsStyleUnit::eStyleUnit_Coord
|
||||||
|
=> Some(LengthOrPercentageOrAuto::Length(Au(unsafe { *union.mInt.as_ref() }))),
|
||||||
|
nsStyleUnit::eStyleUnit_Percent
|
||||||
|
=> Some(LengthOrPercentageOrAuto::Percentage(unsafe { *union.mFloat.as_ref() })),
|
||||||
|
nsStyleUnit::eStyleUnit_Calc
|
||||||
|
=> unimplemented!(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToGeckoStyleCoord for LengthOrPercentageOrNone {
|
impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
|
||||||
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
||||||
match *self {
|
match *self {
|
||||||
LengthOrPercentageOrNone::Length(au) => {
|
LengthOrPercentageOrNone::Length(au) => {
|
||||||
|
@ -127,9 +235,23 @@ impl ToGeckoStyleCoord for LengthOrPercentageOrNone {
|
||||||
LengthOrPercentageOrNone::Calc(_) => unimplemented!(),
|
LengthOrPercentageOrNone::Calc(_) => unimplemented!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
|
||||||
|
match *unit {
|
||||||
|
nsStyleUnit::eStyleUnit_None
|
||||||
|
=> Some(LengthOrPercentageOrNone::None),
|
||||||
|
nsStyleUnit::eStyleUnit_Coord
|
||||||
|
=> Some(LengthOrPercentageOrNone::Length(Au(unsafe { *union.mInt.as_ref() }))),
|
||||||
|
nsStyleUnit::eStyleUnit_Percent
|
||||||
|
=> Some(LengthOrPercentageOrNone::Percentage(unsafe { *union.mFloat.as_ref() })),
|
||||||
|
nsStyleUnit::eStyleUnit_Calc
|
||||||
|
=> unimplemented!(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ToGeckoStyleCoord> ToGeckoStyleCoord for Option<T> {
|
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
|
||||||
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
||||||
if let Some(ref me) = *self {
|
if let Some(ref me) = *self {
|
||||||
me.to_gecko_style_coord(unit, union);
|
me.to_gecko_style_coord(unit, union);
|
||||||
|
@ -138,15 +260,27 @@ impl<T: ToGeckoStyleCoord> ToGeckoStyleCoord for Option<T> {
|
||||||
unsafe { *union.mInt.as_mut() = 0; }
|
unsafe { *union.mInt.as_mut() = 0; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
|
||||||
|
Some(T::from_gecko_style_coord(unit, union))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToGeckoStyleCoord for Angle {
|
impl GeckoStyleCoordConvertible for Angle {
|
||||||
fn to_gecko_style_coord(&self,
|
fn to_gecko_style_coord(&self,
|
||||||
unit: &mut nsStyleUnit,
|
unit: &mut nsStyleUnit,
|
||||||
union: &mut nsStyleUnion) {
|
union: &mut nsStyleUnion) {
|
||||||
*unit = nsStyleUnit::eStyleUnit_Radian;
|
*unit = nsStyleUnit::eStyleUnit_Radian;
|
||||||
unsafe { *union.mFloat.as_mut() = self.radians() };
|
unsafe { *union.mFloat.as_mut() = self.radians() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
|
||||||
|
if *unit == nsStyleUnit::eStyleUnit_Radian {
|
||||||
|
Some(Angle::from_radians(unsafe { *union.mFloat.as_ref() }))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue