mirror of
https://github.com/servo/servo.git
synced 2025-08-13 01:15:34 +01:00
Auto merge of #20786 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See individual commits for details. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20786) <!-- Reviewable:end -->
This commit is contained in:
commit
b536774fbf
36 changed files with 718 additions and 523 deletions
|
@ -54,7 +54,7 @@ use style::logical_geometry::Direction;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::selector_parser::{PseudoElement, RestyleDamage};
|
use style::selector_parser::{PseudoElement, RestyleDamage};
|
||||||
use style::servo::restyle_damage::ServoRestyleDamage;
|
use style::servo::restyle_damage::ServoRestyleDamage;
|
||||||
use style::values::computed::counters::ContentItem;
|
use style::values::generics::counters::ContentItem;
|
||||||
use style::values::generics::url::UrlOrNone as ImageUrlOrNone;
|
use style::values::generics::url::UrlOrNone as ImageUrlOrNone;
|
||||||
use table::TableFlow;
|
use table::TableFlow;
|
||||||
use table_caption::TableCaptionFlow;
|
use table_caption::TableCaptionFlow;
|
||||||
|
|
|
@ -66,7 +66,7 @@ use style::values::computed::Gradient;
|
||||||
use style::values::computed::effects::SimpleShadow;
|
use style::values::computed::effects::SimpleShadow;
|
||||||
use style::values::generics::background::BackgroundSize;
|
use style::values::generics::background::BackgroundSize;
|
||||||
use style::values::generics::image::{GradientKind, Image, PaintWorklet};
|
use style::values::generics::image::{GradientKind, Image, PaintWorklet};
|
||||||
use style::values::generics::pointing::Cursor;
|
use style::values::generics::ui::Cursor;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use style_traits::cursor::CursorKind;
|
use style_traits::cursor::CursorKind;
|
||||||
|
@ -3012,8 +3012,8 @@ impl ComputedValuesCursorUtility for ComputedValues {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_cursor(&self, default_cursor: CursorKind) -> Option<CursorKind> {
|
fn get_cursor(&self, default_cursor: CursorKind) -> Option<CursorKind> {
|
||||||
match (
|
match (
|
||||||
self.get_pointing().pointer_events,
|
self.get_inheritedui().pointer_events,
|
||||||
&self.get_pointing().cursor,
|
&self.get_inheritedui().cursor,
|
||||||
) {
|
) {
|
||||||
(PointerEvents::None, _) => None,
|
(PointerEvents::None, _) => None,
|
||||||
(PointerEvents::Auto, &Cursor { keyword: CursorKind::Auto, .. }) => Some(default_cursor),
|
(PointerEvents::Auto, &Cursor { keyword: CursorKind::Auto, .. }) => Some(default_cursor),
|
||||||
|
|
|
@ -51,6 +51,8 @@ impl ToLayout for Filter {
|
||||||
GenericFilter::Sepia(amount) => wr::FilterOp::Sepia(amount.0),
|
GenericFilter::Sepia(amount) => wr::FilterOp::Sepia(amount.0),
|
||||||
// Statically check that DropShadow is impossible.
|
// Statically check that DropShadow is impossible.
|
||||||
GenericFilter::DropShadow(ref shadow) => match *shadow {},
|
GenericFilter::DropShadow(ref shadow) => match *shadow {},
|
||||||
|
// Statically check that Url is impossible.
|
||||||
|
GenericFilter::Url(ref url) => match *url {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use style::computed_values::list_style_type::T as ListStyleType;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::selector_parser::RestyleDamage;
|
use style::selector_parser::RestyleDamage;
|
||||||
use style::servo::restyle_damage::ServoRestyleDamage;
|
use style::servo::restyle_damage::ServoRestyleDamage;
|
||||||
use style::values::computed::counters::ContentItem;
|
use style::values::generics::counters::ContentItem;
|
||||||
use text::TextRunScanner;
|
use text::TextRunScanner;
|
||||||
use traversal::InorderFlowTraversal;
|
use traversal::InorderFlowTraversal;
|
||||||
|
|
||||||
|
@ -240,6 +240,9 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
|
||||||
self.traversal.quote -= 1
|
self.traversal.quote -= 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GeneratedContentInfo::ContentItem(ContentItem::Url(..)) => {
|
||||||
|
unreachable!("Servo doesn't parse content: url(..) yet")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@ use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSaf
|
||||||
use script_layout_interface::wrapper_traits::GetLayoutData;
|
use script_layout_interface::wrapper_traits::GetLayoutData;
|
||||||
use style::dom::{NodeInfo, TNode};
|
use style::dom::{NodeInfo, TNode};
|
||||||
use style::selector_parser::RestyleDamage;
|
use style::selector_parser::RestyleDamage;
|
||||||
use style::values::computed::counters::{Content, ContentItem};
|
use style::values::computed::counters::ContentItem;
|
||||||
|
use style::values::generics::counters::Content;
|
||||||
|
|
||||||
pub trait LayoutNodeLayoutData {
|
pub trait LayoutNodeLayoutData {
|
||||||
/// Similar to borrow_data*, but returns the full PersistentLayoutData rather
|
/// Similar to borrow_data*, but returns the full PersistentLayoutData rather
|
||||||
|
@ -113,12 +114,12 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
|
||||||
if self.get_pseudo_element_type().is_replaced_content() {
|
if self.get_pseudo_element_type().is_replaced_content() {
|
||||||
let style = self.as_element().unwrap().resolved_style();
|
let style = self.as_element().unwrap().resolved_style();
|
||||||
|
|
||||||
return match style.as_ref().get_counters().content {
|
return TextContent::GeneratedContent(
|
||||||
Content::Items(ref value) if !value.is_empty() => {
|
match style.as_ref().get_counters().content {
|
||||||
TextContent::GeneratedContent((*value).to_vec())
|
Content::Items(ref value) => value.to_vec(),
|
||||||
|
_ => vec![],
|
||||||
}
|
}
|
||||||
_ => TextContent::GeneratedContent(vec![]),
|
);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextContent::Text(self.node_text_content().into_boxed_str())
|
TextContent::Text(self.node_text_content().into_boxed_str())
|
||||||
|
|
|
@ -145,11 +145,11 @@ impl nsStyleImage {
|
||||||
match image {
|
match image {
|
||||||
GenericImage::Gradient(boxed_gradient) => self.set_gradient(*boxed_gradient),
|
GenericImage::Gradient(boxed_gradient) => self.set_gradient(*boxed_gradient),
|
||||||
GenericImage::Url(ref url) => unsafe {
|
GenericImage::Url(ref url) => unsafe {
|
||||||
bindings::Gecko_SetLayerImageImageValue(self, url.image_value.get());
|
bindings::Gecko_SetLayerImageImageValue(self, url.0.image_value.get());
|
||||||
},
|
},
|
||||||
GenericImage::Rect(ref image_rect) => {
|
GenericImage::Rect(ref image_rect) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::Gecko_SetLayerImageImageValue(self, image_rect.url.image_value.get());
|
bindings::Gecko_SetLayerImageImageValue(self, image_rect.url.0.image_value.get());
|
||||||
bindings::Gecko_InitializeImageCropRect(self);
|
bindings::Gecko_InitializeImageCropRect(self);
|
||||||
|
|
||||||
// Set CropRect
|
// Set CropRect
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use app_units::AU_PER_PX;
|
use app_units::AU_PER_PX;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use cssparser::{BasicParseErrorKind, Parser, Token, RGBA};
|
use cssparser::{BasicParseErrorKind, Parser, RGBA};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use euclid::TypedScale;
|
use euclid::TypedScale;
|
||||||
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||||
|
@ -32,7 +32,7 @@ use stylesheets::Origin;
|
||||||
use values::{serialize_atom_identifier, CSSFloat, CustomIdent, KeyframesName};
|
use values::{serialize_atom_identifier, CSSFloat, CustomIdent, KeyframesName};
|
||||||
use values::computed::{self, ToComputedValue};
|
use values::computed::{self, ToComputedValue};
|
||||||
use values::computed::font::FontSize;
|
use values::computed::font::FontSize;
|
||||||
use values::specified::{Integer, Length, Number};
|
use values::specified::{Integer, Length, Number, Resolution};
|
||||||
|
|
||||||
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
||||||
/// and contains all the viewport rule state.
|
/// and contains all the viewport rule state.
|
||||||
|
@ -286,53 +286,6 @@ impl PartialEq for Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A resolution.
|
|
||||||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
|
||||||
pub enum Resolution {
|
|
||||||
/// Dots per inch.
|
|
||||||
#[css(dimension)]
|
|
||||||
Dpi(CSSFloat),
|
|
||||||
/// Dots per pixel.
|
|
||||||
#[css(dimension)]
|
|
||||||
Dppx(CSSFloat),
|
|
||||||
/// Dots per centimeter.
|
|
||||||
#[css(dimension)]
|
|
||||||
Dpcm(CSSFloat),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Resolution {
|
|
||||||
fn to_dpi(&self) -> CSSFloat {
|
|
||||||
match *self {
|
|
||||||
Resolution::Dpi(f) => f,
|
|
||||||
Resolution::Dppx(f) => f * 96.0,
|
|
||||||
Resolution::Dpcm(f) => f * 2.54,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
|
||||||
let location = input.current_source_location();
|
|
||||||
let (value, unit) = match *input.next()? {
|
|
||||||
Token::Dimension {
|
|
||||||
value, ref unit, ..
|
|
||||||
} => (value, unit),
|
|
||||||
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
|
||||||
};
|
|
||||||
|
|
||||||
if value <= 0. {
|
|
||||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
|
||||||
}
|
|
||||||
|
|
||||||
(match_ignore_ascii_case! { &unit,
|
|
||||||
"dpi" => Ok(Resolution::Dpi(value)),
|
|
||||||
"dppx" => Ok(Resolution::Dppx(value)),
|
|
||||||
"dpcm" => Ok(Resolution::Dpcm(value)),
|
|
||||||
_ => Err(())
|
|
||||||
}).map_err(|()| {
|
|
||||||
location.new_custom_error(StyleParseErrorKind::UnexpectedDimension(unit.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A value found or expected in a media expression.
|
/// A value found or expected in a media expression.
|
||||||
///
|
///
|
||||||
/// FIXME(emilio): How should calc() serialize in the Number / Integer /
|
/// FIXME(emilio): How should calc() serialize in the Number / Integer /
|
||||||
|
@ -535,7 +488,7 @@ fn parse_feature_value<'i, 't>(
|
||||||
MediaExpressionValue::IntRatio(a.value() as u32, b.value() as u32)
|
MediaExpressionValue::IntRatio(a.value() as u32, b.value() as u32)
|
||||||
},
|
},
|
||||||
nsMediaFeature_ValueType::eResolution => {
|
nsMediaFeature_ValueType::eResolution => {
|
||||||
MediaExpressionValue::Resolution(Resolution::parse(input)?)
|
MediaExpressionValue::Resolution(Resolution::parse(context, input)?)
|
||||||
},
|
},
|
||||||
nsMediaFeature_ValueType::eEnumerated => {
|
nsMediaFeature_ValueType::eEnumerated => {
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
|
|
|
@ -216,11 +216,7 @@ impl PseudoElement {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs an atom from a string of text, and whether we're in a
|
/// Constructs a pseudo-element from a string of text.
|
||||||
/// user-agent stylesheet.
|
|
||||||
///
|
|
||||||
/// If we're not in a user-agent stylesheet, we will never parse anonymous
|
|
||||||
/// box pseudo-elements.
|
|
||||||
///
|
///
|
||||||
/// Returns `None` if the pseudo-element is not recognised.
|
/// Returns `None` if the pseudo-element is not recognised.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -234,6 +230,10 @@ impl PseudoElement {
|
||||||
return Some(${pseudo_element_variant(pseudo)})
|
return Some(${pseudo_element_variant(pseudo)})
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
|
// Alias "-moz-selection" to "selection" at parse time.
|
||||||
|
"-moz-selection" => {
|
||||||
|
return Some(PseudoElement::Selection);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// FIXME: -moz-tree check should probably be
|
// FIXME: -moz-tree check should probably be
|
||||||
// ascii-case-insensitive.
|
// ascii-case-insensitive.
|
||||||
|
|
|
@ -12,10 +12,13 @@ use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
|
||||||
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
|
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
|
||||||
use gecko_bindings::sugar::refptr::RefPtr;
|
use gecko_bindings::sugar::refptr::RefPtr;
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
use nsstring::nsCString;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use servo_arc::{Arc, RawOffsetArc};
|
use servo_arc::{Arc, RawOffsetArc};
|
||||||
|
use std::fmt::{self, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style_traits::ParseError;
|
use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
|
use values::computed::{Context, ToComputedValue};
|
||||||
|
|
||||||
/// A CSS url() value for gecko.
|
/// A CSS url() value for gecko.
|
||||||
#[css(function = "url")]
|
#[css(function = "url")]
|
||||||
|
@ -70,10 +73,8 @@ impl CssUrl {
|
||||||
self.as_str().chars().next().map_or(false, |c| c == '#')
|
self.as_str().chars().next().map_or(false, |c| c == '#')
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the resolved url as string, or the empty string if it's invalid.
|
/// Return the unresolved url as string, or the empty string if it's
|
||||||
///
|
/// invalid.
|
||||||
/// FIXME(bholley): This returns the unresolved URL while the servo version
|
|
||||||
/// returns the resolved URL.
|
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
&*self.serialization
|
&*self.serialization
|
||||||
}
|
}
|
||||||
|
@ -121,7 +122,7 @@ impl MallocSizeOf for CssUrl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A specified url() value for general usage.
|
/// A specified url() value for general usage.
|
||||||
#[derive(Clone, Debug, SpecifiedValueInfo, ToComputedValue, ToCss)]
|
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
|
||||||
pub struct SpecifiedUrl {
|
pub struct SpecifiedUrl {
|
||||||
/// The specified url value.
|
/// The specified url value.
|
||||||
pub url: CssUrl,
|
pub url: CssUrl,
|
||||||
|
@ -139,15 +140,11 @@ impl SpecifiedUrl {
|
||||||
debug_assert!(!ptr.is_null());
|
debug_assert!(!ptr.is_null());
|
||||||
RefPtr::from_addrefed(ptr)
|
RefPtr::from_addrefed(ptr)
|
||||||
};
|
};
|
||||||
SpecifiedUrl { url, url_value }
|
Self { url, url_value }
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert from URLValueData to SpecifiedUrl.
|
|
||||||
pub unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
|
|
||||||
CssUrl::from_url_value_data(url).map(Self::from_css_url)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for SpecifiedUrl {
|
impl PartialEq for SpecifiedUrl {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.url.eq(&other.url)
|
self.url.eq(&other.url)
|
||||||
|
@ -179,7 +176,7 @@ impl MallocSizeOf for SpecifiedUrl {
|
||||||
/// A specified url() value for image.
|
/// A specified url() value for image.
|
||||||
///
|
///
|
||||||
/// This exists so that we can construct `ImageValue` and reuse it.
|
/// This exists so that we can construct `ImageValue` and reuse it.
|
||||||
#[derive(Clone, Debug, SpecifiedValueInfo, ToComputedValue, ToCss)]
|
#[derive(Clone, Debug, SpecifiedValueInfo, ToCss)]
|
||||||
pub struct SpecifiedImageUrl {
|
pub struct SpecifiedImageUrl {
|
||||||
/// The specified url value.
|
/// The specified url value.
|
||||||
pub url: CssUrl,
|
pub url: CssUrl,
|
||||||
|
@ -190,16 +187,6 @@ pub struct SpecifiedImageUrl {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpecifiedImageUrl {
|
impl SpecifiedImageUrl {
|
||||||
fn from_css_url(url: CssUrl) -> Self {
|
|
||||||
let image_value = unsafe {
|
|
||||||
let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi());
|
|
||||||
// We do not expect Gecko_ImageValue_Create returns null.
|
|
||||||
debug_assert!(!ptr.is_null());
|
|
||||||
RefPtr::from_addrefed(ptr)
|
|
||||||
};
|
|
||||||
SpecifiedImageUrl { url, image_value }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse a URL from a string value. See SpecifiedUrl::parse_from_string.
|
/// Parse a URL from a string value. See SpecifiedUrl::parse_from_string.
|
||||||
pub fn parse_from_string<'a>(
|
pub fn parse_from_string<'a>(
|
||||||
url: String,
|
url: String,
|
||||||
|
@ -208,20 +195,14 @@ impl SpecifiedImageUrl {
|
||||||
CssUrl::parse_from_string(url, context).map(Self::from_css_url)
|
CssUrl::parse_from_string(url, context).map(Self::from_css_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert from URLValueData to SpecifiedUrl.
|
fn from_css_url(url: CssUrl) -> Self {
|
||||||
pub unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
|
let image_value = unsafe {
|
||||||
CssUrl::from_url_value_data(url).map(Self::from_css_url)
|
let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi());
|
||||||
}
|
// We do not expect Gecko_ImageValue_Create returns null.
|
||||||
|
debug_assert!(!ptr.is_null());
|
||||||
/// Convert from nsStyleImageRequest to SpecifiedUrl.
|
RefPtr::from_addrefed(ptr)
|
||||||
pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Result<Self, ()> {
|
};
|
||||||
if image_request.mImageValue.mRawPtr.is_null() {
|
Self { url, image_value }
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let image_value = image_request.mImageValue.mRawPtr.as_ref().unwrap();
|
|
||||||
let url_value_data = &image_value._base;
|
|
||||||
Self::from_url_value_data(url_value_data)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +234,104 @@ impl MallocSizeOf for SpecifiedImageUrl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for SpecifiedUrl {
|
||||||
|
type ComputedValue = ComputedUrl;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
|
||||||
|
ComputedUrl(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
computed.0.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for SpecifiedImageUrl {
|
||||||
|
type ComputedValue = ComputedImageUrl;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
|
||||||
|
ComputedImageUrl(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
computed.0.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_computed_url<W>(
|
||||||
|
url_value_data: &URLValueData,
|
||||||
|
dest: &mut CssWriter<W>,
|
||||||
|
) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
dest.write_str("url(")?;
|
||||||
|
unsafe {
|
||||||
|
let mut string = nsCString::new();
|
||||||
|
bindings::Gecko_GetComputedURLSpec(url_value_data, &mut string);
|
||||||
|
string.as_str_unchecked().to_css(dest)?;
|
||||||
|
}
|
||||||
|
dest.write_char(')')
|
||||||
|
}
|
||||||
|
|
||||||
/// The computed value of a CSS `url()`.
|
/// The computed value of a CSS `url()`.
|
||||||
pub type ComputedUrl = SpecifiedUrl;
|
///
|
||||||
|
/// The only difference between specified and computed URLs is the
|
||||||
|
/// serialization.
|
||||||
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
|
||||||
|
pub struct ComputedUrl(pub SpecifiedUrl);
|
||||||
|
|
||||||
|
impl ToCss for ComputedUrl {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write
|
||||||
|
{
|
||||||
|
serialize_computed_url(&self.0.url_value._base, dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComputedUrl {
|
||||||
|
/// Convert from URLValueData to ComputedUrl.
|
||||||
|
pub unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
|
||||||
|
Ok(ComputedUrl(
|
||||||
|
SpecifiedUrl::from_css_url(CssUrl::from_url_value_data(url)?)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The computed value of a CSS `url()` for image.
|
/// The computed value of a CSS `url()` for image.
|
||||||
pub type ComputedImageUrl = SpecifiedImageUrl;
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
|
||||||
|
pub struct ComputedImageUrl(pub SpecifiedImageUrl);
|
||||||
|
|
||||||
|
impl ToCss for ComputedImageUrl {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write
|
||||||
|
{
|
||||||
|
serialize_computed_url(&self.0.image_value._base, dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComputedImageUrl {
|
||||||
|
/// Convert from URLValueData to SpecifiedUrl.
|
||||||
|
pub unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
|
||||||
|
Ok(ComputedImageUrl(
|
||||||
|
SpecifiedImageUrl::from_css_url(CssUrl::from_url_value_data(url)?)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert from nsStyleImageReques to ComputedImageUrl.
|
||||||
|
pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Result<Self, ()> {
|
||||||
|
if image_request.mImageValue.mRawPtr.is_null() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let image_value = image_request.mImageValue.mRawPtr.as_ref().unwrap();
|
||||||
|
let url_value_data = &image_value._base;
|
||||||
|
Self::from_url_value_data(url_value_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||||
use gecko_bindings::structs::{nscolor, StyleComplexColor};
|
use gecko_bindings::structs::{nscolor, StyleComplexColor};
|
||||||
use values::computed::Color as ComputedColor;
|
use values::computed::Color as ComputedColor;
|
||||||
use values::generics::pointing::CaretColor;
|
use values::generics::ui::CaretColor;
|
||||||
|
|
||||||
impl From<nscolor> for StyleComplexColor {
|
impl From<nscolor> for StyleComplexColor {
|
||||||
fn from(other: nscolor) -> Self {
|
fn from(other: nscolor) -> Self {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
PHYSICAL_SIDES = ["top", "left", "bottom", "right"]
|
PHYSICAL_SIDES = ["top", "right", "bottom", "left"]
|
||||||
LOGICAL_SIDES = ["block-start", "block-end", "inline-start", "inline-end"]
|
LOGICAL_SIDES = ["block-start", "block-end", "inline-start", "inline-end"]
|
||||||
PHYSICAL_SIZES = ["width", "height"]
|
PHYSICAL_SIZES = ["width", "height"]
|
||||||
LOGICAL_SIZES = ["block-size", "inline-size"]
|
LOGICAL_SIZES = ["block-size", "inline-size"]
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
%>
|
%>
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
|
use Atom;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use custom_properties::CustomPropertiesMap;
|
use custom_properties::CustomPropertiesMap;
|
||||||
use gecko_bindings::bindings;
|
use gecko_bindings::bindings;
|
||||||
|
@ -60,7 +61,7 @@ use std::mem::{forget, uninitialized, transmute, zeroed};
|
||||||
use std::{cmp, ops, ptr};
|
use std::{cmp, ops, ptr};
|
||||||
use values::{self, CustomIdent, Either, KeyframesName, None_};
|
use values::{self, CustomIdent, Either, KeyframesName, None_};
|
||||||
use values::computed::{NonNegativeLength, ToComputedValue, Percentage};
|
use values::computed::{NonNegativeLength, ToComputedValue, Percentage};
|
||||||
use values::computed::font::{FontSize, SingleFontFamily};
|
use values::computed::font::FontSize;
|
||||||
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
use values::computed::outline::OutlineStyle;
|
use values::computed::outline::OutlineStyle;
|
||||||
use values::generics::column::ColumnCount;
|
use values::generics::column::ColumnCount;
|
||||||
|
@ -126,8 +127,6 @@ impl ComputedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pseudo(&self) -> Option<PseudoElement> {
|
pub fn pseudo(&self) -> Option<PseudoElement> {
|
||||||
use string_cache::Atom;
|
|
||||||
|
|
||||||
let atom = (self.0).mPseudoTag.mRawPtr;
|
let atom = (self.0).mPseudoTag.mRawPtr;
|
||||||
if atom.is_null() {
|
if atom.is_null() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -698,7 +697,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
}
|
}
|
||||||
SVGPaintKind::PaintServer(url) => {
|
SVGPaintKind::PaintServer(url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.url_value.get());
|
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.0.url_value.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SVGPaintKind::Color(color) => {
|
SVGPaintKind::Color(color) => {
|
||||||
|
@ -738,8 +737,8 @@ def set_gecko_property(ffi_name, expr):
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||||
|
use values::computed::url::ComputedUrl;
|
||||||
use values::generics::svg::{SVGPaint, SVGPaintKind};
|
use values::generics::svg::{SVGPaint, SVGPaintKind};
|
||||||
use values::specified::url::SpecifiedUrl;
|
|
||||||
use self::structs::nsStyleSVGPaintType;
|
use self::structs::nsStyleSVGPaintType;
|
||||||
use self::structs::nsStyleSVGFallbackType;
|
use self::structs::nsStyleSVGFallbackType;
|
||||||
let ref paint = ${get_gecko_property(gecko_ffi_name)};
|
let ref paint = ${get_gecko_property(gecko_ffi_name)};
|
||||||
|
@ -761,7 +760,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
nsStyleSVGPaintType::eStyleSVGPaintType_Server => {
|
nsStyleSVGPaintType::eStyleSVGPaintType_Server => {
|
||||||
unsafe {
|
unsafe {
|
||||||
SVGPaintKind::PaintServer(
|
SVGPaintKind::PaintServer(
|
||||||
SpecifiedUrl::from_url_value_data(
|
ComputedUrl::from_url_value_data(
|
||||||
&(**paint.mPaint.mPaintServer.as_ref())._base
|
&(**paint.mPaint.mPaintServer.as_ref())._base
|
||||||
).unwrap()
|
).unwrap()
|
||||||
)
|
)
|
||||||
|
@ -940,7 +939,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
match v {
|
match v {
|
||||||
UrlOrNone::Url(ref url) => {
|
UrlOrNone::Url(ref url) => {
|
||||||
self.gecko.${gecko_ffi_name}.set_move(url.url_value.clone())
|
self.gecko.${gecko_ffi_name}.set_move(url.0.url_value.clone())
|
||||||
}
|
}
|
||||||
UrlOrNone::None => {
|
UrlOrNone::None => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -962,16 +961,18 @@ def set_gecko_property(ffi_name, expr):
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||||
use values::specified::url::SpecifiedUrl;
|
use values::computed::url::ComputedUrl;
|
||||||
|
|
||||||
if self.gecko.${gecko_ffi_name}.mRawPtr.is_null() {
|
if self.gecko.${gecko_ffi_name}.mRawPtr.is_null() {
|
||||||
UrlOrNone::none()
|
return UrlOrNone::none()
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
let ref gecko_url_value = *self.gecko.${gecko_ffi_name}.mRawPtr;
|
|
||||||
UrlOrNone::Url(SpecifiedUrl::from_url_value_data(&gecko_url_value._base)
|
|
||||||
.expect("${gecko_ffi_name} could not convert to SpecifiedUrl"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let gecko_url_value = &*self.gecko.${gecko_ffi_name}.mRawPtr;
|
||||||
|
UrlOrNone::Url(
|
||||||
|
ComputedUrl::from_url_value_data(&gecko_url_value._base)
|
||||||
|
.expect("${gecko_ffi_name} could not convert to ComputedUrl")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
@ -1861,7 +1862,6 @@ fn static_assert() {
|
||||||
|
|
||||||
pub fn clone_${value.name}(&self) -> longhands::${value.name}::computed_value::T {
|
pub fn clone_${value.name}(&self) -> longhands::${value.name}::computed_value::T {
|
||||||
use gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
|
use gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
|
||||||
use string_cache::Atom;
|
|
||||||
|
|
||||||
longhands::${value.name}::computed_value::T {
|
longhands::${value.name}::computed_value::T {
|
||||||
is_span: self.gecko.${value.gecko}.mHasSpan,
|
is_span: self.gecko.${value.gecko}.mHasSpan,
|
||||||
|
@ -2034,7 +2034,6 @@ fn static_assert() {
|
||||||
|
|
||||||
pub fn clone_grid_template_${kind}(&self) -> longhands::grid_template_${kind}::computed_value::T {
|
pub fn clone_grid_template_${kind}(&self) -> longhands::grid_template_${kind}::computed_value::T {
|
||||||
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
|
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
|
||||||
use Atom;
|
|
||||||
use gecko_bindings::structs::nsTArray;
|
use gecko_bindings::structs::nsTArray;
|
||||||
use nsstring::nsStringRepr;
|
use nsstring::nsStringRepr;
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
|
@ -2309,14 +2308,6 @@ fn static_assert() {
|
||||||
self.gecko.mFont.fontlist.mFontlist.mBasePtr.set_move((v.0).0.clone());
|
self.gecko.mFont.fontlist.mFontlist.mBasePtr.set_move((v.0).0.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn font_family_count(&self) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn font_family_at(&self, _: usize) -> SingleFontFamily {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_font_family_from(&mut self, other: &Self) {
|
pub fn copy_font_family_from(&mut self, other: &Self) {
|
||||||
unsafe { Gecko_CopyFontFamilyFrom(&mut self.gecko.mFont, &other.gecko.mFont); }
|
unsafe { Gecko_CopyFontFamilyFrom(&mut self.gecko.mFont, &other.gecko.mFont); }
|
||||||
self.gecko.mGenericID = other.gecko.mGenericID;
|
self.gecko.mGenericID = other.gecko.mGenericID;
|
||||||
|
@ -2335,14 +2326,25 @@ fn static_assert() {
|
||||||
let shared_fontlist = unsafe { fontlist.mFontlist.mBasePtr.to_safe() };
|
let shared_fontlist = unsafe { fontlist.mFontlist.mBasePtr.to_safe() };
|
||||||
|
|
||||||
if shared_fontlist.mNames.is_empty() {
|
if shared_fontlist.mNames.is_empty() {
|
||||||
let default = match fontlist.mDefaultFontType {
|
let default = fontlist.mDefaultFontType;
|
||||||
|
let default = match default {
|
||||||
FontFamilyType::eFamily_serif => {
|
FontFamilyType::eFamily_serif => {
|
||||||
SingleFontFamily::Generic(atom!("serif"))
|
SingleFontFamily::Generic(atom!("serif"))
|
||||||
}
|
}
|
||||||
FontFamilyType::eFamily_sans_serif => {
|
_ => {
|
||||||
|
// This can break with some combinations of user prefs, see
|
||||||
|
// bug 1442195 for example. It doesn't really matter in this
|
||||||
|
// case...
|
||||||
|
//
|
||||||
|
// FIXME(emilio): Probably should be storing the whole
|
||||||
|
// default font name instead though.
|
||||||
|
debug_assert_eq!(
|
||||||
|
default,
|
||||||
|
FontFamilyType::eFamily_sans_serif,
|
||||||
|
"Default generic should be serif or sans-serif"
|
||||||
|
);
|
||||||
SingleFontFamily::Generic(atom!("sans-serif"))
|
SingleFontFamily::Generic(atom!("sans-serif"))
|
||||||
}
|
}
|
||||||
_ => panic!("Default generic must be serif or sans-serif"),
|
|
||||||
};
|
};
|
||||||
FontFamily(FontFamilyList::new(Box::new([default])))
|
FontFamily(FontFamilyList::new(Box::new([default])))
|
||||||
} else {
|
} else {
|
||||||
|
@ -2683,6 +2685,18 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn reset__x_lang(&mut self, other: &Self) {
|
||||||
|
self.copy__x_lang_from(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn clone__x_lang(&self) -> longhands::_x_lang::computed_value::T {
|
||||||
|
longhands::_x_lang::computed_value::T(unsafe {
|
||||||
|
Atom::from_raw(self.gecko.mLanguage.mRawPtr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set__x_text_zoom(&mut self, v: longhands::_x_text_zoom::computed_value::T) {
|
pub fn set__x_text_zoom(&mut self, v: longhands::_x_text_zoom::computed_value::T) {
|
||||||
self.gecko.mAllowZoom = v.0;
|
self.gecko.mAllowZoom = v.0;
|
||||||
|
@ -2699,8 +2713,8 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn reset__x_lang(&mut self, other: &Self) {
|
pub fn clone__x_text_zoom(&self) -> longhands::_x_text_zoom::computed_value::T {
|
||||||
self.copy__x_lang_from(other)
|
longhands::_x_text_zoom::computed_value::T(self.gecko.mAllowZoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
${impl_simple("_moz_script_level", "mScriptLevel")}
|
${impl_simple("_moz_script_level", "mScriptLevel")}
|
||||||
|
@ -2777,7 +2791,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_font_variant_alternates(&self) -> values::computed::font::FontVariantAlternates {
|
pub fn clone_font_variant_alternates(&self) -> values::computed::font::FontVariantAlternates {
|
||||||
use Atom;
|
|
||||||
% for value in "normal swash stylistic ornaments annotation styleset character_variant historical".split():
|
% for value in "normal swash stylistic ornaments annotation styleset character_variant historical".split():
|
||||||
use gecko_bindings::structs::NS_FONT_VARIANT_ALTERNATES_${value.upper()};
|
use gecko_bindings::structs::NS_FONT_VARIANT_ALTERNATES_${value.upper()};
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -2833,6 +2846,13 @@ fn static_assert() {
|
||||||
${impl_simple_type_with_conversion("font_variant_east_asian", "mFont.variantEastAsian")}
|
${impl_simple_type_with_conversion("font_variant_east_asian", "mFont.variantEastAsian")}
|
||||||
${impl_simple_type_with_conversion("font_variant_numeric", "mFont.variantNumeric")}
|
${impl_simple_type_with_conversion("font_variant_numeric", "mFont.variantNumeric")}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn clone__moz_min_font_size_ratio(
|
||||||
|
&self,
|
||||||
|
) -> longhands::_moz_min_font_size_ratio::computed_value::T {
|
||||||
|
Percentage(self.gecko.mMinFontSizeRatio as f32 / 100.)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set__moz_min_font_size_ratio(&mut self, v: longhands::_moz_min_font_size_ratio::computed_value::T) {
|
pub fn set__moz_min_font_size_ratio(&mut self, v: longhands::_moz_min_font_size_ratio::computed_value::T) {
|
||||||
let scaled = v.0 * 100.;
|
let scaled = v.0 * 100.;
|
||||||
|
@ -3286,7 +3306,6 @@ fn static_assert() {
|
||||||
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_no_properties;
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_no_properties;
|
||||||
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_variable;
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_variable;
|
||||||
use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN;
|
use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN;
|
||||||
use Atom;
|
|
||||||
|
|
||||||
let property = self.gecko.mTransitions[index].mProperty;
|
let property = self.gecko.mTransitions[index].mProperty;
|
||||||
if property == eCSSProperty_UNKNOWN || property == eCSSPropertyExtra_variable {
|
if property == eCSSProperty_UNKNOWN || property == eCSSPropertyExtra_variable {
|
||||||
|
@ -3384,7 +3403,6 @@ fn static_assert() {
|
||||||
pub fn animation_name_at(&self, index: usize)
|
pub fn animation_name_at(&self, index: usize)
|
||||||
-> longhands::animation_name::computed_value::SingleComputedValue {
|
-> longhands::animation_name::computed_value::SingleComputedValue {
|
||||||
use properties::longhands::animation_name::single_value::SpecifiedValue as AnimationName;
|
use properties::longhands::animation_name::single_value::SpecifiedValue as AnimationName;
|
||||||
use Atom;
|
|
||||||
|
|
||||||
let atom = self.gecko.mAnimations[index].mName.mRawPtr;
|
let atom = self.gecko.mAnimations[index].mName.mRawPtr;
|
||||||
if atom == atom!("").as_ptr() {
|
if atom == atom!("").as_ptr() {
|
||||||
|
@ -3590,7 +3608,6 @@ fn static_assert() {
|
||||||
use properties::longhands::will_change::computed_value::T;
|
use properties::longhands::will_change::computed_value::T;
|
||||||
use gecko_bindings::structs::nsAtom;
|
use gecko_bindings::structs::nsAtom;
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
use Atom;
|
|
||||||
|
|
||||||
if self.gecko.mWillChange.len() == 0 {
|
if self.gecko.mWillChange.len() == 0 {
|
||||||
return T::Auto
|
return T::Auto
|
||||||
|
@ -4106,12 +4123,8 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
UrlOrNone::Url(ref url) => {
|
UrlOrNone::Url(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetListStyleImageImageValue(&mut self.gecko, url.image_value.get());
|
Gecko_SetListStyleImageImageValue(&mut self.gecko, url.0.image_value.get());
|
||||||
}
|
}
|
||||||
// We don't need to record this struct as uncacheable, like when setting
|
|
||||||
// background-image to a url() value, since only properties in reset structs
|
|
||||||
// are re-used from the applicable declaration cache, and the List struct
|
|
||||||
// is an inherited struct.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4125,7 +4138,7 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_list_style_image(&self) -> longhands::list_style_image::computed_value::T {
|
pub fn clone_list_style_image(&self) -> longhands::list_style_image::computed_value::T {
|
||||||
use values::specified::url::SpecifiedImageUrl;
|
use values::computed::url::ComputedImageUrl;
|
||||||
|
|
||||||
if self.gecko.mListStyleImage.mRawPtr.is_null() {
|
if self.gecko.mListStyleImage.mRawPtr.is_null() {
|
||||||
return UrlOrNone::None;
|
return UrlOrNone::None;
|
||||||
|
@ -4133,8 +4146,9 @@ fn static_assert() {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ref gecko_image_request = *self.gecko.mListStyleImage.mRawPtr;
|
let ref gecko_image_request = *self.gecko.mListStyleImage.mRawPtr;
|
||||||
UrlOrNone::Url(SpecifiedImageUrl::from_image_request(gecko_image_request)
|
UrlOrNone::Url(ComputedImageUrl::from_image_request(
|
||||||
.expect("mListStyleImage could not convert to SpecifiedImageUrl"))
|
gecko_image_request
|
||||||
|
).expect("mListStyleImage could not convert to ComputedImageUrl"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4269,6 +4283,13 @@ fn static_assert() {
|
||||||
self.gecko.mSpan = v.0
|
self.gecko.mSpan = v.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn clone__x_span(&self) -> longhands::_x_span::computed_value::T {
|
||||||
|
longhands::_x_span::computed_value::T(
|
||||||
|
self.gecko.mSpan
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
${impl_simple_copy('_x_span', 'mSpan')}
|
${impl_simple_copy('_x_span', 'mSpan')}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
|
@ -4473,7 +4494,7 @@ fn static_assert() {
|
||||||
},
|
},
|
||||||
Url(ref url) => {
|
Url(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url.url_value.get());
|
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url.0.url_value.get());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -4492,7 +4513,7 @@ fn static_assert() {
|
||||||
|
|
||||||
pub fn clone_filter(&self) -> longhands::filter::computed_value::T {
|
pub fn clone_filter(&self) -> longhands::filter::computed_value::T {
|
||||||
use values::generics::effects::Filter;
|
use values::generics::effects::Filter;
|
||||||
use values::specified::url::SpecifiedUrl;
|
use values::computed::url::ComputedUrl;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
use gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS;
|
use gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_CONTRAST;
|
use gecko_bindings::structs::NS_STYLE_FILTER_CONTRAST;
|
||||||
|
@ -4534,7 +4555,7 @@ fn static_assert() {
|
||||||
NS_STYLE_FILTER_URL => {
|
NS_STYLE_FILTER_URL => {
|
||||||
filters.push(unsafe {
|
filters.push(unsafe {
|
||||||
Filter::Url(
|
Filter::Url(
|
||||||
SpecifiedUrl::from_url_value_data(&(**filter.__bindgen_anon_1.mURL.as_ref())._base).unwrap()
|
ComputedUrl::from_url_value_data(&(**filter.__bindgen_anon_1.mURL.as_ref())._base).unwrap()
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5000,7 +5021,7 @@ fn static_assert() {
|
||||||
% if ident == "clip_path":
|
% if ident == "clip_path":
|
||||||
ShapeSource::ImageOrUrl(ref url) => {
|
ShapeSource::ImageOrUrl(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::Gecko_StyleShapeSource_SetURLValue(${ident}, url.url_value.get())
|
bindings::Gecko_StyleShapeSource_SetURLValue(${ident}, url.0.url_value.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% elif ident == "shape_outside":
|
% elif ident == "shape_outside":
|
||||||
|
@ -5213,9 +5234,27 @@ clip-path
|
||||||
SVGStrokeDashArray::Values(vec)
|
SVGStrokeDashArray::Values(vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn _moz_context_properties_count(&self) -> usize {
|
||||||
|
self.gecko.mContextProps.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn _moz_context_properties_at(
|
||||||
|
&self,
|
||||||
|
index: usize,
|
||||||
|
) -> longhands::_moz_context_properties::computed_value::single_value::T {
|
||||||
|
longhands::_moz_context_properties::computed_value::single_value::T(
|
||||||
|
CustomIdent(unsafe {
|
||||||
|
Atom::from_raw(self.gecko.mContextProps[index].mRawPtr)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set__moz_context_properties<I>(&mut self, v: I)
|
pub fn set__moz_context_properties<I>(&mut self, v: I)
|
||||||
where I: IntoIterator<Item = longhands::_moz_context_properties::computed_value::single_value::T>,
|
where
|
||||||
|
I: IntoIterator<Item = longhands::_moz_context_properties::computed_value::single_value::T>,
|
||||||
I::IntoIter: ExactSizeIterator
|
I::IntoIter: ExactSizeIterator
|
||||||
{
|
{
|
||||||
let v = v.into_iter();
|
let v = v.into_iter();
|
||||||
|
@ -5266,7 +5305,7 @@ clip-path
|
||||||
}
|
}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Pointing"
|
<%self:impl_trait style_struct_name="InheritedUI"
|
||||||
skip_longhands="cursor caret-color">
|
skip_longhands="cursor caret-color">
|
||||||
pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
|
pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
|
||||||
use style_traits::cursor::CursorKind;
|
use style_traits::cursor::CursorKind;
|
||||||
|
@ -5322,15 +5361,10 @@ clip-path
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetCursorImageValue(
|
Gecko_SetCursorImageValue(
|
||||||
&mut self.gecko.mCursorImages[i],
|
&mut self.gecko.mCursorImages[i],
|
||||||
v.images[i].url.image_value.get(),
|
v.images[i].url.0.image_value.get(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need to record this struct as uncacheable, like when setting
|
|
||||||
// background-image to a url() value, since only properties in reset structs
|
|
||||||
// are re-used from the applicable declaration cache, and the Pointing struct
|
|
||||||
// is an inherited struct.
|
|
||||||
|
|
||||||
match v.images[i].hotspot {
|
match v.images[i].hotspot {
|
||||||
Some((x, y)) => {
|
Some((x, y)) => {
|
||||||
self.gecko.mCursorImages[i].mHaveHotspot = true;
|
self.gecko.mCursorImages[i].mHaveHotspot = true;
|
||||||
|
@ -5356,9 +5390,9 @@ clip-path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T {
|
pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T {
|
||||||
use values::computed::pointing::CursorImage;
|
use values::computed::ui::CursorImage;
|
||||||
|
use values::computed::url::ComputedImageUrl;
|
||||||
use style_traits::cursor::CursorKind;
|
use style_traits::cursor::CursorKind;
|
||||||
use values::specified::url::SpecifiedImageUrl;
|
|
||||||
|
|
||||||
let keyword = match self.gecko.mCursor as u32 {
|
let keyword = match self.gecko.mCursor as u32 {
|
||||||
structs::NS_STYLE_CURSOR_AUTO => CursorKind::Auto,
|
structs::NS_STYLE_CURSOR_AUTO => CursorKind::Auto,
|
||||||
|
@ -5403,8 +5437,8 @@ clip-path
|
||||||
let images = self.gecko.mCursorImages.iter().map(|gecko_cursor_image| {
|
let images = self.gecko.mCursorImages.iter().map(|gecko_cursor_image| {
|
||||||
let url = unsafe {
|
let url = unsafe {
|
||||||
let gecko_image_request = gecko_cursor_image.mImage.mRawPtr.as_ref().unwrap();
|
let gecko_image_request = gecko_cursor_image.mImage.mRawPtr.as_ref().unwrap();
|
||||||
SpecifiedImageUrl::from_image_request(&gecko_image_request)
|
ComputedImageUrl::from_image_request(&gecko_image_request)
|
||||||
.expect("mCursorImages.mImage could not convert to SpecifiedImageUrl")
|
.expect("mCursorImages.mImage could not convert to ComputedImageUrl")
|
||||||
};
|
};
|
||||||
|
|
||||||
let hotspot =
|
let hotspot =
|
||||||
|
@ -5463,7 +5497,7 @@ clip-path
|
||||||
|
|
||||||
pub fn set_content(&mut self, v: longhands::content::computed_value::T, device: &Device) {
|
pub fn set_content(&mut self, v: longhands::content::computed_value::T, device: &Device) {
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
use values::computed::counters::{Content, ContentItem};
|
use values::generics::counters::{Content, ContentItem};
|
||||||
use values::generics::CounterStyleOrNone;
|
use values::generics::CounterStyleOrNone;
|
||||||
use gecko_bindings::structs::nsStyleContentData;
|
use gecko_bindings::structs::nsStyleContentData;
|
||||||
use gecko_bindings::structs::nsStyleContentAttr;
|
use gecko_bindings::structs::nsStyleContentAttr;
|
||||||
|
@ -5590,7 +5624,7 @@ clip-path
|
||||||
unsafe {
|
unsafe {
|
||||||
bindings::Gecko_SetContentDataImageValue(
|
bindings::Gecko_SetContentDataImageValue(
|
||||||
&mut self.gecko.mContents[i],
|
&mut self.gecko.mContents[i],
|
||||||
url.image_value.get(),
|
url.0.image_value.get(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5615,10 +5649,10 @@ clip-path
|
||||||
use {Atom, Namespace};
|
use {Atom, Namespace};
|
||||||
use gecko::conversions::string_from_chars_pointer;
|
use gecko::conversions::string_from_chars_pointer;
|
||||||
use gecko_bindings::structs::nsStyleContentType::*;
|
use gecko_bindings::structs::nsStyleContentType::*;
|
||||||
use values::computed::counters::{Content, ContentItem};
|
use values::generics::counters::{Content, ContentItem};
|
||||||
|
use values::computed::url::ComputedImageUrl;
|
||||||
use values::{CustomIdent, Either};
|
use values::{CustomIdent, Either};
|
||||||
use values::generics::CounterStyleOrNone;
|
use values::generics::CounterStyleOrNone;
|
||||||
use values::specified::url::SpecifiedImageUrl;
|
|
||||||
use values::specified::Attr;
|
use values::specified::Attr;
|
||||||
|
|
||||||
if self.gecko.mContents.is_empty() {
|
if self.gecko.mContents.is_empty() {
|
||||||
|
@ -5679,8 +5713,8 @@ clip-path
|
||||||
let gecko_image_request =
|
let gecko_image_request =
|
||||||
&**gecko_content.mContent.mImage.as_ref();
|
&**gecko_content.mContent.mImage.as_ref();
|
||||||
ContentItem::Url(
|
ContentItem::Url(
|
||||||
SpecifiedImageUrl::from_image_request(gecko_image_request)
|
ComputedImageUrl::from_image_request(gecko_image_request)
|
||||||
.expect("mContent could not convert to SpecifiedImageUrl")
|
.expect("mContent could not convert to ComputedImageUrl")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5719,7 +5753,6 @@ clip-path
|
||||||
) -> longhands::counter_${counter_property.lower()}::computed_value::T {
|
) -> longhands::counter_${counter_property.lower()}::computed_value::T {
|
||||||
use values::generics::counters::CounterPair;
|
use values::generics::counters::CounterPair;
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
use gecko_string_cache::Atom;
|
|
||||||
|
|
||||||
longhands::counter_${counter_property.lower()}::computed_value::T::new(
|
longhands::counter_${counter_property.lower()}::computed_value::T::new(
|
||||||
self.gecko.m${counter_property}s.iter().map(|ref gecko_counter| {
|
self.gecko.m${counter_property}s.iter().map(|ref gecko_counter| {
|
||||||
|
|
|
@ -759,7 +759,7 @@
|
||||||
|
|
||||||
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function,
|
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function,
|
||||||
needs_context=True, allow_quirks=False, **kwargs)">
|
needs_context=True, allow_quirks=False, **kwargs)">
|
||||||
<% sub_properties=' '.join(sub_property_pattern % side for side in ['top', 'right', 'bottom', 'left']) %>
|
<% sub_properties=' '.join(sub_property_pattern % side for side in PHYSICAL_SIDES) %>
|
||||||
<%call expr="self.shorthand(name, sub_properties=sub_properties, **kwargs)">
|
<%call expr="self.shorthand(name, sub_properties=sub_properties, **kwargs)">
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use parser::Parse;
|
use parser::Parse;
|
||||||
|
|
|
@ -54,7 +54,7 @@ ${helpers.predefined_type(
|
||||||
${helpers.single_keyword("background-attachment",
|
${helpers.single_keyword("background-attachment",
|
||||||
"scroll fixed" + (" local" if product == "gecko" else ""),
|
"scroll fixed" + (" local" if product == "gecko" else ""),
|
||||||
vector=True,
|
vector=True,
|
||||||
gecko_constant_prefix="NS_STYLE_IMAGELAYER_ATTACHMENT",
|
gecko_enum_prefix="StyleImageLayerAttachment",
|
||||||
spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
|
spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER")}
|
||||||
|
|
|
@ -136,6 +136,7 @@ ${helpers.predefined_type("-moz-context-properties",
|
||||||
"MozContextProperties",
|
"MozContextProperties",
|
||||||
initial_value=None,
|
initial_value=None,
|
||||||
vector=True,
|
vector=True,
|
||||||
|
need_index=True,
|
||||||
animation_value_type="none",
|
animation_value_type="none",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties)",
|
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties)",
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
<% data.new_style_struct("Pointing", inherited=True, gecko_name="UserInterface") %>
|
<% data.new_style_struct("InheritedUI", inherited=True, gecko_name="UserInterface") %>
|
||||||
|
|
||||||
${helpers.predefined_type("cursor",
|
${helpers.predefined_type("cursor",
|
||||||
"Cursor",
|
"Cursor",
|
||||||
|
@ -44,7 +44,7 @@ ${helpers.single_keyword("-moz-user-focus",
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"caret-color",
|
"caret-color",
|
||||||
"CaretColor",
|
"CaretColor",
|
||||||
"generics::pointing::CaretColor::Auto",
|
"generics::ui::CaretColor::Auto",
|
||||||
spec="https://drafts.csswg.org/css-ui/#caret-color",
|
spec="https://drafts.csswg.org/css-ui/#caret-color",
|
||||||
animation_value_type="AnimatedCaretColor",
|
animation_value_type="AnimatedCaretColor",
|
||||||
ignored_when_colors_disabled=True,
|
ignored_when_colors_disabled=True,
|
|
@ -109,11 +109,11 @@ pub mod longhands {
|
||||||
<%include file="/longhand/inherited_box.mako.rs" />
|
<%include file="/longhand/inherited_box.mako.rs" />
|
||||||
<%include file="/longhand/inherited_table.mako.rs" />
|
<%include file="/longhand/inherited_table.mako.rs" />
|
||||||
<%include file="/longhand/inherited_text.mako.rs" />
|
<%include file="/longhand/inherited_text.mako.rs" />
|
||||||
|
<%include file="/longhand/inherited_ui.mako.rs" />
|
||||||
<%include file="/longhand/list.mako.rs" />
|
<%include file="/longhand/list.mako.rs" />
|
||||||
<%include file="/longhand/margin.mako.rs" />
|
<%include file="/longhand/margin.mako.rs" />
|
||||||
<%include file="/longhand/outline.mako.rs" />
|
<%include file="/longhand/outline.mako.rs" />
|
||||||
<%include file="/longhand/padding.mako.rs" />
|
<%include file="/longhand/padding.mako.rs" />
|
||||||
<%include file="/longhand/pointing.mako.rs" />
|
|
||||||
<%include file="/longhand/position.mako.rs" />
|
<%include file="/longhand/position.mako.rs" />
|
||||||
<%include file="/longhand/table.mako.rs" />
|
<%include file="/longhand/table.mako.rs" />
|
||||||
<%include file="/longhand/text.mako.rs" />
|
<%include file="/longhand/text.mako.rs" />
|
||||||
|
@ -2399,6 +2399,18 @@ pub mod style_structs {
|
||||||
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
|
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
|
||||||
self.${longhand.ident}_at(index % self.${longhand.ident}_count())
|
self.${longhand.ident}_at(index % self.${longhand.ident}_count())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clone the computed value for the property.
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[inline]
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn clone_${longhand.ident}(
|
||||||
|
&self,
|
||||||
|
) -> longhands::${longhand.ident}::computed_value::T {
|
||||||
|
longhands::${longhand.ident}::computed_value::T(
|
||||||
|
self.${longhand.ident}_iter().collect()
|
||||||
|
)
|
||||||
|
}
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
|
@ -2631,10 +2643,10 @@ impl ComputedValuesInner {
|
||||||
/// ineffective, and would yield an empty `::before` or `::after`
|
/// ineffective, and would yield an empty `::before` or `::after`
|
||||||
/// pseudo-element.
|
/// pseudo-element.
|
||||||
pub fn ineffective_content_property(&self) -> bool {
|
pub fn ineffective_content_property(&self) -> bool {
|
||||||
use properties::longhands::content::computed_value::T;
|
use values::generics::counters::Content;
|
||||||
match self.get_counters().content {
|
match self.get_counters().content {
|
||||||
T::Normal | T::None => true,
|
Content::Normal | Content::None => true,
|
||||||
T::Items(ref items) => items.is_empty(),
|
Content::Items(ref items) => items.is_empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
||||||
use values::animated::color::RGBA;
|
use values::animated::color::RGBA;
|
||||||
use values::computed::{Angle, Number};
|
use values::computed::{Angle, Number};
|
||||||
use values::computed::length::Length;
|
use values::computed::length::Length;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use values::computed::url::ComputedUrl;
|
||||||
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
use values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||||
use values::generics::effects::Filter as GenericFilter;
|
use values::generics::effects::Filter as GenericFilter;
|
||||||
|
@ -42,11 +44,11 @@ pub struct FilterList(pub Vec<Filter>);
|
||||||
|
|
||||||
/// An animated value for a single `filter`.
|
/// An animated value for a single `filter`.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow>;
|
pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow, ComputedUrl>;
|
||||||
|
|
||||||
/// An animated value for a single `filter`.
|
/// An animated value for a single `filter`.
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
pub type Filter = GenericFilter<Angle, Number, Length, Impossible>;
|
pub type Filter = GenericFilter<Angle, Number, Length, Impossible, Impossible>;
|
||||||
|
|
||||||
/// An animated value for the `drop-shadow()` filter.
|
/// An animated value for the `drop-shadow()` filter.
|
||||||
pub type SimpleShadow = GenericSimpleShadow<Option<RGBA>, Length, Length>;
|
pub type SimpleShadow = GenericSimpleShadow<Option<RGBA>, Length, Length>;
|
||||||
|
|
|
@ -15,9 +15,7 @@ use values::computed::Angle as ComputedAngle;
|
||||||
use values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
|
use values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
|
||||||
use values::computed::MaxLength as ComputedMaxLength;
|
use values::computed::MaxLength as ComputedMaxLength;
|
||||||
use values::computed::MozLength as ComputedMozLength;
|
use values::computed::MozLength as ComputedMozLength;
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
use values::computed::url::ComputedUrl;
|
use values::computed::url::ComputedUrl;
|
||||||
use values::specified::url::SpecifiedUrl;
|
|
||||||
|
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod effects;
|
pub mod effects;
|
||||||
|
@ -260,8 +258,6 @@ macro_rules! trivial_to_animated_value {
|
||||||
|
|
||||||
trivial_to_animated_value!(Au);
|
trivial_to_animated_value!(Au);
|
||||||
trivial_to_animated_value!(ComputedAngle);
|
trivial_to_animated_value!(ComputedAngle);
|
||||||
trivial_to_animated_value!(SpecifiedUrl);
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
trivial_to_animated_value!(ComputedUrl);
|
trivial_to_animated_value!(ComputedUrl);
|
||||||
trivial_to_animated_value!(bool);
|
trivial_to_animated_value!(bool);
|
||||||
trivial_to_animated_value!(f32);
|
trivial_to_animated_value!(f32);
|
||||||
|
|
|
@ -4,22 +4,10 @@
|
||||||
|
|
||||||
//! Computed values for counter properties
|
//! Computed values for counter properties
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
use values::computed::url::ComputedImageUrl;
|
||||||
use computed_values::list_style_type::T as ListStyleType;
|
use values::generics::counters as generics;
|
||||||
use cssparser::{Parser, Token};
|
|
||||||
use parser::{Parse, ParserContext};
|
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
|
||||||
use style_traits::{ParseError, StyleParseErrorKind};
|
|
||||||
use values::CustomIdent;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
use values::generics::CounterStyleOrNone;
|
|
||||||
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
|
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
|
||||||
use values::generics::counters::CounterReset as GenericCounterReset;
|
use values::generics::counters::CounterReset as GenericCounterReset;
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
use values::specified::Attr;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
use values::specified::url::SpecifiedImageUrl;
|
|
||||||
pub use values::specified::{Content, ContentItem};
|
|
||||||
|
|
||||||
/// A computed value for the `counter-increment` property.
|
/// A computed value for the `counter-increment` property.
|
||||||
pub type CounterIncrement = GenericCounterIncrement<i32>;
|
pub type CounterIncrement = GenericCounterIncrement<i32>;
|
||||||
|
@ -27,134 +15,9 @@ pub type CounterIncrement = GenericCounterIncrement<i32>;
|
||||||
/// A computed value for the `counter-increment` property.
|
/// A computed value for the `counter-increment` property.
|
||||||
pub type CounterReset = GenericCounterReset<i32>;
|
pub type CounterReset = GenericCounterReset<i32>;
|
||||||
|
|
||||||
impl Content {
|
/// A computed value for the `content` property.
|
||||||
/// Set `content` property to `normal`.
|
pub type Content = generics::Content<ComputedImageUrl>;
|
||||||
#[inline]
|
|
||||||
pub fn normal() -> Self {
|
|
||||||
Content::Normal
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
/// A computed content item.
|
||||||
fn parse_counter_style(input: &mut Parser) -> ListStyleType {
|
pub type ContentItem = generics::ContentItem<ComputedImageUrl>;
|
||||||
input
|
|
||||||
.try(|input| {
|
|
||||||
input.expect_comma()?;
|
|
||||||
ListStyleType::parse(input)
|
|
||||||
})
|
|
||||||
.unwrap_or(ListStyleType::Decimal)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyleOrNone {
|
|
||||||
input
|
|
||||||
.try(|input| {
|
|
||||||
input.expect_comma()?;
|
|
||||||
CounterStyleOrNone::parse(context, input)
|
|
||||||
})
|
|
||||||
.unwrap_or(CounterStyleOrNone::decimal())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for Content {
|
|
||||||
// normal | none | [ <string> | <counter> | open-quote | close-quote | no-open-quote |
|
|
||||||
// no-close-quote ]+
|
|
||||||
// TODO: <uri>, attr(<identifier>)
|
|
||||||
fn parse<'i, 't>(
|
|
||||||
_context: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
) -> Result<Self, ParseError<'i>> {
|
|
||||||
if input
|
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
return Ok(Content::Normal);
|
|
||||||
}
|
|
||||||
if input
|
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
return Ok(Content::None);
|
|
||||||
}
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
{
|
|
||||||
if input
|
|
||||||
.try(|input| input.expect_ident_matching("-moz-alt-content"))
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
return Ok(Content::MozAltContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut content = vec![];
|
|
||||||
loop {
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
{
|
|
||||||
if let Ok(url) = input.try(|i| SpecifiedImageUrl::parse(_context, i)) {
|
|
||||||
content.push(ContentItem::Url(url));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
|
||||||
match input.next().map(|t| t.clone()) {
|
|
||||||
Ok(Token::QuotedString(ref value)) => {
|
|
||||||
content.push(ContentItem::String(
|
|
||||||
value.as_ref().to_owned().into_boxed_str(),
|
|
||||||
));
|
|
||||||
},
|
|
||||||
Ok(Token::Function(ref name)) => {
|
|
||||||
let result = match_ignore_ascii_case! { &name,
|
|
||||||
"counter" => Some(input.parse_nested_block(|input| {
|
|
||||||
let location = input.current_source_location();
|
|
||||||
let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?;
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
let style = Content::parse_counter_style(input);
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
let style = Content::parse_counter_style(_context, input);
|
|
||||||
Ok(ContentItem::Counter(name, style))
|
|
||||||
})),
|
|
||||||
"counters" => Some(input.parse_nested_block(|input| {
|
|
||||||
let location = input.current_source_location();
|
|
||||||
let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?;
|
|
||||||
input.expect_comma()?;
|
|
||||||
let separator = input.expect_string()?.as_ref().to_owned().into_boxed_str();
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
let style = Content::parse_counter_style(input);
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
let style = Content::parse_counter_style(_context, input);
|
|
||||||
Ok(ContentItem::Counters(name, separator, style))
|
|
||||||
})),
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
"attr" => Some(input.parse_nested_block(|input| {
|
|
||||||
Ok(ContentItem::Attr(Attr::parse_function(_context, input)?))
|
|
||||||
})),
|
|
||||||
_ => None
|
|
||||||
};
|
|
||||||
match result {
|
|
||||||
Some(result) => content.push(result?),
|
|
||||||
None => {
|
|
||||||
return Err(input.new_custom_error(
|
|
||||||
StyleParseErrorKind::UnexpectedFunction(name.clone()),
|
|
||||||
))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Ok(Token::Ident(ref ident)) => {
|
|
||||||
content.push(match_ignore_ascii_case! { &ident,
|
|
||||||
"open-quote" => ContentItem::OpenQuote,
|
|
||||||
"close-quote" => ContentItem::CloseQuote,
|
|
||||||
"no-open-quote" => ContentItem::NoOpenQuote,
|
|
||||||
"no-close-quote" => ContentItem::NoCloseQuote,
|
|
||||||
_ => return Err(input.new_custom_error(
|
|
||||||
SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
|
||||||
});
|
|
||||||
},
|
|
||||||
Err(_) => break,
|
|
||||||
Ok(t) => return Err(input.new_unexpected_token_error(t)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if content.is_empty() {
|
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
|
||||||
}
|
|
||||||
Ok(Content::Items(content.into_boxed_slice()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ use values::Impossible;
|
||||||
use values::computed::{Angle, NonNegativeNumber};
|
use values::computed::{Angle, NonNegativeNumber};
|
||||||
use values::computed::color::RGBAColor;
|
use values::computed::color::RGBAColor;
|
||||||
use values::computed::length::{Length, NonNegativeLength};
|
use values::computed::length::{Length, NonNegativeLength};
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use values::computed::url::ComputedUrl;
|
||||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||||
use values::generics::effects::Filter as GenericFilter;
|
use values::generics::effects::Filter as GenericFilter;
|
||||||
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||||
|
@ -18,11 +20,11 @@ pub type BoxShadow = GenericBoxShadow<Option<RGBAColor>, Length, NonNegativeLeng
|
||||||
|
|
||||||
/// A computed value for a single `filter`.
|
/// A computed value for a single `filter`.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow>;
|
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow, ComputedUrl>;
|
||||||
|
|
||||||
/// A computed value for a single `filter`.
|
/// A computed value for a single `filter`.
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible>;
|
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible, Impossible>;
|
||||||
|
|
||||||
/// A computed value for the `drop-shadow()` filter.
|
/// A computed value for the `drop-shadow()` filter.
|
||||||
pub type SimpleShadow = GenericSimpleShadow<Option<RGBAColor>, Length, NonNegativeLength>;
|
pub type SimpleShadow = GenericSimpleShadow<Option<RGBAColor>, Length, NonNegativeLength>;
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub use self::inherited_box::{ImageOrientation, Orientation};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::gecko::ScrollSnapPoint;
|
pub use self::gecko::ScrollSnapPoint;
|
||||||
pub use self::rect::LengthOrNumberRect;
|
pub use self::rect::LengthOrNumberRect;
|
||||||
|
pub use self::resolution::Resolution;
|
||||||
pub use super::{Auto, Either, None_};
|
pub use super::{Auto, Either, None_};
|
||||||
pub use super::specified::{BorderStyle, TextDecorationLine};
|
pub use super::specified::{BorderStyle, TextDecorationLine};
|
||||||
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage};
|
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage};
|
||||||
|
@ -67,9 +68,6 @@ pub use self::list::Quotes;
|
||||||
pub use self::list::ListStyleType;
|
pub use self::list::ListStyleType;
|
||||||
pub use self::outline::OutlineStyle;
|
pub use self::outline::OutlineStyle;
|
||||||
pub use self::percentage::{Percentage, NonNegativePercentage};
|
pub use self::percentage::{Percentage, NonNegativePercentage};
|
||||||
pub use self::pointing::{CaretColor, Cursor};
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub use self::pointing::CursorImage;
|
|
||||||
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, ZIndex};
|
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, ZIndex};
|
||||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
||||||
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
|
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
|
||||||
|
@ -80,7 +78,9 @@ pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle, TextOve
|
||||||
pub use self::time::Time;
|
pub use self::time::Time;
|
||||||
pub use self::transform::{Rotate, Scale, TimingFunction, Transform, TransformOperation};
|
pub use self::transform::{Rotate, Scale, TimingFunction, Transform, TransformOperation};
|
||||||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||||
pub use self::ui::MozForceBrokenImageIcon;
|
pub use self::ui::{CaretColor, Cursor, MozForceBrokenImageIcon};
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub use self::ui::CursorImage;
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub mod align;
|
pub mod align;
|
||||||
|
@ -104,9 +104,9 @@ pub mod length;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod outline;
|
pub mod outline;
|
||||||
pub mod percentage;
|
pub mod percentage;
|
||||||
pub mod pointing;
|
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod resolution;
|
||||||
pub mod svg;
|
pub mod svg;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/* 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 http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
//! Computed values for Pointing properties.
|
|
||||||
//!
|
|
||||||
//! https://drafts.csswg.org/css-ui/#pointing-keyboard
|
|
||||||
|
|
||||||
use values::computed::Number;
|
|
||||||
use values::computed::color::Color;
|
|
||||||
use values::computed::url::ComputedImageUrl;
|
|
||||||
use values::generics::pointing as generics;
|
|
||||||
|
|
||||||
/// A computed value for the `caret-color` property.
|
|
||||||
pub type CaretColor = generics::CaretColor<Color>;
|
|
||||||
|
|
||||||
/// A computed value for the `cursor` property.
|
|
||||||
pub type Cursor = generics::Cursor<CursorImage>;
|
|
||||||
|
|
||||||
/// A computed value for item of `image cursors`.
|
|
||||||
pub type CursorImage = generics::CursorImage<ComputedImageUrl, Number>;
|
|
48
components/style/values/computed/resolution.rs
Normal file
48
components/style/values/computed/resolution.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Resolution values:
|
||||||
|
//!
|
||||||
|
//! https://drafts.csswg.org/css-values/#resolution
|
||||||
|
|
||||||
|
use std::fmt::{self, Write};
|
||||||
|
use style_traits::{CssWriter, ToCss};
|
||||||
|
use values::CSSFloat;
|
||||||
|
use values::computed::{Context, ToComputedValue};
|
||||||
|
use values::specified;
|
||||||
|
|
||||||
|
/// A computed `<resolution>`.
|
||||||
|
pub struct Resolution(CSSFloat);
|
||||||
|
|
||||||
|
impl Resolution {
|
||||||
|
/// Returns this resolution value as dppx.
|
||||||
|
#[inline]
|
||||||
|
pub fn dppx(&self) -> CSSFloat {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for specified::Resolution {
|
||||||
|
type ComputedValue = Resolution;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
|
||||||
|
Resolution(self.to_dppx())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
specified::Resolution::Dppx(computed.dppx())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for Resolution {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: fmt::Write,
|
||||||
|
{
|
||||||
|
self.dppx().to_css(dest)?;
|
||||||
|
dest.write_str("dppx")
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,4 +4,18 @@
|
||||||
|
|
||||||
//! Computed values for UI properties
|
//! Computed values for UI properties
|
||||||
|
|
||||||
|
use values::computed::Number;
|
||||||
|
use values::computed::color::Color;
|
||||||
|
use values::computed::url::ComputedImageUrl;
|
||||||
|
use values::generics::ui as generics;
|
||||||
|
|
||||||
pub use values::specified::ui::MozForceBrokenImageIcon;
|
pub use values::specified::ui::MozForceBrokenImageIcon;
|
||||||
|
|
||||||
|
/// A computed value for the `caret-color` property.
|
||||||
|
pub type CaretColor = generics::CaretColor<Color>;
|
||||||
|
|
||||||
|
/// A computed value for the `cursor` property.
|
||||||
|
pub type Cursor = generics::Cursor<CursorImage>;
|
||||||
|
|
||||||
|
/// A computed value for item of `image cursors`.
|
||||||
|
pub type CursorImage = generics::CursorImage<ComputedImageUrl, Number>;
|
||||||
|
|
|
@ -4,8 +4,14 @@
|
||||||
|
|
||||||
//! Generic types for counters-related CSS values.
|
//! Generic types for counters-related CSS values.
|
||||||
|
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
use computed_values::list_style_type::T as ListStyleType;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use values::generics::CounterStyleOrNone;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use values::specified::Attr;
|
||||||
|
|
||||||
/// A name / value pair for counters.
|
/// A name / value pair for counters.
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
||||||
|
@ -74,3 +80,78 @@ impl<I> Default for Counters<I> {
|
||||||
Counters(vec![].into_boxed_slice())
|
Counters(vec![].into_boxed_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
type CounterStyleType = ListStyleType;
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
type CounterStyleType = CounterStyleOrNone;
|
||||||
|
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
#[inline]
|
||||||
|
fn is_decimal(counter_type: &CounterStyleType) -> bool {
|
||||||
|
*counter_type == ListStyleType::Decimal
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
#[inline]
|
||||||
|
fn is_decimal(counter_type: &CounterStyleType) -> bool {
|
||||||
|
*counter_type == CounterStyleOrNone::decimal()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The specified value for the `content` property.
|
||||||
|
///
|
||||||
|
/// https://drafts.csswg.org/css-content/#propdef-content
|
||||||
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
||||||
|
ToComputedValue, ToCss)]
|
||||||
|
pub enum Content<ImageUrl> {
|
||||||
|
/// `normal` reserved keyword.
|
||||||
|
Normal,
|
||||||
|
/// `none` reserved keyword.
|
||||||
|
None,
|
||||||
|
/// `-moz-alt-content`.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
MozAltContent,
|
||||||
|
/// Content items.
|
||||||
|
Items(#[css(iterable)] Box<[ContentItem<ImageUrl>]>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<ImageUrl> Content<ImageUrl> {
|
||||||
|
/// Set `content` property to `normal`.
|
||||||
|
#[inline]
|
||||||
|
pub fn normal() -> Self {
|
||||||
|
Content::Normal
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Items for the `content` property.
|
||||||
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
||||||
|
ToComputedValue, ToCss)]
|
||||||
|
pub enum ContentItem<ImageUrl> {
|
||||||
|
/// Literal string content.
|
||||||
|
String(Box<str>),
|
||||||
|
/// `counter(name, style)`.
|
||||||
|
#[css(comma, function)]
|
||||||
|
Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
|
||||||
|
/// `counters(name, separator, style)`.
|
||||||
|
#[css(comma, function)]
|
||||||
|
Counters(
|
||||||
|
CustomIdent,
|
||||||
|
Box<str>,
|
||||||
|
#[css(skip_if = "is_decimal")] CounterStyleType,
|
||||||
|
),
|
||||||
|
/// `open-quote`.
|
||||||
|
OpenQuote,
|
||||||
|
/// `close-quote`.
|
||||||
|
CloseQuote,
|
||||||
|
/// `no-open-quote`.
|
||||||
|
NoOpenQuote,
|
||||||
|
/// `no-close-quote`.
|
||||||
|
NoCloseQuote,
|
||||||
|
/// `attr([namespace? `|`]? ident)`
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
Attr(Attr),
|
||||||
|
/// `url(url)`
|
||||||
|
Url(ImageUrl),
|
||||||
|
}
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
|
|
||||||
//! Generic types for CSS values related to effects.
|
//! Generic types for CSS values related to effects.
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
use values::specified::url::SpecifiedUrl;
|
|
||||||
|
|
||||||
/// A generic value for a single `box-shadow`.
|
/// A generic value for a single `box-shadow`.
|
||||||
#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
||||||
ToAnimatedValue, ToAnimatedZero, ToCss)]
|
ToAnimatedValue, ToAnimatedZero, ToCss)]
|
||||||
|
@ -23,9 +20,10 @@ pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
|
||||||
|
|
||||||
/// A generic value for a single `filter`.
|
/// A generic value for a single `filter`.
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
|
#[animation(no_bound(Url))]
|
||||||
#[derive(Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq,
|
#[derive(Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq,
|
||||||
SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss)]
|
SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss)]
|
||||||
pub enum Filter<Angle, Factor, Length, DropShadow> {
|
pub enum Filter<Angle, Factor, Length, DropShadow, Url> {
|
||||||
/// `blur(<length>)`
|
/// `blur(<length>)`
|
||||||
#[css(function)]
|
#[css(function)]
|
||||||
Blur(Length),
|
Blur(Length),
|
||||||
|
@ -58,8 +56,7 @@ pub enum Filter<Angle, Factor, Length, DropShadow> {
|
||||||
DropShadow(DropShadow),
|
DropShadow(DropShadow),
|
||||||
/// `<url>`
|
/// `<url>`
|
||||||
#[animation(error)]
|
#[animation(error)]
|
||||||
#[cfg(feature = "gecko")]
|
Url(Url),
|
||||||
Url(SpecifiedUrl),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A generic value for the `drop-shadow()` filter and the `text-shadow` property.
|
/// A generic value for the `drop-shadow()` filter and the `text-shadow` property.
|
||||||
|
|
|
@ -26,13 +26,13 @@ pub mod font;
|
||||||
pub mod gecko;
|
pub mod gecko;
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod pointing;
|
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
pub mod size;
|
pub mod size;
|
||||||
pub mod svg;
|
pub mod svg;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
|
pub mod ui;
|
||||||
pub mod url;
|
pub mod url;
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! Generic values for pointing properties.
|
//! Generic values for UI properties.
|
||||||
|
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
|
@ -8,17 +8,18 @@
|
||||||
use computed_values::list_style_type::T as ListStyleType;
|
use computed_values::list_style_type::T as ListStyleType;
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use style_traits::{ParseError, StyleParseErrorKind};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
use values::CustomIdent;
|
use values::CustomIdent;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use values::generics::CounterStyleOrNone;
|
use values::generics::CounterStyleOrNone;
|
||||||
|
use values::generics::counters as generics;
|
||||||
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
|
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
|
||||||
use values::generics::counters::CounterPair;
|
use values::generics::counters::CounterPair;
|
||||||
use values::generics::counters::CounterReset as GenericCounterReset;
|
use values::generics::counters::CounterReset as GenericCounterReset;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use values::specified::Attr;
|
use values::specified::Attr;
|
||||||
use values::specified::Integer;
|
use values::specified::Integer;
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
use values::specified::url::SpecifiedImageUrl;
|
use values::specified::url::SpecifiedImageUrl;
|
||||||
|
|
||||||
/// A specified value for the `counter-increment` property.
|
/// A specified value for the `counter-increment` property.
|
||||||
|
@ -79,69 +80,129 @@ fn parse_counters<'i, 't>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
type CounterStyleType = ListStyleType;
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
type CounterStyleType = CounterStyleOrNone;
|
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
#[inline]
|
|
||||||
fn is_decimal(counter_type: &CounterStyleType) -> bool {
|
|
||||||
*counter_type == ListStyleType::Decimal
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
#[inline]
|
|
||||||
fn is_decimal(counter_type: &CounterStyleType) -> bool {
|
|
||||||
*counter_type == CounterStyleOrNone::decimal()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The specified value for the `content` property.
|
/// The specified value for the `content` property.
|
||||||
///
|
pub type Content = generics::Content<SpecifiedImageUrl>;
|
||||||
/// https://drafts.csswg.org/css-content/#propdef-content
|
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
/// The specified value for a content item in the `content` property.
|
||||||
ToComputedValue, ToCss)]
|
pub type ContentItem = generics::ContentItem<SpecifiedImageUrl>;
|
||||||
pub enum Content {
|
|
||||||
/// `normal` reserved keyword.
|
impl Content {
|
||||||
Normal,
|
#[cfg(feature = "servo")]
|
||||||
/// `none` reserved keyword.
|
fn parse_counter_style(_: &ParserContext, input: &mut Parser) -> ListStyleType {
|
||||||
None,
|
input
|
||||||
/// `-moz-alt-content`.
|
.try(|input| {
|
||||||
|
input.expect_comma()?;
|
||||||
|
ListStyleType::parse(input)
|
||||||
|
})
|
||||||
|
.unwrap_or(ListStyleType::Decimal)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
MozAltContent,
|
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyleOrNone {
|
||||||
/// Content items.
|
input
|
||||||
Items(#[css(iterable)] Box<[ContentItem]>),
|
.try(|input| {
|
||||||
|
input.expect_comma()?;
|
||||||
|
CounterStyleOrNone::parse(context, input)
|
||||||
|
})
|
||||||
|
.unwrap_or(CounterStyleOrNone::decimal())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Items for the `content` property.
|
impl Parse for Content {
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
// normal | none | [ <string> | <counter> | open-quote | close-quote | no-open-quote |
|
||||||
ToComputedValue, ToCss)]
|
// no-close-quote ]+
|
||||||
pub enum ContentItem {
|
// TODO: <uri>, attr(<identifier>)
|
||||||
/// Literal string content.
|
fn parse<'i, 't>(
|
||||||
String(Box<str>),
|
context: &ParserContext,
|
||||||
/// `counter(name, style)`.
|
input: &mut Parser<'i, 't>,
|
||||||
#[css(comma, function)]
|
) -> Result<Self, ParseError<'i>> {
|
||||||
Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
|
if input
|
||||||
/// `counters(name, separator, style)`.
|
.try(|input| input.expect_ident_matching("normal"))
|
||||||
#[css(comma, function)]
|
.is_ok()
|
||||||
Counters(
|
{
|
||||||
CustomIdent,
|
return Ok(generics::Content::Normal);
|
||||||
Box<str>,
|
}
|
||||||
#[css(skip_if = "is_decimal")] CounterStyleType,
|
if input
|
||||||
),
|
.try(|input| input.expect_ident_matching("none"))
|
||||||
/// `open-quote`.
|
.is_ok()
|
||||||
OpenQuote,
|
{
|
||||||
/// `close-quote`.
|
return Ok(generics::Content::None);
|
||||||
CloseQuote,
|
}
|
||||||
/// `no-open-quote`.
|
|
||||||
NoOpenQuote,
|
|
||||||
/// `no-close-quote`.
|
|
||||||
NoCloseQuote,
|
|
||||||
/// `attr([namespace? `|`]? ident)`
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
Attr(Attr),
|
{
|
||||||
/// `url(url)`
|
if input
|
||||||
|
.try(|input| input.expect_ident_matching("-moz-alt-content"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
return Ok(generics::Content::MozAltContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut content = vec![];
|
||||||
|
loop {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
Url(SpecifiedImageUrl),
|
{
|
||||||
|
if let Ok(url) = input.try(|i| SpecifiedImageUrl::parse(context, i)) {
|
||||||
|
content.push(generics::ContentItem::Url(url));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
|
match input.next().map(|t| t.clone()) {
|
||||||
|
Ok(Token::QuotedString(ref value)) => {
|
||||||
|
content.push(generics::ContentItem::String(
|
||||||
|
value.as_ref().to_owned().into_boxed_str(),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
Ok(Token::Function(ref name)) => {
|
||||||
|
let result = match_ignore_ascii_case! { &name,
|
||||||
|
"counter" => Some(input.parse_nested_block(|input| {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?;
|
||||||
|
let style = Content::parse_counter_style(context, input);
|
||||||
|
Ok(generics::ContentItem::Counter(name, style))
|
||||||
|
})),
|
||||||
|
"counters" => Some(input.parse_nested_block(|input| {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?;
|
||||||
|
input.expect_comma()?;
|
||||||
|
let separator = input.expect_string()?.as_ref().to_owned().into_boxed_str();
|
||||||
|
let style = Content::parse_counter_style(context, input);
|
||||||
|
Ok(generics::ContentItem::Counters(name, separator, style))
|
||||||
|
})),
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
"attr" => Some(input.parse_nested_block(|input| {
|
||||||
|
Ok(generics::ContentItem::Attr(Attr::parse_function(context, input)?))
|
||||||
|
})),
|
||||||
|
_ => None
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Some(result) => content.push(result?),
|
||||||
|
None => {
|
||||||
|
return Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnexpectedFunction(name.clone()),
|
||||||
|
))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Ok(Token::Ident(ref ident)) => {
|
||||||
|
content.push(match_ignore_ascii_case! { &ident,
|
||||||
|
"open-quote" => generics::ContentItem::OpenQuote,
|
||||||
|
"close-quote" => generics::ContentItem::CloseQuote,
|
||||||
|
"no-open-quote" => generics::ContentItem::NoOpenQuote,
|
||||||
|
"no-close-quote" => generics::ContentItem::NoCloseQuote,
|
||||||
|
_ => return Err(input.new_custom_error(
|
||||||
|
SelectorParseErrorKind::UnexpectedIdent(ident.clone())
|
||||||
|
))
|
||||||
|
});
|
||||||
|
},
|
||||||
|
Err(_) => break,
|
||||||
|
Ok(t) => return Err(input.new_unexpected_token_error(t)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if content.is_empty() {
|
||||||
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
Ok(generics::Content::Items(content.into_boxed_slice()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,11 @@ pub type BoxShadow =
|
||||||
|
|
||||||
/// A specified value for a single `filter`.
|
/// A specified value for a single `filter`.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, SimpleShadow>;
|
pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, SimpleShadow, SpecifiedUrl>;
|
||||||
|
|
||||||
/// A specified value for a single `filter`.
|
/// A specified value for a single `filter`.
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, Impossible>;
|
pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, Impossible, Impossible>;
|
||||||
|
|
||||||
/// A value for the `<factor>` parts in `Filter`.
|
/// A value for the `<factor>` parts in `Filter`.
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
|
||||||
|
|
|
@ -61,10 +61,8 @@ pub use self::list::Quotes;
|
||||||
pub use self::list::ListStyleType;
|
pub use self::list::ListStyleType;
|
||||||
pub use self::outline::OutlineStyle;
|
pub use self::outline::OutlineStyle;
|
||||||
pub use self::rect::LengthOrNumberRect;
|
pub use self::rect::LengthOrNumberRect;
|
||||||
|
pub use self::resolution::Resolution;
|
||||||
pub use self::percentage::Percentage;
|
pub use self::percentage::Percentage;
|
||||||
pub use self::pointing::{CaretColor, Cursor};
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
pub use self::pointing::CursorImage;
|
|
||||||
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position};
|
pub use self::position::{GridAutoFlow, GridTemplateAreas, Position};
|
||||||
pub use self::position::{PositionComponent, ZIndex};
|
pub use self::position::{PositionComponent, ZIndex};
|
||||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
|
||||||
|
@ -77,7 +75,9 @@ pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpa
|
||||||
pub use self::time::Time;
|
pub use self::time::Time;
|
||||||
pub use self::transform::{Rotate, Scale, TimingFunction, Transform};
|
pub use self::transform::{Rotate, Scale, TimingFunction, Transform};
|
||||||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||||
pub use self::ui::MozForceBrokenImageIcon;
|
pub use self::ui::{CaretColor, Cursor, MozForceBrokenImageIcon};
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub use self::ui::CursorImage;
|
||||||
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -104,9 +104,9 @@ pub mod length;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod outline;
|
pub mod outline;
|
||||||
pub mod percentage;
|
pub mod percentage;
|
||||||
pub mod pointing;
|
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod resolution;
|
||||||
pub mod source_size_list;
|
pub mod source_size_list;
|
||||||
pub mod svg;
|
pub mod svg;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
/* 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 http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
//! Specified values for Pointing properties.
|
|
||||||
//!
|
|
||||||
//! https://drafts.csswg.org/css-ui/#pointing-keyboard
|
|
||||||
|
|
||||||
use cssparser::Parser;
|
|
||||||
use parser::{Parse, ParserContext};
|
|
||||||
use style_traits::{ParseError, StyleParseErrorKind};
|
|
||||||
use style_traits::cursor::CursorKind;
|
|
||||||
use values::generics::pointing as generics;
|
|
||||||
use values::specified::Number;
|
|
||||||
use values::specified::color::Color;
|
|
||||||
use values::specified::url::SpecifiedImageUrl;
|
|
||||||
|
|
||||||
/// A specified value for the `caret-color` property.
|
|
||||||
pub type CaretColor = generics::CaretColor<Color>;
|
|
||||||
|
|
||||||
impl Parse for CaretColor {
|
|
||||||
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(generics::CaretColor::Auto);
|
|
||||||
}
|
|
||||||
Ok(generics::CaretColor::Color(Color::parse(context, input)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A specified value for the `cursor` property.
|
|
||||||
pub type Cursor = generics::Cursor<CursorImage>;
|
|
||||||
|
|
||||||
/// A specified value for item of `image cursors`.
|
|
||||||
pub type CursorImage = generics::CursorImage<SpecifiedImageUrl, Number>;
|
|
||||||
|
|
||||||
impl Parse for Cursor {
|
|
||||||
/// cursor: [<url> [<number> <number>]?]# [auto | default | ...]
|
|
||||||
fn parse<'i, 't>(
|
|
||||||
context: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
) -> Result<Self, ParseError<'i>> {
|
|
||||||
let mut images = vec![];
|
|
||||||
loop {
|
|
||||||
match input.try(|input| CursorImage::parse(context, input)) {
|
|
||||||
Ok(image) => images.push(image),
|
|
||||||
Err(_) => break,
|
|
||||||
}
|
|
||||||
input.expect_comma()?;
|
|
||||||
}
|
|
||||||
Ok(Self {
|
|
||||||
images: images.into_boxed_slice(),
|
|
||||||
keyword: CursorKind::parse(context, input)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for CursorKind {
|
|
||||||
fn parse<'i, 't>(
|
|
||||||
_context: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
) -> Result<Self, ParseError<'i>> {
|
|
||||||
let location = input.current_source_location();
|
|
||||||
let ident = input.expect_ident()?;
|
|
||||||
CursorKind::from_css_keyword(&ident).map_err(|_| {
|
|
||||||
location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for CursorImage {
|
|
||||||
fn parse<'i, 't>(
|
|
||||||
context: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
) -> Result<Self, ParseError<'i>> {
|
|
||||||
Ok(Self {
|
|
||||||
url: SpecifiedImageUrl::parse(context, input)?,
|
|
||||||
hotspot: match input.try(|input| Number::parse(context, input)) {
|
|
||||||
Ok(number) => Some((number, Number::parse(context, input)?)),
|
|
||||||
Err(_) => None,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
79
components/style/values/specified/resolution.rs
Normal file
79
components/style/values/specified/resolution.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Resolution values:
|
||||||
|
//!
|
||||||
|
//! https://drafts.csswg.org/css-values/#resolution
|
||||||
|
|
||||||
|
use cssparser::{Parser, Token};
|
||||||
|
use parser::{Parse, ParserContext};
|
||||||
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
|
use values::CSSFloat;
|
||||||
|
|
||||||
|
/// A specified resolution.
|
||||||
|
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||||
|
pub enum Resolution {
|
||||||
|
/// Dots per inch.
|
||||||
|
#[css(dimension)]
|
||||||
|
Dpi(CSSFloat),
|
||||||
|
/// An alias unit for dots per pixel.
|
||||||
|
#[css(dimension)]
|
||||||
|
X(CSSFloat),
|
||||||
|
/// Dots per pixel.
|
||||||
|
#[css(dimension)]
|
||||||
|
Dppx(CSSFloat),
|
||||||
|
/// Dots per centimeter.
|
||||||
|
#[css(dimension)]
|
||||||
|
Dpcm(CSSFloat),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Resolution {
|
||||||
|
/// Convert this resolution value to dppx units.
|
||||||
|
pub fn to_dppx(&self) -> CSSFloat {
|
||||||
|
match *self {
|
||||||
|
Resolution::X(f) |
|
||||||
|
Resolution::Dppx(f) => f,
|
||||||
|
_ => self.to_dpi() / 96.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert this resolution value to dpi units.
|
||||||
|
pub fn to_dpi(&self) -> CSSFloat {
|
||||||
|
match *self {
|
||||||
|
Resolution::Dpi(f) => f,
|
||||||
|
Resolution::X(f) |
|
||||||
|
Resolution::Dppx(f) => f * 96.0,
|
||||||
|
Resolution::Dpcm(f) => f * 2.54,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for Resolution {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
_: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let (value, unit) = match *input.next()? {
|
||||||
|
Token::Dimension {
|
||||||
|
value, ref unit, ..
|
||||||
|
} => (value, unit),
|
||||||
|
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
|
};
|
||||||
|
|
||||||
|
if value <= 0. {
|
||||||
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
|
||||||
|
match_ignore_ascii_case! { &unit,
|
||||||
|
"dpi" => Ok(Resolution::Dpi(value)),
|
||||||
|
"dppx" => Ok(Resolution::Dppx(value)),
|
||||||
|
"dpcm" => Ok(Resolution::Dpcm(value)),
|
||||||
|
"x" => Ok(Resolution::X(value)),
|
||||||
|
_ => Err(location.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnexpectedDimension(unit.clone())
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,81 @@ use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||||
|
use style_traits::cursor::CursorKind;
|
||||||
|
use values::generics::ui as generics;
|
||||||
|
use values::specified::Number;
|
||||||
|
use values::specified::color::Color;
|
||||||
|
use values::specified::url::SpecifiedImageUrl;
|
||||||
|
|
||||||
|
/// A specified value for the `caret-color` property.
|
||||||
|
pub type CaretColor = generics::CaretColor<Color>;
|
||||||
|
|
||||||
|
impl Parse for CaretColor {
|
||||||
|
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(generics::CaretColor::Auto);
|
||||||
|
}
|
||||||
|
Ok(generics::CaretColor::Color(Color::parse(context, input)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A specified value for the `cursor` property.
|
||||||
|
pub type Cursor = generics::Cursor<CursorImage>;
|
||||||
|
|
||||||
|
/// A specified value for item of `image cursors`.
|
||||||
|
pub type CursorImage = generics::CursorImage<SpecifiedImageUrl, Number>;
|
||||||
|
|
||||||
|
impl Parse for Cursor {
|
||||||
|
/// cursor: [<url> [<number> <number>]?]# [auto | default | ...]
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let mut images = vec![];
|
||||||
|
loop {
|
||||||
|
match input.try(|input| CursorImage::parse(context, input)) {
|
||||||
|
Ok(image) => images.push(image),
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
|
input.expect_comma()?;
|
||||||
|
}
|
||||||
|
Ok(Self {
|
||||||
|
images: images.into_boxed_slice(),
|
||||||
|
keyword: CursorKind::parse(context, input)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for CursorKind {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
_context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
let ident = input.expect_ident()?;
|
||||||
|
CursorKind::from_css_keyword(&ident).map_err(|_| {
|
||||||
|
location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for CursorImage {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
Ok(Self {
|
||||||
|
url: SpecifiedImageUrl::parse(context, input)?,
|
||||||
|
hotspot: match input.try(|input| Number::parse(context, input)) {
|
||||||
|
Ok(number) => Some((number, Number::parse(context, input)?)),
|
||||||
|
Err(_) => None,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Specified value of `-moz-force-broken-image-icon`
|
/// Specified value of `-moz-force-broken-image-icon`
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
|
||||||
|
|
|
@ -401,6 +401,7 @@ macro_rules! impl_to_css_for_predefined_type {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_to_css_for_predefined_type!(f32);
|
impl_to_css_for_predefined_type!(f32);
|
||||||
|
impl_to_css_for_predefined_type!(i8);
|
||||||
impl_to_css_for_predefined_type!(i32);
|
impl_to_css_for_predefined_type!(i32);
|
||||||
impl_to_css_for_predefined_type!(u16);
|
impl_to_css_for_predefined_type!(u16);
|
||||||
impl_to_css_for_predefined_type!(u32);
|
impl_to_css_for_predefined_type!(u32);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue