mirror of
https://github.com/servo/servo.git
synced 2025-07-03 13:33:39 +01:00
Auto merge of #24404 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See individual commits for details. https://bugzilla.mozilla.org/show_bug.cgi?id=1587368 <!-- 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/24404) <!-- Reviewable:end -->
This commit is contained in:
commit
2c280ab6ac
39 changed files with 561 additions and 744 deletions
|
@ -17,6 +17,8 @@ use std::ops::{BitAnd, BitOr, BitXor, Sub};
|
||||||
use super::hash_map::{self, HashMap, Keys, RandomState};
|
use super::hash_map::{self, HashMap, Keys, RandomState};
|
||||||
use super::Recover;
|
use super::Recover;
|
||||||
|
|
||||||
|
use crate::FailedAllocationError;
|
||||||
|
|
||||||
// Future Optimization (FIXME!)
|
// Future Optimization (FIXME!)
|
||||||
// =============================
|
// =============================
|
||||||
//
|
//
|
||||||
|
@ -589,6 +591,12 @@ where
|
||||||
self.map.insert(value, ()).is_none()
|
self.map.insert(value, ()).is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fallible version of `insert`.
|
||||||
|
#[inline]
|
||||||
|
pub fn try_insert(&mut self, value: T) -> Result<bool, FailedAllocationError> {
|
||||||
|
Ok(self.map.try_insert(value, ())?.is_none())
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
|
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
|
||||||
/// one. Returns the replaced value.
|
/// one. Returns the replaced value.
|
||||||
pub fn replace(&mut self, value: T) -> Option<T> {
|
pub fn replace(&mut self, value: T) -> Option<T> {
|
||||||
|
|
|
@ -25,6 +25,7 @@ servo-layout-2020 = []
|
||||||
gecko_debug = []
|
gecko_debug = []
|
||||||
gecko_refcount_logging = []
|
gecko_refcount_logging = []
|
||||||
gecko_profiler = []
|
gecko_profiler = []
|
||||||
|
moz_xbl = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.7"
|
app_units = "0.7"
|
||||||
|
|
|
@ -187,10 +187,11 @@ pub mod basic_shape {
|
||||||
|
|
||||||
impl<'a> From<&'a StyleShapeSource> for OffsetPath {
|
impl<'a> From<&'a StyleShapeSource> for OffsetPath {
|
||||||
fn from(other: &'a StyleShapeSource) -> Self {
|
fn from(other: &'a StyleShapeSource) -> Self {
|
||||||
|
use crate::values::generics::motion::GenericOffsetPath;
|
||||||
match other.mType {
|
match other.mType {
|
||||||
StyleShapeSourceType::Path => {
|
StyleShapeSourceType::Path => GenericOffsetPath::Path(
|
||||||
OffsetPath::Path(other.to_svg_path().expect("Cannot convert to SVGPathData"))
|
other.to_svg_path().expect("Cannot convert to SVGPathData"),
|
||||||
},
|
),
|
||||||
StyleShapeSourceType::None => OffsetPath::none(),
|
StyleShapeSourceType::None => OffsetPath::none(),
|
||||||
StyleShapeSourceType::Shape |
|
StyleShapeSourceType::Shape |
|
||||||
StyleShapeSourceType::Box |
|
StyleShapeSourceType::Box |
|
||||||
|
|
|
@ -44,6 +44,8 @@ use crate::gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWThe
|
||||||
use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
|
use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
|
||||||
use crate::gecko_bindings::structs;
|
use crate::gecko_bindings::structs;
|
||||||
use crate::gecko_bindings::structs::nsChangeHint;
|
use crate::gecko_bindings::structs::nsChangeHint;
|
||||||
|
#[cfg(feature = "moz_xbl")]
|
||||||
|
use crate::gecko_bindings::structs::nsXBLBinding as RawGeckoXBLBinding;
|
||||||
use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme;
|
use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme;
|
||||||
use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
|
use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
|
||||||
use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT;
|
use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT;
|
||||||
|
@ -53,9 +55,7 @@ use crate::gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT;
|
||||||
use crate::gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES;
|
use crate::gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES;
|
||||||
use crate::gecko_bindings::structs::NODE_NEEDS_FRAME;
|
use crate::gecko_bindings::structs::NODE_NEEDS_FRAME;
|
||||||
use crate::gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag};
|
use crate::gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag};
|
||||||
use crate::gecko_bindings::structs::{
|
use crate::gecko_bindings::structs::{nsINode as RawGeckoNode, Element as RawGeckoElement};
|
||||||
nsINode as RawGeckoNode, nsXBLBinding as RawGeckoXBLBinding, Element as RawGeckoElement,
|
|
||||||
};
|
|
||||||
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
|
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
|
||||||
use crate::global_style_data::GLOBAL_STYLE_DATA;
|
use crate::global_style_data::GLOBAL_STYLE_DATA;
|
||||||
use crate::hash::FxHashMap;
|
use crate::hash::FxHashMap;
|
||||||
|
@ -86,6 +86,8 @@ use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
#[cfg(not(feature = "moz_xbl"))]
|
||||||
|
use values::Impossible;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn elements_with_id<'a, 'le>(
|
fn elements_with_id<'a, 'le>(
|
||||||
|
@ -529,9 +531,11 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer.
|
/// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer.
|
||||||
|
#[cfg(feature = "moz_xbl")]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding);
|
pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding);
|
||||||
|
|
||||||
|
#[cfg(feature = "moz_xbl")]
|
||||||
impl<'lb> GeckoXBLBinding<'lb> {
|
impl<'lb> GeckoXBLBinding<'lb> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn base_binding(&self) -> Option<Self> {
|
fn base_binding(&self) -> Option<Self> {
|
||||||
|
@ -556,6 +560,22 @@ impl<'lb> GeckoXBLBinding<'lb> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A stub wraper for GeckoXBLBinding.
|
||||||
|
#[cfg(not(feature = "moz_xbl"))]
|
||||||
|
pub struct GeckoXBLBinding<'lb>(&'lb Impossible);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "moz_xbl"))]
|
||||||
|
impl<'lb> GeckoXBLBinding<'lb> {
|
||||||
|
#[inline]
|
||||||
|
fn anon_content(&self) -> *const nsIContent {
|
||||||
|
match *self.0 {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binding_with_content(&self) -> Option<Self> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A simple wrapper over a non-null Gecko `Element` pointer.
|
/// A simple wrapper over a non-null Gecko `Element` pointer.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct GeckoElement<'le>(pub &'le RawGeckoElement);
|
pub struct GeckoElement<'le>(pub &'le RawGeckoElement);
|
||||||
|
@ -681,11 +701,13 @@ impl<'le> GeckoElement<'le> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "moz_xbl")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn may_be_in_binding_manager(&self) -> bool {
|
fn may_be_in_binding_manager(&self) -> bool {
|
||||||
self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) != 0
|
self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "moz_xbl")]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> {
|
fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> {
|
||||||
if !self.may_be_in_binding_manager() {
|
if !self.may_be_in_binding_manager() {
|
||||||
|
@ -696,6 +718,12 @@ impl<'le> GeckoElement<'le> {
|
||||||
unsafe { slots.mXBLBinding.mRawPtr.as_ref().map(GeckoXBLBinding) }
|
unsafe { slots.mXBLBinding.mRawPtr.as_ref().map(GeckoXBLBinding) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "moz_xbl"))]
|
||||||
|
#[inline]
|
||||||
|
fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn xbl_binding_with_content(&self) -> Option<GeckoXBLBinding<'le>> {
|
fn xbl_binding_with_content(&self) -> Option<GeckoXBLBinding<'le>> {
|
||||||
self.xbl_binding().and_then(|b| b.binding_with_content())
|
self.xbl_binding().and_then(|b| b.binding_with_content())
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
use crate::dom::{TDocument, TElement, TNode};
|
use crate::dom::{TDocument, TElement, TNode};
|
||||||
|
use crate::hash::HashSet;
|
||||||
use crate::invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
|
use crate::invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper};
|
||||||
use crate::invalidation::element::restyle_hints::RestyleHint;
|
use crate::invalidation::element::restyle_hints::RestyleHint;
|
||||||
use crate::media_queries::Device;
|
use crate::media_queries::Device;
|
||||||
|
@ -17,9 +18,12 @@ use crate::stylesheets::{CssRule, StylesheetInDocument};
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use crate::CaseSensitivityExt;
|
use crate::CaseSensitivityExt;
|
||||||
use crate::LocalName as SelectorLocalName;
|
use crate::LocalName as SelectorLocalName;
|
||||||
use fxhash::FxHashSet;
|
use fxhash::FxHasher;
|
||||||
use selectors::attr::CaseSensitivity;
|
use selectors::attr::CaseSensitivity;
|
||||||
use selectors::parser::{Component, LocalName, Selector};
|
use selectors::parser::{Component, LocalName, Selector};
|
||||||
|
use std::hash::BuildHasherDefault;
|
||||||
|
|
||||||
|
type FxHashSet<K> = HashSet<K, BuildHasherDefault<FxHasher>>;
|
||||||
|
|
||||||
/// A style sheet invalidation represents a kind of element or subtree that may
|
/// A style sheet invalidation represents a kind of element or subtree that may
|
||||||
/// need to be restyled. Whether it represents a whole subtree or just a single
|
/// need to be restyled. Whether it represents a whole subtree or just a single
|
||||||
|
@ -400,17 +404,22 @@ impl StylesheetInvalidationSet {
|
||||||
|
|
||||||
if let Some(s) = subtree_invalidation {
|
if let Some(s) = subtree_invalidation {
|
||||||
debug!(" > Found subtree invalidation: {:?}", s);
|
debug!(" > Found subtree invalidation: {:?}", s);
|
||||||
self.invalid_scopes.insert(s);
|
if self.invalid_scopes.try_insert(s).is_ok() {
|
||||||
} else if let Some(s) = element_invalidation {
|
return;
|
||||||
debug!(" > Found element invalidation: {:?}", s);
|
|
||||||
self.invalid_elements.insert(s);
|
|
||||||
} else {
|
|
||||||
// The selector was of a form that we can't handle. Any element
|
|
||||||
// could match it, so let's just bail out.
|
|
||||||
debug!(" > Can't handle selector, marking fully invalid");
|
|
||||||
self.fully_invalid = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(s) = element_invalidation {
|
||||||
|
debug!(" > Found element invalidation: {:?}", s);
|
||||||
|
if self.invalid_elements.try_insert(s).is_ok() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The selector was of a form that we can't handle. Any element could
|
||||||
|
// match it, so let's just bail out.
|
||||||
|
debug!(" > Can't handle selector or OOMd, marking fully invalid");
|
||||||
|
self.fully_invalid = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Collects invalidations for a given CSS rule.
|
/// Collects invalidations for a given CSS rule.
|
||||||
fn collect_invalidations_for_rule(
|
fn collect_invalidations_for_rule(
|
||||||
|
|
|
@ -50,16 +50,22 @@ bitflags!(
|
||||||
const LINE_INVERTED = 1 << 3;
|
const LINE_INVERTED = 1 << 3;
|
||||||
/// direction is rtl.
|
/// direction is rtl.
|
||||||
const RTL = 1 << 4;
|
const RTL = 1 << 4;
|
||||||
/// Horizontal text within a vertical writing mode is displayed sideways
|
/// All text within a vertical writing mode is displayed sideways
|
||||||
/// and runs top-to-bottom or bottom-to-top; set in these cases:
|
/// and runs top-to-bottom or bottom-to-top; set in these cases:
|
||||||
///
|
///
|
||||||
/// * writing-mode: vertical-rl; text-orientation: sideways;
|
|
||||||
/// * writing-mode: vertical-lr; text-orientation: sideways;
|
|
||||||
/// * writing-mode: sideways-rl;
|
/// * writing-mode: sideways-rl;
|
||||||
/// * writing-mode: sideways-lr;
|
/// * writing-mode: sideways-lr;
|
||||||
///
|
///
|
||||||
/// Never set without VERTICAL.
|
/// Never set without VERTICAL.
|
||||||
const SIDEWAYS = 1 << 5;
|
const VERTICAL_SIDEWAYS = 1 << 5;
|
||||||
|
/// Similar to VERTICAL_SIDEWAYS, but is set via text-orientation;
|
||||||
|
/// set in these cases:
|
||||||
|
///
|
||||||
|
/// * writing-mode: vertical-rl; text-orientation: sideways;
|
||||||
|
/// * writing-mode: vertical-lr; text-orientation: sideways;
|
||||||
|
///
|
||||||
|
/// Never set without VERTICAL.
|
||||||
|
const TEXT_SIDEWAYS = 1 << 6;
|
||||||
/// Horizontal text within a vertical writing mode is displayed with each
|
/// Horizontal text within a vertical writing mode is displayed with each
|
||||||
/// glyph upright; set in these cases:
|
/// glyph upright; set in these cases:
|
||||||
///
|
///
|
||||||
|
@ -67,7 +73,7 @@ bitflags!(
|
||||||
/// * writing-mode: vertical-lr: text-orientation: upright;
|
/// * writing-mode: vertical-lr: text-orientation: upright;
|
||||||
///
|
///
|
||||||
/// Never set without VERTICAL.
|
/// Never set without VERTICAL.
|
||||||
const UPRIGHT = 1 << 6;
|
const UPRIGHT = 1 << 7;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -112,7 +118,7 @@ impl WritingMode {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
SpecifiedWritingMode::SidewaysRl => {
|
SpecifiedWritingMode::SidewaysRl => {
|
||||||
flags.insert(WritingMode::VERTICAL);
|
flags.insert(WritingMode::VERTICAL);
|
||||||
flags.insert(WritingMode::SIDEWAYS);
|
flags.insert(WritingMode::VERTICAL_SIDEWAYS);
|
||||||
if direction == Direction::Rtl {
|
if direction == Direction::Rtl {
|
||||||
flags.insert(WritingMode::INLINE_REVERSED);
|
flags.insert(WritingMode::INLINE_REVERSED);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +127,7 @@ impl WritingMode {
|
||||||
SpecifiedWritingMode::SidewaysLr => {
|
SpecifiedWritingMode::SidewaysLr => {
|
||||||
flags.insert(WritingMode::VERTICAL);
|
flags.insert(WritingMode::VERTICAL);
|
||||||
flags.insert(WritingMode::VERTICAL_LR);
|
flags.insert(WritingMode::VERTICAL_LR);
|
||||||
flags.insert(WritingMode::SIDEWAYS);
|
flags.insert(WritingMode::VERTICAL_SIDEWAYS);
|
||||||
if direction == Direction::Ltr {
|
if direction == Direction::Ltr {
|
||||||
flags.insert(WritingMode::INLINE_REVERSED);
|
flags.insert(WritingMode::INLINE_REVERSED);
|
||||||
}
|
}
|
||||||
|
@ -140,9 +146,18 @@ impl WritingMode {
|
||||||
TextOrientation::Mixed => {},
|
TextOrientation::Mixed => {},
|
||||||
TextOrientation::Upright => {
|
TextOrientation::Upright => {
|
||||||
flags.insert(WritingMode::UPRIGHT);
|
flags.insert(WritingMode::UPRIGHT);
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-writing-modes-3/#valdef-text-orientation-upright:
|
||||||
|
//
|
||||||
|
// > This value causes the used value of direction
|
||||||
|
// > to be ltr, and for the purposes of bidi
|
||||||
|
// > reordering, causes all characters to be treated
|
||||||
|
// > as strong LTR.
|
||||||
|
flags.remove(WritingMode::RTL);
|
||||||
|
flags.remove(WritingMode::INLINE_REVERSED);
|
||||||
},
|
},
|
||||||
TextOrientation::Sideways => {
|
TextOrientation::Sideways => {
|
||||||
flags.insert(WritingMode::SIDEWAYS);
|
flags.insert(WritingMode::TEXT_SIDEWAYS);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -178,7 +193,7 @@ impl WritingMode {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_sideways(&self) -> bool {
|
pub fn is_sideways(&self) -> bool {
|
||||||
self.intersects(WritingMode::SIDEWAYS)
|
self.intersects(WritingMode::VERTICAL_SIDEWAYS | WritingMode::TEXT_SIDEWAYS)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -316,7 +331,7 @@ impl fmt::Display for WritingMode {
|
||||||
} else {
|
} else {
|
||||||
write!(formatter, " RL")?;
|
write!(formatter, " RL")?;
|
||||||
}
|
}
|
||||||
if self.intersects(WritingMode::SIDEWAYS) {
|
if self.is_sideways() {
|
||||||
write!(formatter, " Sideways")?;
|
write!(formatter, " Sideways")?;
|
||||||
}
|
}
|
||||||
if self.intersects(WritingMode::LINE_INVERTED) {
|
if self.intersects(WritingMode::LINE_INVERTED) {
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl ToCss for AspectRatio {
|
||||||
W: fmt::Write,
|
W: fmt::Write,
|
||||||
{
|
{
|
||||||
self.0.to_css(dest)?;
|
self.0.to_css(dest)?;
|
||||||
dest.write_char('/')?;
|
dest.write_str(" / ")?;
|
||||||
self.1.to_css(dest)
|
self.1.to_css(dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,9 +362,20 @@ fn should_ignore_declaration_when_ignoring_document_colors(
|
||||||
// Treat background-color a bit differently. If the specified color is
|
// Treat background-color a bit differently. If the specified color is
|
||||||
// anything other than a fully transparent color, convert it into the
|
// anything other than a fully transparent color, convert it into the
|
||||||
// Device's default background color.
|
// Device's default background color.
|
||||||
|
// Also: for now, we treat background-image a bit differently, too.
|
||||||
|
// background-image is marked as ignored, but really, we only ignore
|
||||||
|
// it when backplates are disabled (since then text may be unreadable over
|
||||||
|
// a background image, if we're ignoring document colors).
|
||||||
|
// Here we check backplate status to decide if ignoring background-image
|
||||||
|
// is the right decision.
|
||||||
{
|
{
|
||||||
let background_color = match **declaration {
|
let background_color = match **declaration {
|
||||||
PropertyDeclaration::BackgroundColor(ref color) => color,
|
PropertyDeclaration::BackgroundColor(ref color) => color,
|
||||||
|
// In the future, if/when we remove the backplate pref, we can remove this
|
||||||
|
// special case along with the 'ignored_when_colors_disabled=True' mako line
|
||||||
|
// for the "background-image" property.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
PropertyDeclaration::BackgroundImage(..) => return !static_prefs::pref!("browser.display.permit_backplate"),
|
||||||
_ => return true,
|
_ => return true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
# "column-span",
|
# "column-span",
|
||||||
# "offset-distance",
|
# "offset-distance",
|
||||||
# "offset-path",
|
# "offset-path",
|
||||||
# "offset-rotate"
|
# "offset-rotate",
|
||||||
|
# "offset"
|
||||||
COUNTED_UNKNOWN_PROPERTIES = [
|
COUNTED_UNKNOWN_PROPERTIES = [
|
||||||
"-webkit-font-smoothing",
|
"-webkit-font-smoothing",
|
||||||
"zoom",
|
"zoom",
|
||||||
|
@ -82,7 +83,6 @@ COUNTED_UNKNOWN_PROPERTIES = [
|
||||||
"-webkit-ruby-position",
|
"-webkit-ruby-position",
|
||||||
"-webkit-column-break-after",
|
"-webkit-column-break-after",
|
||||||
"-webkit-margin-collapse",
|
"-webkit-margin-collapse",
|
||||||
"offset",
|
|
||||||
"-webkit-border-before",
|
"-webkit-border-before",
|
||||||
"-webkit-border-end",
|
"-webkit-border-end",
|
||||||
"-webkit-border-after",
|
"-webkit-border-after",
|
||||||
|
|
|
@ -768,10 +768,12 @@ animated_list_impl!(<T> for crate::OwnedSlice<T>);
|
||||||
animated_list_impl!(<T> for SmallVec<[T; 1]>);
|
animated_list_impl!(<T> for SmallVec<[T; 1]>);
|
||||||
animated_list_impl!(<T> for Vec<T>);
|
animated_list_impl!(<T> for Vec<T>);
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-transitions/#animtype-visibility>
|
/// <https://drafts.csswg.org/web-animations-1/#animating-visibility>
|
||||||
impl Animate for Visibility {
|
impl Animate for Visibility {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
|
match procedure {
|
||||||
|
Procedure::Interpolate { .. } => {
|
||||||
let (this_weight, other_weight) = procedure.weights();
|
let (this_weight, other_weight) = procedure.weights();
|
||||||
match (*self, *other) {
|
match (*self, *other) {
|
||||||
(Visibility::Visible, _) => {
|
(Visibility::Visible, _) => {
|
||||||
|
@ -782,6 +784,9 @@ impl Animate for Visibility {
|
||||||
},
|
},
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ ${helpers.predefined_type(
|
||||||
initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())",
|
initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())",
|
||||||
initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())",
|
initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())",
|
||||||
spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
|
spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
|
||||||
animation_value_type="discrete",
|
animation_value_type="NonNegativeLengthOrNumberRect",
|
||||||
boxed=True,
|
boxed=True,
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ ${helpers.predefined_type(
|
||||||
initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())",
|
initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())",
|
||||||
initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
|
initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
|
||||||
spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
|
spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
|
||||||
animation_value_type="discrete",
|
animation_value_type="BorderImageWidth",
|
||||||
boxed=True,
|
boxed=True,
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -158,6 +158,6 @@ ${helpers.predefined_type(
|
||||||
initial_value="computed::BorderImageSlice::hundred_percent()",
|
initial_value="computed::BorderImageSlice::hundred_percent()",
|
||||||
initial_specified_value="specified::BorderImageSlice::hundred_percent()",
|
initial_specified_value="specified::BorderImageSlice::hundred_percent()",
|
||||||
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
|
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
|
||||||
animation_value_type="discrete",
|
animation_value_type="BorderImageSlice",
|
||||||
boxed=True,
|
boxed=True,
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -91,6 +91,7 @@ ${helpers.single_keyword(
|
||||||
extra_prefixes="webkit",
|
extra_prefixes="webkit",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
servo_restyle_damage = "reflow",
|
servo_restyle_damage = "reflow",
|
||||||
|
gecko_enum_prefix = "StyleFlexWrap",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
% if engine == "servo-2013":
|
% if engine == "servo-2013":
|
||||||
|
|
|
@ -1793,7 +1793,7 @@ impl ToCss for PropertyId {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The counted unknown property list which is used for css use counters.
|
/// The counted unknown property list which is used for css use counters.
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, PartialEq)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum CountedUnknownProperty {
|
pub enum CountedUnknownProperty {
|
||||||
% for prop in data.counted_unknown_properties:
|
% for prop in data.counted_unknown_properties:
|
||||||
|
@ -1821,16 +1821,6 @@ impl CountedUnknownProperty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fn is_counted_unknown_use_counters_enabled() -> bool {
|
|
||||||
static_prefs::pref!("layout.css.use-counters-unimplemented.enabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
fn is_counted_unknown_use_counters_enabled() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PropertyId {
|
impl PropertyId {
|
||||||
/// Return the longhand id that this property id represents.
|
/// Return the longhand id that this property id represents.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1890,11 +1880,9 @@ impl PropertyId {
|
||||||
StaticId::LonghandAlias(id, alias) => PropertyId::LonghandAlias(id, alias),
|
StaticId::LonghandAlias(id, alias) => PropertyId::LonghandAlias(id, alias),
|
||||||
StaticId::ShorthandAlias(id, alias) => PropertyId::ShorthandAlias(id, alias),
|
StaticId::ShorthandAlias(id, alias) => PropertyId::ShorthandAlias(id, alias),
|
||||||
StaticId::CountedUnknown(unknown_prop) => {
|
StaticId::CountedUnknown(unknown_prop) => {
|
||||||
if is_counted_unknown_use_counters_enabled() {
|
|
||||||
if let Some(counters) = use_counters {
|
if let Some(counters) = use_counters {
|
||||||
counters.counted_unknown_properties.record(unknown_prop);
|
counters.counted_unknown_properties.record(unknown_prop);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Always return Err(()) because these aren't valid custom property names.
|
// Always return Err(()) because these aren't valid custom property names.
|
||||||
return Err(());
|
return Err(());
|
||||||
|
|
|
@ -365,3 +365,79 @@ ${helpers.two_properties_shorthand(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
||||||
|
<%helpers:shorthand name="offset"
|
||||||
|
engines="gecko"
|
||||||
|
sub_properties="offset-path offset-distance offset-rotate offset-anchor"
|
||||||
|
gecko_pref="layout.css.motion-path.enabled",
|
||||||
|
spec="https://drafts.fxtf.org/motion-1/#offset-shorthand">
|
||||||
|
use crate::parser::Parse;
|
||||||
|
use crate::values::specified::motion::{OffsetPath, OffsetRotate};
|
||||||
|
use crate::values::specified::position::PositionOrAuto;
|
||||||
|
use crate::values::specified::LengthPercentage;
|
||||||
|
use crate::Zero;
|
||||||
|
|
||||||
|
pub fn parse_value<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
|
// FIXME: Bug 1559232: Support offset-position.
|
||||||
|
// Per the spec, this must have offet-position and/or offset-path. However, we don't
|
||||||
|
// support offset-position, so offset-path is necessary now.
|
||||||
|
let offset_path = OffsetPath::parse(context, input)?;
|
||||||
|
|
||||||
|
let mut offset_distance = None;
|
||||||
|
let mut offset_rotate = None;
|
||||||
|
loop {
|
||||||
|
if offset_distance.is_none() {
|
||||||
|
if let Ok(value) = input.try(|i| LengthPercentage::parse(context, i)) {
|
||||||
|
offset_distance = Some(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if offset_rotate.is_none() {
|
||||||
|
if let Ok(value) = input.try(|i| OffsetRotate::parse(context, i)) {
|
||||||
|
offset_rotate = Some(value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset_anchor = input.try(|i| {
|
||||||
|
i.expect_delim('/')?;
|
||||||
|
PositionOrAuto::parse(context, i)
|
||||||
|
}).ok();
|
||||||
|
|
||||||
|
Ok(expanded! {
|
||||||
|
offset_path: offset_path,
|
||||||
|
offset_distance: offset_distance.unwrap_or(LengthPercentage::zero()),
|
||||||
|
offset_rotate: offset_rotate.unwrap_or(OffsetRotate::auto()),
|
||||||
|
offset_anchor: offset_anchor.unwrap_or(PositionOrAuto::auto()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||||
|
// FIXME: Bug 1559232: Support offset-position. We don't support offset-position,
|
||||||
|
// so always serialize offset-path now.
|
||||||
|
self.offset_path.to_css(dest)?;
|
||||||
|
|
||||||
|
if !self.offset_distance.is_zero() {
|
||||||
|
dest.write_str(" ")?;
|
||||||
|
self.offset_distance.to_css(dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.offset_rotate.is_auto() {
|
||||||
|
dest.write_str(" ")?;
|
||||||
|
self.offset_rotate.to_css(dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if *self.offset_anchor != PositionOrAuto::auto() {
|
||||||
|
dest.write_str(" / ")?;
|
||||||
|
self.offset_anchor.to_css(dest)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -26,13 +26,10 @@ impl Animate for LengthPercentage {
|
||||||
.animate(&other.unclamped_length(), procedure)?;
|
.animate(&other.unclamped_length(), procedure)?;
|
||||||
let percentage =
|
let percentage =
|
||||||
animate_percentage_half(self.specified_percentage(), other.specified_percentage())?;
|
animate_percentage_half(self.specified_percentage(), other.specified_percentage())?;
|
||||||
let is_calc =
|
|
||||||
self.was_calc || other.was_calc || self.has_percentage != other.has_percentage;
|
|
||||||
Ok(Self::with_clamping_mode(
|
Ok(Self::with_clamping_mode(
|
||||||
length,
|
length,
|
||||||
percentage,
|
percentage,
|
||||||
self.clamping_mode,
|
self.clamping_mode,
|
||||||
is_calc,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,10 @@
|
||||||
use crate::values::computed::position::Position;
|
use crate::values::computed::position::Position;
|
||||||
use crate::values::computed::url::ComputedImageUrl;
|
use crate::values::computed::url::ComputedImageUrl;
|
||||||
use crate::values::computed::{Angle, Color, Context};
|
use crate::values::computed::{Angle, Color, Context};
|
||||||
use crate::values::computed::{Length, LengthPercentage, NumberOrPercentage, ToComputedValue};
|
use crate::values::computed::{
|
||||||
|
LengthPercentage, NonNegativeLength, NonNegativeLengthPercentage, NumberOrPercentage,
|
||||||
|
ToComputedValue,
|
||||||
|
};
|
||||||
use crate::values::generics::image::{self as generic, GradientCompatMode};
|
use crate::values::generics::image::{self as generic, GradientCompatMode};
|
||||||
use crate::values::specified::image::LineDirection as SpecifiedLineDirection;
|
use crate::values::specified::image::LineDirection as SpecifiedLineDirection;
|
||||||
use crate::values::specified::position::{HorizontalPositionKeyword, VerticalPositionKeyword};
|
use crate::values::specified::position::{HorizontalPositionKeyword, VerticalPositionKeyword};
|
||||||
|
@ -27,12 +30,17 @@ pub type Image = generic::GenericImage<Gradient, MozImageRect, ComputedImageUrl>
|
||||||
|
|
||||||
/// Computed values for a CSS gradient.
|
/// Computed values for a CSS gradient.
|
||||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||||
pub type Gradient =
|
pub type Gradient = generic::GenericGradient<
|
||||||
generic::GenericGradient<LineDirection, Length, LengthPercentage, Position, Color>;
|
LineDirection,
|
||||||
|
LengthPercentage,
|
||||||
|
NonNegativeLength,
|
||||||
|
NonNegativeLengthPercentage,
|
||||||
|
Position,
|
||||||
|
Color,
|
||||||
|
>;
|
||||||
|
|
||||||
/// A computed gradient kind.
|
/// A computed radial gradient ending shape.
|
||||||
pub type GradientKind =
|
pub type EndingShape = generic::GenericEndingShape<NonNegativeLength, NonNegativeLengthPercentage>;
|
||||||
generic::GenericGradientKind<LineDirection, Length, LengthPercentage, Position>;
|
|
||||||
|
|
||||||
/// A computed gradient line direction.
|
/// A computed gradient line direction.
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToResolvedValue)]
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToResolvedValue)]
|
||||||
|
@ -48,9 +56,6 @@ pub enum LineDirection {
|
||||||
Corner(HorizontalPositionKeyword, VerticalPositionKeyword),
|
Corner(HorizontalPositionKeyword, VerticalPositionKeyword),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A computed radial gradient ending shape.
|
|
||||||
pub type EndingShape = generic::EndingShape<Length, LengthPercentage>;
|
|
||||||
|
|
||||||
/// A computed gradient item.
|
/// A computed gradient item.
|
||||||
pub type GradientItem = generic::GenericGradientItem<Color, LengthPercentage>;
|
pub type GradientItem = generic::GenericGradientItem<Color, LengthPercentage>;
|
||||||
|
|
||||||
|
|
|
@ -85,25 +85,20 @@ pub struct LengthPercentage {
|
||||||
/// Whether we specified a percentage or not.
|
/// Whether we specified a percentage or not.
|
||||||
#[animation(constant)]
|
#[animation(constant)]
|
||||||
pub has_percentage: bool,
|
pub has_percentage: bool,
|
||||||
/// Whether this was from a calc() expression. This is needed because right
|
|
||||||
/// now we don't treat calc() the same way as non-calc everywhere, but
|
|
||||||
/// that's a bug in most cases.
|
|
||||||
///
|
|
||||||
/// Please don't add new uses of this that aren't for converting to Gecko's
|
|
||||||
/// representation, or to interpolate values.
|
|
||||||
///
|
|
||||||
/// See https://github.com/w3c/csswg-drafts/issues/3482.
|
|
||||||
#[animation(constant)]
|
|
||||||
pub was_calc: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(emilio): This is a bit of a hack that can disappear as soon as we share
|
// NOTE(emilio): We don't compare `clamping_mode` since we want to preserve the
|
||||||
// representation of LengthPercentage with Gecko. The issue here is that Gecko
|
// invariant that `from_computed_value(length).to_computed_value(..) == length`.
|
||||||
// uses CalcValue to represent position components, so they always come back as
|
|
||||||
// was_calc == true, and we mess up in the transitions code.
|
|
||||||
//
|
//
|
||||||
// This was a pre-existing bug, though arguably so only in pretty obscure cases
|
// Right now for e.g. a non-negative length, we set clamping_mode to `All`
|
||||||
// like calc(0px + 5%) and such.
|
// unconditionally for non-calc values, and to `NonNegative` for calc.
|
||||||
|
//
|
||||||
|
// If we determine that it's sound, from_computed_value() can generate an
|
||||||
|
// absolute length, which then would get `All` as the clamping mode.
|
||||||
|
//
|
||||||
|
// We may want to just eagerly-detect whether we can clamp in
|
||||||
|
// `LengthPercentage::new` and switch to `AllowedNumericType::NonNegative` then,
|
||||||
|
// maybe.
|
||||||
impl PartialEq for LengthPercentage {
|
impl PartialEq for LengthPercentage {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.length == other.length &&
|
self.length == other.length &&
|
||||||
|
@ -129,12 +124,7 @@ impl LengthPercentage {
|
||||||
/// Returns a new `LengthPercentage`.
|
/// Returns a new `LengthPercentage`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(length: Length, percentage: Option<Percentage>) -> Self {
|
pub fn new(length: Length, percentage: Option<Percentage>) -> Self {
|
||||||
Self::with_clamping_mode(
|
Self::with_clamping_mode(length, percentage, AllowedNumericType::All)
|
||||||
length,
|
|
||||||
percentage,
|
|
||||||
AllowedNumericType::All,
|
|
||||||
/* was_calc = */ false,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new `LengthPercentage` with zero length and some percentage.
|
/// Returns a new `LengthPercentage` with zero length and some percentage.
|
||||||
|
@ -148,14 +138,12 @@ impl LengthPercentage {
|
||||||
length: Length,
|
length: Length,
|
||||||
percentage: Option<Percentage>,
|
percentage: Option<Percentage>,
|
||||||
clamping_mode: AllowedNumericType,
|
clamping_mode: AllowedNumericType,
|
||||||
was_calc: bool,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
clamping_mode,
|
clamping_mode,
|
||||||
length,
|
length,
|
||||||
percentage: percentage.unwrap_or_default(),
|
percentage: percentage.unwrap_or_default(),
|
||||||
has_percentage: percentage.is_some(),
|
has_percentage: percentage.is_some(),
|
||||||
was_calc,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +273,6 @@ impl specified::CalcLengthPercentage {
|
||||||
Length::new(length.min(f32::MAX).max(f32::MIN)),
|
Length::new(length.min(f32::MAX).max(f32::MIN)),
|
||||||
self.percentage,
|
self.percentage,
|
||||||
self.clamping_mode,
|
self.clamping_mode,
|
||||||
/* was_calc = */ true,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,35 +368,25 @@ impl LengthPercentage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the clamped non-negative values.
|
/// Returns the clamped non-negative values.
|
||||||
///
|
|
||||||
/// TODO(emilio): It's a bit unfortunate that this depends on whether the
|
|
||||||
/// value was a `calc()` value or not. Should it?
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clamp_to_non_negative(self) -> Self {
|
pub fn clamp_to_non_negative(self) -> Self {
|
||||||
if self.was_calc {
|
|
||||||
return Self::with_clamping_mode(
|
|
||||||
self.length,
|
|
||||||
self.specified_percentage(),
|
|
||||||
AllowedNumericType::NonNegative,
|
|
||||||
self.was_calc,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert!(!self.has_percentage || self.unclamped_length() == Length::zero());
|
|
||||||
if let Some(p) = self.specified_percentage() {
|
if let Some(p) = self.specified_percentage() {
|
||||||
|
// If we can eagerly clamp the percentage then just do that.
|
||||||
|
if self.length.is_zero() {
|
||||||
return Self::with_clamping_mode(
|
return Self::with_clamping_mode(
|
||||||
Length::zero(),
|
Length::zero(),
|
||||||
Some(p.clamp_to_non_negative()),
|
Some(p.clamp_to_non_negative()),
|
||||||
AllowedNumericType::NonNegative,
|
AllowedNumericType::NonNegative,
|
||||||
self.was_calc,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Self::with_clamping_mode(self.length, Some(p), AllowedNumericType::NonNegative);
|
||||||
|
}
|
||||||
|
|
||||||
Self::with_clamping_mode(
|
Self::with_clamping_mode(
|
||||||
self.length.clamp_to_non_negative(),
|
self.length.clamp_to_non_negative(),
|
||||||
None,
|
None,
|
||||||
AllowedNumericType::NonNegative,
|
AllowedNumericType::NonNegative,
|
||||||
self.was_calc,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -577,7 +577,16 @@ impl From<GreaterThanOrEqualToOneNumber> for CSSFloat {
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue,
|
Animate,
|
||||||
|
Clone,
|
||||||
|
ComputeSquaredDistance,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
ToAnimatedZero,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
)]
|
)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum NumberOrPercentage {
|
pub enum NumberOrPercentage {
|
||||||
|
|
|
@ -5,12 +5,11 @@
|
||||||
//! Computed types for CSS values that are related to motion path.
|
//! Computed types for CSS values that are related to motion path.
|
||||||
|
|
||||||
use crate::values::computed::Angle;
|
use crate::values::computed::Angle;
|
||||||
|
use crate::values::generics::motion::GenericOffsetPath;
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
|
|
||||||
/// A computed offset-path. The computed value is as specified value.
|
/// The computed value of `offset-path`.
|
||||||
///
|
pub type OffsetPath = GenericOffsetPath<Angle>;
|
||||||
/// https://drafts.fxtf.org/motion-1/#offset-path-property
|
|
||||||
pub use crate::values::specified::motion::OffsetPath;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_auto_zero_angle(auto: &bool, angle: &Angle) -> bool {
|
fn is_auto_zero_angle(auto: &bool, angle: &Angle) -> bool {
|
||||||
|
|
|
@ -12,12 +12,17 @@ use style_traits::{CssWriter, ToCss};
|
||||||
|
|
||||||
/// A generic value for a single side of a `border-image-width` property.
|
/// A generic value for a single side of a `border-image-width` property.
|
||||||
#[derive(
|
#[derive(
|
||||||
|
Animate,
|
||||||
Clone,
|
Clone,
|
||||||
|
ComputeSquaredDistance,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
|
Parse,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedValue,
|
||||||
|
ToAnimatedZero,
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
|
@ -25,10 +30,13 @@ use style_traits::{CssWriter, ToCss};
|
||||||
)]
|
)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum GenericBorderImageSideWidth<LP, N> {
|
pub enum GenericBorderImageSideWidth<LP, N> {
|
||||||
|
/// `<number>`
|
||||||
|
///
|
||||||
|
/// NOTE: Numbers need to be before length-percentagess, in order to parse
|
||||||
|
/// them first, since `0` should be a number, not the `0px` length.
|
||||||
|
Number(N),
|
||||||
/// `<length-or-percentage>`
|
/// `<length-or-percentage>`
|
||||||
LengthPercentage(LP),
|
LengthPercentage(LP),
|
||||||
/// `<number>`
|
|
||||||
Number(N),
|
|
||||||
/// `auto`
|
/// `auto`
|
||||||
Auto,
|
Auto,
|
||||||
}
|
}
|
||||||
|
@ -37,12 +45,16 @@ pub use self::GenericBorderImageSideWidth as BorderImageSideWidth;
|
||||||
|
|
||||||
/// A generic value for the `border-image-slice` property.
|
/// A generic value for the `border-image-slice` property.
|
||||||
#[derive(
|
#[derive(
|
||||||
|
Animate,
|
||||||
Clone,
|
Clone,
|
||||||
|
ComputeSquaredDistance,
|
||||||
Copy,
|
Copy,
|
||||||
Debug,
|
Debug,
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedValue,
|
||||||
|
ToAnimatedZero,
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
|
@ -54,6 +66,7 @@ pub struct GenericBorderImageSlice<NumberOrPercentage> {
|
||||||
#[css(field_bound)]
|
#[css(field_bound)]
|
||||||
pub offsets: Rect<NumberOrPercentage>,
|
pub offsets: Rect<NumberOrPercentage>,
|
||||||
/// Whether to fill the middle part.
|
/// Whether to fill the middle part.
|
||||||
|
#[animation(constant)]
|
||||||
#[css(represents_keyword)]
|
#[css(represents_keyword)]
|
||||||
pub fill: bool,
|
pub fill: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -646,11 +646,8 @@ impl Parse for LineNameList {
|
||||||
|
|
||||||
if let Ok((mut names_list, count)) = repeat_parse_result {
|
if let Ok((mut names_list, count)) = repeat_parse_result {
|
||||||
match count {
|
match count {
|
||||||
// FIXME(emilio): we probably shouldn't expand repeat() at
|
// FIXME(emilio): we shouldn't expand repeat() at
|
||||||
// parse time for subgrid.
|
// parse time for subgrid. (bug 1583429)
|
||||||
//
|
|
||||||
// Also this doesn't have the merging semantics that
|
|
||||||
// non-subgrid has... But maybe that's ok?
|
|
||||||
RepeatCount::Number(num) => line_names.extend(
|
RepeatCount::Number(num) => line_names.extend(
|
||||||
names_list
|
names_list
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -660,6 +657,8 @@ impl Parse for LineNameList {
|
||||||
),
|
),
|
||||||
RepeatCount::AutoFill if fill_idx.is_none() => {
|
RepeatCount::AutoFill if fill_idx.is_none() => {
|
||||||
// `repeat(autof-fill, ..)` should have just one line name.
|
// `repeat(autof-fill, ..)` should have just one line name.
|
||||||
|
// FIXME(bug 1341507) the above comment is wrong per:
|
||||||
|
// https://drafts.csswg.org/css-grid-2/#typedef-name-repeat
|
||||||
if names_list.len() != 1 {
|
if names_list.len() != 1 {
|
||||||
return Err(
|
return Err(
|
||||||
input.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
input.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
||||||
|
|
|
@ -73,9 +73,21 @@ pub use self::GenericImage as Image;
|
||||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GenericGradient<LineDirection, Length, LengthPercentage, Position, Color> {
|
pub struct GenericGradient<
|
||||||
|
LineDirection,
|
||||||
|
LengthPercentage,
|
||||||
|
NonNegativeLength,
|
||||||
|
NonNegativeLengthPercentage,
|
||||||
|
Position,
|
||||||
|
Color,
|
||||||
|
> {
|
||||||
/// Gradients can be linear or radial.
|
/// Gradients can be linear or radial.
|
||||||
pub kind: GenericGradientKind<LineDirection, Length, LengthPercentage, Position>,
|
pub kind: GenericGradientKind<
|
||||||
|
LineDirection,
|
||||||
|
NonNegativeLength,
|
||||||
|
NonNegativeLengthPercentage,
|
||||||
|
Position,
|
||||||
|
>,
|
||||||
/// The color stops and interpolation hints.
|
/// The color stops and interpolation hints.
|
||||||
pub items: crate::OwnedSlice<GenericGradientItem<Color, LengthPercentage>>,
|
pub items: crate::OwnedSlice<GenericGradientItem<Color, LengthPercentage>>,
|
||||||
/// True if this is a repeating gradient.
|
/// True if this is a repeating gradient.
|
||||||
|
@ -101,11 +113,19 @@ pub enum GradientCompatMode {
|
||||||
/// A gradient kind.
|
/// A gradient kind.
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum GenericGradientKind<LineDirection, Length, LengthPercentage, Position> {
|
pub enum GenericGradientKind<
|
||||||
|
LineDirection,
|
||||||
|
NonNegativeLength,
|
||||||
|
NonNegativeLengthPercentage,
|
||||||
|
Position,
|
||||||
|
> {
|
||||||
/// A linear gradient.
|
/// A linear gradient.
|
||||||
Linear(LineDirection),
|
Linear(LineDirection),
|
||||||
/// A radial gradient.
|
/// A radial gradient.
|
||||||
Radial(GenericEndingShape<Length, LengthPercentage>, Position),
|
Radial(
|
||||||
|
GenericEndingShape<NonNegativeLength, NonNegativeLengthPercentage>,
|
||||||
|
Position,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::GenericGradientKind as GradientKind;
|
pub use self::GenericGradientKind as GradientKind;
|
||||||
|
@ -115,11 +135,11 @@ pub use self::GenericGradientKind as GradientKind;
|
||||||
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
|
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum GenericEndingShape<Length, LengthPercentage> {
|
pub enum GenericEndingShape<NonNegativeLength, NonNegativeLengthPercentage> {
|
||||||
/// A circular gradient.
|
/// A circular gradient.
|
||||||
Circle(GenericCircle<Length>),
|
Circle(GenericCircle<NonNegativeLength>),
|
||||||
/// An elliptic gradient.
|
/// An elliptic gradient.
|
||||||
Ellipse(GenericEllipse<LengthPercentage>),
|
Ellipse(GenericEllipse<NonNegativeLengthPercentage>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::GenericEndingShape as EndingShape;
|
pub use self::GenericEndingShape as EndingShape;
|
||||||
|
@ -127,9 +147,9 @@ pub use self::GenericEndingShape as EndingShape;
|
||||||
/// A circle shape.
|
/// A circle shape.
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum GenericCircle<Length> {
|
pub enum GenericCircle<NonNegativeLength> {
|
||||||
/// A circle radius.
|
/// A circle radius.
|
||||||
Radius(Length),
|
Radius(NonNegativeLength),
|
||||||
/// A circle extent.
|
/// A circle extent.
|
||||||
Extent(ShapeExtent),
|
Extent(ShapeExtent),
|
||||||
}
|
}
|
||||||
|
@ -141,9 +161,9 @@ pub use self::GenericCircle as Circle;
|
||||||
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
|
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(C, u8)]
|
#[repr(C, u8)]
|
||||||
pub enum GenericEllipse<LengthPercentage> {
|
pub enum GenericEllipse<NonNegativeLengthPercentage> {
|
||||||
/// An ellipse pair of radii.
|
/// An ellipse pair of radii.
|
||||||
Radii(LengthPercentage, LengthPercentage),
|
Radii(NonNegativeLengthPercentage, NonNegativeLengthPercentage),
|
||||||
/// An ellipse extent.
|
/// An ellipse extent.
|
||||||
Extent(ShapeExtent),
|
Extent(ShapeExtent),
|
||||||
}
|
}
|
||||||
|
@ -314,11 +334,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, L, LoP, P, C> ToCss for Gradient<D, L, LoP, P, C>
|
impl<D, LP, NL, NLP, P, C> ToCss for Gradient<D, LP, NL, NLP, P, C>
|
||||||
where
|
where
|
||||||
D: LineDirection,
|
D: LineDirection,
|
||||||
L: ToCss,
|
LP: ToCss,
|
||||||
LoP: ToCss,
|
NL: ToCss,
|
||||||
|
NLP: ToCss,
|
||||||
P: ToCss,
|
P: ToCss,
|
||||||
C: ToCss,
|
C: ToCss,
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub mod font;
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
|
pub mod motion;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
pub mod size;
|
pub mod size;
|
||||||
|
|
110
components/style/values/generics/motion.rs
Normal file
110
components/style/values/generics/motion.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Generic types for CSS Motion Path.
|
||||||
|
|
||||||
|
use crate::values::specified::SVGPathData;
|
||||||
|
|
||||||
|
/// The <size> in ray() function.
|
||||||
|
///
|
||||||
|
/// https://drafts.fxtf.org/motion-1/#valdef-offsetpath-size
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
MallocSizeOf,
|
||||||
|
Parse,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum RaySize {
|
||||||
|
ClosestSide,
|
||||||
|
ClosestCorner,
|
||||||
|
FarthestSide,
|
||||||
|
FarthestCorner,
|
||||||
|
Sides,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `ray()` function, `ray( [ <angle> && <size> && contain? ] )`
|
||||||
|
///
|
||||||
|
/// https://drafts.fxtf.org/motion-1/#valdef-offsetpath-ray
|
||||||
|
#[derive(
|
||||||
|
Animate,
|
||||||
|
Clone,
|
||||||
|
ComputeSquaredDistance,
|
||||||
|
Debug,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct RayFunction<Angle> {
|
||||||
|
/// The bearing angle with `0deg` pointing up and positive angles
|
||||||
|
/// representing clockwise rotation.
|
||||||
|
pub angle: Angle,
|
||||||
|
/// Decide the path length used when `offset-distance` is expressed
|
||||||
|
/// as a percentage.
|
||||||
|
#[animation(constant)]
|
||||||
|
pub size: RaySize,
|
||||||
|
/// Clamp `offset-distance` so that the box is entirely contained
|
||||||
|
/// within the path.
|
||||||
|
#[animation(constant)]
|
||||||
|
#[css(represents_keyword)]
|
||||||
|
pub contain: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The offset-path value.
|
||||||
|
///
|
||||||
|
/// https://drafts.fxtf.org/motion-1/#offset-path-property
|
||||||
|
#[derive(
|
||||||
|
Animate,
|
||||||
|
Clone,
|
||||||
|
ComputeSquaredDistance,
|
||||||
|
Debug,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
#[repr(C, u8)]
|
||||||
|
pub enum GenericOffsetPath<Angle> {
|
||||||
|
// We could merge SVGPathData into ShapeSource, so we could reuse them. However,
|
||||||
|
// we don't want to support other value for offset-path, so use SVGPathData only for now.
|
||||||
|
/// Path value for path(<string>).
|
||||||
|
#[css(function)]
|
||||||
|
Path(SVGPathData),
|
||||||
|
/// ray() function, which defines a path in the polar coordinate system.
|
||||||
|
#[css(function)]
|
||||||
|
Ray(RayFunction<Angle>),
|
||||||
|
/// None value.
|
||||||
|
#[animation(error)]
|
||||||
|
None,
|
||||||
|
// Bug 1186329: Implement <basic-shape>, <geometry-box>, and <url>.
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use self::GenericOffsetPath as OffsetPath;
|
||||||
|
|
||||||
|
impl<Angle> OffsetPath<Angle> {
|
||||||
|
/// Return None.
|
||||||
|
#[inline]
|
||||||
|
pub fn none() -> Self {
|
||||||
|
OffsetPath::None
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToAnimatedValue,
|
ToAnimatedValue,
|
||||||
|
ToAnimatedZero,
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
|
|
|
@ -180,24 +180,6 @@ impl BorderImageSideWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for BorderImageSideWidth {
|
|
||||||
fn parse<'i, 't>(
|
|
||||||
context: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
) -> Result<Self, ParseError<'i>> {
|
|
||||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
|
||||||
return Ok(GenericBorderImageSideWidth::Auto);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(len) = input.try(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
|
||||||
return Ok(GenericBorderImageSideWidth::LengthPercentage(len));
|
|
||||||
}
|
|
||||||
|
|
||||||
let num = NonNegativeNumber::parse(context, input)?;
|
|
||||||
Ok(GenericBorderImageSideWidth::Number(num))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for BorderImageSlice {
|
impl Parse for BorderImageSlice {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
|
|
|
@ -393,6 +393,22 @@ impl Display {
|
||||||
};
|
};
|
||||||
Display::from3(DisplayOutside::Block, inside, self.is_list_item())
|
Display::from3(DisplayOutside::Block, inside, self.is_list_item())
|
||||||
},
|
},
|
||||||
|
// If this pref is true, then we'll blockify "-moz-inline-box" to
|
||||||
|
// "-moz-box", and blockify "-moz-box" to itself. Otherwise, we
|
||||||
|
// blockify both to "block".
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
DisplayOutside::XUL => {
|
||||||
|
if static_prefs::pref!(
|
||||||
|
"layout.css.xul-box-display-values.survive-blockification.enabled"
|
||||||
|
) {
|
||||||
|
match self.inside() {
|
||||||
|
DisplayInside::MozInlineBox | DisplayInside::MozBox => Display::MozBox,
|
||||||
|
_ => Display::Block,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Display::Block
|
||||||
|
}
|
||||||
|
},
|
||||||
DisplayOutside::Block | DisplayOutside::None => *self,
|
DisplayOutside::Block | DisplayOutside::None => *self,
|
||||||
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
|
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
|
||||||
_ => Display::Block,
|
_ => Display::Block,
|
||||||
|
@ -1140,6 +1156,8 @@ fn change_bits_for_longhand(longhand: LonghandId) -> WillChangeBits {
|
||||||
let mut flags = match longhand {
|
let mut flags = match longhand {
|
||||||
LonghandId::Opacity => WillChangeBits::OPACITY,
|
LonghandId::Opacity => WillChangeBits::OPACITY,
|
||||||
LonghandId::Transform => WillChangeBits::TRANSFORM,
|
LonghandId::Transform => WillChangeBits::TRANSFORM,
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
LonghandId::Translate | LonghandId::Rotate | LonghandId::Scale => WillChangeBits::TRANSFORM,
|
||||||
_ => WillChangeBits::empty(),
|
_ => WillChangeBits::empty(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,13 @@ use crate::values::generics::image::{
|
||||||
self as generic, Circle, Ellipse, GradientCompatMode, ShapeExtent,
|
self as generic, Circle, Ellipse, GradientCompatMode, ShapeExtent,
|
||||||
};
|
};
|
||||||
use crate::values::generics::position::Position as GenericPosition;
|
use crate::values::generics::position::Position as GenericPosition;
|
||||||
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::specified::position::{HorizontalPositionKeyword, VerticalPositionKeyword};
|
use crate::values::specified::position::{HorizontalPositionKeyword, VerticalPositionKeyword};
|
||||||
use crate::values::specified::position::{Position, PositionComponent, Side};
|
use crate::values::specified::position::{Position, PositionComponent, Side};
|
||||||
use crate::values::specified::url::SpecifiedImageUrl;
|
use crate::values::specified::url::SpecifiedImageUrl;
|
||||||
use crate::values::specified::{Angle, Color, Length, LengthPercentage};
|
use crate::values::specified::{
|
||||||
|
Angle, Color, Length, LengthPercentage, NonNegativeLength, NonNegativeLengthPercentage,
|
||||||
|
};
|
||||||
use crate::values::specified::{Number, NumberOrPercentage, Percentage};
|
use crate::values::specified::{Number, NumberOrPercentage, Percentage};
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use cssparser::{Delimiter, Parser, Token};
|
use cssparser::{Delimiter, Parser, Token};
|
||||||
|
@ -54,7 +57,14 @@ pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>;
|
||||||
|
|
||||||
/// Specified values for a CSS gradient.
|
/// Specified values for a CSS gradient.
|
||||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||||
pub type Gradient = generic::Gradient<LineDirection, Length, LengthPercentage, Position, Color>;
|
pub type Gradient = generic::Gradient<
|
||||||
|
LineDirection,
|
||||||
|
LengthPercentage,
|
||||||
|
NonNegativeLength,
|
||||||
|
NonNegativeLengthPercentage,
|
||||||
|
Position,
|
||||||
|
Color,
|
||||||
|
>;
|
||||||
|
|
||||||
impl SpecifiedValueInfo for Gradient {
|
impl SpecifiedValueInfo for Gradient {
|
||||||
const SUPPORTED_TYPES: u8 = CssType::GRADIENT;
|
const SUPPORTED_TYPES: u8 = CssType::GRADIENT;
|
||||||
|
@ -80,7 +90,8 @@ impl SpecifiedValueInfo for Gradient {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A specified gradient kind.
|
/// A specified gradient kind.
|
||||||
pub type GradientKind = generic::GradientKind<LineDirection, Length, LengthPercentage, Position>;
|
pub type GradientKind =
|
||||||
|
generic::GradientKind<LineDirection, NonNegativeLength, NonNegativeLengthPercentage, Position>;
|
||||||
|
|
||||||
/// A specified gradient line direction.
|
/// A specified gradient line direction.
|
||||||
///
|
///
|
||||||
|
@ -98,7 +109,7 @@ pub enum LineDirection {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A specified ending shape.
|
/// A specified ending shape.
|
||||||
pub type EndingShape = generic::EndingShape<Length, LengthPercentage>;
|
pub type EndingShape = generic::EndingShape<NonNegativeLength, NonNegativeLengthPercentage>;
|
||||||
|
|
||||||
/// A specified gradient item.
|
/// A specified gradient item.
|
||||||
pub type GradientItem = generic::GradientItem<Color, LengthPercentage>;
|
pub type GradientItem = generic::GradientItem<Color, LengthPercentage>;
|
||||||
|
@ -391,11 +402,11 @@ impl Gradient {
|
||||||
"radial" => {
|
"radial" => {
|
||||||
let first_point = Point::parse(context, input)?;
|
let first_point = Point::parse(context, input)?;
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
let first_radius = Number::parse(context, input)?;
|
let first_radius = Number::parse_non_negative(context, input)?;
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
let second_point = Point::parse(context, input)?;
|
let second_point = Point::parse(context, input)?;
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
let second_radius = Number::parse(context, input)?;
|
let second_radius = Number::parse_non_negative(context, input)?;
|
||||||
|
|
||||||
let (reverse_stops, point, radius) = if second_radius.value >= first_radius.value {
|
let (reverse_stops, point, radius) = if second_radius.value >= first_radius.value {
|
||||||
(false, second_point, second_radius)
|
(false, second_point, second_radius)
|
||||||
|
@ -403,7 +414,7 @@ impl Gradient {
|
||||||
(true, first_point, first_radius)
|
(true, first_point, first_radius)
|
||||||
};
|
};
|
||||||
|
|
||||||
let rad = Circle::Radius(Length::from_px(radius.value));
|
let rad = Circle::Radius(NonNegative(Length::from_px(radius.value)));
|
||||||
let shape = generic::EndingShape::Circle(rad);
|
let shape = generic::EndingShape::Circle(rad);
|
||||||
let position: Position = point.into();
|
let position: Position = point.into();
|
||||||
|
|
||||||
|
@ -678,7 +689,7 @@ impl EndingShape {
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Extent(extent)));
|
return Ok(generic::EndingShape::Circle(Circle::Extent(extent)));
|
||||||
}
|
}
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
if let Ok(length) = input.try(|i| Length::parse(context, i)) {
|
if let Ok(length) = input.try(|i| NonNegativeLength::parse(context, i)) {
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -692,8 +703,8 @@ impl EndingShape {
|
||||||
}
|
}
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let pair: Result<_, ParseError> = input.try(|i| {
|
let pair: Result<_, ParseError> = input.try(|i| {
|
||||||
let x = LengthPercentage::parse(context, i)?;
|
let x = NonNegativeLengthPercentage::parse(context, i)?;
|
||||||
let y = LengthPercentage::parse(context, i)?;
|
let y = NonNegativeLengthPercentage::parse(context, i)?;
|
||||||
Ok((x, y))
|
Ok((x, y))
|
||||||
});
|
});
|
||||||
if let Ok((x, y)) = pair {
|
if let Ok((x, y)) = pair {
|
||||||
|
@ -704,24 +715,24 @@ impl EndingShape {
|
||||||
ShapeExtent::FarthestCorner,
|
ShapeExtent::FarthestCorner,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if let Ok(length) = input.try(|i| Length::parse(context, i)) {
|
if let Ok(length) = input.try(|i| NonNegativeLength::parse(context, i)) {
|
||||||
if let Ok(y) = input.try(|i| LengthPercentage::parse(context, i)) {
|
if let Ok(y) = input.try(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let _ = input.try(|i| i.expect_ident_matching("ellipse"));
|
let _ = input.try(|i| i.expect_ident_matching("ellipse"));
|
||||||
}
|
}
|
||||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
||||||
length.into(),
|
NonNegative(LengthPercentage::from(length.0)),
|
||||||
y,
|
y,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let y = input.try(|i| {
|
let y = input.try(|i| {
|
||||||
i.expect_ident_matching("ellipse")?;
|
i.expect_ident_matching("ellipse")?;
|
||||||
LengthPercentage::parse(context, i)
|
NonNegativeLengthPercentage::parse(context, i)
|
||||||
});
|
});
|
||||||
if let Ok(y) = y {
|
if let Ok(y) = y {
|
||||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
||||||
length.into(),
|
NonNegative(LengthPercentage::from(length.0)),
|
||||||
y,
|
y,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -731,8 +742,8 @@ impl EndingShape {
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
||||||
}
|
}
|
||||||
input.try(|i| {
|
input.try(|i| {
|
||||||
let x = Percentage::parse(context, i)?;
|
let x = Percentage::parse_non_negative(context, i)?;
|
||||||
let y = if let Ok(y) = i.try(|i| LengthPercentage::parse(context, i)) {
|
let y = if let Ok(y) = i.try(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let _ = i.try(|i| i.expect_ident_matching("ellipse"));
|
let _ = i.try(|i| i.expect_ident_matching("ellipse"));
|
||||||
}
|
}
|
||||||
|
@ -741,9 +752,12 @@ impl EndingShape {
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
i.expect_ident_matching("ellipse")?;
|
i.expect_ident_matching("ellipse")?;
|
||||||
}
|
}
|
||||||
LengthPercentage::parse(context, i)?
|
NonNegativeLengthPercentage::parse(context, i)?
|
||||||
};
|
};
|
||||||
Ok(generic::EndingShape::Ellipse(Ellipse::Radii(x.into(), y)))
|
Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
||||||
|
NonNegative(LengthPercentage::from(x)),
|
||||||
|
y,
|
||||||
|
)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -704,14 +704,14 @@ impl Parse for NonNegativeLength {
|
||||||
impl From<NoCalcLength> for NonNegativeLength {
|
impl From<NoCalcLength> for NonNegativeLength {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(len: NoCalcLength) -> Self {
|
fn from(len: NoCalcLength) -> Self {
|
||||||
NonNegative::<Length>(Length::NoCalc(len))
|
NonNegative(Length::NoCalc(len))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Length> for NonNegativeLength {
|
impl From<Length> for NonNegativeLength {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(len: Length) -> Self {
|
fn from(len: Length) -> Self {
|
||||||
NonNegative::<Length>(len)
|
NonNegative(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,9 @@ pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLe
|
||||||
pub use self::length::{LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
pub use self::length::{LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
||||||
pub use self::length::{MaxSize, Size};
|
pub use self::length::{MaxSize, Size};
|
||||||
pub use self::length::{NoCalcLength, ViewportPercentageLength};
|
pub use self::length::{NoCalcLength, ViewportPercentageLength};
|
||||||
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
pub use self::length::{
|
||||||
|
NonNegativeLength, NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
|
||||||
|
};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::list::ListStyleType;
|
pub use self::list::ListStyleType;
|
||||||
pub use self::list::MozListReversed;
|
pub use self::list::MozListReversed;
|
||||||
|
|
|
@ -7,46 +7,53 @@
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::values::computed::motion::OffsetRotate as ComputedOffsetRotate;
|
use crate::values::computed::motion::OffsetRotate as ComputedOffsetRotate;
|
||||||
use crate::values::computed::{Context, ToComputedValue};
|
use crate::values::computed::{Context, ToComputedValue};
|
||||||
|
use crate::values::generics::motion::{GenericOffsetPath, RayFunction, RaySize};
|
||||||
use crate::values::specified::{Angle, SVGPathData};
|
use crate::values::specified::{Angle, SVGPathData};
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use style_traits::{ParseError, StyleParseErrorKind};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
|
|
||||||
/// The offset-path value.
|
/// The specified value of `offset-path`.
|
||||||
///
|
pub type OffsetPath = GenericOffsetPath<Angle>;
|
||||||
/// https://drafts.fxtf.org/motion-1/#offset-path-property
|
|
||||||
#[derive(
|
impl Parse for RayFunction<Angle> {
|
||||||
Animate,
|
fn parse<'i, 't>(
|
||||||
Clone,
|
context: &ParserContext,
|
||||||
ComputeSquaredDistance,
|
input: &mut Parser<'i, 't>,
|
||||||
Debug,
|
) -> Result<Self, ParseError<'i>> {
|
||||||
MallocSizeOf,
|
let mut angle = None;
|
||||||
PartialEq,
|
let mut size = None;
|
||||||
SpecifiedValueInfo,
|
let mut contain = false;
|
||||||
ToAnimatedZero,
|
loop {
|
||||||
ToComputedValue,
|
if angle.is_none() {
|
||||||
ToCss,
|
angle = input.try(|i| Angle::parse(context, i)).ok();
|
||||||
ToResolvedValue,
|
|
||||||
ToShmem,
|
|
||||||
)]
|
|
||||||
#[repr(C, u8)]
|
|
||||||
pub enum OffsetPath {
|
|
||||||
// We could merge SVGPathData into ShapeSource, so we could reuse them. However,
|
|
||||||
// we don't want to support other value for offset-path, so use SVGPathData only for now.
|
|
||||||
/// Path value for path(<string>).
|
|
||||||
#[css(function)]
|
|
||||||
Path(SVGPathData),
|
|
||||||
/// None value.
|
|
||||||
#[animation(error)]
|
|
||||||
None,
|
|
||||||
// Bug 1186329: Implement ray(), <basic-shape>, <geometry-box>, and <url>.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OffsetPath {
|
if size.is_none() {
|
||||||
/// Return None.
|
size = input.try(RaySize::parse).ok();
|
||||||
#[inline]
|
if size.is_some() {
|
||||||
pub fn none() -> Self {
|
continue;
|
||||||
OffsetPath::None
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !contain {
|
||||||
|
contain = input.try(|i| i.expect_ident_matching("contain")).is_ok();
|
||||||
|
if contain {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if angle.is_none() || size.is_none() {
|
||||||
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(RayFunction {
|
||||||
|
angle: angle.unwrap(),
|
||||||
|
size: size.unwrap(),
|
||||||
|
contain,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,9 +72,10 @@ impl Parse for OffsetPath {
|
||||||
let function = input.expect_function()?.clone();
|
let function = input.expect_function()?.clone();
|
||||||
input.parse_nested_block(move |i| {
|
input.parse_nested_block(move |i| {
|
||||||
match_ignore_ascii_case! { &function,
|
match_ignore_ascii_case! { &function,
|
||||||
// Bug 1186329: Implement the parser for ray(), <basic-shape>, <geometry-box>,
|
// Bug 1186329: Implement the parser for <basic-shape>, <geometry-box>,
|
||||||
// and <url>.
|
// and <url>.
|
||||||
"path" => SVGPathData::parse(context, i).map(OffsetPath::Path),
|
"path" => SVGPathData::parse(context, i).map(GenericOffsetPath::Path),
|
||||||
|
"ray" => RayFunction::parse(context, i).map(GenericOffsetPath::Ray),
|
||||||
_ => {
|
_ => {
|
||||||
Err(location.new_custom_error(
|
Err(location.new_custom_error(
|
||||||
StyleParseErrorKind::UnexpectedFunction(function.clone())
|
StyleParseErrorKind::UnexpectedFunction(function.clone())
|
||||||
|
@ -122,6 +130,23 @@ pub struct OffsetRotate {
|
||||||
angle: Angle,
|
angle: Angle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OffsetRotate {
|
||||||
|
/// Returns the initial value, auto.
|
||||||
|
#[inline]
|
||||||
|
pub fn auto() -> Self {
|
||||||
|
OffsetRotate {
|
||||||
|
direction: OffsetRotateDirection::Auto,
|
||||||
|
angle: Angle::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if self is auto 0deg.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_auto(&self) -> bool {
|
||||||
|
self.direction == OffsetRotateDirection::Auto && self.angle.is_zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Parse for OffsetRotate {
|
impl Parse for OffsetRotate {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
|
|
|
@ -297,12 +297,7 @@ impl<S: Side> ToComputedValue for PositionComponent<S> {
|
||||||
let p = Percentage(1. - length.percentage());
|
let p = Percentage(1. - length.percentage());
|
||||||
let l = -length.unclamped_length();
|
let l = -length.unclamped_length();
|
||||||
// We represent `<end-side> <length>` as `calc(100% - <length>)`.
|
// We represent `<end-side> <length>` as `calc(100% - <length>)`.
|
||||||
ComputedLengthPercentage::with_clamping_mode(
|
ComputedLengthPercentage::with_clamping_mode(l, Some(p), length.clamping_mode)
|
||||||
l,
|
|
||||||
Some(p),
|
|
||||||
length.clamping_mode,
|
|
||||||
/* was_calc = */ true,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
PositionComponent::Side(_, Some(ref length)) |
|
PositionComponent::Side(_, Some(ref length)) |
|
||||||
PositionComponent::Length(ref length) => length.to_computed_value(context),
|
PositionComponent::Length(ref length) => length.to_computed_value(context),
|
||||||
|
|
|
@ -6,20 +6,44 @@ use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
||||||
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn modes() -> [WritingMode; 13] {
|
fn modes() -> [WritingMode; 21] {
|
||||||
[
|
[
|
||||||
WritingMode::empty(),
|
WritingMode::empty(),
|
||||||
WritingMode::VERTICAL,
|
WritingMode::VERTICAL,
|
||||||
WritingMode::VERTICAL | WritingMode::VERTICAL_LR,
|
WritingMode::VERTICAL | WritingMode::VERTICAL_LR,
|
||||||
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::SIDEWAYS,
|
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::VERTICAL_SIDEWAYS,
|
||||||
WritingMode::VERTICAL | WritingMode::SIDEWAYS,
|
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::TEXT_SIDEWAYS,
|
||||||
|
WritingMode::VERTICAL |
|
||||||
|
WritingMode::VERTICAL_LR |
|
||||||
|
WritingMode::VERTICAL_SIDEWAYS |
|
||||||
|
WritingMode::TEXT_SIDEWAYS,
|
||||||
|
WritingMode::VERTICAL | WritingMode::VERTICAL_SIDEWAYS,
|
||||||
|
WritingMode::VERTICAL | WritingMode::TEXT_SIDEWAYS,
|
||||||
|
WritingMode::VERTICAL | WritingMode::VERTICAL_SIDEWAYS | WritingMode::TEXT_SIDEWAYS,
|
||||||
WritingMode::VERTICAL | WritingMode::UPRIGHT,
|
WritingMode::VERTICAL | WritingMode::UPRIGHT,
|
||||||
WritingMode::RTL,
|
WritingMode::RTL,
|
||||||
WritingMode::VERTICAL | WritingMode::RTL,
|
WritingMode::VERTICAL | WritingMode::RTL,
|
||||||
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::RTL,
|
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::RTL,
|
||||||
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::SIDEWAYS | WritingMode::RTL,
|
WritingMode::VERTICAL |
|
||||||
|
WritingMode::VERTICAL_LR |
|
||||||
|
WritingMode::VERTICAL_SIDEWAYS |
|
||||||
|
WritingMode::RTL,
|
||||||
|
WritingMode::VERTICAL |
|
||||||
|
WritingMode::VERTICAL_LR |
|
||||||
|
WritingMode::TEXT_SIDEWAYS |
|
||||||
|
WritingMode::RTL,
|
||||||
|
WritingMode::VERTICAL |
|
||||||
|
WritingMode::VERTICAL_LR |
|
||||||
|
WritingMode::VERTICAL_SIDEWAYS |
|
||||||
|
WritingMode::TEXT_SIDEWAYS |
|
||||||
|
WritingMode::RTL,
|
||||||
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::UPRIGHT | WritingMode::RTL,
|
WritingMode::VERTICAL | WritingMode::VERTICAL_LR | WritingMode::UPRIGHT | WritingMode::RTL,
|
||||||
WritingMode::VERTICAL | WritingMode::SIDEWAYS | WritingMode::RTL,
|
WritingMode::VERTICAL | WritingMode::VERTICAL_SIDEWAYS | WritingMode::RTL,
|
||||||
|
WritingMode::VERTICAL | WritingMode::TEXT_SIDEWAYS | WritingMode::RTL,
|
||||||
|
WritingMode::VERTICAL |
|
||||||
|
WritingMode::VERTICAL_SIDEWAYS |
|
||||||
|
WritingMode::TEXT_SIDEWAYS |
|
||||||
|
WritingMode::RTL,
|
||||||
WritingMode::VERTICAL | WritingMode::UPRIGHT | WritingMode::RTL,
|
WritingMode::VERTICAL | WritingMode::UPRIGHT | WritingMode::RTL,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
[background-image-computed.sub.html]
|
|
||||||
[Property background-image value 'radial-gradient(ellipse calc(-0.5em + 10px) calc(0.5em + 10px) at 20px 30px, red, blue)' computes to 'radial-gradient(0px 30px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))']
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Property background-image value 'radial-gradient(circle calc(-0.5em + 10px) at calc(-1em + 10px) calc(-2em + 10px), red, blue)' computes to 'radial-gradient(0px at -30px -70px, rgb(255, 0, 0), rgb(0, 0, 255))']
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Property background-image value 'radial-gradient(ellipse calc(0.5em + 10px) calc(-0.5em + 10px) at 20px 30px, red, blue)' computes to 'radial-gradient(30px 0px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))']
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
[background-image-invalid.html]
|
|
||||||
[e.style['background-image'\] = "radial-gradient(ellipse -20px 30px at center, red, blue)" should not set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['background-image'\] = "repeating-radial-gradient(-20% 30% at center, red, blue)" should not set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['background-image'\] = "radial-gradient(circle -10px at center, red, blue)" should not set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['background-image'\] = "repeating-radial-gradient(20px -30px ellipse at center, red, blue)" should not set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['background-image'\] = "radial-gradient(20px -30px at center, red, blue)" should not set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['background-image'\] = "repeating-radial-gradient(-10px at center, red, blue)" should not set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[border-image-width-computed.html]
|
|
||||||
[Property border-image-width value '0' computes to '0']
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,481 +0,0 @@
|
||||||
[font-valid.html]
|
|
||||||
[message-box should be a supported system font.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[status-bar should be a supported system font.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[menu should be a supported system font.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[icon should be a supported system font.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[small-caption should be a supported system font.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[caption should be a supported system font.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic normal extra-expanded 900 calc(30% - 40px)/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded normal bolder italic xx-large/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "condensed italic normal small-caps calc(30% - 40px)/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps oblique ultra-expanded lighter 20%/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded 900 normal larger/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bold italic small-caps ultra-condensed calc(30% - 40px)/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal small-caps 20%/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic extra-expanded small-caps larger/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique normal expanded small-caps 20%/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded normal normal larger/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal italic normal 20%/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "100 normal small-caps condensed larger/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique expanded normal bolder xx-large/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique normal 20%/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique extra-condensed 20%/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "condensed 100 italic calc(30% - 40px)/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal oblique bolder calc(30% - 40px)/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "900 normal italic extra-condensed calc(30% - 40px)/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal italic 900 semi-condensed xx-large/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal xx-large/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique normal normal 100 xx-large/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "100 normal oblique small-caps 20%/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic bold larger/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "100 extra-condensed small-caps 20%/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded italic small-caps 900 larger/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal oblique normal normal calc(30% - 40px)/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "100 oblique semi-condensed small-caps xx-large/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique normal lighter small-caps xx-large/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps 900 normal xx-large/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps normal bolder larger/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal italic expanded larger/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal extra-expanded bolder oblique larger/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps bolder condensed calc(30% - 40px)/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "lighter normal extra-expanded small-caps calc(30% - 40px)/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "lighter normal small-caps oblique xx-large/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bold extra-condensed 20%/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bolder small-caps oblique expanded xx-large/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal lighter semi-condensed calc(30% - 40px)/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal lighter condensed calc(30% - 40px)/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal bold oblique 20%/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique extra-condensed 100 20%/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal normal bolder 20%/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps oblique normal normal 20%/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "lighter small-caps extra-expanded larger/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique normal small-caps 900 20%/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal oblique lighter xx-large/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded oblique small-caps normal xx-large/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-condensed normal normal small-caps 20%/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique lighter small-caps expanded xx-large/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal 100 small-caps larger/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded normal lighter small-caps larger/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal normal small-caps 20%/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic normal normal calc(30% - 40px)/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic normal normal ultra-condensed larger/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal extra-condensed italic xx-large/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps oblique bold normal xx-large/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "lighter small-caps normal italic 20%/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic small-caps 100 ultra-condensed calc(30% - 40px)/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic 900 normal semi-expanded calc(30% - 40px)/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal bold normal normal larger/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-condensed lighter normal small-caps 20%/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal extra-condensed small-caps normal 20%/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-condensed small-caps oblique 900 20%/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal extra-expanded italic small-caps larger/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal condensed lighter larger/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic condensed normal calc(30% - 40px)/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bold normal 20%/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal 900 normal xx-large/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded lighter small-caps normal larger/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique 100 normal small-caps 20%/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "condensed normal normal bolder calc(30% - 40px)/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded 100 xx-large/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal normal larger/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps expanded bolder xx-large/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic small-caps normal bold larger/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "condensed small-caps bold calc(30% - 40px)/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal oblique small-caps larger/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal oblique semi-expanded larger/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal bolder small-caps 20%/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps italic normal 100 calc(30% - 40px)/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique small-caps lighter normal 20%/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique small-caps semi-condensed 900 xx-large/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps condensed italic calc(30% - 40px)/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "900 normal normal small-caps xx-large/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "900 condensed small-caps normal calc(30% - 40px)/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal condensed small-caps italic calc(30% - 40px)/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-condensed oblique normal normal 20%/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bolder normal expanded italic 20%/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "900 small-caps larger/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-condensed normal small-caps oblique 20%/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps bolder normal italic xx-large/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "condensed small-caps calc(30% - 40px)/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps italic bolder semi-expanded larger/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "100 small-caps normal semi-expanded calc(30% - 40px)/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal bolder small-caps extra-condensed 20%/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal ultra-expanded small-caps larger/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bold oblique normal normal xx-large/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic condensed 900 normal calc(30% - 40px)/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal small-caps normal calc(30% - 40px)/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bold normal normal ultra-condensed larger/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bold extra-expanded italic larger/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps extra-condensed normal 900 20%/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps extra-expanded lighter normal larger/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps italic lighter calc(30% - 40px)/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal italic ultra-expanded bold 20%/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal xx-large/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal condensed normal small-caps calc(30% - 40px)/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps bold italic larger/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps oblique normal 20%/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps expanded xx-large/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-condensed oblique lighter small-caps 20%/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal expanded oblique normal xx-large/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal extra-condensed normal oblique 20%/1.2 cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal normal larger/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded normal oblique small-caps xx-large/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "oblique small-caps normal normal xx-large/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "900 oblique small-caps normal 20%/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal extra-expanded italic xx-large/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps bold oblique extra-condensed 20%/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded small-caps normal italic xx-large/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic 100 extra-expanded larger/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal expanded bold normal xx-large/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal 900 oblique calc(30% - 40px)/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps expanded oblique calc(30% - 40px)/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "condensed normal small-caps 100 calc(30% - 40px)/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded small-caps normal 100 larger/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic normal 100 condensed larger/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal normal bold calc(30% - 40px)/calc(120% + 1.2em) serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal normal semi-expanded calc(30% - 40px)/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps calc(30% - 40px)/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps 100 calc(30% - 40px)/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps lighter normal ultra-condensed larger/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal bold expanded small-caps xx-large/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal extra-expanded larger/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps normal bolder extra-expanded calc(30% - 40px)/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "italic normal small-caps extra-condensed calc(30% - 40px)/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal 100 larger/calc(120% + 1.2em) Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "extra-expanded normal italic lighter larger/calc(120% + 1.2em) sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps normal oblique xx-large/1.2 sans-serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bolder italic normal small-caps larger/calc(120% + 1.2em) fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal oblique small-caps larger/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal lighter italic ultra-condensed xx-large/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal 100 normal ultra-expanded 20%/1.2 serif" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal italic small-caps condensed 20%/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal italic normal extra-condensed xx-large/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal italic normal xx-large/1.2 fantasy" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "small-caps extra-expanded normal larger/calc(120% + 1.2em) \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bolder condensed normal calc(30% - 40px)/calc(120% + 1.2em) cursive" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal small-caps semi-expanded normal 20%/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded normal xx-large/1.2 \\"FB Armada\\"" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "bolder normal normal calc(30% - 40px)/calc(120% + 1.2em) monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "expanded bolder small-caps xx-large/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "normal normal small-caps condensed xx-large/1.2 monospace" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[e.style['font'\] = "900 expanded normal small-caps xx-large/1.2 Menu" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[font-shorthand-serialization.html]
|
|
||||||
[The font shorthand should be serialized just like any other shorthand.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue