diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index af052179d2c..86961c89192 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -43,7 +43,7 @@ #![allow(unused_imports)] % if not property.derived_from: use cssparser::Parser; - use parser::ParserContext; + use parser::{ParserContext, ParserContextExtraData}; use properties::{CSSWideKeyword, DeclaredValue, Shorthand}; % endif use error_reporting::ParseErrorReporter; diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 6fd36b71a4d..f80a42c88d2 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -851,3 +851,78 @@ ${helpers.single_keyword("-moz-appearance", gecko_ffi_name="mAppearance", gecko_constant_prefix="NS_THEME", products="gecko")} + +// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding +<%helpers:longhand name="-moz-binding" products="gecko"> + use cssparser::{CssStringWriter, ToCss}; + use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; + use std::fmt::{self, Write}; + use url::Url; + use values::computed::ComputedValueAsSpecified; + + #[derive(PartialEq, Clone, Debug, HeapSizeOf)] + pub struct UrlExtraData { + pub base: GeckoArcURI, + pub referrer: GeckoArcURI, + pub principal: GeckoArcPrincipal, + } + + #[derive(PartialEq, Clone, Debug, HeapSizeOf)] + pub enum SpecifiedValue { + Url(Url, UrlExtraData), + None, + } + + impl ComputedValueAsSpecified for SpecifiedValue {} + + impl ToCss for SpecifiedValue { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + use values::LocalToCss; + match *self { + SpecifiedValue::Url(ref url, _) => { + url.to_css(dest) + } + SpecifiedValue::None => { + try!(dest.write_str("none")); + Ok(()) + } + } + } + } + + pub mod computed_value { + pub type T = super::SpecifiedValue; + } + + #[inline] pub fn get_initial_value() -> SpecifiedValue { + SpecifiedValue::None + } + + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + return Ok(SpecifiedValue::None); + } + + let url = context.parse_url(&*try!(input.expect_url())); + match context.extra_data { + ParserContextExtraData { + base: Some(ref base), + referrer: Some(ref referrer), + principal: Some(ref principal), + } => { + let extra_data = UrlExtraData { + base: base.clone(), + referrer: referrer.clone(), + principal: principal.clone(), + }; + Ok(SpecifiedValue::Url(url, extra_data)) + }, + _ => { + // FIXME(heycam) should ensure we always have a principal, etc., when parsing + // style attributes and re-parsing due to CSS Variables. + println!("stylo: skipping -moz-binding declaration without ParserContextExtraData"); + Err(()) + }, + } + } + diff --git a/ports/geckolib/properties.mako.rs b/ports/geckolib/properties.mako.rs index 55a9a528bbd..387f5e02edb 100644 --- a/ports/geckolib/properties.mako.rs +++ b/ports/geckolib/properties.mako.rs @@ -16,7 +16,8 @@ use gecko_bindings::bindings::Gecko_Construct_${style_struct.gecko_ffi_name}; use gecko_bindings::bindings::Gecko_CopyConstruct_${style_struct.gecko_ffi_name}; use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name}; % endfor -use gecko_bindings::bindings::{Gecko_CopyListStyleTypeFrom, Gecko_SetListStyleType}; +use gecko_bindings::bindings::{Gecko_CopyMozBindingFrom, Gecko_CopyListStyleTypeFrom}; +use gecko_bindings::bindings::{Gecko_SetMozBinding, Gecko_SetListStyleType}; use gecko_bindings::structs; use glue::ArcHelpers; use heapsize::HeapSizeOf; @@ -625,7 +626,7 @@ fn static_assert() { -<%self:impl_trait style_struct_name="Box" skip_longhands="display overflow-y vertical-align"> +<%self:impl_trait style_struct_name="Box" skip_longhands="display overflow-y vertical-align -moz-binding"> // We manually-implement the |display| property until we get general // infrastructure for preffing certain values. @@ -677,6 +678,25 @@ fn static_assert() { self.gecko.mVerticalAlign.mValue = other.gecko.mVerticalAlign.mValue; } + fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) { + use style::properties::longhands::_moz_binding::SpecifiedValue as BindingValue; + match v { + BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()), + BindingValue::Url(ref url, ref extra_data) => { + unsafe { + Gecko_SetMozBinding(&mut self.gecko, + url.as_str().as_ptr(), + url.as_str().len() as u32, + extra_data.base.as_raw(), + extra_data.referrer.as_raw(), + extra_data.principal.as_raw()); + } + } + } + } + fn copy__moz_binding_from(&mut self, other: &Self) { + unsafe { Gecko_CopyMozBindingFrom(&mut self.gecko, &other.gecko); } + } <%self:impl_trait style_struct_name="Background" skip_longhands="background-color" skip_additionals="*">