aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-10-17 01:11:39 -0500
committerGitHub <noreply@github.com>2017-10-17 01:11:39 -0500
commitac74cd57a257fc95e0513524e196c91807c18bba (patch)
tree5620f6ab8f90c2d6dbf7f7dd4f38e62254b3b556
parent1715329eb1037cb4f0c723d3db2e22d722c7290d (diff)
parentef28ccb1a32290115e14f1cb46b7f56bbf307657 (diff)
downloadservo-ac74cd57a257fc95e0513524e196c91807c18bba.tar.gz
servo-ac74cd57a257fc95e0513524e196c91807c18bba.zip
Auto merge of #18915 - heycam:observer, r=upsuper
style: Add FFI function for parsing IntersectionObserver rootMargin values. Servo-side part of https://bugzilla.mozilla.org/show_bug.cgi?id=1408305, reviewed there by Xidorn. <!-- 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/18915) <!-- Reviewable:end -->
-rw-r--r--components/style/gecko_bindings/sugar/ns_css_value.rs14
-rw-r--r--components/style/values/specified/gecko.rs71
-rw-r--r--ports/geckolib/glue.rs40
3 files changed, 120 insertions, 5 deletions
diff --git a/components/style/gecko_bindings/sugar/ns_css_value.rs b/components/style/gecko_bindings/sugar/ns_css_value.rs
index 9c57b788ef1..8c1d83c8ffd 100644
--- a/components/style/gecko_bindings/sugar/ns_css_value.rs
+++ b/components/style/gecko_bindings/sugar/ns_css_value.rs
@@ -75,10 +75,10 @@ impl nsCSSValue {
pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) {
match lop {
LengthOrPercentage::Length(px) => {
- bindings::Gecko_CSSValue_SetPixelLength(self, px.px())
+ self.set_px(px.px())
}
LengthOrPercentage::Percentage(pc) => {
- bindings::Gecko_CSSValue_SetPercentage(self, pc.0)
+ self.set_percentage(pc.0)
}
LengthOrPercentage::Calc(calc) => {
bindings::Gecko_CSSValue_SetCalc(self, calc.into())
@@ -86,6 +86,16 @@ impl nsCSSValue {
}
}
+ /// Sets a px value to this nsCSSValue.
+ pub unsafe fn set_px(&mut self, px: f32) {
+ bindings::Gecko_CSSValue_SetPixelLength(self, px)
+ }
+
+ /// Sets a percentage value to this nsCSSValue.
+ pub unsafe fn set_percentage(&mut self, unit_value: f32) {
+ bindings::Gecko_CSSValue_SetPercentage(self, unit_value)
+ }
+
/// Returns LengthOrPercentage value.
pub unsafe fn get_lop(&self) -> LengthOrPercentage {
use values::computed::Length;
diff --git a/components/style/values/specified/gecko.rs b/components/style/values/specified/gecko.rs
index 507a3b160de..b36cd582aed 100644
--- a/components/style/values/specified/gecko.rs
+++ b/components/style/values/specified/gecko.rs
@@ -4,10 +4,15 @@
//! Specified types for legacy Gecko-only properties.
-use cssparser::Parser;
+use cssparser::{Parser, Token};
+use gecko_bindings::structs;
+use gecko_bindings::sugar::ns_css_value::ToNsCssValue;
use parser::{Parse, ParserContext};
-use style_traits::ParseError;
+use style_traits::{ParseError, StyleParseErrorKind};
+use values::CSSFloat;
+use values::computed;
use values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint;
+use values::generics::rect::Rect;
use values::specified::length::LengthOrPercentage;
/// A specified type for scroll snap points.
@@ -25,3 +30,65 @@ impl Parse for ScrollSnapPoint {
Ok(GenericScrollSnapPoint::Repeat(length))
}
}
+
+/// A component of an IntersectionObserverRootMargin.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum PixelOrPercentage {
+ /// An absolute length in pixels (px)
+ Px(CSSFloat),
+ /// A percentage (%)
+ Percentage(computed::Percentage),
+}
+
+impl Parse for PixelOrPercentage {
+ fn parse<'i, 't>(
+ _context: &ParserContext,
+ input: &mut Parser<'i, 't>
+ ) -> Result<Self, ParseError<'i>> {
+ let location = input.current_source_location();
+ let token = input.next()?;
+ let value = match *token {
+ Token::Dimension { value, ref unit, .. } => {
+ match_ignore_ascii_case! { unit,
+ "px" => Ok(PixelOrPercentage::Px(value)),
+ _ => Err(()),
+ }
+ }
+ Token::Percentage { unit_value, .. } => {
+ Ok(PixelOrPercentage::Percentage(
+ computed::Percentage(unit_value)
+ ))
+ }
+ _ => Err(()),
+ };
+ value.map_err(|()| {
+ location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
+ })
+ }
+}
+
+impl ToNsCssValue for PixelOrPercentage {
+ fn convert(self, nscssvalue: &mut structs::nsCSSValue) {
+ match self {
+ PixelOrPercentage::Px(px) => {
+ unsafe { nscssvalue.set_px(px); }
+ }
+ PixelOrPercentage::Percentage(pc) => {
+ unsafe { nscssvalue.set_percentage(pc.0); }
+ }
+ }
+ }
+}
+
+/// The value of an IntersectionObserver's rootMargin property.
+pub struct IntersectionObserverRootMargin(pub Rect<PixelOrPercentage>);
+
+impl Parse for IntersectionObserverRootMargin {
+ fn parse<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Self, ParseError<'i>> {
+ let rect = Rect::parse_with(context, input, PixelOrPercentage::parse)?;
+ Ok(IntersectionObserverRootMargin(rect))
+ }
+}
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index 9e7c2f22f2d..c1b0f7a8445 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -112,7 +112,7 @@ use style::gecko_bindings::sugar::refptr::RefPtr;
use style::gecko_properties::style_structs;
use style::invalidation::element::restyle_hints;
use style::media_queries::{Device, MediaList, parse_media_query_list};
-use style::parser::{ParserContext, self};
+use style::parser::{Parse, ParserContext, self};
use style::properties::{CascadeFlags, ComputedValues, DeclarationSource, Importance};
use style::properties::{IS_FIELDSET_CONTENT, IS_LINK, IS_VISITED_LINK, LonghandIdSet};
use style::properties::{LonghandId, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
@@ -146,6 +146,7 @@ use style::values::animated::{Animate, Procedure, ToAnimatedZero};
use style::values::computed::{Context, ToComputedValue};
use style::values::distance::ComputeSquaredDistance;
use style::values::specified;
+use style::values::specified::gecko::IntersectionObserverRootMargin;
use style_traits::{PARSING_MODE_DEFAULT, ToCss};
use super::error_reporter::ErrorReporter;
use super::stylesheet_loader::StylesheetLoader;
@@ -2212,6 +2213,7 @@ pub extern "C" fn Servo_ParseEasing(
) -> bool {
use style::properties::longhands::transition_timing_function;
+ // FIXME Dummy URL data would work fine here.
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let context = ParserContext::new(Origin::Author,
url_data,
@@ -4270,3 +4272,39 @@ pub extern "C" fn Servo_ComputeColor(
Err(_) => false,
}
}
+
+#[no_mangle]
+pub extern "C" fn Servo_ParseIntersectionObserverRootMargin(
+ value: *const nsAString,
+ result: *mut structs::nsCSSRect,
+) -> bool {
+ let value = unsafe { value.as_ref().unwrap().to_string() };
+ let result = unsafe { result.as_mut().unwrap() };
+
+ let mut input = ParserInput::new(&value);
+ let mut parser = Parser::new(&mut input);
+
+ let url_data = unsafe { dummy_url_data() };
+ let context = ParserContext::new(
+ Origin::Author,
+ url_data,
+ Some(CssRuleType::Style),
+ PARSING_MODE_DEFAULT,
+ QuirksMode::NoQuirks,
+ );
+
+ let margin = parser.parse_entirely(|p| {
+ IntersectionObserverRootMargin::parse(&context, p)
+ });
+ match margin {
+ Ok(margin) => {
+ let rect = margin.0;
+ result.mTop.set_from(rect.0);
+ result.mRight.set_from(rect.1);
+ result.mBottom.set_from(rect.2);
+ result.mLeft.set_from(rect.3);
+ true
+ }
+ Err(..) => false,
+ }
+}