mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Auto merge of #22352 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See each individual commit for details. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22352) <!-- Reviewable:end -->
This commit is contained in:
commit
5bdea7dc1c
26 changed files with 2100 additions and 1984 deletions
|
@ -1499,8 +1499,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
let outline_style = match style.get_outline().outline_style {
|
let outline_style = match style.get_outline().outline_style {
|
||||||
OutlineStyle::Auto => BorderStyle::Solid,
|
OutlineStyle::Auto => BorderStyle::Solid,
|
||||||
OutlineStyle::Other(BorderStyle::None) => return,
|
// FIXME(emilio): I don't think this border-style check is
|
||||||
OutlineStyle::Other(border_style) => border_style,
|
// necessary, since border-style: none implies an outline-width of
|
||||||
|
// zero at computed value time.
|
||||||
|
OutlineStyle::BorderStyle(BorderStyle::None) => return,
|
||||||
|
OutlineStyle::BorderStyle(s) => s,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Outlines are not accounted for in the dimensions of the border box, so adjust the
|
// Outlines are not accounted for in the dimensions of the border box, so adjust the
|
||||||
|
|
|
@ -31,6 +31,7 @@ include = ["cssparser"]
|
||||||
|
|
||||||
[struct]
|
[struct]
|
||||||
derive_eq = true
|
derive_eq = true
|
||||||
|
derive_neq = true
|
||||||
|
|
||||||
[enum]
|
[enum]
|
||||||
derive_helper_methods = true
|
derive_helper_methods = true
|
||||||
|
@ -41,6 +42,8 @@ include = [
|
||||||
"Appearance",
|
"Appearance",
|
||||||
"BreakBetween",
|
"BreakBetween",
|
||||||
"BreakWithin",
|
"BreakWithin",
|
||||||
|
"BorderStyle",
|
||||||
|
"OutlineStyle",
|
||||||
"ComputedFontStretchRange",
|
"ComputedFontStretchRange",
|
||||||
"ComputedFontStyleDescriptor",
|
"ComputedFontStyleDescriptor",
|
||||||
"ComputedFontWeightRange",
|
"ComputedFontWeightRange",
|
||||||
|
|
|
@ -283,18 +283,32 @@ impl VariableValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(
|
fn push<'i>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
input: &Parser<'i, '_>,
|
||||||
css: &str,
|
css: &str,
|
||||||
css_first_token_type: TokenSerializationType,
|
css_first_token_type: TokenSerializationType,
|
||||||
css_last_token_type: TokenSerializationType,
|
css_last_token_type: TokenSerializationType,
|
||||||
) {
|
) -> Result<(), ParseError<'i>> {
|
||||||
|
/// Prevent values from getting terribly big since you can use custom
|
||||||
|
/// properties exponentially.
|
||||||
|
///
|
||||||
|
/// This number (1MB) is somewhat arbitrary, but silly enough that no
|
||||||
|
/// sane page would hit it. We could limit by number of total
|
||||||
|
/// substitutions, but that was very easy to work around in practice
|
||||||
|
/// (just choose a larger initial value and boom).
|
||||||
|
const MAX_VALUE_LENGTH_IN_BYTES: usize = 1024 * 1024;
|
||||||
|
|
||||||
|
if self.css.len() + css.len() > MAX_VALUE_LENGTH_IN_BYTES {
|
||||||
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
|
||||||
// This happens e.g. between two subsequent var() functions:
|
// This happens e.g. between two subsequent var() functions:
|
||||||
// `var(--a)var(--b)`.
|
// `var(--a)var(--b)`.
|
||||||
//
|
//
|
||||||
// In that case, css_*_token_type is nonsensical.
|
// In that case, css_*_token_type is nonsensical.
|
||||||
if css.is_empty() {
|
if css.is_empty() {
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.first_token_type.set_if_nothing(css_first_token_type);
|
self.first_token_type.set_if_nothing(css_first_token_type);
|
||||||
|
@ -307,21 +321,32 @@ impl VariableValue {
|
||||||
self.css.push_str("/**/")
|
self.css.push_str("/**/")
|
||||||
}
|
}
|
||||||
self.css.push_str(css);
|
self.css.push_str(css);
|
||||||
self.last_token_type = css_last_token_type
|
self.last_token_type = css_last_token_type;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_from(
|
fn push_from<'i>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
input: &Parser<'i, '_>,
|
||||||
position: (SourcePosition, TokenSerializationType),
|
position: (SourcePosition, TokenSerializationType),
|
||||||
input: &Parser,
|
|
||||||
last_token_type: TokenSerializationType,
|
last_token_type: TokenSerializationType,
|
||||||
) {
|
) -> Result<(), ParseError<'i>> {
|
||||||
self.push(input.slice_from(position.0), position.1, last_token_type)
|
self.push(
|
||||||
|
input,
|
||||||
|
input.slice_from(position.0),
|
||||||
|
position.1,
|
||||||
|
last_token_type,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_variable(&mut self, variable: &ComputedValue) {
|
fn push_variable<'i>(
|
||||||
|
&mut self,
|
||||||
|
input: &Parser<'i, '_>,
|
||||||
|
variable: &ComputedValue,
|
||||||
|
) -> Result<(), ParseError<'i>> {
|
||||||
debug_assert!(variable.references.is_empty());
|
debug_assert!(variable.references.is_empty());
|
||||||
self.push(
|
self.push(
|
||||||
|
input,
|
||||||
&variable.css,
|
&variable.css,
|
||||||
variable.first_token_type,
|
variable.first_token_type,
|
||||||
variable.last_token_type,
|
variable.last_token_type,
|
||||||
|
@ -727,6 +752,7 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
// title=Tarjan%27s_strongly_connected_components_algorithm&oldid=801728495
|
// title=Tarjan%27s_strongly_connected_components_algorithm&oldid=801728495
|
||||||
|
|
||||||
/// Struct recording necessary information for each variable.
|
/// Struct recording necessary information for each variable.
|
||||||
|
#[derive(Debug)]
|
||||||
struct VarInfo {
|
struct VarInfo {
|
||||||
/// The name of the variable. It will be taken to save addref
|
/// The name of the variable. It will be taken to save addref
|
||||||
/// when the corresponding variable is popped from the stack.
|
/// when the corresponding variable is popped from the stack.
|
||||||
|
@ -741,6 +767,7 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap, environment:
|
||||||
}
|
}
|
||||||
/// Context struct for traversing the variable graph, so that we can
|
/// Context struct for traversing the variable graph, so that we can
|
||||||
/// avoid referencing all the fields multiple times.
|
/// avoid referencing all the fields multiple times.
|
||||||
|
#[derive(Debug)]
|
||||||
struct Context<'a> {
|
struct Context<'a> {
|
||||||
/// Number of variables visited. This is used as the order index
|
/// Number of variables visited. This is used as the order index
|
||||||
/// when we visit a new unresolved variable.
|
/// when we visit a new unresolved variable.
|
||||||
|
@ -941,7 +968,7 @@ fn substitute_references_in_value<'i>(
|
||||||
environment,
|
environment,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
computed_value.push_from(position, &input, last_token_type);
|
computed_value.push_from(&input, position, last_token_type)?;
|
||||||
Ok(computed_value)
|
Ok(computed_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -955,8 +982,8 @@ fn substitute_references_in_value<'i>(
|
||||||
///
|
///
|
||||||
/// Return `Err(())` if `input` is invalid at computed-value time.
|
/// Return `Err(())` if `input` is invalid at computed-value time.
|
||||||
/// or `Ok(last_token_type that was pushed to partial_computed_value)` otherwise.
|
/// or `Ok(last_token_type that was pushed to partial_computed_value)` otherwise.
|
||||||
fn substitute_block<'i, 't>(
|
fn substitute_block<'i>(
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, '_>,
|
||||||
position: &mut (SourcePosition, TokenSerializationType),
|
position: &mut (SourcePosition, TokenSerializationType),
|
||||||
partial_computed_value: &mut ComputedValue,
|
partial_computed_value: &mut ComputedValue,
|
||||||
custom_properties: &CustomPropertiesMap,
|
custom_properties: &CustomPropertiesMap,
|
||||||
|
@ -991,10 +1018,11 @@ fn substitute_block<'i, 't>(
|
||||||
let is_env = name.eq_ignore_ascii_case("env");
|
let is_env = name.eq_ignore_ascii_case("env");
|
||||||
|
|
||||||
partial_computed_value.push(
|
partial_computed_value.push(
|
||||||
|
input,
|
||||||
input.slice(position.0..before_this_token),
|
input.slice(position.0..before_this_token),
|
||||||
position.1,
|
position.1,
|
||||||
last_token_type,
|
last_token_type,
|
||||||
);
|
)?;
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
// parse_var_function() / parse_env_function() ensure neither .unwrap() will fail.
|
// parse_var_function() / parse_env_function() ensure neither .unwrap() will fail.
|
||||||
let name = {
|
let name = {
|
||||||
|
@ -1014,7 +1042,7 @@ fn substitute_block<'i, 't>(
|
||||||
|
|
||||||
if let Some(v) = value {
|
if let Some(v) = value {
|
||||||
last_token_type = v.last_token_type;
|
last_token_type = v.last_token_type;
|
||||||
partial_computed_value.push_variable(v);
|
partial_computed_value.push_variable(input, v)?;
|
||||||
// Skip over the fallback, as `parse_nested_block` would return `Err`
|
// Skip over the fallback, as `parse_nested_block` would return `Err`
|
||||||
// if we don't consume all of `input`.
|
// if we don't consume all of `input`.
|
||||||
// FIXME: Add a specialized method to cssparser to do this with less work.
|
// FIXME: Add a specialized method to cssparser to do this with less work.
|
||||||
|
@ -1036,7 +1064,7 @@ fn substitute_block<'i, 't>(
|
||||||
custom_properties,
|
custom_properties,
|
||||||
env,
|
env,
|
||||||
)?;
|
)?;
|
||||||
partial_computed_value.push_from(position, input, last_token_type);
|
partial_computed_value.push_from(input, position, last_token_type)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
@ -1096,6 +1124,6 @@ pub fn substitute<'i>(
|
||||||
&custom_properties,
|
&custom_properties,
|
||||||
env,
|
env,
|
||||||
)?;
|
)?;
|
||||||
substituted.push_from(position, &input, last_token_type);
|
substituted.push_from(&input, position, last_token_type)?;
|
||||||
Ok(substituted.css)
|
Ok(substituted.css)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,13 @@
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||||
use crate::gecko_bindings::bindings;
|
use crate::gecko_bindings::bindings;
|
||||||
|
use crate::gecko_bindings::structs::RawGeckoGfxMatrix4x4;
|
||||||
use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue};
|
use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue};
|
||||||
use crate::gecko_bindings::structs::{nsStyleImage, nsresult, SheetType};
|
use crate::gecko_bindings::structs::{nsStyleImage, nsresult, SheetType};
|
||||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
||||||
use crate::stylesheets::{Origin, RulesMutateError};
|
use crate::stylesheets::{Origin, RulesMutateError};
|
||||||
use crate::values::computed::image::LineDirection;
|
use crate::values::computed::image::LineDirection;
|
||||||
|
use crate::values::computed::transform::Matrix3D;
|
||||||
use crate::values::computed::url::ComputedImageUrl;
|
use crate::values::computed::url::ComputedImageUrl;
|
||||||
use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
|
use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
|
||||||
use crate::values::computed::{Integer, LengthOrPercentage};
|
use crate::values::computed::{Integer, LengthOrPercentage};
|
||||||
|
@ -1142,3 +1144,36 @@ pub unsafe fn string_from_chars_pointer(p: *const u16) -> String {
|
||||||
let char_vec = slice::from_raw_parts(p, length as usize);
|
let char_vec = slice::from_raw_parts(p, length as usize);
|
||||||
String::from_utf16_lossy(char_vec)
|
String::from_utf16_lossy(char_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a RawGeckoGfxMatrix4x4> for Matrix3D {
|
||||||
|
fn from(m: &'a RawGeckoGfxMatrix4x4) -> Matrix3D {
|
||||||
|
Matrix3D {
|
||||||
|
m11: m[0],
|
||||||
|
m12: m[1],
|
||||||
|
m13: m[2],
|
||||||
|
m14: m[3],
|
||||||
|
m21: m[4],
|
||||||
|
m22: m[5],
|
||||||
|
m23: m[6],
|
||||||
|
m24: m[7],
|
||||||
|
m31: m[8],
|
||||||
|
m32: m[9],
|
||||||
|
m33: m[10],
|
||||||
|
m34: m[11],
|
||||||
|
m41: m[12],
|
||||||
|
m42: m[13],
|
||||||
|
m43: m[14],
|
||||||
|
m44: m[15],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Matrix3D> for RawGeckoGfxMatrix4x4 {
|
||||||
|
fn from(matrix: Matrix3D) -> RawGeckoGfxMatrix4x4 {
|
||||||
|
[
|
||||||
|
matrix.m11, matrix.m12, matrix.m13, matrix.m14, matrix.m21, matrix.m22, matrix.m23,
|
||||||
|
matrix.m24, matrix.m31, matrix.m32, matrix.m33, matrix.m34, matrix.m41, matrix.m42,
|
||||||
|
matrix.m43, matrix.m44,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -462,22 +462,6 @@ impl PropertyDeclarationBlock {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As a compatibility hack, specially on Android,
|
|
||||||
// don't allow to override a prefixed webkit display
|
|
||||||
// value with an unprefixed version from parsing
|
|
||||||
// code.
|
|
||||||
//
|
|
||||||
// TODO(emilio): Unship.
|
|
||||||
if let PropertyDeclaration::Display(old_display) = *slot {
|
|
||||||
use crate::properties::longhands::display::computed_value::T as display;
|
|
||||||
|
|
||||||
if let PropertyDeclaration::Display(new_display) = declaration {
|
|
||||||
if display::should_ignore_parsed_value(old_display, new_display) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index_to_remove = Some(i);
|
index_to_remove = Some(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -933,6 +917,10 @@ impl PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
already_serialized.insert(shorthand.into());
|
already_serialized.insert(shorthand.into());
|
||||||
|
|
||||||
|
if shorthand.is_legacy_shorthand() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Substep 2 & 3
|
// Substep 2 & 3
|
||||||
let mut current_longhands = SmallVec::<[_; 10]>::new();
|
let mut current_longhands = SmallVec::<[_; 10]>::new();
|
||||||
let mut important_count = 0;
|
let mut important_count = 0;
|
||||||
|
|
|
@ -58,15 +58,14 @@ use std::mem::{forget, uninitialized, transmute, zeroed};
|
||||||
use std::{cmp, ops, ptr};
|
use std::{cmp, ops, ptr};
|
||||||
use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
|
use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
|
||||||
use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty};
|
use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty};
|
||||||
|
use crate::values::computed::BorderStyle;
|
||||||
use crate::values::computed::font::FontSize;
|
use crate::values::computed::font::FontSize;
|
||||||
use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
use crate::values::computed::outline::OutlineStyle;
|
|
||||||
use crate::values::generics::column::ColumnCount;
|
use crate::values::generics::column::ColumnCount;
|
||||||
use crate::values::generics::position::ZIndex;
|
use crate::values::generics::position::ZIndex;
|
||||||
use crate::values::generics::text::MozTabSize;
|
use crate::values::generics::text::MozTabSize;
|
||||||
use crate::values::generics::transform::TransformStyle;
|
use crate::values::generics::transform::TransformStyle;
|
||||||
use crate::values::generics::url::UrlOrNone;
|
use crate::values::generics::url::UrlOrNone;
|
||||||
use crate::computed_values::border_style;
|
|
||||||
|
|
||||||
pub mod style_structs {
|
pub mod style_structs {
|
||||||
% for style_struct in data.style_structs:
|
% for style_struct in data.style_structs:
|
||||||
|
@ -333,13 +332,10 @@ impl ${style_struct.gecko_struct_name} {
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_simple_copy(ident, gecko_ffi_name, on_set=None, *kwargs)">
|
<%def name="impl_simple_copy(ident, gecko_ffi_name, *kwargs)">
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
pub 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};
|
||||||
% if on_set:
|
|
||||||
self.${on_set}();
|
|
||||||
% endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -368,7 +364,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
return "self.gecko.%s = %s;" % (ffi_name, expr)
|
return "self.gecko.%s = %s;" % (ffi_name, expr)
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<%def name="impl_keyword_setter(ident, gecko_ffi_name, keyword, cast_type='u8', on_set=None)">
|
<%def name="impl_keyword_setter(ident, gecko_ffi_name, keyword, cast_type='u8')">
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
use crate::properties::longhands::${ident}::computed_value::T as Keyword;
|
use crate::properties::longhands::${ident}::computed_value::T as Keyword;
|
||||||
|
@ -380,9 +376,6 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% endfor
|
% endfor
|
||||||
};
|
};
|
||||||
${set_gecko_property(gecko_ffi_name, "result")}
|
${set_gecko_property(gecko_ffi_name, "result")}
|
||||||
% if on_set:
|
|
||||||
self.${on_set}();
|
|
||||||
% endif
|
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
@ -1515,9 +1508,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<% border_style_keyword = Keyword("border-style",
|
|
||||||
"none solid double dotted dashed hidden groove ridge inset outset") %>
|
|
||||||
|
|
||||||
<% skip_border_longhands = " ".join(["border-{0}-{1}".format(x.ident, y)
|
<% skip_border_longhands = " ".join(["border-{0}-{1}".format(x.ident, y)
|
||||||
for x in SIDES
|
for x in SIDES
|
||||||
for y in ["color", "style", "width"]] +
|
for y in ["color", "style", "width"]] +
|
||||||
|
@ -1528,41 +1518,55 @@ fn static_assert() {
|
||||||
skip_longhands="${skip_border_longhands} border-image-source border-image-outset
|
skip_longhands="${skip_border_longhands} border-image-source border-image-outset
|
||||||
border-image-repeat border-image-width border-image-slice">
|
border-image-repeat border-image-width border-image-slice">
|
||||||
% for side in SIDES:
|
% for side in SIDES:
|
||||||
<% impl_keyword("border_%s_style" % side.ident,
|
pub fn set_border_${side.ident}_style(&mut self, v: BorderStyle) {
|
||||||
"mBorderStyle[%s]" % side.index,
|
self.gecko.mBorderStyle[${side.index}] = v;
|
||||||
border_style_keyword,
|
|
||||||
on_set="update_border_%s" % side.ident) %>
|
|
||||||
|
|
||||||
// This is needed because the initial mComputedBorder value is set to zero.
|
// This is needed because the initial mComputedBorder value is set to
|
||||||
//
|
// zero.
|
||||||
// In order to compute stuff, we start from the initial struct, and keep
|
//
|
||||||
// going down the tree applying properties.
|
// In order to compute stuff, we start from the initial struct, and keep
|
||||||
//
|
// going down the tree applying properties.
|
||||||
// That means, effectively, that when we set border-style to something
|
//
|
||||||
// non-hidden, we should use the initial border instead.
|
// That means, effectively, that when we set border-style to something
|
||||||
//
|
// non-hidden, we should use the initial border instead.
|
||||||
// Servo stores the initial border-width in the initial struct, and then
|
//
|
||||||
// adjusts as needed in the fixup phase. This means that the initial struct
|
// Servo stores the initial border-width in the initial struct, and then
|
||||||
// is technically not valid without fixups, and that you lose pretty much
|
// adjusts as needed in the fixup phase. This means that the initial
|
||||||
// any sharing of the initial struct, which is kind of unfortunate.
|
// struct is technically not valid without fixups, and that you lose
|
||||||
//
|
// pretty much any sharing of the initial struct, which is kind of
|
||||||
// Gecko has two fields for this, one that stores the "specified" border,
|
// unfortunate.
|
||||||
// and other that stores the actual computed one. That means that when we
|
//
|
||||||
// set border-style, border-width may change and we need to sync back to the
|
// Gecko has two fields for this, one that stores the "specified"
|
||||||
// specified one. This is what this function does.
|
// border, and other that stores the actual computed one. That means
|
||||||
//
|
// that when we set border-style, border-width may change and we need to
|
||||||
// Note that this doesn't impose any dependency in the order of computation
|
// sync back to the specified one. This is what this function does.
|
||||||
// of the properties. This is only relevant if border-style is specified,
|
//
|
||||||
// but border-width isn't. If border-width is specified at some point, the
|
// Note that this doesn't impose any dependency in the order of
|
||||||
// two mBorder and mComputedBorder fields would be the same already.
|
// computation of the properties. This is only relevant if border-style
|
||||||
//
|
// is specified, but border-width isn't. If border-width is specified at
|
||||||
// Once we're here, we know that we'll run style fixups, so it's fine to
|
// some point, the two mBorder and mComputedBorder fields would be the
|
||||||
// just copy the specified border here, we'll adjust it if it's incorrect
|
// same already.
|
||||||
// later.
|
//
|
||||||
fn update_border_${side.ident}(&mut self) {
|
// Once we're here, we know that we'll run style fixups, so it's fine to
|
||||||
|
// just copy the specified border here, we'll adjust it if it's
|
||||||
|
// incorrect later.
|
||||||
self.gecko.mComputedBorder.${side.ident} = self.gecko.mBorder.${side.ident};
|
self.gecko.mComputedBorder.${side.ident} = self.gecko.mBorder.${side.ident};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copy_border_${side.ident}_style_from(&mut self, other: &Self) {
|
||||||
|
self.gecko.mBorderStyle[${side.index}] = other.gecko.mBorderStyle[${side.index}];
|
||||||
|
self.gecko.mComputedBorder.${side.ident} = self.gecko.mBorder.${side.ident};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset_border_${side.ident}_style(&mut self, other: &Self) {
|
||||||
|
self.copy_border_${side.ident}_style_from(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn clone_border_${side.ident}_style(&self) -> BorderStyle {
|
||||||
|
self.gecko.mBorderStyle[${side.index}]
|
||||||
|
}
|
||||||
|
|
||||||
<% impl_color("border_%s_color" % side.ident, "mBorder%sColor" % side.name) %>
|
<% impl_color("border_%s_color" % side.ident, "mBorder%sColor" % side.name) %>
|
||||||
|
|
||||||
<% impl_non_negative_length("border_%s_width" % side.ident,
|
<% impl_non_negative_length("border_%s_width" % side.ident,
|
||||||
|
@ -2170,50 +2174,26 @@ fn static_assert() {
|
||||||
<%self:impl_trait style_struct_name="Outline"
|
<%self:impl_trait style_struct_name="Outline"
|
||||||
skip_longhands="${skip_outline_longhands}">
|
skip_longhands="${skip_outline_longhands}">
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn set_outline_style(&mut self, v: longhands::outline_style::computed_value::T) {
|
pub fn set_outline_style(&mut self, v: longhands::outline_style::computed_value::T) {
|
||||||
// FIXME(bholley): Align binary representations and ditch |match| for
|
self.gecko.mOutlineStyle = v;
|
||||||
// cast + static_asserts
|
|
||||||
let result = match v {
|
|
||||||
% for value in border_style_keyword.values_for('gecko'):
|
|
||||||
OutlineStyle::Other(border_style::T::${to_camel_case(value)}) =>
|
|
||||||
structs::${border_style_keyword.gecko_constant(value)} ${border_style_keyword.maybe_cast("u8")},
|
|
||||||
% endfor
|
|
||||||
OutlineStyle::Auto =>
|
|
||||||
structs::${border_style_keyword.gecko_constant('auto')} ${border_style_keyword.maybe_cast("u8")},
|
|
||||||
};
|
|
||||||
${set_gecko_property("mOutlineStyle", "result")}
|
|
||||||
|
|
||||||
// NB: This is needed to correctly handling the initial value of
|
// NB: This is needed to correctly handling the initial value of
|
||||||
// outline-width when outline-style changes, see the
|
// outline-width when outline-style changes, see the
|
||||||
// update_border_${side.ident} comment for more details.
|
// update_border_${side.ident} comment for more details.
|
||||||
self.gecko.mActualOutlineWidth = self.gecko.mOutlineWidth;
|
self.gecko.mActualOutlineWidth = self.gecko.mOutlineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn copy_outline_style_from(&mut self, other: &Self) {
|
pub fn copy_outline_style_from(&mut self, other: &Self) {
|
||||||
|
// FIXME(emilio): Why doesn't this need to reset mActualOutlineWidth?
|
||||||
|
// Looks fishy.
|
||||||
self.gecko.mOutlineStyle = other.gecko.mOutlineStyle;
|
self.gecko.mOutlineStyle = other.gecko.mOutlineStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn reset_outline_style(&mut self, other: &Self) {
|
pub fn reset_outline_style(&mut self, other: &Self) {
|
||||||
self.copy_outline_style_from(other)
|
self.copy_outline_style_from(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn clone_outline_style(&self) -> longhands::outline_style::computed_value::T {
|
pub fn clone_outline_style(&self) -> longhands::outline_style::computed_value::T {
|
||||||
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
|
self.gecko.mOutlineStyle.clone()
|
||||||
match ${get_gecko_property("mOutlineStyle")} ${border_style_keyword.maybe_cast("u32")} {
|
|
||||||
% for value in border_style_keyword.values_for('gecko'):
|
|
||||||
structs::${border_style_keyword.gecko_constant(value)} => {
|
|
||||||
OutlineStyle::Other(border_style::T::${to_camel_case(value)})
|
|
||||||
},
|
|
||||||
% endfor
|
|
||||||
structs::${border_style_keyword.gecko_constant('auto')} => OutlineStyle::Auto,
|
|
||||||
% if border_style_keyword.gecko_inexhaustive:
|
|
||||||
_ => panic!("Found unexpected value in style struct for outline_style property"),
|
|
||||||
% endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<% impl_non_negative_length("outline_width", "mActualOutlineWidth",
|
<% impl_non_negative_length("outline_width", "mActualOutlineWidth",
|
||||||
|
@ -5410,7 +5390,7 @@ clip-path
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Column"
|
<%self:impl_trait style_struct_name="Column"
|
||||||
skip_longhands="column-count column-rule-width">
|
skip_longhands="column-count column-rule-width column-rule-style">
|
||||||
|
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
pub fn set_column_count(&mut self, v: longhands::column_count::computed_value::T) {
|
pub fn set_column_count(&mut self, v: longhands::column_count::computed_value::T) {
|
||||||
|
@ -5439,6 +5419,7 @@ clip-path
|
||||||
|
|
||||||
<% impl_non_negative_length("column_rule_width", "mColumnRuleWidth",
|
<% impl_non_negative_length("column_rule_width", "mColumnRuleWidth",
|
||||||
round_to_pixels=True) %>
|
round_to_pixels=True) %>
|
||||||
|
${impl_simple('column_rule_style', 'mColumnRuleStyle')}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Counters"
|
<%self:impl_trait style_struct_name="Counters"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,8 @@ ${helpers.predefined_type(
|
||||||
animation_value_type="AnimatedColor",
|
animation_value_type="AnimatedColor",
|
||||||
ignored_when_colors_disabled=True,
|
ignored_when_colors_disabled=True,
|
||||||
allow_quirks=True,
|
allow_quirks=True,
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER \
|
||||||
|
CAN_ANIMATE_ON_COMPOSITOR",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
|
|
|
@ -63,7 +63,9 @@
|
||||||
|
|
||||||
${helpers.gecko_keyword_conversion(
|
${helpers.gecko_keyword_conversion(
|
||||||
Keyword('border-style',
|
Keyword('border-style',
|
||||||
"none solid double dotted dashed hidden groove ridge inset outset"),
|
"none solid double dotted dashed hidden groove ridge inset outset",
|
||||||
|
gecko_enum_prefix="StyleBorderStyle",
|
||||||
|
gecko_inexhaustive=True),
|
||||||
type="crate::values::specified::BorderStyle",
|
type="crate::values::specified::BorderStyle",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -438,33 +438,33 @@ ${helpers.single_keyword(
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"page-break-after",
|
"break-after",
|
||||||
"BreakBetween",
|
"BreakBetween",
|
||||||
"computed::BreakBetween::Auto",
|
"computed::BreakBetween::Auto",
|
||||||
needs_context=False,
|
needs_context=False,
|
||||||
products="gecko",
|
products="gecko",
|
||||||
spec="https://drafts.csswg.org/css2/page.html#propdef-page-break-after",
|
spec="https://drafts.csswg.org/css-break/#propdef-break-after",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"page-break-before",
|
"break-before",
|
||||||
"BreakBetween",
|
"BreakBetween",
|
||||||
"computed::BreakBetween::Auto",
|
"computed::BreakBetween::Auto",
|
||||||
needs_context=False,
|
needs_context=False,
|
||||||
products="gecko",
|
products="gecko",
|
||||||
spec="https://drafts.csswg.org/css2/page.html#propdef-page-break-before",
|
spec="https://drafts.csswg.org/css-break/#propdef-break-before",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"page-break-inside",
|
"break-inside",
|
||||||
"BreakWithin",
|
"BreakWithin",
|
||||||
"computed::BreakWithin::Auto",
|
"computed::BreakWithin::Auto",
|
||||||
gecko_ffi_name="mBreakInside",
|
|
||||||
needs_context=False,
|
needs_context=False,
|
||||||
products="gecko",
|
products="gecko",
|
||||||
spec="https://drafts.csswg.org/css2/page.html#propdef-page-break-inside",
|
alias="page-break-inside",
|
||||||
|
spec="https://drafts.csswg.org/css-break/#propdef-break-inside",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,14 @@ ${helpers.single_keyword(
|
||||||
extra_prefixes="moz:layout.css.column-span.enabled",
|
extra_prefixes="moz:layout.css.column-span.enabled",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.single_keyword(
|
${helpers.predefined_type(
|
||||||
"column-rule-style",
|
"column-rule-style",
|
||||||
"none hidden dotted dashed solid double groove ridge inset outset",
|
"BorderStyle",
|
||||||
|
"computed::BorderStyle::None",
|
||||||
|
needs_context=False,
|
||||||
|
initial_specified_value="specified::BorderStyle::None",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
extra_prefixes="moz",
|
extra_prefixes="moz",
|
||||||
gecko_constant_prefix="NS_STYLE_BORDER_STYLE",
|
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-style",
|
spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-style",
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -337,6 +337,7 @@ ${helpers.single_keyword(
|
||||||
${helpers.single_keyword(
|
${helpers.single_keyword(
|
||||||
"text-rendering",
|
"text-rendering",
|
||||||
"auto optimizespeed optimizelegibility geometricprecision",
|
"auto optimizespeed optimizelegibility geometricprecision",
|
||||||
|
gecko_enum_prefix="StyleTextRendering",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#TextRenderingProperty",
|
spec="https://www.w3.org/TR/SVG11/painting.html#TextRenderingProperty",
|
||||||
servo_restyle_damage="rebuild_and_reflow",
|
servo_restyle_damage="rebuild_and_reflow",
|
||||||
|
|
|
@ -39,6 +39,7 @@ ${helpers.predefined_type(
|
||||||
gecko_ffi_name="mUserSelect",
|
gecko_ffi_name="mUserSelect",
|
||||||
alias="-webkit-user-select",
|
alias="-webkit-user-select",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
|
needs_context=False,
|
||||||
spec="https://drafts.csswg.org/css-ui-4/#propdef-user-select",
|
spec="https://drafts.csswg.org/css-ui-4/#propdef-user-select",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -948,6 +948,10 @@ bitflags! {
|
||||||
/// This property's getComputedStyle implementation requires layout
|
/// This property's getComputedStyle implementation requires layout
|
||||||
/// to be flushed.
|
/// to be flushed.
|
||||||
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 6;
|
const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 6;
|
||||||
|
/// This property is a legacy shorthand.
|
||||||
|
///
|
||||||
|
/// https://drafts.csswg.org/css-cascade/#legacy-shorthand
|
||||||
|
const IS_LEGACY_SHORTHAND = 1 << 7;
|
||||||
|
|
||||||
/* The following flags are currently not used in Rust code, they
|
/* The following flags are currently not used in Rust code, they
|
||||||
* only need to be listed in corresponding properties so that
|
* only need to be listed in corresponding properties so that
|
||||||
|
@ -1461,17 +1465,24 @@ impl ShorthandId {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns PropertyFlags for given shorthand property.
|
/// Returns PropertyFlags for the given shorthand property.
|
||||||
pub fn flags(&self) -> PropertyFlags {
|
#[inline]
|
||||||
match *self {
|
pub fn flags(self) -> PropertyFlags {
|
||||||
|
const FLAGS: [u8; ${len(data.shorthands)}] = [
|
||||||
% for property in data.shorthands:
|
% for property in data.shorthands:
|
||||||
ShorthandId::${property.camel_case} =>
|
% for flag in property.flags:
|
||||||
% for flag in property.flags:
|
PropertyFlags::${flag}.bits |
|
||||||
PropertyFlags::${flag} |
|
% endfor
|
||||||
% endfor
|
0,
|
||||||
PropertyFlags::empty(),
|
|
||||||
% endfor
|
% endfor
|
||||||
}
|
];
|
||||||
|
PropertyFlags::from_bits_truncate(FLAGS[self as usize])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether this property is a legacy shorthand.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_legacy_shorthand(self) -> bool {
|
||||||
|
self.flags().contains(PropertyFlags::IS_LEGACY_SHORTHAND)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the order in which this property appears relative to other
|
/// Returns the order in which this property appears relative to other
|
||||||
|
|
|
@ -447,3 +447,51 @@ macro_rules! try_parse_one {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
||||||
|
<%helpers:shorthand
|
||||||
|
name="page-break-before"
|
||||||
|
products="gecko"
|
||||||
|
flags="SHORTHAND_IN_GETCS IS_LEGACY_SHORTHAND"
|
||||||
|
sub_properties="break-before"
|
||||||
|
spec="https://drafts.csswg.org/css2/page.html#propdef-page-break-before"
|
||||||
|
>
|
||||||
|
pub fn parse_value<'i>(
|
||||||
|
_: &ParserContext,
|
||||||
|
input: &mut Parser<'i, '_>,
|
||||||
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
|
use crate::values::specified::box_::BreakBetween;
|
||||||
|
Ok(expanded! {
|
||||||
|
break_before: BreakBetween::parse_legacy(input)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||||
|
self.break_before.to_css_legacy(dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
||||||
|
|
||||||
|
<%helpers:shorthand
|
||||||
|
name="page-break-after"
|
||||||
|
products="gecko"
|
||||||
|
flags="SHORTHAND_IN_GETCS IS_LEGACY_SHORTHAND"
|
||||||
|
sub_properties="break-after"
|
||||||
|
spec="https://drafts.csswg.org/css2/page.html#propdef-page-break-after"
|
||||||
|
>
|
||||||
|
pub fn parse_value<'i>(
|
||||||
|
_: &ParserContext,
|
||||||
|
input: &mut Parser<'i, '_>,
|
||||||
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
|
use crate::values::specified::box_::BreakBetween;
|
||||||
|
Ok(expanded! {
|
||||||
|
break_after: BreakBetween::parse_legacy(input)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||||
|
self.break_after.to_css_legacy(dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -453,6 +453,7 @@ impl RuleTree {
|
||||||
StyleSource::from_declarations(pdb.clone_arc()),
|
StyleSource::from_declarations(pdb.clone_arc()),
|
||||||
level,
|
level,
|
||||||
);
|
);
|
||||||
|
*important_rules_changed = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if pdb.read_with(level.guard(guards)).any_normal() {
|
if pdb.read_with(level.guard(guards)).any_normal() {
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::values::computed::length::CalcLengthOrPercentage;
|
||||||
use crate::values::computed::url::ComputedUrl;
|
use crate::values::computed::url::ComputedUrl;
|
||||||
use crate::values::computed::Angle as ComputedAngle;
|
use crate::values::computed::Angle as ComputedAngle;
|
||||||
use crate::values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
|
use crate::values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
|
||||||
|
use crate::values::CSSFloat;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -23,6 +24,7 @@ pub mod effects;
|
||||||
mod font;
|
mod font;
|
||||||
mod length;
|
mod length;
|
||||||
mod svg;
|
mod svg;
|
||||||
|
pub mod transform;
|
||||||
|
|
||||||
/// The category a property falls into for ordering purposes.
|
/// The category a property falls into for ordering purposes.
|
||||||
///
|
///
|
||||||
|
@ -86,6 +88,15 @@ pub fn compare_property_priority(a: &PropertyId, b: &PropertyId) -> cmp::Orderin
|
||||||
.then_with(|| a.idl_name_sort_order().cmp(&b.idl_name_sort_order()))
|
.then_with(|| a.idl_name_sort_order().cmp(&b.idl_name_sort_order()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A helper function to animate two multiplicative factor.
|
||||||
|
pub fn animate_multiplicative_factor(
|
||||||
|
this: CSSFloat,
|
||||||
|
other: CSSFloat,
|
||||||
|
procedure: Procedure,
|
||||||
|
) -> Result<CSSFloat, ()> {
|
||||||
|
Ok((this - 1.).animate(&(other - 1.), procedure)? + 1.)
|
||||||
|
}
|
||||||
|
|
||||||
/// Animate from one value to another.
|
/// Animate from one value to another.
|
||||||
///
|
///
|
||||||
/// This trait is derivable with `#[derive(Animate)]`. The derived
|
/// This trait is derivable with `#[derive(Animate)]`. The derived
|
||||||
|
|
1502
components/style/values/animated/transform.rs
Normal file
1502
components/style/values/animated/transform.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -5,6 +5,7 @@
|
||||||
//! Computed types for CSS values that are related to transformations.
|
//! Computed types for CSS values that are related to transformations.
|
||||||
|
|
||||||
use super::CSSFloat;
|
use super::CSSFloat;
|
||||||
|
use crate::values::animated::transform::{Perspective, Scale3D, Translate3D};
|
||||||
use crate::values::animated::ToAnimatedZero;
|
use crate::values::animated::ToAnimatedZero;
|
||||||
use crate::values::computed::{Angle, Integer, Length, LengthOrPercentage, Number, Percentage};
|
use crate::values::computed::{Angle, Integer, Length, LengthOrPercentage, Number, Percentage};
|
||||||
use crate::values::generics::transform as generic;
|
use crate::values::generics::transform as generic;
|
||||||
|
@ -47,8 +48,8 @@ pub type Matrix = generic::Matrix<Number>;
|
||||||
// matrices instead of being split across lines
|
// matrices instead of being split across lines
|
||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
impl Matrix3D {
|
impl Matrix3D {
|
||||||
#[inline]
|
|
||||||
/// Get an identity matrix
|
/// Get an identity matrix
|
||||||
|
#[inline]
|
||||||
pub fn identity() -> Self {
|
pub fn identity() -> Self {
|
||||||
Self {
|
Self {
|
||||||
m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0,
|
m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0,
|
||||||
|
@ -59,6 +60,7 @@ impl Matrix3D {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to a 2D Matrix
|
/// Convert to a 2D Matrix
|
||||||
|
#[inline]
|
||||||
pub fn into_2d(self) -> Result<Matrix, ()> {
|
pub fn into_2d(self) -> Result<Matrix, ()> {
|
||||||
if self.m13 == 0. && self.m23 == 0. &&
|
if self.m13 == 0. && self.m23 == 0. &&
|
||||||
self.m31 == 0. && self.m32 == 0. &&
|
self.m31 == 0. && self.m32 == 0. &&
|
||||||
|
@ -73,6 +75,253 @@ impl Matrix3D {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return true if this has 3D components.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_3d(&self) -> bool {
|
||||||
|
self.m13 != 0.0 || self.m14 != 0.0 ||
|
||||||
|
self.m23 != 0.0 || self.m24 != 0.0 ||
|
||||||
|
self.m31 != 0.0 || self.m32 != 0.0 ||
|
||||||
|
self.m33 != 1.0 || self.m34 != 0.0 ||
|
||||||
|
self.m43 != 0.0 || self.m44 != 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return determinant value.
|
||||||
|
#[inline]
|
||||||
|
pub fn determinant(&self) -> CSSFloat {
|
||||||
|
self.m14 * self.m23 * self.m32 * self.m41 -
|
||||||
|
self.m13 * self.m24 * self.m32 * self.m41 -
|
||||||
|
self.m14 * self.m22 * self.m33 * self.m41 +
|
||||||
|
self.m12 * self.m24 * self.m33 * self.m41 +
|
||||||
|
self.m13 * self.m22 * self.m34 * self.m41 -
|
||||||
|
self.m12 * self.m23 * self.m34 * self.m41 -
|
||||||
|
self.m14 * self.m23 * self.m31 * self.m42 +
|
||||||
|
self.m13 * self.m24 * self.m31 * self.m42 +
|
||||||
|
self.m14 * self.m21 * self.m33 * self.m42 -
|
||||||
|
self.m11 * self.m24 * self.m33 * self.m42 -
|
||||||
|
self.m13 * self.m21 * self.m34 * self.m42 +
|
||||||
|
self.m11 * self.m23 * self.m34 * self.m42 +
|
||||||
|
self.m14 * self.m22 * self.m31 * self.m43 -
|
||||||
|
self.m12 * self.m24 * self.m31 * self.m43 -
|
||||||
|
self.m14 * self.m21 * self.m32 * self.m43 +
|
||||||
|
self.m11 * self.m24 * self.m32 * self.m43 +
|
||||||
|
self.m12 * self.m21 * self.m34 * self.m43 -
|
||||||
|
self.m11 * self.m22 * self.m34 * self.m43 -
|
||||||
|
self.m13 * self.m22 * self.m31 * self.m44 +
|
||||||
|
self.m12 * self.m23 * self.m31 * self.m44 +
|
||||||
|
self.m13 * self.m21 * self.m32 * self.m44 -
|
||||||
|
self.m11 * self.m23 * self.m32 * self.m44 -
|
||||||
|
self.m12 * self.m21 * self.m33 * self.m44 +
|
||||||
|
self.m11 * self.m22 * self.m33 * self.m44
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transpose a matrix.
|
||||||
|
#[inline]
|
||||||
|
pub fn transpose(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
m11: self.m11, m12: self.m21, m13: self.m31, m14: self.m41,
|
||||||
|
m21: self.m12, m22: self.m22, m23: self.m32, m24: self.m42,
|
||||||
|
m31: self.m13, m32: self.m23, m33: self.m33, m34: self.m43,
|
||||||
|
m41: self.m14, m42: self.m24, m43: self.m34, m44: self.m44,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return inverse matrix.
|
||||||
|
pub fn inverse(&self) -> Result<Matrix3D, ()> {
|
||||||
|
let mut det = self.determinant();
|
||||||
|
|
||||||
|
if det == 0.0 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
det = 1.0 / det;
|
||||||
|
let x = Matrix3D {
|
||||||
|
m11: det *
|
||||||
|
(self.m23 * self.m34 * self.m42 - self.m24 * self.m33 * self.m42 +
|
||||||
|
self.m24 * self.m32 * self.m43 - self.m22 * self.m34 * self.m43 -
|
||||||
|
self.m23 * self.m32 * self.m44 + self.m22 * self.m33 * self.m44),
|
||||||
|
m12: det *
|
||||||
|
(self.m14 * self.m33 * self.m42 - self.m13 * self.m34 * self.m42 -
|
||||||
|
self.m14 * self.m32 * self.m43 + self.m12 * self.m34 * self.m43 +
|
||||||
|
self.m13 * self.m32 * self.m44 - self.m12 * self.m33 * self.m44),
|
||||||
|
m13: det *
|
||||||
|
(self.m13 * self.m24 * self.m42 - self.m14 * self.m23 * self.m42 +
|
||||||
|
self.m14 * self.m22 * self.m43 - self.m12 * self.m24 * self.m43 -
|
||||||
|
self.m13 * self.m22 * self.m44 + self.m12 * self.m23 * self.m44),
|
||||||
|
m14: det *
|
||||||
|
(self.m14 * self.m23 * self.m32 - self.m13 * self.m24 * self.m32 -
|
||||||
|
self.m14 * self.m22 * self.m33 + self.m12 * self.m24 * self.m33 +
|
||||||
|
self.m13 * self.m22 * self.m34 - self.m12 * self.m23 * self.m34),
|
||||||
|
m21: det *
|
||||||
|
(self.m24 * self.m33 * self.m41 - self.m23 * self.m34 * self.m41 -
|
||||||
|
self.m24 * self.m31 * self.m43 + self.m21 * self.m34 * self.m43 +
|
||||||
|
self.m23 * self.m31 * self.m44 - self.m21 * self.m33 * self.m44),
|
||||||
|
m22: det *
|
||||||
|
(self.m13 * self.m34 * self.m41 - self.m14 * self.m33 * self.m41 +
|
||||||
|
self.m14 * self.m31 * self.m43 - self.m11 * self.m34 * self.m43 -
|
||||||
|
self.m13 * self.m31 * self.m44 + self.m11 * self.m33 * self.m44),
|
||||||
|
m23: det *
|
||||||
|
(self.m14 * self.m23 * self.m41 - self.m13 * self.m24 * self.m41 -
|
||||||
|
self.m14 * self.m21 * self.m43 + self.m11 * self.m24 * self.m43 +
|
||||||
|
self.m13 * self.m21 * self.m44 - self.m11 * self.m23 * self.m44),
|
||||||
|
m24: det *
|
||||||
|
(self.m13 * self.m24 * self.m31 - self.m14 * self.m23 * self.m31 +
|
||||||
|
self.m14 * self.m21 * self.m33 - self.m11 * self.m24 * self.m33 -
|
||||||
|
self.m13 * self.m21 * self.m34 + self.m11 * self.m23 * self.m34),
|
||||||
|
m31: det *
|
||||||
|
(self.m22 * self.m34 * self.m41 - self.m24 * self.m32 * self.m41 +
|
||||||
|
self.m24 * self.m31 * self.m42 - self.m21 * self.m34 * self.m42 -
|
||||||
|
self.m22 * self.m31 * self.m44 + self.m21 * self.m32 * self.m44),
|
||||||
|
m32: det *
|
||||||
|
(self.m14 * self.m32 * self.m41 - self.m12 * self.m34 * self.m41 -
|
||||||
|
self.m14 * self.m31 * self.m42 + self.m11 * self.m34 * self.m42 +
|
||||||
|
self.m12 * self.m31 * self.m44 - self.m11 * self.m32 * self.m44),
|
||||||
|
m33: det *
|
||||||
|
(self.m12 * self.m24 * self.m41 - self.m14 * self.m22 * self.m41 +
|
||||||
|
self.m14 * self.m21 * self.m42 - self.m11 * self.m24 * self.m42 -
|
||||||
|
self.m12 * self.m21 * self.m44 + self.m11 * self.m22 * self.m44),
|
||||||
|
m34: det *
|
||||||
|
(self.m14 * self.m22 * self.m31 - self.m12 * self.m24 * self.m31 -
|
||||||
|
self.m14 * self.m21 * self.m32 + self.m11 * self.m24 * self.m32 +
|
||||||
|
self.m12 * self.m21 * self.m34 - self.m11 * self.m22 * self.m34),
|
||||||
|
m41: det *
|
||||||
|
(self.m23 * self.m32 * self.m41 - self.m22 * self.m33 * self.m41 -
|
||||||
|
self.m23 * self.m31 * self.m42 + self.m21 * self.m33 * self.m42 +
|
||||||
|
self.m22 * self.m31 * self.m43 - self.m21 * self.m32 * self.m43),
|
||||||
|
m42: det *
|
||||||
|
(self.m12 * self.m33 * self.m41 - self.m13 * self.m32 * self.m41 +
|
||||||
|
self.m13 * self.m31 * self.m42 - self.m11 * self.m33 * self.m42 -
|
||||||
|
self.m12 * self.m31 * self.m43 + self.m11 * self.m32 * self.m43),
|
||||||
|
m43: det *
|
||||||
|
(self.m13 * self.m22 * self.m41 - self.m12 * self.m23 * self.m41 -
|
||||||
|
self.m13 * self.m21 * self.m42 + self.m11 * self.m23 * self.m42 +
|
||||||
|
self.m12 * self.m21 * self.m43 - self.m11 * self.m22 * self.m43),
|
||||||
|
m44: det *
|
||||||
|
(self.m12 * self.m23 * self.m31 - self.m13 * self.m22 * self.m31 +
|
||||||
|
self.m13 * self.m21 * self.m32 - self.m11 * self.m23 * self.m32 -
|
||||||
|
self.m12 * self.m21 * self.m33 + self.m11 * self.m22 * self.m33),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Multiply `pin * self`.
|
||||||
|
#[inline]
|
||||||
|
pub fn pre_mul_point4(&self, pin: &[f32; 4]) -> [f32; 4] {
|
||||||
|
[
|
||||||
|
pin[0] * self.m11 + pin[1] * self.m21 + pin[2] * self.m31 + pin[3] * self.m41,
|
||||||
|
pin[0] * self.m12 + pin[1] * self.m22 + pin[2] * self.m32 + pin[3] * self.m42,
|
||||||
|
pin[0] * self.m13 + pin[1] * self.m23 + pin[2] * self.m33 + pin[3] * self.m43,
|
||||||
|
pin[0] * self.m14 + pin[1] * self.m24 + pin[2] * self.m34 + pin[3] * self.m44,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the multiplication of two 4x4 matrices.
|
||||||
|
#[inline]
|
||||||
|
pub fn multiply(&self, other: &Self) -> Self {
|
||||||
|
Matrix3D {
|
||||||
|
m11: self.m11 * other.m11 + self.m12 * other.m21 +
|
||||||
|
self.m13 * other.m31 + self.m14 * other.m41,
|
||||||
|
m12: self.m11 * other.m12 + self.m12 * other.m22 +
|
||||||
|
self.m13 * other.m32 + self.m14 * other.m42,
|
||||||
|
m13: self.m11 * other.m13 + self.m12 * other.m23 +
|
||||||
|
self.m13 * other.m33 + self.m14 * other.m43,
|
||||||
|
m14: self.m11 * other.m14 + self.m12 * other.m24 +
|
||||||
|
self.m13 * other.m34 + self.m14 * other.m44,
|
||||||
|
m21: self.m21 * other.m11 + self.m22 * other.m21 +
|
||||||
|
self.m23 * other.m31 + self.m24 * other.m41,
|
||||||
|
m22: self.m21 * other.m12 + self.m22 * other.m22 +
|
||||||
|
self.m23 * other.m32 + self.m24 * other.m42,
|
||||||
|
m23: self.m21 * other.m13 + self.m22 * other.m23 +
|
||||||
|
self.m23 * other.m33 + self.m24 * other.m43,
|
||||||
|
m24: self.m21 * other.m14 + self.m22 * other.m24 +
|
||||||
|
self.m23 * other.m34 + self.m24 * other.m44,
|
||||||
|
m31: self.m31 * other.m11 + self.m32 * other.m21 +
|
||||||
|
self.m33 * other.m31 + self.m34 * other.m41,
|
||||||
|
m32: self.m31 * other.m12 + self.m32 * other.m22 +
|
||||||
|
self.m33 * other.m32 + self.m34 * other.m42,
|
||||||
|
m33: self.m31 * other.m13 + self.m32 * other.m23 +
|
||||||
|
self.m33 * other.m33 + self.m34 * other.m43,
|
||||||
|
m34: self.m31 * other.m14 + self.m32 * other.m24 +
|
||||||
|
self.m33 * other.m34 + self.m34 * other.m44,
|
||||||
|
m41: self.m41 * other.m11 + self.m42 * other.m21 +
|
||||||
|
self.m43 * other.m31 + self.m44 * other.m41,
|
||||||
|
m42: self.m41 * other.m12 + self.m42 * other.m22 +
|
||||||
|
self.m43 * other.m32 + self.m44 * other.m42,
|
||||||
|
m43: self.m41 * other.m13 + self.m42 * other.m23 +
|
||||||
|
self.m43 * other.m33 + self.m44 * other.m43,
|
||||||
|
m44: self.m41 * other.m14 + self.m42 * other.m24 +
|
||||||
|
self.m43 * other.m34 + self.m44 * other.m44,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scale the matrix by a factor.
|
||||||
|
#[inline]
|
||||||
|
pub fn scale_by_factor(&mut self, scaling_factor: CSSFloat) {
|
||||||
|
self.m11 *= scaling_factor;
|
||||||
|
self.m12 *= scaling_factor;
|
||||||
|
self.m13 *= scaling_factor;
|
||||||
|
self.m14 *= scaling_factor;
|
||||||
|
self.m21 *= scaling_factor;
|
||||||
|
self.m22 *= scaling_factor;
|
||||||
|
self.m23 *= scaling_factor;
|
||||||
|
self.m24 *= scaling_factor;
|
||||||
|
self.m31 *= scaling_factor;
|
||||||
|
self.m32 *= scaling_factor;
|
||||||
|
self.m33 *= scaling_factor;
|
||||||
|
self.m34 *= scaling_factor;
|
||||||
|
self.m41 *= scaling_factor;
|
||||||
|
self.m42 *= scaling_factor;
|
||||||
|
self.m43 *= scaling_factor;
|
||||||
|
self.m44 *= scaling_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the matrix 3x3 part (top-left corner).
|
||||||
|
/// This is used by retrieving the scale and shear factors
|
||||||
|
/// during decomposing a 3d matrix.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_matrix_3x3_part(&self) -> [[f32; 3]; 3] {
|
||||||
|
[
|
||||||
|
[ self.m11, self.m12, self.m13 ],
|
||||||
|
[ self.m21, self.m22, self.m23 ],
|
||||||
|
[ self.m31, self.m32, self.m33 ],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set perspective on the matrix.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_perspective(&mut self, perspective: &Perspective) {
|
||||||
|
self.m14 = perspective.0;
|
||||||
|
self.m24 = perspective.1;
|
||||||
|
self.m34 = perspective.2;
|
||||||
|
self.m44 = perspective.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply translate on the matrix.
|
||||||
|
#[inline]
|
||||||
|
pub fn apply_translate(&mut self, translate: &Translate3D) {
|
||||||
|
self.m41 += translate.0 * self.m11 + translate.1 * self.m21 + translate.2 * self.m31;
|
||||||
|
self.m42 += translate.0 * self.m12 + translate.1 * self.m22 + translate.2 * self.m32;
|
||||||
|
self.m43 += translate.0 * self.m13 + translate.1 * self.m23 + translate.2 * self.m33;
|
||||||
|
self.m44 += translate.0 * self.m14 + translate.1 * self.m24 + translate.2 * self.m34;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply scale on the matrix.
|
||||||
|
#[inline]
|
||||||
|
pub fn apply_scale(&mut self, scale: &Scale3D) {
|
||||||
|
self.m11 *= scale.0;
|
||||||
|
self.m12 *= scale.0;
|
||||||
|
self.m13 *= scale.0;
|
||||||
|
self.m14 *= scale.0;
|
||||||
|
self.m21 *= scale.1;
|
||||||
|
self.m22 *= scale.1;
|
||||||
|
self.m23 *= scale.1;
|
||||||
|
self.m24 *= scale.1;
|
||||||
|
self.m31 *= scale.2;
|
||||||
|
self.m32 *= scale.2;
|
||||||
|
self.m33 *= scale.2;
|
||||||
|
self.m34 *= scale.2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
|
|
@ -529,15 +529,7 @@ pub fn get_normalized_vector_and_angle<T: Zero>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue,
|
||||||
ComputeSquaredDistance,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
MallocSizeOf,
|
|
||||||
PartialEq,
|
|
||||||
SpecifiedValueInfo,
|
|
||||||
ToAnimatedZero,
|
|
||||||
ToComputedValue,
|
|
||||||
)]
|
)]
|
||||||
/// A value of the `Rotate` property
|
/// A value of the `Rotate` property
|
||||||
///
|
///
|
||||||
|
@ -599,15 +591,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue,
|
||||||
ComputeSquaredDistance,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
MallocSizeOf,
|
|
||||||
PartialEq,
|
|
||||||
SpecifiedValueInfo,
|
|
||||||
ToAnimatedZero,
|
|
||||||
ToComputedValue,
|
|
||||||
)]
|
)]
|
||||||
/// A value of the `Scale` property
|
/// A value of the `Scale` property
|
||||||
///
|
///
|
||||||
|
@ -648,14 +632,7 @@ impl<Number: ToCss + PartialEq> ToCss for Scale<Number> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue,
|
||||||
ComputeSquaredDistance,
|
|
||||||
Debug,
|
|
||||||
MallocSizeOf,
|
|
||||||
PartialEq,
|
|
||||||
SpecifiedValueInfo,
|
|
||||||
ToAnimatedZero,
|
|
||||||
ToComputedValue,
|
|
||||||
)]
|
)]
|
||||||
/// A value of the `Translate` property
|
/// A value of the `Translate` property
|
||||||
///
|
///
|
||||||
|
|
|
@ -19,6 +19,48 @@ use cssparser::Parser;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ParseError, ToCss};
|
use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
|
|
||||||
|
/// A specified value for a single side of a `border-style` property.
|
||||||
|
///
|
||||||
|
/// The order here corresponds to the integer values from the border conflict
|
||||||
|
/// resolution rules in CSS 2.1 § 17.6.2.1. Higher values override lower values.
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
MallocSizeOf,
|
||||||
|
Ord,
|
||||||
|
Parse,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum BorderStyle {
|
||||||
|
Hidden,
|
||||||
|
None,
|
||||||
|
Inset,
|
||||||
|
Groove,
|
||||||
|
Outset,
|
||||||
|
Ridge,
|
||||||
|
Dotted,
|
||||||
|
Dashed,
|
||||||
|
Solid,
|
||||||
|
Double,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BorderStyle {
|
||||||
|
/// Whether this border style is either none or hidden.
|
||||||
|
#[inline]
|
||||||
|
pub fn none_or_hidden(&self) -> bool {
|
||||||
|
matches!(*self, BorderStyle::None | BorderStyle::Hidden)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A specified value for a single side of the `border-width` property.
|
/// A specified value for a single side of the `border-width` property.
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||||
pub enum BorderSideWidth {
|
pub enum BorderSideWidth {
|
||||||
|
|
|
@ -178,30 +178,6 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether `new_display` should be ignored, given a previous
|
|
||||||
/// `old_display` value.
|
|
||||||
///
|
|
||||||
/// This is used to ignore `display: -moz-box` declarations after an
|
|
||||||
/// equivalent `display: -webkit-box` declaration, since the former
|
|
||||||
/// has a vastly different meaning. See bug 1107378 and bug 1407701.
|
|
||||||
///
|
|
||||||
/// FIXME(emilio): This is a pretty decent hack, we should try to
|
|
||||||
/// remove it.
|
|
||||||
pub fn should_ignore_parsed_value(_old_display: Self, _new_display: Self) -> bool {
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
{
|
|
||||||
match (_old_display, _new_display) {
|
|
||||||
(Display::WebkitBox, Display::MozBox) |
|
|
||||||
(Display::WebkitInlineBox, Display::MozInlineBox) => {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether this "display" value is one of the types for
|
/// Returns whether this "display" value is one of the types for
|
||||||
/// ruby.
|
/// ruby.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -1155,10 +1131,11 @@ pub enum Appearance {
|
||||||
TabScrollArrowBack,
|
TabScrollArrowBack,
|
||||||
#[parse(condition = "in_ua_or_chrome_sheet")]
|
#[parse(condition = "in_ua_or_chrome_sheet")]
|
||||||
TabScrollArrowForward,
|
TabScrollArrowForward,
|
||||||
/// A textfield or text area.
|
/// A multi-line text field, e.g. HTML <textarea>.
|
||||||
|
#[parse(aliases = "textfield-multiline")]
|
||||||
|
Textarea,
|
||||||
|
/// A single-line text field, e.g. HTML <input type=text>.
|
||||||
Textfield,
|
Textfield,
|
||||||
/// A multiline text field.
|
|
||||||
TextfieldMultiline,
|
|
||||||
/// A toolbar in an application window.
|
/// A toolbar in an application window.
|
||||||
#[parse(condition = "in_ua_or_chrome_sheet")]
|
#[parse(condition = "in_ua_or_chrome_sheet")]
|
||||||
Toolbar,
|
Toolbar,
|
||||||
|
@ -1309,13 +1286,58 @@ pub enum Appearance {
|
||||||
)]
|
)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum BreakBetween {
|
pub enum BreakBetween {
|
||||||
Auto,
|
|
||||||
Always,
|
Always,
|
||||||
|
Auto,
|
||||||
|
Page,
|
||||||
Avoid,
|
Avoid,
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BreakBetween {
|
||||||
|
/// Parse a legacy break-between value for `page-break-*`.
|
||||||
|
///
|
||||||
|
/// See https://drafts.csswg.org/css-break/#page-break-properties.
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_legacy<'i>(input: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let ident = input.expect_ident()?;
|
||||||
|
let break_value = match BreakBetween::from_ident(ident) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(()) => {
|
||||||
|
return Err(location
|
||||||
|
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
match break_value {
|
||||||
|
BreakBetween::Always => Ok(BreakBetween::Page),
|
||||||
|
BreakBetween::Auto | BreakBetween::Avoid | BreakBetween::Left | BreakBetween::Right => {
|
||||||
|
Ok(break_value)
|
||||||
|
},
|
||||||
|
BreakBetween::Page => {
|
||||||
|
Err(location
|
||||||
|
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serialize a legacy break-between value for `page-break-*`.
|
||||||
|
///
|
||||||
|
/// See https://drafts.csswg.org/css-break/#page-break-properties.
|
||||||
|
pub fn to_css_legacy<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
match *self {
|
||||||
|
BreakBetween::Auto | BreakBetween::Avoid | BreakBetween::Left | BreakBetween::Right => {
|
||||||
|
self.to_css(dest)
|
||||||
|
},
|
||||||
|
BreakBetween::Page => dest.write_str("always"),
|
||||||
|
BreakBetween::Always => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A kind of break within a box.
|
/// A kind of break within a box.
|
||||||
///
|
///
|
||||||
/// https://drafts.csswg.org/css-break/#break-within
|
/// https://drafts.csswg.org/css-break/#break-within
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub use self::background::{BackgroundRepeat, BackgroundSize};
|
||||||
pub use self::basic_shape::FillRule;
|
pub use self::basic_shape::FillRule;
|
||||||
pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
||||||
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
|
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
|
||||||
pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing};
|
pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle};
|
||||||
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
||||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
|
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
|
||||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||||
|
@ -152,46 +152,6 @@ fn parse_number_with_clamping_mode<'i, 't>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// The integer values here correspond to the border conflict resolution rules in CSS 2.1 §
|
|
||||||
// 17.6.2.1. Higher values override lower values.
|
|
||||||
//
|
|
||||||
// FIXME(emilio): Should move to border.rs
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
|
||||||
#[derive(
|
|
||||||
Clone,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
Eq,
|
|
||||||
MallocSizeOf,
|
|
||||||
Ord,
|
|
||||||
Parse,
|
|
||||||
PartialEq,
|
|
||||||
PartialOrd,
|
|
||||||
SpecifiedValueInfo,
|
|
||||||
ToComputedValue,
|
|
||||||
ToCss,
|
|
||||||
)]
|
|
||||||
pub enum BorderStyle {
|
|
||||||
None = -1,
|
|
||||||
Solid = 6,
|
|
||||||
Double = 7,
|
|
||||||
Dotted = 4,
|
|
||||||
Dashed = 5,
|
|
||||||
Hidden = -2,
|
|
||||||
Groove = 1,
|
|
||||||
Ridge = 3,
|
|
||||||
Inset = 0,
|
|
||||||
Outset = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BorderStyle {
|
|
||||||
/// Whether this border style is either none or hidden.
|
|
||||||
pub fn none_or_hidden(&self) -> bool {
|
|
||||||
matches!(*self, BorderStyle::None | BorderStyle::Hidden)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A CSS `<number>` specified value.
|
/// A CSS `<number>` specified value.
|
||||||
///
|
///
|
||||||
/// https://drafts.csswg.org/css-values-3/#number-value
|
/// https://drafts.csswg.org/css-values-3/#number-value
|
||||||
|
|
|
@ -23,19 +23,20 @@ use style_traits::ParseError;
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
)]
|
)]
|
||||||
|
#[repr(C, u8)]
|
||||||
/// <https://drafts.csswg.org/css-ui/#propdef-outline-style>
|
/// <https://drafts.csswg.org/css-ui/#propdef-outline-style>
|
||||||
pub enum OutlineStyle {
|
pub enum OutlineStyle {
|
||||||
/// auto
|
/// auto
|
||||||
Auto,
|
Auto,
|
||||||
/// <border-style>
|
/// <border-style>
|
||||||
Other(BorderStyle),
|
BorderStyle(BorderStyle),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutlineStyle {
|
impl OutlineStyle {
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Get default value as None
|
/// Get default value as None
|
||||||
pub fn none() -> OutlineStyle {
|
pub fn none() -> OutlineStyle {
|
||||||
OutlineStyle::Other(BorderStyle::None)
|
OutlineStyle::BorderStyle(BorderStyle::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -43,7 +44,7 @@ impl OutlineStyle {
|
||||||
pub fn none_or_hidden(&self) -> bool {
|
pub fn none_or_hidden(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
OutlineStyle::Auto => false,
|
OutlineStyle::Auto => false,
|
||||||
OutlineStyle::Other(ref border_style) => border_style.none_or_hidden(),
|
OutlineStyle::BorderStyle(ref style) => style.none_or_hidden(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +60,7 @@ impl Parse for OutlineStyle {
|
||||||
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())));
|
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(OutlineStyle::Other(border_style));
|
return Ok(OutlineStyle::BorderStyle(border_style));
|
||||||
}
|
}
|
||||||
|
|
||||||
input.expect_ident_matching("auto")?;
|
input.expect_ident_matching("auto")?;
|
||||||
|
|
|
@ -141,11 +141,6 @@ impl Parse for ScrollbarColor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_ua_sheet(context: &ParserContext) -> bool {
|
|
||||||
use crate::stylesheets::Origin;
|
|
||||||
context.stylesheet_origin == Origin::UserAgent
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The specified value for the `user-select` property.
|
/// The specified value for the `user-select` property.
|
||||||
///
|
///
|
||||||
/// https://drafts.csswg.org/css-ui-4/#propdef-user-select
|
/// https://drafts.csswg.org/css-ui-4/#propdef-user-select
|
||||||
|
@ -168,15 +163,6 @@ pub enum UserSelect {
|
||||||
Text,
|
Text,
|
||||||
#[parse(aliases = "-moz-none")]
|
#[parse(aliases = "-moz-none")]
|
||||||
None,
|
None,
|
||||||
/// Force selection of all children, unless an ancestor has `none` set.
|
/// Force selection of all children.
|
||||||
All,
|
All,
|
||||||
/// Like `text`, except that it won't get overridden by ancestors having
|
|
||||||
/// `all`.
|
|
||||||
///
|
|
||||||
/// FIXME(emilio): This only has one use in contenteditable.css, can we find
|
|
||||||
/// a better way to do this?
|
|
||||||
///
|
|
||||||
/// See bug 1181130.
|
|
||||||
#[parse(condition = "in_ua_sheet")]
|
|
||||||
MozText,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[variable-exponential-blowup.html]
|
|
||||||
expected: TIMEOUT
|
|
Loading…
Add table
Add a link
Reference in a new issue