mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #15627 - Manishearth:stylo-svg, r=heycam
stylo: Finish all SVG properties reviewed in bug https://bugzilla.mozilla.org/show_bug.cgi?id=1338388 <!-- 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/15627) <!-- Reviewable:end -->
This commit is contained in:
commit
d3ba09e588
17 changed files with 844 additions and 101 deletions
|
@ -365,6 +365,7 @@ mod bindings {
|
||||||
"nsStylePadding",
|
"nsStylePadding",
|
||||||
"nsStylePosition",
|
"nsStylePosition",
|
||||||
"nsStyleSVG",
|
"nsStyleSVG",
|
||||||
|
"nsStyleSVGPaint",
|
||||||
"nsStyleSVGReset",
|
"nsStyleSVGReset",
|
||||||
"nsStyleTable",
|
"nsStyleTable",
|
||||||
"nsStyleTableBorder",
|
"nsStyleTableBorder",
|
||||||
|
@ -383,6 +384,7 @@ mod bindings {
|
||||||
"PropertyValuePair",
|
"PropertyValuePair",
|
||||||
"Runnable",
|
"Runnable",
|
||||||
"ServoAttrSnapshot",
|
"ServoAttrSnapshot",
|
||||||
|
"ServoBundledURI",
|
||||||
"ServoElementSnapshot",
|
"ServoElementSnapshot",
|
||||||
"SheetParsingMode",
|
"SheetParsingMode",
|
||||||
"StaticRefPtr",
|
"StaticRefPtr",
|
||||||
|
@ -506,6 +508,7 @@ mod bindings {
|
||||||
.whitelisted_function("Servo_.*")
|
.whitelisted_function("Servo_.*")
|
||||||
.whitelisted_function("Gecko_.*");
|
.whitelisted_function("Gecko_.*");
|
||||||
let structs_types = [
|
let structs_types = [
|
||||||
|
"mozilla::css::URLValue",
|
||||||
"RawGeckoDocument",
|
"RawGeckoDocument",
|
||||||
"RawGeckoElement",
|
"RawGeckoElement",
|
||||||
"RawGeckoKeyframeList",
|
"RawGeckoKeyframeList",
|
||||||
|
@ -523,6 +526,7 @@ mod bindings {
|
||||||
"FontFamilyList",
|
"FontFamilyList",
|
||||||
"FontFamilyType",
|
"FontFamilyType",
|
||||||
"Keyframe",
|
"Keyframe",
|
||||||
|
"ServoBundledURI",
|
||||||
"ServoElementSnapshot",
|
"ServoElementSnapshot",
|
||||||
"SheetParsingMode",
|
"SheetParsingMode",
|
||||||
"StyleBasicShape",
|
"StyleBasicShape",
|
||||||
|
@ -550,6 +554,7 @@ mod bindings {
|
||||||
"nsStyleCoord_CalcValue",
|
"nsStyleCoord_CalcValue",
|
||||||
"nsStyleDisplay",
|
"nsStyleDisplay",
|
||||||
"nsStyleEffects",
|
"nsStyleEffects",
|
||||||
|
"nsStyleFilter",
|
||||||
"nsStyleFont",
|
"nsStyleFont",
|
||||||
"nsStyleGradient",
|
"nsStyleGradient",
|
||||||
"nsStyleGradientStop",
|
"nsStyleGradientStop",
|
||||||
|
@ -565,6 +570,7 @@ mod bindings {
|
||||||
"nsStylePosition",
|
"nsStylePosition",
|
||||||
"nsStyleQuoteValues",
|
"nsStyleQuoteValues",
|
||||||
"nsStyleSVG",
|
"nsStyleSVG",
|
||||||
|
"nsStyleSVGPaint",
|
||||||
"nsStyleSVGReset",
|
"nsStyleSVGReset",
|
||||||
"nsStyleTable",
|
"nsStyleTable",
|
||||||
"nsStyleTableBorder",
|
"nsStyleTableBorder",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
pub use nsstring::{nsACString, nsAString};
|
pub use nsstring::{nsACString, nsAString};
|
||||||
type nsACString_internal = nsACString;
|
type nsACString_internal = nsACString;
|
||||||
type nsAString_internal = nsAString;
|
type nsAString_internal = nsAString;
|
||||||
|
use gecko_bindings::structs::mozilla::css::URLValue;
|
||||||
use gecko_bindings::structs::RawGeckoDocument;
|
use gecko_bindings::structs::RawGeckoDocument;
|
||||||
use gecko_bindings::structs::RawGeckoElement;
|
use gecko_bindings::structs::RawGeckoElement;
|
||||||
use gecko_bindings::structs::RawGeckoKeyframeList;
|
use gecko_bindings::structs::RawGeckoKeyframeList;
|
||||||
|
@ -20,6 +21,7 @@ use gecko_bindings::structs::TraversalRootBehavior;
|
||||||
use gecko_bindings::structs::FontFamilyList;
|
use gecko_bindings::structs::FontFamilyList;
|
||||||
use gecko_bindings::structs::FontFamilyType;
|
use gecko_bindings::structs::FontFamilyType;
|
||||||
use gecko_bindings::structs::Keyframe;
|
use gecko_bindings::structs::Keyframe;
|
||||||
|
use gecko_bindings::structs::ServoBundledURI;
|
||||||
use gecko_bindings::structs::ServoElementSnapshot;
|
use gecko_bindings::structs::ServoElementSnapshot;
|
||||||
use gecko_bindings::structs::SheetParsingMode;
|
use gecko_bindings::structs::SheetParsingMode;
|
||||||
use gecko_bindings::structs::StyleBasicShape;
|
use gecko_bindings::structs::StyleBasicShape;
|
||||||
|
@ -69,6 +71,9 @@ unsafe impl Sync for nsStyleDisplay {}
|
||||||
use gecko_bindings::structs::nsStyleEffects;
|
use gecko_bindings::structs::nsStyleEffects;
|
||||||
unsafe impl Send for nsStyleEffects {}
|
unsafe impl Send for nsStyleEffects {}
|
||||||
unsafe impl Sync for nsStyleEffects {}
|
unsafe impl Sync for nsStyleEffects {}
|
||||||
|
use gecko_bindings::structs::nsStyleFilter;
|
||||||
|
unsafe impl Send for nsStyleFilter {}
|
||||||
|
unsafe impl Sync for nsStyleFilter {}
|
||||||
use gecko_bindings::structs::nsStyleFont;
|
use gecko_bindings::structs::nsStyleFont;
|
||||||
unsafe impl Send for nsStyleFont {}
|
unsafe impl Send for nsStyleFont {}
|
||||||
unsafe impl Sync for nsStyleFont {}
|
unsafe impl Sync for nsStyleFont {}
|
||||||
|
@ -114,6 +119,9 @@ unsafe impl Sync for nsStyleQuoteValues {}
|
||||||
use gecko_bindings::structs::nsStyleSVG;
|
use gecko_bindings::structs::nsStyleSVG;
|
||||||
unsafe impl Send for nsStyleSVG {}
|
unsafe impl Send for nsStyleSVG {}
|
||||||
unsafe impl Sync for nsStyleSVG {}
|
unsafe impl Sync for nsStyleSVG {}
|
||||||
|
use gecko_bindings::structs::nsStyleSVGPaint;
|
||||||
|
unsafe impl Send for nsStyleSVGPaint {}
|
||||||
|
unsafe impl Sync for nsStyleSVGPaint {}
|
||||||
use gecko_bindings::structs::nsStyleSVGReset;
|
use gecko_bindings::structs::nsStyleSVGReset;
|
||||||
unsafe impl Send for nsStyleSVGReset {}
|
unsafe impl Send for nsStyleSVGReset {}
|
||||||
unsafe impl Sync for nsStyleSVGReset {}
|
unsafe impl Sync for nsStyleSVGReset {}
|
||||||
|
@ -590,11 +598,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_SetListStyleImage(style_struct: *mut nsStyleList,
|
pub fn Gecko_SetListStyleImage(style_struct: *mut nsStyleList,
|
||||||
string_bytes: *const u8,
|
uri: ServoBundledURI);
|
||||||
string_length: u32,
|
|
||||||
base_uri: *mut ThreadSafeURIHolder,
|
|
||||||
referrer: *mut ThreadSafeURIHolder,
|
|
||||||
principal: *mut ThreadSafePrincipalHolder);
|
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_CopyListStyleImageFrom(dest: *mut nsStyleList,
|
pub fn Gecko_CopyListStyleImageFrom(dest: *mut nsStyleList,
|
||||||
|
@ -615,17 +619,6 @@ extern "C" {
|
||||||
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
|
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
|
||||||
src: *const nsStyleUserInterface);
|
src: *const nsStyleUserInterface);
|
||||||
}
|
}
|
||||||
extern "C" {
|
|
||||||
pub fn Gecko_SetMozBinding(style_struct: *mut nsStyleDisplay,
|
|
||||||
string_bytes: *const u8, string_length: u32,
|
|
||||||
base_uri: *mut ThreadSafeURIHolder,
|
|
||||||
referrer: *mut ThreadSafeURIHolder,
|
|
||||||
principal: *mut ThreadSafePrincipalHolder);
|
|
||||||
}
|
|
||||||
extern "C" {
|
|
||||||
pub fn Gecko_CopyMozBindingFrom(des: *mut nsStyleDisplay,
|
|
||||||
src: *const nsStyleDisplay);
|
|
||||||
}
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32;
|
pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32;
|
||||||
}
|
}
|
||||||
|
@ -707,6 +700,10 @@ extern "C" {
|
||||||
pub fn Gecko_NewBasicShape(type_: StyleBasicShapeType)
|
pub fn Gecko_NewBasicShape(type_: StyleBasicShapeType)
|
||||||
-> *mut StyleBasicShape;
|
-> *mut StyleBasicShape;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_StyleClipPath_SetURLValue(clip: *mut StyleClipPath,
|
||||||
|
uri: ServoBundledURI);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_ResetFilters(effects: *mut nsStyleEffects, new_len: usize);
|
pub fn Gecko_ResetFilters(effects: *mut nsStyleEffects, new_len: usize);
|
||||||
}
|
}
|
||||||
|
@ -714,6 +711,38 @@ extern "C" {
|
||||||
pub fn Gecko_CopyFiltersFrom(aSrc: *mut nsStyleEffects,
|
pub fn Gecko_CopyFiltersFrom(aSrc: *mut nsStyleEffects,
|
||||||
aDest: *mut nsStyleEffects);
|
aDest: *mut nsStyleEffects);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleFilter_SetURLValue(effects: *mut nsStyleFilter,
|
||||||
|
uri: ServoBundledURI);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVGPaint_CopyFrom(dest: *mut nsStyleSVGPaint,
|
||||||
|
src: *const nsStyleSVGPaint);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVGPaint_SetURLValue(paint: *mut nsStyleSVGPaint,
|
||||||
|
uri: ServoBundledURI);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVGPaint_Reset(paint: *mut nsStyleSVGPaint);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVG_SetDashArrayLength(svg: *mut nsStyleSVG,
|
||||||
|
len: u32);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVG_CopyDashArray(dst: *mut nsStyleSVG,
|
||||||
|
src: *const nsStyleSVG);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_NewURLValue(uri: ServoBundledURI) -> *mut URLValue;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_AddRefCSSURLValueArbitraryThread(aPtr: *mut URLValue);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_ReleaseCSSURLValueArbitraryThread(aPtr: *mut URLValue);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_FillAllBackgroundLists(layers: *mut nsStyleImageLayers,
|
pub fn Gecko_FillAllBackgroundLists(layers: *mut nsStyleImageLayers,
|
||||||
max_len: u32);
|
max_len: u32);
|
||||||
|
|
|
@ -25363,6 +25363,23 @@ pub mod root {
|
||||||
pub type ThreadSafePrincipalHolder =
|
pub type ThreadSafePrincipalHolder =
|
||||||
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
||||||
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy)]
|
||||||
|
pub struct ServoBundledURI {
|
||||||
|
pub mURLString: *const u8,
|
||||||
|
pub mURLStringLength: u32,
|
||||||
|
pub mBaseURI: *mut root::ThreadSafeURIHolder,
|
||||||
|
pub mReferrer: *mut root::ThreadSafeURIHolder,
|
||||||
|
pub mPrincipal: *mut root::ThreadSafePrincipalHolder,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_ServoBundledURI() {
|
||||||
|
assert_eq!(::std::mem::size_of::<ServoBundledURI>() , 40usize);
|
||||||
|
assert_eq!(::std::mem::align_of::<ServoBundledURI>() , 8usize);
|
||||||
|
}
|
||||||
|
impl Clone for ServoBundledURI {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
pub type nsMediaFeatureValueGetter =
|
pub type nsMediaFeatureValueGetter =
|
||||||
::std::option::Option<unsafe extern "C" fn(aPresContext:
|
::std::option::Option<unsafe extern "C" fn(aPresContext:
|
||||||
*mut root::nsPresContext,
|
*mut root::nsPresContext,
|
||||||
|
|
|
@ -24719,6 +24719,23 @@ pub mod root {
|
||||||
pub type ThreadSafePrincipalHolder =
|
pub type ThreadSafePrincipalHolder =
|
||||||
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
||||||
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy)]
|
||||||
|
pub struct ServoBundledURI {
|
||||||
|
pub mURLString: *const u8,
|
||||||
|
pub mURLStringLength: u32,
|
||||||
|
pub mBaseURI: *mut root::ThreadSafeURIHolder,
|
||||||
|
pub mReferrer: *mut root::ThreadSafeURIHolder,
|
||||||
|
pub mPrincipal: *mut root::ThreadSafePrincipalHolder,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_ServoBundledURI() {
|
||||||
|
assert_eq!(::std::mem::size_of::<ServoBundledURI>() , 40usize);
|
||||||
|
assert_eq!(::std::mem::align_of::<ServoBundledURI>() , 8usize);
|
||||||
|
}
|
||||||
|
impl Clone for ServoBundledURI {
|
||||||
|
fn clone(&self) -> Self { *self }
|
||||||
|
}
|
||||||
pub type nsMediaFeatureValueGetter =
|
pub type nsMediaFeatureValueGetter =
|
||||||
::std::option::Option<unsafe extern "C" fn(aPresContext:
|
::std::option::Option<unsafe extern "C" fn(aPresContext:
|
||||||
*mut root::nsPresContext,
|
*mut root::nsPresContext,
|
||||||
|
|
|
@ -264,6 +264,9 @@ impl_threadsafe_refcount!(::gecko_bindings::structs::nsStyleQuoteValues,
|
||||||
impl_threadsafe_refcount!(::gecko_bindings::structs::nsCSSValueSharedList,
|
impl_threadsafe_refcount!(::gecko_bindings::structs::nsCSSValueSharedList,
|
||||||
Gecko_AddRefCSSValueSharedListArbitraryThread,
|
Gecko_AddRefCSSValueSharedListArbitraryThread,
|
||||||
Gecko_ReleaseCSSValueSharedListArbitraryThread);
|
Gecko_ReleaseCSSValueSharedListArbitraryThread);
|
||||||
|
impl_threadsafe_refcount!(::gecko_bindings::structs::mozilla::css::URLValue,
|
||||||
|
Gecko_AddRefCSSURLValueArbitraryThread,
|
||||||
|
Gecko_ReleaseCSSURLValueArbitraryThread);
|
||||||
/// A Gecko `ThreadSafePrincipalHolder` wrapped in a safe refcounted pointer, to
|
/// A Gecko `ThreadSafePrincipalHolder` wrapped in a safe refcounted pointer, to
|
||||||
/// use during stylesheet parsing and style computation.
|
/// use during stylesheet parsing and style computation.
|
||||||
pub type GeckoArcPrincipal = RefPtr<::gecko_bindings::structs::ThreadSafePrincipalHolder>;
|
pub type GeckoArcPrincipal = RefPtr<::gecko_bindings::structs::ThreadSafePrincipalHolder>;
|
||||||
|
|
|
@ -110,6 +110,22 @@ impl<T> Parse for Vec<T> where T: Parse + OneOrMoreCommaSeparated {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a non-empty space-separated or comma-separated list of objects parsed by parse_one
|
||||||
|
pub fn parse_space_or_comma_separated<F, T>(input: &mut Parser, mut parse_one: F)
|
||||||
|
-> Result<Vec<T>, ()>
|
||||||
|
where F: FnMut(&mut Parser) -> Result<T, ()> {
|
||||||
|
let first = parse_one(input)?;
|
||||||
|
let mut vec = vec![first];
|
||||||
|
loop {
|
||||||
|
let _ = input.try(|i| i.expect_comma());
|
||||||
|
if let Ok(val) = input.try(|i| parse_one(i)) {
|
||||||
|
vec.push(val)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
impl Parse for UnicodeRange {
|
impl Parse for UnicodeRange {
|
||||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
UnicodeRange::parse(input)
|
UnicodeRange::parse(input)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use cssparser::Color;
|
||||||
use custom_properties::ComputedValuesMap;
|
use custom_properties::ComputedValuesMap;
|
||||||
use gecko_bindings::bindings;
|
use gecko_bindings::bindings;
|
||||||
% for style_struct in data.style_structs:
|
% for style_struct in data.style_structs:
|
||||||
|
@ -25,7 +26,6 @@ use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom;
|
||||||
use gecko_bindings::bindings::Gecko_CopyImageValueFrom;
|
use gecko_bindings::bindings::Gecko_CopyImageValueFrom;
|
||||||
use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
|
use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
|
||||||
use gecko_bindings::bindings::Gecko_CopyListStyleTypeFrom;
|
use gecko_bindings::bindings::Gecko_CopyListStyleTypeFrom;
|
||||||
use gecko_bindings::bindings::Gecko_CopyMozBindingFrom;
|
|
||||||
use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
|
use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
|
||||||
use gecko_bindings::bindings::Gecko_FontFamilyList_AppendGeneric;
|
use gecko_bindings::bindings::Gecko_FontFamilyList_AppendGeneric;
|
||||||
use gecko_bindings::bindings::Gecko_FontFamilyList_AppendNamed;
|
use gecko_bindings::bindings::Gecko_FontFamilyList_AppendNamed;
|
||||||
|
@ -36,7 +36,6 @@ use gecko_bindings::bindings::Gecko_NewCSSShadowArray;
|
||||||
use gecko_bindings::bindings::Gecko_SetListStyleImage;
|
use gecko_bindings::bindings::Gecko_SetListStyleImage;
|
||||||
use gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
use gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
||||||
use gecko_bindings::bindings::Gecko_SetListStyleType;
|
use gecko_bindings::bindings::Gecko_SetListStyleType;
|
||||||
use gecko_bindings::bindings::Gecko_SetMozBinding;
|
|
||||||
use gecko_bindings::bindings::Gecko_SetNullImageValue;
|
use gecko_bindings::bindings::Gecko_SetNullImageValue;
|
||||||
use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
|
use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
|
||||||
use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
|
use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
|
||||||
|
@ -274,6 +273,19 @@ def set_gecko_property(ffi_name, expr):
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
||||||
|
/// Convert a Servo color into an nscolor; with currentColor as 0
|
||||||
|
///
|
||||||
|
/// Call sites will need to be updated after https://bugzilla.mozilla.org/show_bug.cgi?id=760345
|
||||||
|
fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
|
||||||
|
match color {
|
||||||
|
Color::RGBA(rgba) => {
|
||||||
|
convert_rgba_to_nscolor(&rgba)
|
||||||
|
},
|
||||||
|
Color::CurrentColor => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<%def name="impl_color_setter(ident, gecko_ffi_name, complex_color=True)">
|
<%def name="impl_color_setter(ident, gecko_ffi_name, complex_color=True)">
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -281,12 +293,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% if complex_color:
|
% if complex_color:
|
||||||
let result = v.into();
|
let result = v.into();
|
||||||
% else:
|
% else:
|
||||||
use cssparser::Color;
|
let result = color_to_nscolor_zero_currentcolor(v);
|
||||||
let result = match v {
|
|
||||||
Color::RGBA(rgba) => convert_rgba_to_nscolor(&rgba),
|
|
||||||
// FIXME #13547
|
|
||||||
Color::CurrentColor => 0,
|
|
||||||
};
|
|
||||||
% endif
|
% endif
|
||||||
${set_gecko_property(gecko_ffi_name, "result")}
|
${set_gecko_property(gecko_ffi_name, "result")}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +313,6 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% if complex_color:
|
% if complex_color:
|
||||||
${get_gecko_property(gecko_ffi_name)}.into()
|
${get_gecko_property(gecko_ffi_name)}.into()
|
||||||
% else:
|
% else:
|
||||||
use cssparser::Color;
|
|
||||||
Color::RGBA(convert_nscolor_to_rgba(${get_gecko_property(gecko_ffi_name)}))
|
Color::RGBA(convert_nscolor_to_rgba(${get_gecko_property(gecko_ffi_name)}))
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
@ -369,6 +375,58 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% endif
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
<%def name="impl_svg_paint(ident, gecko_ffi_name, need_clone=False, complex_color=True)">
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn set_${ident}(&mut self, mut v: longhands::${ident}::computed_value::T) {
|
||||||
|
use values::computed::SVGPaintKind;
|
||||||
|
use self::structs::nsStyleSVGPaintType;
|
||||||
|
|
||||||
|
let ref mut paint = ${get_gecko_property(gecko_ffi_name)};
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVGPaint_Reset(paint);
|
||||||
|
}
|
||||||
|
let fallback = v.fallback.take();
|
||||||
|
match v.kind {
|
||||||
|
SVGPaintKind::None => return,
|
||||||
|
SVGPaintKind::ContextFill => {
|
||||||
|
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextFill;
|
||||||
|
}
|
||||||
|
SVGPaintKind::ContextStroke => {
|
||||||
|
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke;
|
||||||
|
}
|
||||||
|
SVGPaintKind::PaintServer(url) => {
|
||||||
|
unsafe {
|
||||||
|
if let Some(ffi) = url.for_ffi() {
|
||||||
|
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, ffi);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SVGPaintKind::Color(color) => {
|
||||||
|
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color;
|
||||||
|
unsafe {
|
||||||
|
*paint.mPaint.mColor.as_mut() = color_to_nscolor_zero_currentcolor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fallback) = fallback {
|
||||||
|
paint.mFallbackColor = color_to_nscolor_zero_currentcolor(fallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVGPaint_CopyFrom(
|
||||||
|
&mut ${get_gecko_property(gecko_ffi_name)},
|
||||||
|
& ${get_gecko_property(gecko_ffi_name, "other")}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
|
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
|
@ -455,6 +513,41 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% endif
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
<%def name="impl_css_url(ident, gecko_ffi_name, need_clone=False)">
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
|
use gecko_bindings::sugar::refptr::RefPtr;
|
||||||
|
match v {
|
||||||
|
Either::First(url) => {
|
||||||
|
let refptr = unsafe {
|
||||||
|
if let Some(ffi) = url.for_ffi() {
|
||||||
|
let ptr = bindings::Gecko_NewURLValue(ffi);
|
||||||
|
RefPtr::from_addrefed(ptr)
|
||||||
|
} else {
|
||||||
|
self.gecko.${gecko_ffi_name}.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.gecko.${gecko_ffi_name}.set_move(refptr)
|
||||||
|
}
|
||||||
|
Either::Second(_none) => {
|
||||||
|
unsafe {
|
||||||
|
self.gecko.${gecko_ffi_name}.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
self.gecko.${gecko_ffi_name}.set(&other.gecko.${gecko_ffi_name});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% if need_clone:
|
||||||
|
<% raise Exception("Do not know how to handle clone ") %>
|
||||||
|
% endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_logical(name, need_clone=False, **kwargs)">
|
<%def name="impl_logical(name, need_clone=False, **kwargs)">
|
||||||
${helpers.logical_setter(name, need_clone)}
|
${helpers.logical_setter(name, need_clone)}
|
||||||
</%def>
|
</%def>
|
||||||
|
@ -543,6 +636,8 @@ impl Debug for ${style_struct.gecko_struct_name} {
|
||||||
"Number": impl_simple,
|
"Number": impl_simple,
|
||||||
"Opacity": impl_simple,
|
"Opacity": impl_simple,
|
||||||
"CSSColor": impl_color,
|
"CSSColor": impl_color,
|
||||||
|
"SVGPaint": impl_svg_paint,
|
||||||
|
"UrlOrNone": impl_css_url,
|
||||||
}
|
}
|
||||||
|
|
||||||
def longhand_method(longhand):
|
def longhand_method(longhand):
|
||||||
|
@ -1221,7 +1316,7 @@ fn static_assert() {
|
||||||
animation-name animation-delay animation-duration
|
animation-name animation-delay animation-duration
|
||||||
animation-direction animation-fill-mode animation-play-state
|
animation-direction animation-fill-mode animation-play-state
|
||||||
animation-iteration-count animation-timing-function
|
animation-iteration-count animation-timing-function
|
||||||
-moz-binding page-break-before page-break-after
|
page-break-before page-break-after
|
||||||
scroll-snap-points-x scroll-snap-points-y transform
|
scroll-snap-points-x scroll-snap-points-y transform
|
||||||
scroll-snap-type-y scroll-snap-coordinate
|
scroll-snap-type-y scroll-snap-coordinate
|
||||||
perspective-origin transform-origin""" %>
|
perspective-origin transform-origin""" %>
|
||||||
|
@ -1316,33 +1411,6 @@ fn static_assert() {
|
||||||
|
|
||||||
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
|
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
|
|
||||||
use values::Either;
|
|
||||||
match v {
|
|
||||||
Either::Second(_none) => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
|
|
||||||
Either::First(ref url) => {
|
|
||||||
let extra_data = url.extra_data();
|
|
||||||
let (ptr, len) = match url.as_slice_components() {
|
|
||||||
Ok(value) => value,
|
|
||||||
Err(_) => (ptr::null(), 0),
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
Gecko_SetMozBinding(&mut self.gecko,
|
|
||||||
ptr,
|
|
||||||
len as u32,
|
|
||||||
extra_data.base.get(),
|
|
||||||
extra_data.referrer.get(),
|
|
||||||
extra_data.principal.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn copy__moz_binding_from(&mut self, other: &Self) {
|
|
||||||
unsafe { Gecko_CopyMozBindingFrom(&mut self.gecko, &other.gecko); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temp fix for Bugzilla bug 24000.
|
// Temp fix for Bugzilla bug 24000.
|
||||||
// Map 'auto' and 'avoid' to false, and 'always', 'left', and 'right' to true.
|
// Map 'auto' and 'avoid' to false, and 'always', 'left', and 'right' to true.
|
||||||
// "A conforming user agent may interpret the values 'left' and 'right'
|
// "A conforming user agent may interpret the values 'left' and 'right'
|
||||||
|
@ -2066,17 +2134,13 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Either::First(ref url) => {
|
Either::First(ref url) => {
|
||||||
let (ptr, len) = match url.as_slice_components() {
|
|
||||||
Ok(value) | Err(value) => value
|
|
||||||
};
|
|
||||||
let extra_data = url.extra_data();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetListStyleImage(&mut self.gecko,
|
if let Some(ffi) = url.for_ffi() {
|
||||||
ptr,
|
Gecko_SetListStyleImage(&mut self.gecko,
|
||||||
len as u32,
|
ffi);
|
||||||
extra_data.base.get(),
|
} else {
|
||||||
extra_data.referrer.get(),
|
Gecko_SetListStyleImageNone(&mut self.gecko);
|
||||||
extra_data.principal.get());
|
}
|
||||||
}
|
}
|
||||||
// We don't need to record this struct as uncacheable, like when setting
|
// 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
|
// background-image to a url() value, since only properties in reset structs
|
||||||
|
@ -2147,7 +2211,6 @@ fn static_assert() {
|
||||||
<%self:impl_trait style_struct_name="Effects"
|
<%self:impl_trait style_struct_name="Effects"
|
||||||
skip_longhands="box-shadow filter">
|
skip_longhands="box-shadow filter">
|
||||||
pub fn set_box_shadow(&mut self, v: longhands::box_shadow::computed_value::T) {
|
pub fn set_box_shadow(&mut self, v: longhands::box_shadow::computed_value::T) {
|
||||||
use cssparser::Color;
|
|
||||||
|
|
||||||
self.gecko.mBoxShadow.replace_with_new(v.0.len() as u32);
|
self.gecko.mBoxShadow.replace_with_new(v.0.len() as u32);
|
||||||
|
|
||||||
|
@ -2178,8 +2241,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_box_shadow(&self) -> longhands::box_shadow::computed_value::T {
|
pub fn clone_box_shadow(&self) -> longhands::box_shadow::computed_value::T {
|
||||||
use cssparser::Color;
|
|
||||||
|
|
||||||
let buf = self.gecko.mBoxShadow.iter().map(|shadow| {
|
let buf = self.gecko.mBoxShadow.iter().map(|shadow| {
|
||||||
longhands::box_shadow::single_value::computed_value::T {
|
longhands::box_shadow::single_value::computed_value::T {
|
||||||
offset_x: Au(shadow.mXOffset),
|
offset_x: Au(shadow.mXOffset),
|
||||||
|
@ -2194,7 +2255,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_filter(&mut self, v: longhands::filter::computed_value::T) {
|
pub fn set_filter(&mut self, v: longhands::filter::computed_value::T) {
|
||||||
use cssparser::Color;
|
|
||||||
use properties::longhands::filter::computed_value::Filter::*;
|
use properties::longhands::filter::computed_value::Filter::*;
|
||||||
use gecko_bindings::structs::nsCSSShadowArray;
|
use gecko_bindings::structs::nsCSSShadowArray;
|
||||||
use gecko_bindings::structs::nsStyleFilter;
|
use gecko_bindings::structs::nsStyleFilter;
|
||||||
|
@ -2279,6 +2339,13 @@ fn static_assert() {
|
||||||
Color::CurrentColor => 0,
|
Color::CurrentColor => 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Url(ref url) => {
|
||||||
|
unsafe {
|
||||||
|
if let Some(ffi) = url.for_ffi() {
|
||||||
|
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, ffi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2316,7 +2383,6 @@ fn static_assert() {
|
||||||
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
|
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
|
||||||
|
|
||||||
pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) {
|
pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) {
|
||||||
use cssparser::Color;
|
|
||||||
self.gecko.mTextShadow.replace_with_new(v.0.len() as u32);
|
self.gecko.mTextShadow.replace_with_new(v.0.len() as u32);
|
||||||
|
|
||||||
for (servo, gecko_shadow) in v.0.into_iter()
|
for (servo, gecko_shadow) in v.0.into_iter()
|
||||||
|
@ -2344,7 +2410,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_text_shadow(&self) -> longhands::text_shadow::computed_value::T {
|
pub fn clone_text_shadow(&self) -> longhands::text_shadow::computed_value::T {
|
||||||
use cssparser::Color;
|
|
||||||
|
|
||||||
let buf = self.gecko.mTextShadow.iter().map(|shadow| {
|
let buf = self.gecko.mTextShadow.iter().map(|shadow| {
|
||||||
longhands::text_shadow::computed_value::TextShadow {
|
longhands::text_shadow::computed_value::TextShadow {
|
||||||
|
@ -2636,7 +2701,13 @@ clip-path
|
||||||
clip_path.mType = StyleShapeSourceType::None;
|
clip_path.mType = StyleShapeSourceType::None;
|
||||||
|
|
||||||
match v {
|
match v {
|
||||||
ShapeSource::Url(..) => warn!("stylo: clip-path: url() not yet implemented"),
|
ShapeSource::Url(ref url) => {
|
||||||
|
unsafe {
|
||||||
|
if let Some(ffi) = url.for_ffi() {
|
||||||
|
bindings::Gecko_StyleClipPath_SetURLValue(clip_path, ffi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ShapeSource::None => {} // don't change the type
|
ShapeSource::None => {} // don't change the type
|
||||||
ShapeSource::Box(reference) => {
|
ShapeSource::Box(reference) => {
|
||||||
clip_path.mReferenceBox = reference.into();
|
clip_path.mReferenceBox = reference.into();
|
||||||
|
@ -2726,32 +2797,51 @@ clip-path
|
||||||
Gecko_CopyClipPathValueFrom(&mut self.gecko.mClipPath, &other.gecko.mClipPath);
|
Gecko_CopyClipPathValueFrom(&mut self.gecko.mClipPath, &other.gecko.mClipPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</%self:impl_trait>
|
||||||
|
|
||||||
pub fn clone_clip_path(&self) -> longhands::clip_path::computed_value::T {
|
<%self:impl_trait style_struct_name="InheritedSVG"
|
||||||
use gecko_bindings::structs::StyleShapeSourceType;
|
skip_longhands="paint-order stroke-dasharray"
|
||||||
use gecko_bindings::structs::StyleGeometryBox;
|
skip_additionals="*">
|
||||||
use values::computed::basic_shape::*;
|
pub fn set_paint_order(&mut self, v: longhands::paint_order::computed_value::T) {
|
||||||
let ref clip_path = self.gecko.mClipPath;
|
use self::longhands::paint_order;
|
||||||
|
|
||||||
match clip_path.mType {
|
if v.0 == 0 {
|
||||||
StyleShapeSourceType::None => ShapeSource::None,
|
self.gecko.mPaintOrder = structs::NS_STYLE_PAINT_ORDER_NORMAL as u8;
|
||||||
StyleShapeSourceType::Box => {
|
} else {
|
||||||
ShapeSource::Box(clip_path.mReferenceBox.into())
|
let mut order = 0;
|
||||||
}
|
|
||||||
StyleShapeSourceType::URL => {
|
for pos in 0..3 {
|
||||||
warn!("stylo: clip-path: url() not implemented yet");
|
let geckoval = match v.bits_at(pos) {
|
||||||
Default::default()
|
paint_order::FILL => structs::NS_STYLE_PAINT_ORDER_FILL as u8,
|
||||||
}
|
paint_order::STROKE => structs::NS_STYLE_PAINT_ORDER_STROKE as u8,
|
||||||
StyleShapeSourceType::Shape => {
|
paint_order::MARKERS => structs::NS_STYLE_PAINT_ORDER_MARKERS as u8,
|
||||||
let reference = if let StyleGeometryBox::NoBox = clip_path.mReferenceBox {
|
_ => unreachable!(),
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(clip_path.mReferenceBox.into())
|
|
||||||
};
|
};
|
||||||
let union = clip_path.__bindgen_anon_1;
|
order |= geckoval << (pos * structs::NS_STYLE_PAINT_ORDER_BITWIDTH as u8);
|
||||||
let shape = unsafe { &**union.mBasicShape.as_ref() };
|
|
||||||
ShapeSource::Shape(shape.into(), reference)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.gecko.mPaintOrder = order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${impl_simple_copy('paint_order', 'mPaintOrder')}
|
||||||
|
|
||||||
|
pub fn set_stroke_dasharray(&mut self, v: longhands::stroke_dasharray::computed_value::T) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVG_SetDashArrayLength(&mut self.gecko, v.0.len() as u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mut gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v.0.into_iter()) {
|
||||||
|
match servo {
|
||||||
|
Either::First(lop) => gecko.set(lop),
|
||||||
|
Either::Second(number) => gecko.set_value(CoordDataValue::Factor(number)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_stroke_dasharray_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVG_CopyDashArray(&mut self.gecko, &other.gecko);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
|
@ -66,7 +66,8 @@
|
||||||
We assume that the default/initial value is an empty vector for these.
|
We assume that the default/initial value is an empty vector for these.
|
||||||
`initial_value` need not be defined for these.
|
`initial_value` need not be defined for these.
|
||||||
</%doc>
|
</%doc>
|
||||||
<%def name="vector_longhand(name, gecko_only=False, allow_empty=False, delegate_animate=False, **kwargs)">
|
<%def name="vector_longhand(name, gecko_only=False, allow_empty=False,
|
||||||
|
delegate_animate=False, space_separated_allowed=False, **kwargs)">
|
||||||
<%call expr="longhand(name, **kwargs)">
|
<%call expr="longhand(name, **kwargs)">
|
||||||
% if not gecko_only:
|
% if not gecko_only:
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -86,6 +87,7 @@
|
||||||
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
|
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
use values::{computed, specified};
|
use values::{computed, specified};
|
||||||
|
use values::{Auto, Either, None_, Normal};
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,16 +168,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
|
use parser::parse_space_or_comma_separated;
|
||||||
|
|
||||||
|
<%
|
||||||
|
parse_func = "Parser::parse_comma_separated"
|
||||||
|
if space_separated_allowed:
|
||||||
|
parse_func = "parse_space_or_comma_separated"
|
||||||
|
%>
|
||||||
% if allow_empty:
|
% if allow_empty:
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
Ok(SpecifiedValue(Vec::new()))
|
Ok(SpecifiedValue(Vec::new()))
|
||||||
} else {
|
} else {
|
||||||
input.parse_comma_separated(|parser| {
|
${parse_func}(input, |parser| {
|
||||||
single_value::parse(context, parser)
|
single_value::parse(context, parser)
|
||||||
}).map(SpecifiedValue)
|
}).map(SpecifiedValue)
|
||||||
}
|
}
|
||||||
% else:
|
% else:
|
||||||
input.parse_comma_separated(|parser| {
|
${parse_func}(input, |parser| {
|
||||||
single_value::parse(context, parser)
|
single_value::parse(context, parser)
|
||||||
}).map(SpecifiedValue)
|
}).map(SpecifiedValue)
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -1922,6 +1922,7 @@ ${helpers.single_keyword("-moz-appearance",
|
||||||
${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)",
|
${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
animatable="False",
|
animatable="False",
|
||||||
|
gecko_ffi_name="mBinding",
|
||||||
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)",
|
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)",
|
||||||
disable_when_testing="True",
|
disable_when_testing="True",
|
||||||
boxed=True)}
|
boxed=True)}
|
||||||
|
|
|
@ -94,6 +94,7 @@ ${helpers.predefined_type("clip",
|
||||||
use style_traits::{self, ToCss};
|
use style_traits::{self, ToCss};
|
||||||
use values::{CSSFloat, HasViewportPercentage};
|
use values::{CSSFloat, HasViewportPercentage};
|
||||||
use values::specified::{Angle, CSSColor, Length, Shadow};
|
use values::specified::{Angle, CSSColor, Length, Shadow};
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedValue {
|
impl HasViewportPercentage for SpecifiedValue {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
|
@ -129,6 +130,7 @@ ${helpers.predefined_type("clip",
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
DropShadow(Shadow),
|
DropShadow(Shadow),
|
||||||
|
Url(SpecifiedUrl),
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +138,8 @@ ${helpers.predefined_type("clip",
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
use values::computed::{CSSColor, Shadow};
|
use values::computed::{CSSColor, Shadow};
|
||||||
use values::specified::{Angle};
|
use values::specified::Angle;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||||
|
@ -152,6 +155,7 @@ ${helpers.predefined_type("clip",
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
DropShadow(Shadow),
|
DropShadow(Shadow),
|
||||||
|
Url(SpecifiedUrl),
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +266,11 @@ ${helpers.predefined_type("clip",
|
||||||
try!(shadow.color.to_css(dest));
|
try!(shadow.color.to_css(dest));
|
||||||
try!(dest.write_str(")"));
|
try!(dest.write_str(")"));
|
||||||
}
|
}
|
||||||
|
computed_value::Filter::Url(ref url) => {
|
||||||
|
dest.write_str("url(")?;
|
||||||
|
url.to_css(dest)?;
|
||||||
|
dest.write_str(")")?;
|
||||||
|
}
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -302,6 +311,11 @@ ${helpers.predefined_type("clip",
|
||||||
}
|
}
|
||||||
try!(dest.write_str(")"));
|
try!(dest.write_str(")"));
|
||||||
}
|
}
|
||||||
|
SpecifiedFilter::Url(ref url) => {
|
||||||
|
dest.write_str("url(")?;
|
||||||
|
url.to_css(dest)?;
|
||||||
|
dest.write_str(")")?;
|
||||||
|
}
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -319,6 +333,11 @@ ${helpers.predefined_type("clip",
|
||||||
return Ok(SpecifiedValue(filters))
|
return Ok(SpecifiedValue(filters))
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
|
% if product == "gecko":
|
||||||
|
if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) {
|
||||||
|
filters.push(SpecifiedFilter::Url(url));
|
||||||
|
} else
|
||||||
|
% endif
|
||||||
if let Ok(function_name) = input.try(|input| input.expect_function()) {
|
if let Ok(function_name) = input.try(|input| input.expect_function()) {
|
||||||
filters.push(try!(input.parse_nested_block(|input| {
|
filters.push(try!(input.parse_nested_block(|input| {
|
||||||
match_ignore_ascii_case! { function_name,
|
match_ignore_ascii_case! { function_name,
|
||||||
|
@ -375,6 +394,9 @@ ${helpers.predefined_type("clip",
|
||||||
SpecifiedFilter::DropShadow(ref shadow) => {
|
SpecifiedFilter::DropShadow(ref shadow) => {
|
||||||
computed_value::Filter::DropShadow(shadow.to_computed_value(context))
|
computed_value::Filter::DropShadow(shadow.to_computed_value(context))
|
||||||
},
|
},
|
||||||
|
SpecifiedFilter::Url(ref url) => {
|
||||||
|
computed_value::Filter::Url(url.to_computed_value(context))
|
||||||
|
}
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
}).collect() }
|
}).collect() }
|
||||||
|
@ -394,9 +416,14 @@ ${helpers.predefined_type("clip",
|
||||||
computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor),
|
computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor),
|
||||||
computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor),
|
computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
computed_value::Filter::DropShadow(shadow) => {
|
computed_value::Filter::DropShadow(ref shadow) => {
|
||||||
SpecifiedFilter::DropShadow(
|
SpecifiedFilter::DropShadow(
|
||||||
ToComputedValue::from_computed_value(&shadow),
|
ToComputedValue::from_computed_value(shadow),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
computed_value::Filter::Url(ref url) => {
|
||||||
|
SpecifiedFilter::Url(
|
||||||
|
ToComputedValue::from_computed_value(url),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -33,6 +33,14 @@ ${helpers.single_keyword("color-interpolation-filters", "auto sRGB linearRGB",
|
||||||
animatable=False,
|
animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"fill", "SVGPaint",
|
||||||
|
"::values::computed::SVGPaint::black()",
|
||||||
|
products="gecko",
|
||||||
|
animatable=False,
|
||||||
|
boxed=True,
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint")}
|
||||||
|
|
||||||
${helpers.predefined_type("fill-opacity", "Opacity", "1.0",
|
${helpers.predefined_type("fill-opacity", "Opacity", "1.0",
|
||||||
products="gecko", animatable=False,
|
products="gecko", animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}
|
||||||
|
@ -49,6 +57,23 @@ ${helpers.single_keyword("shape-rendering",
|
||||||
animatable=False,
|
animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"stroke", "SVGPaint",
|
||||||
|
"Default::default()",
|
||||||
|
products="gecko",
|
||||||
|
animatable=False,
|
||||||
|
boxed=True,
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"stroke-width", "LengthOrPercentage",
|
||||||
|
"computed::LengthOrPercentage::one()",
|
||||||
|
"parse_numbers_are_pixels_non_negative",
|
||||||
|
products="gecko",
|
||||||
|
animatable=True,
|
||||||
|
needs_context=False,
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth")}
|
||||||
|
|
||||||
${helpers.single_keyword("stroke-linecap", "butt round square",
|
${helpers.single_keyword("stroke-linecap", "butt round square",
|
||||||
products="gecko", animatable=False,
|
products="gecko", animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty")}
|
||||||
|
@ -67,6 +92,23 @@ ${helpers.predefined_type("stroke-opacity", "Opacity", "1.0",
|
||||||
products="gecko", animatable=False,
|
products="gecko", animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type("stroke-dasharray", "LoPOrNumber", "Either::Second(0.0)",
|
||||||
|
"parse_non_negative",
|
||||||
|
vector="True",
|
||||||
|
products="gecko",
|
||||||
|
animatable="False",
|
||||||
|
space_separated_allowed="True",
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"stroke-dashoffset", "LengthOrPercentage",
|
||||||
|
"computed::LengthOrPercentage::zero()",
|
||||||
|
"parse_numbers_are_pixels",
|
||||||
|
products="gecko",
|
||||||
|
animatable=True,
|
||||||
|
needs_context=False,
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}
|
||||||
|
|
||||||
// Section 14 - Clipping, Masking and Compositing
|
// Section 14 - Clipping, Masking and Compositing
|
||||||
${helpers.single_keyword("clip-rule", "nonzero evenodd",
|
${helpers.single_keyword("clip-rule", "nonzero evenodd",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
|
@ -74,3 +116,153 @@ ${helpers.single_keyword("clip-rule", "nonzero evenodd",
|
||||||
gecko_inexhaustive=True,
|
gecko_inexhaustive=True,
|
||||||
animatable=False,
|
animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty")}
|
spec="https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type("marker-start", "UrlOrNone", "Either::Second(None_)",
|
||||||
|
products="gecko",
|
||||||
|
animatable="False",
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}
|
||||||
|
|
||||||
|
${helpers.predefined_type("marker-mid", "UrlOrNone", "Either::Second(None_)",
|
||||||
|
products="gecko",
|
||||||
|
animatable="False",
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}
|
||||||
|
|
||||||
|
${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
|
||||||
|
products="gecko",
|
||||||
|
animatable="False",
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")}
|
||||||
|
|
||||||
|
<%helpers:longhand name="paint-order"
|
||||||
|
animatable="False"
|
||||||
|
products="gecko"
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder">
|
||||||
|
|
||||||
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
use std::fmt;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
use values::HasViewportPercentage;
|
||||||
|
|
||||||
|
pub const NORMAL: u8 = 0;
|
||||||
|
pub const FILL: u8 = 1;
|
||||||
|
pub const STROKE: u8 = 2;
|
||||||
|
pub const MARKERS: u8 = 3;
|
||||||
|
|
||||||
|
// number of bits for each component
|
||||||
|
pub const SHIFT: u8 = 2;
|
||||||
|
// mask with above bits set
|
||||||
|
pub const MASK: u8 = 0b11;
|
||||||
|
// number of non-normal keyword values
|
||||||
|
pub const COUNT: u8 = 3;
|
||||||
|
// all keywords
|
||||||
|
pub const ALL: [u8; 3] = [FILL, STROKE, MARKERS];
|
||||||
|
|
||||||
|
/// Represented as a six-bit field, of 3 two-bit pairs
|
||||||
|
///
|
||||||
|
/// Each pair can be set to FILL, STROKE, or MARKERS
|
||||||
|
/// Lowest significant bit pairs are highest priority.
|
||||||
|
/// `normal` is the empty bitfield. The three pairs are
|
||||||
|
/// never zero in any case other than `normal`.
|
||||||
|
///
|
||||||
|
/// Higher priority values, i.e. the values specified first,
|
||||||
|
/// will be painted first (and may be covered by paintings of lower priority)
|
||||||
|
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct SpecifiedValue(pub u8);
|
||||||
|
|
||||||
|
pub mod computed_value {
|
||||||
|
pub use super::SpecifiedValue as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_initial_value() -> SpecifiedValue {
|
||||||
|
SpecifiedValue(NORMAL)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpecifiedValue {
|
||||||
|
pub fn bits_at(&self, pos: u8) -> u8 {
|
||||||
|
(self.0 >> pos * SHIFT) & MASK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
|
||||||
|
if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
|
||||||
|
Ok(SpecifiedValue(0))
|
||||||
|
} else {
|
||||||
|
let mut value = 0;
|
||||||
|
// bitfield representing what we've seen so far
|
||||||
|
// bit 1 is fill, bit 2 is stroke, bit 3 is markers
|
||||||
|
let mut seen = 0;
|
||||||
|
let mut pos = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
|
||||||
|
let result = input.try(|i| {
|
||||||
|
match_ignore_ascii_case! { i.expect_ident()?,
|
||||||
|
"fill" => Ok(FILL),
|
||||||
|
"stroke" => Ok(STROKE),
|
||||||
|
"markers" => Ok(MARKERS),
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(val) => {
|
||||||
|
if (seen & (1 << val)) != 0 {
|
||||||
|
// don't parse the same ident twice
|
||||||
|
return Err(())
|
||||||
|
} else {
|
||||||
|
value |= val << (pos * SHIFT);
|
||||||
|
seen |= 1 << val;
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(()) => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if value == 0 {
|
||||||
|
// couldn't find any keyword
|
||||||
|
Err(())
|
||||||
|
} else {
|
||||||
|
// fill in rest
|
||||||
|
for i in pos..COUNT {
|
||||||
|
for paint in &ALL {
|
||||||
|
// if not seen, set bit at position, mark as seen
|
||||||
|
if (seen & (1 << paint)) == 0 {
|
||||||
|
seen |= 1 << paint;
|
||||||
|
value |= paint << (i * SHIFT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(SpecifiedValue(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
if self.0 == 0 {
|
||||||
|
return dest.write_str("normal")
|
||||||
|
}
|
||||||
|
|
||||||
|
for pos in 0..COUNT {
|
||||||
|
if pos != 0 {
|
||||||
|
dest.write_str(" ")?
|
||||||
|
}
|
||||||
|
match self.bits_at(pos) {
|
||||||
|
FILL => dest.write_str("fill")?,
|
||||||
|
STROKE => dest.write_str("stroke")?,
|
||||||
|
MARKERS => dest.write_str("markers")?,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
no_viewport_percentage!(SpecifiedValue);
|
||||||
|
|
||||||
|
impl ComputedValueAsSpecified for SpecifiedValue { }
|
||||||
|
</%helpers:longhand>
|
||||||
|
|
||||||
|
|
36
components/style/properties/shorthand/inherited_svg.mako.rs
Normal file
36
components/style/properties/shorthand/inherited_svg.mako.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
|
<%helpers:shorthand name="marker" products="gecko"
|
||||||
|
sub_properties="marker-start marker-end marker-mid"
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#MarkerShorthand">
|
||||||
|
use values::specified::UrlOrNone;
|
||||||
|
|
||||||
|
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||||
|
let url = UrlOrNone::parse(context, input)?;
|
||||||
|
|
||||||
|
Ok(Longhands {
|
||||||
|
marker_start: url.clone(),
|
||||||
|
marker_mid: url.clone(),
|
||||||
|
marker_end: url,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LonghandsToSerialize<'a> {
|
||||||
|
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
if let DeclaredValue::Value(ref start) = *self.marker_start {
|
||||||
|
if let DeclaredValue::Value(ref mid) = *self.marker_mid {
|
||||||
|
if let DeclaredValue::Value(ref end) = *self.marker_end {
|
||||||
|
if start == mid && mid == end {
|
||||||
|
start.to_css(dest)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! `<length>` computed values, and related ones.
|
//! `<length>` computed values, and related ones.
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::{Au, AU_PER_PX};
|
||||||
use ordered_float::NotNaN;
|
use ordered_float::NotNaN;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
@ -195,6 +195,12 @@ impl LengthOrPercentage {
|
||||||
LengthOrPercentage::Length(Au(0))
|
LengthOrPercentage::Length(Au(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// 1px length value for SVG defaults
|
||||||
|
pub fn one() -> LengthOrPercentage {
|
||||||
|
LengthOrPercentage::Length(Au(AU_PER_PX))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the computed value is absolute 0 or 0%.
|
/// Returns true if the computed value is absolute 0 or 0%.
|
||||||
///
|
///
|
||||||
/// (Returns false for calc() values, even if ones that may resolve to zero.)
|
/// (Returns false for calc() values, even if ones that may resolve to zero.)
|
||||||
|
|
|
@ -10,7 +10,7 @@ use font_metrics::FontMetricsProvider;
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use super::{CSSFloat, specified};
|
use super::{CSSFloat, RGBA, specified};
|
||||||
|
|
||||||
pub use cssparser::Color as CSSColor;
|
pub use cssparser::Color as CSSColor;
|
||||||
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image};
|
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image};
|
||||||
|
@ -19,7 +19,7 @@ pub use super::{Auto, Either, None_};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use super::specified::{AlignJustifyContent, AlignJustifySelf};
|
pub use super::specified::{AlignJustifyContent, AlignJustifySelf};
|
||||||
pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone};
|
pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone};
|
||||||
pub use super::specified::url::UrlExtraData;
|
pub use super::specified::url::{SpecifiedUrl, UrlExtraData};
|
||||||
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
||||||
pub use self::position::Position;
|
pub use self::position::Position;
|
||||||
|
@ -185,6 +185,83 @@ pub type Number = CSSFloat;
|
||||||
pub type Opacity = CSSFloat;
|
pub type Opacity = CSSFloat;
|
||||||
|
|
||||||
|
|
||||||
|
/// An SVG paint value
|
||||||
|
///
|
||||||
|
/// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct SVGPaint {
|
||||||
|
/// The paint source
|
||||||
|
pub kind: SVGPaintKind,
|
||||||
|
/// The fallback color
|
||||||
|
pub fallback: Option<CSSColor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SVGPaint {
|
||||||
|
fn default() -> Self {
|
||||||
|
SVGPaint {
|
||||||
|
kind: SVGPaintKind::None,
|
||||||
|
fallback: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SVGPaint {
|
||||||
|
/// Opaque black color
|
||||||
|
pub fn black() -> Self {
|
||||||
|
let rgba = RGBA::from_floats(0., 0., 0., 1.);
|
||||||
|
SVGPaint {
|
||||||
|
kind: SVGPaintKind::Color(CSSColor::RGBA(rgba)),
|
||||||
|
fallback: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An SVG paint value without the fallback
|
||||||
|
///
|
||||||
|
/// Whereas the spec only allows PaintServer
|
||||||
|
/// to have a fallback, Gecko lets the context
|
||||||
|
/// properties have a fallback as well.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub enum SVGPaintKind {
|
||||||
|
/// `none`
|
||||||
|
None,
|
||||||
|
/// `<color>`
|
||||||
|
Color(CSSColor),
|
||||||
|
/// `url(...)`
|
||||||
|
PaintServer(SpecifiedUrl),
|
||||||
|
/// `context-fill`
|
||||||
|
ContextFill,
|
||||||
|
/// `context-stroke`
|
||||||
|
ContextStroke,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SVGPaintKind {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
match *self {
|
||||||
|
SVGPaintKind::None => dest.write_str("none"),
|
||||||
|
SVGPaintKind::ContextStroke => dest.write_str("context-stroke"),
|
||||||
|
SVGPaintKind::ContextFill => dest.write_str("context-fill"),
|
||||||
|
SVGPaintKind::Color(ref color) => color.to_css(dest),
|
||||||
|
SVGPaintKind::PaintServer(ref server) => server.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SVGPaint {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
self.kind.to_css(dest)?;
|
||||||
|
if let Some(ref fallback) = self.fallback {
|
||||||
|
fallback.to_css(dest)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <length> | <percentage> | <number>
|
||||||
|
pub type LoPOrNumber = Either<LengthOrPercentage, Number>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
|
|
@ -987,6 +987,34 @@ impl LengthOrPercentage {
|
||||||
LengthOrPercentage::parse_internal(input, AllowedNumericType::NonNegative)
|
LengthOrPercentage::parse_internal(input, AllowedNumericType::NonNegative)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a length, treating dimensionless numbers as pixels
|
||||||
|
///
|
||||||
|
/// https://www.w3.org/TR/SVG2/types.html#presentation-attribute-css-value
|
||||||
|
pub fn parse_numbers_are_pixels(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||||
|
if let Ok(lop) = input.try(|i| Self::parse_internal(i, AllowedNumericType::All)) {
|
||||||
|
Ok(lop)
|
||||||
|
} else {
|
||||||
|
let num = input.expect_number()?;
|
||||||
|
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(Au((AU_PER_PX * num) as i32))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a non-negative length, treating dimensionless numbers as pixels
|
||||||
|
///
|
||||||
|
/// This is nonstandard behavior used by Firefox for SVG
|
||||||
|
pub fn parse_numbers_are_pixels_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||||
|
if let Ok(lop) = input.try(|i| Self::parse_internal(i, AllowedNumericType::NonNegative)) {
|
||||||
|
Ok(lop)
|
||||||
|
} else {
|
||||||
|
let num = input.expect_number()?;
|
||||||
|
if num >= 0. {
|
||||||
|
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(Au((AU_PER_PX * num) as i32))))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Extract value from ref without a clone, replacing it with a 0 Au
|
/// Extract value from ref without a clone, replacing it with a 0 Au
|
||||||
///
|
///
|
||||||
/// Use when you need to move out of a length array without cloning
|
/// Use when you need to move out of a length array without cloning
|
||||||
|
|
|
@ -670,6 +670,175 @@ impl Shadow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_viewport_percentage!(SVGPaint);
|
||||||
|
|
||||||
|
/// An SVG paint value
|
||||||
|
///
|
||||||
|
/// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct SVGPaint {
|
||||||
|
/// The paint source
|
||||||
|
pub kind: SVGPaintKind,
|
||||||
|
/// The fallback color
|
||||||
|
pub fallback: Option<CSSColor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An SVG paint value without the fallback
|
||||||
|
///
|
||||||
|
/// Whereas the spec only allows PaintServer
|
||||||
|
/// to have a fallback, Gecko lets the context
|
||||||
|
/// properties have a fallback as well.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub enum SVGPaintKind {
|
||||||
|
/// `none`
|
||||||
|
None,
|
||||||
|
/// `<color>`
|
||||||
|
Color(CSSColor),
|
||||||
|
/// `url(...)`
|
||||||
|
PaintServer(SpecifiedUrl),
|
||||||
|
/// `context-fill`
|
||||||
|
ContextFill,
|
||||||
|
/// `context-stroke`
|
||||||
|
ContextStroke,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SVGPaintKind {
|
||||||
|
fn parse_ident(input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
Ok(match_ignore_ascii_case! { input.expect_ident()?,
|
||||||
|
"none" => SVGPaintKind::None,
|
||||||
|
"context-fill" => SVGPaintKind::ContextFill,
|
||||||
|
"context-stroke" => SVGPaintKind::ContextStroke,
|
||||||
|
_ => return Err(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for SVGPaint {
|
||||||
|
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) {
|
||||||
|
let fallback = input.try(|i| CSSColor::parse(context, i));
|
||||||
|
Ok(SVGPaint {
|
||||||
|
kind: SVGPaintKind::PaintServer(url),
|
||||||
|
fallback: fallback.ok(),
|
||||||
|
})
|
||||||
|
} else if let Ok(kind) = input.try(SVGPaintKind::parse_ident) {
|
||||||
|
if kind == SVGPaintKind::None {
|
||||||
|
Ok(SVGPaint {
|
||||||
|
kind: kind,
|
||||||
|
fallback: None,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let fallback = input.try(|i| CSSColor::parse(context, i));
|
||||||
|
Ok(SVGPaint {
|
||||||
|
kind: kind,
|
||||||
|
fallback: fallback.ok(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if let Ok(color) = input.try(|i| CSSColor::parse(context, i)) {
|
||||||
|
Ok(SVGPaint {
|
||||||
|
kind: SVGPaintKind::Color(color),
|
||||||
|
fallback: None,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SVGPaintKind {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
match *self {
|
||||||
|
SVGPaintKind::None => dest.write_str("none"),
|
||||||
|
SVGPaintKind::ContextStroke => dest.write_str("context-stroke"),
|
||||||
|
SVGPaintKind::ContextFill => dest.write_str("context-fill"),
|
||||||
|
SVGPaintKind::Color(ref color) => color.to_css(dest),
|
||||||
|
SVGPaintKind::PaintServer(ref server) => server.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SVGPaint {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
self.kind.to_css(dest)?;
|
||||||
|
if let Some(ref fallback) = self.fallback {
|
||||||
|
fallback.to_css(dest)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl ToComputedValue for SVGPaint {
|
||||||
|
type ComputedValue = super::computed::SVGPaint;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
|
super::computed::SVGPaint {
|
||||||
|
kind: self.kind.to_computed_value(context),
|
||||||
|
fallback: self.fallback.as_ref().map(|f| f.to_computed_value(context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
SVGPaint {
|
||||||
|
kind: ToComputedValue::from_computed_value(&computed.kind),
|
||||||
|
fallback: computed.fallback.as_ref().map(ToComputedValue::from_computed_value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for SVGPaintKind {
|
||||||
|
type ComputedValue = super::computed::SVGPaintKind;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
|
match *self {
|
||||||
|
SVGPaintKind::None => super::computed::SVGPaintKind::None,
|
||||||
|
SVGPaintKind::ContextStroke => super::computed::SVGPaintKind::ContextStroke,
|
||||||
|
SVGPaintKind::ContextFill => super::computed::SVGPaintKind::ContextFill,
|
||||||
|
SVGPaintKind::Color(ref color) => {
|
||||||
|
super::computed::SVGPaintKind::Color(color.to_computed_value(context))
|
||||||
|
}
|
||||||
|
SVGPaintKind::PaintServer(ref server) => {
|
||||||
|
super::computed::SVGPaintKind::PaintServer(server.to_computed_value(context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
match *computed {
|
||||||
|
super::computed::SVGPaintKind::None => SVGPaintKind::None,
|
||||||
|
super::computed::SVGPaintKind::ContextStroke => SVGPaintKind::ContextStroke,
|
||||||
|
super::computed::SVGPaintKind::ContextFill => SVGPaintKind::ContextFill,
|
||||||
|
super::computed::SVGPaintKind::Color(ref color) => {
|
||||||
|
SVGPaintKind::Color(ToComputedValue::from_computed_value(color))
|
||||||
|
}
|
||||||
|
super::computed::SVGPaintKind::PaintServer(ref server) => {
|
||||||
|
SVGPaintKind::PaintServer(ToComputedValue::from_computed_value(server))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <length> | <percentage> | <number>
|
||||||
|
pub type LoPOrNumber = Either<LengthOrPercentage, Number>;
|
||||||
|
|
||||||
|
impl LoPOrNumber {
|
||||||
|
/// parse a <length-percentage> | <number> enforcing that the contents aren't negative
|
||||||
|
pub fn parse_non_negative(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
if let Ok(lop) = input.try(LengthOrPercentage::parse_non_negative) {
|
||||||
|
Ok(Either::First(lop))
|
||||||
|
} else if let Ok(num) = input.try(Number::parse_non_negative) {
|
||||||
|
Ok(Either::Second(num))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasViewportPercentage for ClipRect {
|
impl HasViewportPercentage for ClipRect {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
use cssparser::{CssStringWriter, Parser};
|
use cssparser::{CssStringWriter, Parser};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
use gecko_bindings::structs::ServoBundledURI;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
|
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -167,6 +169,24 @@ impl SpecifiedUrl {
|
||||||
extra_data: UrlExtraData {}
|
extra_data: UrlExtraData {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a bundled URI suitable for sending to Gecko
|
||||||
|
/// to be constructed into a css::URLValue
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn for_ffi(&self) -> Option<ServoBundledURI> {
|
||||||
|
let extra_data = self.extra_data();
|
||||||
|
let (ptr, len) = match self.as_slice_components() {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
Some(ServoBundledURI {
|
||||||
|
mURLString: ptr,
|
||||||
|
mURLStringLength: len as u32,
|
||||||
|
mBaseURI: extra_data.base.get(),
|
||||||
|
mReferrer: extra_data.referrer.get(),
|
||||||
|
mPrincipal: extra_data.principal.get(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for SpecifiedUrl {
|
impl PartialEq for SpecifiedUrl {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue