mirror of
https://github.com/servo/servo.git
synced 2025-07-23 23:33:43 +01:00
add support for mask_position_parse/serial
This commit is contained in:
parent
725b805c45
commit
eb115e02e1
5 changed files with 212 additions and 181 deletions
|
@ -1683,72 +1683,56 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
</%self:simple_image_array_property>
|
</%self:simple_image_array_property>
|
||||||
|
|
||||||
% if shorthand != "background":
|
% for orientation in [("x", "Horizontal"), ("y", "Vertical")]:
|
||||||
pub fn copy_${shorthand}_position_from(&mut self, other: &Self) {
|
pub fn copy_${shorthand}_position_${orientation[0]}_from(&mut self, other: &Self) {
|
||||||
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
||||||
|
|
||||||
self.gecko.${image_layers_field}.mPositionXCount
|
self.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count
|
||||||
= cmp::min(1, other.gecko.${image_layers_field}.mPositionXCount);
|
= cmp::min(1, other.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count);
|
||||||
self.gecko.${image_layers_field}.mPositionYCount
|
|
||||||
= cmp::min(1, other.gecko.${image_layers_field}.mPositionYCount);
|
|
||||||
self.gecko.${image_layers_field}.mLayers.mFirstElement.mPosition =
|
self.gecko.${image_layers_field}.mLayers.mFirstElement.mPosition =
|
||||||
other.gecko.${image_layers_field}.mLayers.mFirstElement.mPosition;
|
other.gecko.${image_layers_field}.mLayers.mFirstElement.mPosition;
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_EnsureImageLayersLength(&mut self.gecko.${image_layers_field},
|
Gecko_EnsureImageLayersLength(&mut self.gecko.${image_layers_field},
|
||||||
other.gecko.${image_layers_field}.mLayers.len(),
|
other.gecko.${image_layers_field}.mLayers.len(),
|
||||||
LayerType::${shorthand.title()});
|
LayerType::${shorthand.capitalize()});
|
||||||
}
|
|
||||||
for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut()
|
|
||||||
.zip(other.gecko.${image_layers_field}.mLayers.iter())
|
|
||||||
.take(other.gecko.${image_layers_field}.mPositionXCount as usize) {
|
|
||||||
layer.mPosition.mXPosition
|
|
||||||
= other.mPosition.mXPosition;
|
|
||||||
}
|
|
||||||
for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut()
|
|
||||||
.zip(other.gecko.${image_layers_field}.mLayers.iter())
|
|
||||||
.take(other.gecko.${image_layers_field}.mPositionYCount as usize) {
|
|
||||||
layer.mPosition.mYPosition
|
|
||||||
= other.mPosition.mYPosition;
|
|
||||||
}
|
|
||||||
self.gecko.${image_layers_field}.mPositionXCount
|
|
||||||
= other.gecko.${image_layers_field}.mPositionXCount;
|
|
||||||
self.gecko.${image_layers_field}.mPositionYCount
|
|
||||||
= other.gecko.${image_layers_field}.mPositionYCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_${shorthand}_position(&self)
|
for (layer, other) in self.gecko.${image_layers_field}.mLayers.iter_mut()
|
||||||
-> longhands::${shorthand}_position::computed_value::T {
|
.zip(other.gecko.${image_layers_field}.mLayers.iter()) {
|
||||||
use values::computed::position::Position;
|
layer.mPosition.m${orientation[0].upper()}Position
|
||||||
longhands::${shorthand}_position::computed_value::T(
|
= other.mPosition.m${orientation[0].upper()}Position;
|
||||||
|
}
|
||||||
|
self.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count
|
||||||
|
= other.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_${shorthand}_position_${orientation[0]}(&self)
|
||||||
|
-> longhands::${shorthand}_position_${orientation[0]}::computed_value::T {
|
||||||
|
use values::computed::position::${orientation[1]}Position;
|
||||||
|
longhands::${shorthand}_position_${orientation[0]}::computed_value::T(
|
||||||
self.gecko.${image_layers_field}.mLayers.iter()
|
self.gecko.${image_layers_field}.mLayers.iter()
|
||||||
.take(self.gecko.${image_layers_field}.mPositionXCount as usize)
|
.take(self.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count as usize)
|
||||||
.take(self.gecko.${image_layers_field}.mPositionYCount as usize)
|
.map(|position| ${orientation[1]}Position(position.mPosition.m${orientation[0].upper()}Position.into()))
|
||||||
.map(|position| Position {
|
|
||||||
horizontal: position.mPosition.mXPosition.into(),
|
|
||||||
vertical: position.mPosition.mYPosition.into(),
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_${shorthand}_position(&mut self,
|
pub fn set_${shorthand}_position_${orientation[0]}(&mut self,
|
||||||
v: longhands::${shorthand}_position::computed_value::T) {
|
v: longhands::${shorthand}_position_${orientation[0]}::computed_value::T) {
|
||||||
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_EnsureImageLayersLength(&mut self.gecko.${image_layers_field}, v.0.len(),
|
Gecko_EnsureImageLayersLength(&mut self.gecko.${image_layers_field}, v.0.len(),
|
||||||
LayerType::${shorthand.title()});
|
LayerType::${shorthand.capitalize()});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.gecko.${image_layers_field}.mPositionXCount = v.0.len() as u32;
|
self.gecko.${image_layers_field}.mPosition${orientation[0].upper()}Count = v.0.len() as u32;
|
||||||
self.gecko.${image_layers_field}.mPositionYCount = v.0.len() as u32;
|
|
||||||
for (servo, geckolayer) in v.0.into_iter().zip(self.gecko.${image_layers_field}
|
for (servo, geckolayer) in v.0.into_iter().zip(self.gecko.${image_layers_field}
|
||||||
.mLayers.iter_mut()) {
|
.mLayers.iter_mut()) {
|
||||||
geckolayer.mPosition.mXPosition = servo.horizontal.into();
|
geckolayer.mPosition.m${orientation[0].upper()}Position = servo.0.into();
|
||||||
geckolayer.mPosition.mYPosition = servo.vertical.into();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% endif
|
% endfor
|
||||||
|
|
||||||
<%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize">
|
<%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize">
|
||||||
use gecko_bindings::structs::nsStyleImageLayers_Size_Dimension;
|
use gecko_bindings::structs::nsStyleImageLayers_Size_Dimension;
|
||||||
|
@ -1938,56 +1922,6 @@ fn static_assert() {
|
||||||
T::luminosity => structs::NS_STYLE_BLEND_LUMINOSITY as u8,
|
T::luminosity => structs::NS_STYLE_BLEND_LUMINOSITY as u8,
|
||||||
}
|
}
|
||||||
</%self:simple_image_array_property>
|
</%self:simple_image_array_property>
|
||||||
|
|
||||||
% for orientation in [("x", "Horizontal"), ("y", "Vertical")]:
|
|
||||||
pub fn copy_background_position_${orientation[0]}_from(&mut self, other: &Self) {
|
|
||||||
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
|
||||||
|
|
||||||
self.gecko.mImage.mPosition${orientation[0].upper()}Count
|
|
||||||
= cmp::min(1, other.gecko.mImage.mPosition${orientation[0].upper()}Count);
|
|
||||||
self.gecko.mImage.mLayers.mFirstElement.mPosition =
|
|
||||||
other.gecko.mImage.mLayers.mFirstElement.mPosition;
|
|
||||||
unsafe {
|
|
||||||
Gecko_EnsureImageLayersLength(&mut self.gecko.mImage,
|
|
||||||
other.gecko.mImage.mLayers.len(),
|
|
||||||
LayerType::Background);
|
|
||||||
}
|
|
||||||
for (layer, other) in self.gecko.mImage.mLayers.iter_mut()
|
|
||||||
.zip(other.gecko.mImage.mLayers.iter()) {
|
|
||||||
layer.mPosition.m${orientation[0].upper()}Position
|
|
||||||
= other.mPosition.m${orientation[0].upper()}Position;
|
|
||||||
}
|
|
||||||
self.gecko.mImage.mPosition${orientation[0].upper()}Count
|
|
||||||
= other.gecko.mImage.mPosition${orientation[0].upper()}Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clone_background_position_${orientation[0]}(&self)
|
|
||||||
-> longhands::background_position_${orientation[0]}::computed_value::T {
|
|
||||||
use values::computed::position::${orientation[1]}Position;
|
|
||||||
longhands::background_position_${orientation[0]}::computed_value::T(
|
|
||||||
self.gecko.mImage.mLayers.iter()
|
|
||||||
.take(self.gecko.mImage.mPosition${orientation[0].upper()}Count as usize)
|
|
||||||
.map(|position| ${orientation[1]}Position(position.mPosition.m${orientation[0].upper()}Position.into()))
|
|
||||||
.collect()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_background_position_${orientation[0]}(&mut self,
|
|
||||||
v: longhands::background_position_${orientation[0]}::computed_value::T) {
|
|
||||||
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
Gecko_EnsureImageLayersLength(&mut self.gecko.mImage, v.0.len(),
|
|
||||||
LayerType::Background);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.gecko.mImage.mPosition${orientation[0].upper()}Count = v.0.len() as u32;
|
|
||||||
for (servo, geckolayer) in v.0.into_iter().zip(self.gecko.mImage
|
|
||||||
.mLayers.iter_mut()) {
|
|
||||||
geckolayer.mPosition.m${orientation[0].upper()}Position = servo.0.into();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
% endfor
|
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="List"
|
<%self:impl_trait style_struct_name="List"
|
||||||
|
@ -2471,7 +2405,7 @@ fn static_assert() {
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<% skip_svg_longhands = """
|
<% skip_svg_longhands = """
|
||||||
mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position mask-size mask-image
|
mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-position-y mask-size mask-image
|
||||||
clip-path
|
clip-path
|
||||||
"""
|
"""
|
||||||
%>
|
%>
|
||||||
|
@ -2633,7 +2567,6 @@ clip-path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Color"
|
<%self:impl_trait style_struct_name="Color"
|
||||||
|
|
|
@ -103,59 +103,46 @@ ${helpers.single_keyword("mask-repeat",
|
||||||
animatable=False,
|
animatable=False,
|
||||||
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-repeat")}
|
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-repeat")}
|
||||||
|
|
||||||
<%helpers:vector_longhand name="mask-position" products="gecko" animatable="True" extra_prefixes="webkit"
|
<%helpers:vector_longhand name="mask-position-x" products="gecko" animatable="True" extra_prefixes="webkit"
|
||||||
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-position">
|
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-position">
|
||||||
use std::fmt;
|
pub use properties::longhands::background_position_x::single_value::get_initial_value;
|
||||||
use style_traits::ToCss;
|
pub use properties::longhands::background_position_x::single_value::get_initial_position_value;
|
||||||
use values::HasViewportPercentage;
|
pub use properties::longhands::background_position_x::single_value::get_initial_specified_value;
|
||||||
use values::specified::position::Position;
|
pub use properties::longhands::background_position_x::single_value::parse;
|
||||||
|
pub use properties::longhands::background_position_x::single_value::SpecifiedValue;
|
||||||
pub mod computed_value {
|
pub use properties::longhands::background_position_x::single_value::computed_value;
|
||||||
use values::computed::position::Position;
|
|
||||||
use properties::animated_properties::{Interpolate, RepeatableListInterpolate};
|
use properties::animated_properties::{Interpolate, RepeatableListInterpolate};
|
||||||
use properties::longhands::mask_position::computed_value::T as MaskPosition;
|
use properties::longhands::mask_position_x::computed_value::T as MaskPositionX;
|
||||||
|
|
||||||
pub type T = Position;
|
impl Interpolate for MaskPositionX {
|
||||||
|
#[inline]
|
||||||
impl RepeatableListInterpolate for MaskPosition {}
|
|
||||||
|
|
||||||
impl Interpolate for MaskPosition {
|
|
||||||
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
||||||
Ok(MaskPosition(try!(self.0.interpolate(&other.0, progress))))
|
Ok(MaskPositionX(try!(self.0.interpolate(&other.0, progress))))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SpecifiedValue = Position;
|
impl RepeatableListInterpolate for MaskPositionX {}
|
||||||
|
</%helpers:vector_longhand>
|
||||||
|
|
||||||
|
<%helpers:vector_longhand name="mask-position-y" products="gecko" animatable="True" extra_prefixes="webkit"
|
||||||
|
spec="https://drafts.fxtf.org/css-masking/#propdef-mask-position">
|
||||||
|
pub use properties::longhands::background_position_y::single_value::get_initial_value;
|
||||||
|
pub use properties::longhands::background_position_y::single_value::get_initial_position_value;
|
||||||
|
pub use properties::longhands::background_position_y::single_value::get_initial_specified_value;
|
||||||
|
pub use properties::longhands::background_position_y::single_value::parse;
|
||||||
|
pub use properties::longhands::background_position_y::single_value::SpecifiedValue;
|
||||||
|
pub use properties::longhands::background_position_y::single_value::computed_value;
|
||||||
|
use properties::animated_properties::{Interpolate, RepeatableListInterpolate};
|
||||||
|
use properties::longhands::mask_position_y::computed_value::T as MaskPositionY;
|
||||||
|
|
||||||
|
impl Interpolate for MaskPositionY {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
|
||||||
use values::computed::position::Position;
|
Ok(MaskPositionY(try!(self.0.interpolate(&other.0, progress))))
|
||||||
Position {
|
|
||||||
horizontal: computed::LengthOrPercentage::Percentage(0.0),
|
|
||||||
vertical: computed::LengthOrPercentage::Percentage(0.0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
|
||||||
use values::specified::Percentage;
|
|
||||||
use values::specified::position::{HorizontalPosition, VerticalPosition};
|
|
||||||
Position {
|
|
||||||
horizontal: HorizontalPosition {
|
|
||||||
keyword: None,
|
|
||||||
position: Some(specified::LengthOrPercentage::Percentage(Percentage(0.0))),
|
|
||||||
},
|
|
||||||
vertical: VerticalPosition {
|
|
||||||
keyword: None,
|
|
||||||
position: Some(specified::LengthOrPercentage::Percentage(Percentage(0.0))),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser)
|
impl RepeatableListInterpolate for MaskPositionY {}
|
||||||
-> Result<SpecifiedValue, ()> {
|
|
||||||
Position::parse(context, input)
|
|
||||||
}
|
|
||||||
</%helpers:vector_longhand>
|
</%helpers:vector_longhand>
|
||||||
|
|
||||||
${helpers.single_keyword("mask-clip",
|
${helpers.single_keyword("mask-clip",
|
||||||
|
|
|
@ -5,11 +5,14 @@
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
<%helpers:shorthand name="mask" products="gecko" extra_prefixes="webkit"
|
<%helpers:shorthand name="mask" products="gecko" extra_prefixes="webkit"
|
||||||
sub_properties="mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position
|
sub_properties="mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x
|
||||||
mask-size mask-image"
|
mask-position-y mask-size mask-image"
|
||||||
spec="https://drafts.fxtf.org/css-masking/#propdef-mask">
|
spec="https://drafts.fxtf.org/css-masking/#propdef-mask">
|
||||||
use properties::longhands::{mask_mode, mask_repeat, mask_clip, mask_origin, mask_composite, mask_position};
|
use properties::longhands::{mask_mode, mask_repeat, mask_clip, mask_origin, mask_composite, mask_position_x,
|
||||||
|
mask_position_y};
|
||||||
use properties::longhands::{mask_size, mask_image};
|
use properties::longhands::{mask_size, mask_image};
|
||||||
|
use values::specified::position::Position;
|
||||||
|
use parser::Parse;
|
||||||
|
|
||||||
impl From<mask_origin::single_value::SpecifiedValue> for mask_clip::single_value::SpecifiedValue {
|
impl From<mask_origin::single_value::SpecifiedValue> for mask_clip::single_value::SpecifiedValue {
|
||||||
fn from(origin: mask_origin::single_value::SpecifiedValue) -> mask_clip::single_value::SpecifiedValue {
|
fn from(origin: mask_origin::single_value::SpecifiedValue) -> mask_clip::single_value::SpecifiedValue {
|
||||||
|
@ -33,12 +36,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
% for name in "image mode position_x position_y size repeat origin clip composite".split():
|
||||||
let mut mask_${name} = mask_${name}::SpecifiedValue(Vec::new());
|
let mut mask_${name} = mask_${name}::SpecifiedValue(Vec::new());
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
try!(input.parse_comma_separated(|input| {
|
try!(input.parse_comma_separated(|input| {
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
% for name in "image mode position_x position_y size repeat origin clip composite".split():
|
||||||
let mut ${name} = None;
|
let mut ${name} = None;
|
||||||
% endfor
|
% endfor
|
||||||
loop {
|
loop {
|
||||||
|
@ -53,10 +56,10 @@
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if position.is_none() {
|
if position_x.is_none() && position_y.is_none() {
|
||||||
if let Ok(value) = input.try(|input| mask_position::single_value
|
if let Ok(value) = input.try(|input| Position::parse(context, input)) {
|
||||||
::parse(context, input)) {
|
position_x = Some(value.horizontal);
|
||||||
position = Some(value);
|
position_y = Some(value.vertical);
|
||||||
|
|
||||||
// Parse mask size, if applicable.
|
// Parse mask size, if applicable.
|
||||||
size = input.try(|input| {
|
size = input.try(|input| {
|
||||||
|
@ -84,11 +87,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut any = false;
|
let mut any = false;
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
% for name in "image mode position_x position_y size repeat origin clip composite".split():
|
||||||
any = any || ${name}.is_some();
|
any = any || ${name}.is_some();
|
||||||
% endfor
|
% endfor
|
||||||
if any {
|
if any {
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
if position_x.is_some() || position_y.is_some() {
|
||||||
|
% for name in "position_x position_y".split():
|
||||||
|
if let Some(bg_${name}) = ${name} {
|
||||||
|
mask_${name}.0.push(bg_${name});
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
} else {
|
||||||
|
% for name in "position_x position_y".split():
|
||||||
|
mask_${name}.0.push(mask_${name}::single_value
|
||||||
|
::get_initial_position_value());
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
% for name in "image mode size repeat origin clip composite".split():
|
||||||
if let Some(m_${name}) = ${name} {
|
if let Some(m_${name}) = ${name} {
|
||||||
mask_${name}.0.push(m_${name});
|
mask_${name}.0.push(m_${name});
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,7 +118,7 @@
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Ok(Longhands {
|
Ok(Longhands {
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
% for name in "image mode position_x position_y size repeat origin clip composite".split():
|
||||||
mask_${name}: Some(mask_${name}),
|
mask_${name}: Some(mask_${name}),
|
||||||
% endfor
|
% endfor
|
||||||
})
|
})
|
||||||
|
@ -120,7 +135,7 @@
|
||||||
}
|
}
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
let mut len = 0;
|
let mut len = 0;
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
% for name in "image mode position_x position_y size repeat origin clip composite".split():
|
||||||
len = cmp::max(len, extract_value(self.mask_${name}).map(|i| i.0.len())
|
len = cmp::max(len, extract_value(self.mask_${name}).map(|i| i.0.len())
|
||||||
.unwrap_or(0));
|
.unwrap_or(0));
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -131,7 +146,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
% for name in "image mode position size repeat origin clip composite".split():
|
% for name in "image mode position_x position_y size repeat origin clip composite".split():
|
||||||
let ${name} = if let DeclaredValue::Value(ref arr) = *self.mask_${name} {
|
let ${name} = if let DeclaredValue::Value(ref arr) = *self.mask_${name} {
|
||||||
arr.0.get(i % arr.0.len())
|
arr.0.get(i % arr.0.len())
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,8 +170,14 @@
|
||||||
|
|
||||||
try!(write!(dest, " "));
|
try!(write!(dest, " "));
|
||||||
|
|
||||||
try!(position.unwrap_or(&mask_position::single_value
|
try!(position_x.unwrap_or(&mask_position_x::single_value
|
||||||
::get_initial_specified_value())
|
::get_initial_position_value())
|
||||||
|
.to_css(dest));
|
||||||
|
|
||||||
|
try!(write!(dest, " "));
|
||||||
|
|
||||||
|
try!(position_y.unwrap_or(&mask_position_y::single_value
|
||||||
|
::get_initial_position_value())
|
||||||
.to_css(dest));
|
.to_css(dest));
|
||||||
|
|
||||||
if let Some(size) = size {
|
if let Some(size) = size {
|
||||||
|
@ -212,3 +233,85 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
||||||
|
<%helpers:shorthand name="mask-position" products="gecko" extra_prefixes="webkit"
|
||||||
|
sub_properties="mask-position-x mask-position-y"
|
||||||
|
spec="https://drafts.csswg.org/css-masks-4/#the-mask-position">
|
||||||
|
use properties::longhands::{mask_position_x,mask_position_y};
|
||||||
|
use values::specified::position::Position;
|
||||||
|
use parser::Parse;
|
||||||
|
|
||||||
|
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||||
|
let mut position_x = mask_position_x::SpecifiedValue(Vec::new());
|
||||||
|
let mut position_y = mask_position_y::SpecifiedValue(Vec::new());
|
||||||
|
let mut any = false;
|
||||||
|
|
||||||
|
try!(input.parse_comma_separated(|input| {
|
||||||
|
loop {
|
||||||
|
if let Ok(value) = input.try(|input| Position::parse(context, input)) {
|
||||||
|
position_x.0.push(value.horizontal);
|
||||||
|
position_y.0.push(value.vertical);
|
||||||
|
any = true;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}));
|
||||||
|
if any == false {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Longhands {
|
||||||
|
mask_position_x: Some(position_x),
|
||||||
|
mask_position_y: Some(position_y),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LonghandsToSerialize<'a> {
|
||||||
|
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
// mako doesn't like ampersands following `<`
|
||||||
|
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
|
||||||
|
match *x {
|
||||||
|
DeclaredValue::Value(ref val) => Some(val),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use std::cmp;
|
||||||
|
let mut len = 0;
|
||||||
|
% for name in "x y".split():
|
||||||
|
len = cmp::max(len, extract_value(self.mask_position_${name})
|
||||||
|
.map(|i| i.0.len())
|
||||||
|
.unwrap_or(0));
|
||||||
|
% endfor
|
||||||
|
|
||||||
|
// There should be at least one declared value
|
||||||
|
if len == 0 {
|
||||||
|
return dest.write_str("")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..len {
|
||||||
|
% for name in "x y".split():
|
||||||
|
let position_${name} = if let DeclaredValue::Value(ref arr) =
|
||||||
|
*self.mask_position_${name} {
|
||||||
|
arr.0.get(i % arr.0.len())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
% endfor
|
||||||
|
|
||||||
|
try!(position_x.unwrap_or(&mask_position_x::single_value
|
||||||
|
::get_initial_position_value())
|
||||||
|
.to_css(dest));
|
||||||
|
|
||||||
|
try!(write!(dest, " "));
|
||||||
|
|
||||||
|
try!(position_y.unwrap_or(&mask_position_y::single_value
|
||||||
|
::get_initial_position_value())
|
||||||
|
.to_css(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -7,7 +7,7 @@ use media_queries::CSSErrorReporterTest;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use style::parser::ParserContext;
|
use style::parser::ParserContext;
|
||||||
use style::properties::longhands::{mask_clip, mask_composite, mask_image, mask_mode};
|
use style::properties::longhands::{mask_clip, mask_composite, mask_image, mask_mode};
|
||||||
use style::properties::longhands::{mask_origin, mask_position, mask_repeat, mask_size};
|
use style::properties::longhands::{mask_origin, mask_position_x, mask_position_y, mask_repeat, mask_size};
|
||||||
use style::properties::shorthands::mask;
|
use style::properties::shorthands::mask;
|
||||||
use style::stylesheets::Origin;
|
use style::stylesheets::Origin;
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ fn mask_shorthand_should_parse_all_available_properties_when_specified() {
|
||||||
|
|
||||||
assert_eq!(result.mask_image.unwrap(), parse_longhand!(mask_image, "url(\"http://servo/test.png\")"));
|
assert_eq!(result.mask_image.unwrap(), parse_longhand!(mask_image, "url(\"http://servo/test.png\")"));
|
||||||
assert_eq!(result.mask_mode.unwrap(), parse_longhand!(mask_mode, "luminance"));
|
assert_eq!(result.mask_mode.unwrap(), parse_longhand!(mask_mode, "luminance"));
|
||||||
assert_eq!(result.mask_position.unwrap(), parse_longhand!(mask_position, "7px 4px"));
|
assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "7px"));
|
||||||
|
assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "4px"));
|
||||||
assert_eq!(result.mask_size.unwrap(), parse_longhand!(mask_size, "70px 50px"));
|
assert_eq!(result.mask_size.unwrap(), parse_longhand!(mask_size, "70px 50px"));
|
||||||
assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat-x"));
|
assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat-x"));
|
||||||
assert_eq!(result.mask_origin.unwrap(), parse_longhand!(mask_origin, "padding-box"));
|
assert_eq!(result.mask_origin.unwrap(), parse_longhand!(mask_origin, "padding-box"));
|
||||||
|
@ -36,7 +37,8 @@ fn mask_shorthand_should_parse_when_some_fields_set() {
|
||||||
let mut parser = Parser::new("14px 40px repeat-y");
|
let mut parser = Parser::new("14px 40px repeat-y");
|
||||||
let result = mask::parse_value(&context, &mut parser).unwrap();
|
let result = mask::parse_value(&context, &mut parser).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.mask_position.unwrap(), parse_longhand!(mask_position, "14px 40px"));
|
assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "14px"));
|
||||||
|
assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "40px"));
|
||||||
assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat-y"));
|
assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat-y"));
|
||||||
|
|
||||||
let mut parser = Parser::new("url(\"http://servo/test.png\") repeat add");
|
let mut parser = Parser::new("url(\"http://servo/test.png\") repeat add");
|
||||||
|
@ -64,12 +66,14 @@ fn mask_shorthand_should_parse_position_and_size_correctly() {
|
||||||
let mut parser = Parser::new("7px 4px");
|
let mut parser = Parser::new("7px 4px");
|
||||||
let result = mask::parse_value(&context, &mut parser).unwrap();
|
let result = mask::parse_value(&context, &mut parser).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.mask_position.unwrap(), parse_longhand!(mask_position, "7px 4px"));
|
assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "7px"));
|
||||||
|
assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "4px"));
|
||||||
|
|
||||||
let mut parser = Parser::new("7px 4px / 30px 20px");
|
let mut parser = Parser::new("7px 4px / 30px 20px");
|
||||||
let result = mask::parse_value(&context, &mut parser).unwrap();
|
let result = mask::parse_value(&context, &mut parser).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.mask_position.unwrap(), parse_longhand!(mask_position, "7px 4px"));
|
assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "7px"));
|
||||||
|
assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "4px"));
|
||||||
assert_eq!(result.mask_size.unwrap(), parse_longhand!(mask_size, "30px 20px"));
|
assert_eq!(result.mask_size.unwrap(), parse_longhand!(mask_size, "30px 20px"));
|
||||||
|
|
||||||
let mut parser = Parser::new("/ 30px 20px");
|
let mut parser = Parser::new("/ 30px 20px");
|
||||||
|
|
|
@ -879,7 +879,8 @@ mod shorthand_serialization {
|
||||||
use style::properties::longhands::mask_image as image;
|
use style::properties::longhands::mask_image as image;
|
||||||
use style::properties::longhands::mask_mode as mode;
|
use style::properties::longhands::mask_mode as mode;
|
||||||
use style::properties::longhands::mask_origin as origin;
|
use style::properties::longhands::mask_origin as origin;
|
||||||
use style::properties::longhands::mask_position as position;
|
use style::properties::longhands::mask_position_x as position_x;
|
||||||
|
use style::properties::longhands::mask_position_y as position_y;
|
||||||
use style::properties::longhands::mask_repeat as repeat;
|
use style::properties::longhands::mask_repeat as repeat;
|
||||||
use style::properties::longhands::mask_size as size;
|
use style::properties::longhands::mask_size as size;
|
||||||
use style::values::specified::Image;
|
use style::values::specified::Image;
|
||||||
|
@ -918,16 +919,16 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
let mode = single_vec_keyword_value!(mode, luminance);
|
let mode = single_vec_keyword_value!(mode, luminance);
|
||||||
|
|
||||||
let position = single_vec_value_typedef!(position,
|
let position_x = single_vec_value_typedef!(position_x,
|
||||||
Position {
|
HorizontalPosition {
|
||||||
horizontal: HorizontalPosition {
|
|
||||||
keyword: None,
|
keyword: None,
|
||||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))),
|
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))),
|
||||||
},
|
}
|
||||||
vertical: VerticalPosition {
|
);
|
||||||
|
let position_y = single_vec_value_typedef!(position_y,
|
||||||
|
VerticalPosition {
|
||||||
keyword: None,
|
keyword: None,
|
||||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -947,7 +948,8 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
properties.push(PropertyDeclaration::MaskImage(image));
|
properties.push(PropertyDeclaration::MaskImage(image));
|
||||||
properties.push(PropertyDeclaration::MaskMode(mode));
|
properties.push(PropertyDeclaration::MaskMode(mode));
|
||||||
properties.push(PropertyDeclaration::MaskPosition(position));
|
properties.push(PropertyDeclaration::MaskPositionX(position_x));
|
||||||
|
properties.push(PropertyDeclaration::MaskPositionY(position_y));
|
||||||
properties.push(PropertyDeclaration::MaskSize(size));
|
properties.push(PropertyDeclaration::MaskSize(size));
|
||||||
properties.push(PropertyDeclaration::MaskRepeat(repeat));
|
properties.push(PropertyDeclaration::MaskRepeat(repeat));
|
||||||
properties.push(PropertyDeclaration::MaskOrigin(origin));
|
properties.push(PropertyDeclaration::MaskOrigin(origin));
|
||||||
|
@ -972,16 +974,17 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
let mode = single_vec_keyword_value!(mode, luminance);
|
let mode = single_vec_keyword_value!(mode, luminance);
|
||||||
|
|
||||||
let position = single_vec_value_typedef!(position,
|
let position_x = single_vec_value_typedef!(position_x,
|
||||||
Position {
|
HorizontalPosition {
|
||||||
horizontal: HorizontalPosition {
|
|
||||||
keyword: None,
|
keyword: None,
|
||||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))),
|
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))),
|
||||||
},
|
}
|
||||||
vertical: VerticalPosition {
|
);
|
||||||
|
|
||||||
|
let position_y = single_vec_value_typedef!(position_y,
|
||||||
|
VerticalPosition {
|
||||||
keyword: None,
|
keyword: None,
|
||||||
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1001,7 +1004,8 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
properties.push(PropertyDeclaration::MaskImage(image));
|
properties.push(PropertyDeclaration::MaskImage(image));
|
||||||
properties.push(PropertyDeclaration::MaskMode(mode));
|
properties.push(PropertyDeclaration::MaskMode(mode));
|
||||||
properties.push(PropertyDeclaration::MaskPosition(position));
|
properties.push(PropertyDeclaration::MaskPositionX(position_x));
|
||||||
|
properties.push(PropertyDeclaration::MaskPositionY(position_y));
|
||||||
properties.push(PropertyDeclaration::MaskSize(size));
|
properties.push(PropertyDeclaration::MaskSize(size));
|
||||||
properties.push(PropertyDeclaration::MaskRepeat(repeat));
|
properties.push(PropertyDeclaration::MaskRepeat(repeat));
|
||||||
properties.push(PropertyDeclaration::MaskOrigin(origin));
|
properties.push(PropertyDeclaration::MaskOrigin(origin));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue