From 56e70aec517b3791be252f52d45135bf8421c861 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Thu, 15 Sep 2016 16:03:41 +0900 Subject: [PATCH] Bug 1302949 - Add a method to parse a property-value pair into a declaration block; r=Manishearth The property may be a shorthand property in which case the declaration block will contain the expanded longhand properties and values. MozReview-Commit-ID: KxqlYgbIZqL --- components/style/gecko_bindings/bindings.rs | 12 +++++ ports/geckolib/Cargo.lock | 2 + ports/geckolib/Cargo.toml | 1 + ports/geckolib/glue.rs | 55 ++++++++++++++++++++- ports/geckolib/lib.rs | 1 + tests/unit/stylo/Cargo.toml | 1 + tests/unit/stylo/lib.rs | 1 + 7 files changed, 71 insertions(+), 2 deletions(-) diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index 3781bbe81d4..46131cf6908 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -847,6 +847,18 @@ extern "C" { reference: RawServoStyleSheetBorrowed); } +extern "C" { + pub fn Servo_ParseProperty(property_bytes: *const u8, + property_length: u32, + value_bytes: *const u8, + value_length: u32, + base_bytes: *const u8, + base_length: u32, + base: *mut ThreadSafeURIHolder, + referrer: *mut ThreadSafeURIHolder, + principal: *mut ThreadSafePrincipalHolder) + -> ServoDeclarationBlockStrong; +} extern "C" { pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, cache: *mut nsHTMLCSSStyleSheet) diff --git a/ports/geckolib/Cargo.lock b/ports/geckolib/Cargo.lock index 8b9e70c0d8f..17b8d28f868 100644 --- a/ports/geckolib/Cargo.lock +++ b/ports/geckolib/Cargo.lock @@ -3,6 +3,7 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -407,6 +408,7 @@ name = "stylo_tests" version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml index 50260374172..ebe538fabb9 100644 --- a/ports/geckolib/Cargo.toml +++ b/ports/geckolib/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["staticlib", "rlib"] [dependencies] app_units = "0.3" +cssparser = {version = "0.7"} env_logger = "0.3" euclid = "0.10.1" lazy_static = "0.2" diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 4d710c7376c..33a78d874b2 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::Au; +use cssparser::Parser; use env_logger; use euclid::Size2D; use parking_lot::RwLock; @@ -37,8 +38,10 @@ use style::gecko_bindings::structs::nsRestyleHint; use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI}; use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong}; use style::parallel; -use style::parser::ParserContextExtraData; -use style::properties::{ComputedValues, parse_one_declaration}; +use style::parser::{ParserContext, ParserContextExtraData}; +use style::properties::{ComputedValues, Importance, PropertyDeclaration}; +use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock}; +use style::properties::parse_one_declaration; use style::selector_impl::PseudoElementCascadeType; use style::sequential; use style::string_cache::Atom; @@ -338,6 +341,54 @@ pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () { let _ = data.into_box::(); } + +#[no_mangle] +pub extern "C" fn Servo_ParseProperty(property_bytes: *const u8, + property_length: u32, + value_bytes: *const u8, + value_length: u32, + base_bytes: *const u8, + base_length: u32, + base: *mut ThreadSafeURIHolder, + referrer: *mut ThreadSafeURIHolder, + principal: *mut ThreadSafePrincipalHolder) + -> ServoDeclarationBlockStrong { + // All this string wrangling is temporary until the Gecko string bindings land (bug 1294742). + let name = unsafe { from_utf8_unchecked(slice::from_raw_parts(property_bytes, + property_length as usize)) }; + let value_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(value_bytes, + value_length as usize)) }; + let base_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(base_bytes, + base_length as usize)) }; + let base_url = Url::parse(base_str).unwrap(); + let extra_data = ParserContextExtraData { + base: Some(GeckoArcURI::new(base)), + referrer: Some(GeckoArcURI::new(referrer)), + principal: Some(GeckoArcPrincipal::new(principal)), + }; + + let context = ParserContext::new_with_extra_data(Origin::Author, &base_url, + Box::new(StdoutErrorReporter), + extra_data); + + let mut results = vec![]; + match PropertyDeclaration::parse(name, &context, &mut Parser::new(value_str), + &mut results, false) { + PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {}, + _ => return ServoDeclarationBlockStrong::null(), + } + + let results = results.into_iter().map(|r| (r, Importance::Normal)).collect(); + + Arc::new(GeckoDeclarationBlock { + declarations: Some(Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: results, + important_count: 0, + }))), + cache: AtomicPtr::new(ptr::null_mut()), + immutable: AtomicBool::new(false), + }).into_strong() +} #[no_mangle] pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, cache: *mut nsHTMLCSSStyleSheet) diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 0b6493db278..cdfca9b8653 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -5,6 +5,7 @@ #[macro_use]extern crate style; extern crate app_units; +extern crate cssparser; extern crate env_logger; extern crate euclid; extern crate libc; diff --git a/tests/unit/stylo/Cargo.toml b/tests/unit/stylo/Cargo.toml index 300f31cea64..87dc62cd042 100644 --- a/tests/unit/stylo/Cargo.toml +++ b/tests/unit/stylo/Cargo.toml @@ -13,6 +13,7 @@ doctest = false [dependencies] app_units = "0.3" +cssparser = {version = "0.7"} env_logger = "0.3" euclid = "0.10.1" lazy_static = "0.2" diff --git a/tests/unit/stylo/lib.rs b/tests/unit/stylo/lib.rs index d4d3711279c..8690c17f517 100644 --- a/tests/unit/stylo/lib.rs +++ b/tests/unit/stylo/lib.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate app_units; +extern crate cssparser; extern crate env_logger; extern crate euclid; extern crate geckoservo;