aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/wrapper.rs10
-rw-r--r--components/style/gecko_bindings/bindings.rs28
-rw-r--r--ports/geckolib/Cargo.lock2
-rw-r--r--ports/geckolib/Cargo.toml1
-rw-r--r--ports/geckolib/glue.rs128
-rw-r--r--ports/geckolib/lib.rs1
-rw-r--r--tests/unit/stylo/Cargo.toml1
-rw-r--r--tests/unit/stylo/lib.rs1
8 files changed, 170 insertions, 2 deletions
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index f2a7532883c..407ff4694e4 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -70,6 +70,16 @@ pub struct GeckoDeclarationBlock {
pub immutable: AtomicBool,
}
+impl PartialEq for GeckoDeclarationBlock {
+ fn eq(&self, other: &GeckoDeclarationBlock) -> bool {
+ match (&self.declarations, &other.declarations) {
+ (&None, &None) => true,
+ (&Some(ref s), &Some(ref other)) => *s.read() == *other.read(),
+ _ => false,
+ }
+ }
+}
+
unsafe impl HasFFI for GeckoDeclarationBlock {
type FFIType = bindings::ServoDeclarationBlock;
}
diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs
index 3781bbe81d4..3529dce9b87 100644
--- a/components/style/gecko_bindings/bindings.rs
+++ b/components/style/gecko_bindings/bindings.rs
@@ -165,6 +165,7 @@ use gecko_bindings::structs::nsINode;
use gecko_bindings::structs::nsIDocument;
use gecko_bindings::structs::nsIPrincipal;
use gecko_bindings::structs::nsIURI;
+use gecko_bindings::structs::nsString;
use gecko_bindings::structs::RawGeckoNode;
use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoDocument;
@@ -400,6 +401,11 @@ extern "C" {
aLength: u32) -> bool;
}
extern "C" {
+ pub fn Gecko_Utf8SliceToString(aString: *mut nsString,
+ aBuffer: *const u8,
+ aBufferLen: usize);
+}
+extern "C" {
pub fn Gecko_FontFamilyList_Clear(aList: *mut FontFamilyList);
}
extern "C" {
@@ -848,6 +854,18 @@ extern "C" {
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)
-> ServoDeclarationBlockStrong;
@@ -861,6 +879,11 @@ extern "C" {
ServoDeclarationBlockBorrowed);
}
extern "C" {
+ pub fn Servo_DeclarationBlock_Equals(a: ServoDeclarationBlockBorrowed,
+ b: ServoDeclarationBlockBorrowed)
+ -> bool;
+}
+extern "C" {
pub fn Servo_DeclarationBlock_GetCache(declarations:
ServoDeclarationBlockBorrowed)
-> *mut nsHTMLCSSStyleSheet;
@@ -930,6 +953,11 @@ extern "C" {
set: RawServoStyleSetBorrowedMut);
}
extern "C" {
+ pub fn Servo_RestyleWithAddedDeclaration(declarations: ServoDeclarationBlockBorrowed,
+ previous_style: ServoComputedValuesBorrowed)
+ -> ServoComputedValuesStrong;
+}
+extern "C" {
pub fn Servo_GetStyleFont(computed_values:
ServoComputedValuesBorrowedOrNull)
-> *const nsStyleFont;
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..f7237b59561 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, ToCss};
use env_logger;
use euclid::Size2D;
use parking_lot::RwLock;
@@ -29,17 +30,22 @@ use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedVal
use style::gecko_bindings::bindings::{ServoDeclarationBlockBorrowed, ServoDeclarationBlockStrong};
use style::gecko_bindings::bindings::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
use style::gecko_bindings::bindings::{nsHTMLCSSStyleSheet, ServoComputedValuesBorrowedOrNull};
+use style::gecko_bindings::bindings::Gecko_Utf8SliceToString;
use style::gecko_bindings::bindings::RawServoStyleSetBorrowedMut;
use style::gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom};
use style::gecko_bindings::structs::ServoElementSnapshot;
use style::gecko_bindings::structs::nsRestyleHint;
+use style::gecko_bindings::structs::nsString;
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::{cascade, parse_one_declaration};
use style::selector_impl::PseudoElementCascadeType;
+use style::selector_matching::ApplicableDeclarationBlock;
use style::sequential;
use style::string_cache::Atom;
use style::stylesheets::{Origin, Stylesheet};
@@ -91,6 +97,7 @@ fn restyle_subtree(node: GeckoNode, raw_data: RawServoStyleSetBorrowedMut) {
LocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone());
let shared_style_context = SharedStyleContext {
+ // FIXME (bug 1303229): Use the actual viewport size here
viewport_size: Size2D::new(Au(0), Au(0)),
screen_size_changed: false,
generation: 0,
@@ -121,6 +128,35 @@ pub extern "C" fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed,
}
#[no_mangle]
+pub extern "C" fn Servo_RestyleWithAddedDeclaration(declarations: ServoDeclarationBlockBorrowed,
+ previous_style: ServoComputedValuesBorrowed)
+ -> ServoComputedValuesStrong
+{
+ match GeckoDeclarationBlock::as_arc(&declarations).declarations {
+ Some(ref declarations) => {
+ let declaration_block = ApplicableDeclarationBlock {
+ mixed_declarations: declarations.clone(),
+ importance: Importance::Normal,
+ source_order: 0,
+ specificity: ::std::u32::MAX,
+ };
+ let previous_style = ComputedValues::as_arc(&previous_style);
+
+ // FIXME (bug 1303229): Use the actual viewport size here
+ let (computed, _) = cascade(Size2D::new(Au(0), Au(0)),
+ &[declaration_block],
+ false,
+ Some(previous_style),
+ None,
+ None,
+ Box::new(StdoutErrorReporter));
+ Arc::new(computed).into_strong()
+ },
+ None => ServoComputedValuesStrong::null(),
+ }
+}
+
+#[no_mangle]
pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 {
*NUM_THREADS as u32
}
@@ -338,6 +374,54 @@ pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () {
let _ = data.into_box::<PerDocumentStyleData>();
}
+
+#[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)
@@ -363,6 +447,13 @@ pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationB
}
#[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_Equals(a: ServoDeclarationBlockBorrowed,
+ b: ServoDeclarationBlockBorrowed)
+ -> bool {
+ GeckoDeclarationBlock::as_arc(&a) == GeckoDeclarationBlock::as_arc(&b)
+}
+
+#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockBorrowed)
-> *mut nsHTMLCSSStyleSheet {
GeckoDeclarationBlock::as_arc(&declarations).cache.load(Ordering::Relaxed)
@@ -379,6 +470,39 @@ pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDe
}
#[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
+ declarations: ServoDeclarationBlockBorrowed,
+ buffer: *mut nsString)
+{
+ let mut string = String::new();
+
+ if let Some(ref declarations) = GeckoDeclarationBlock::as_arc(&declarations).declarations {
+ declarations.read().to_css(&mut string).unwrap();
+ // FIXME: We are expecting |declarations| to be a declaration block with either a single
+ // longhand property-declaration or a series of longhand property-declarations that make
+ // up a single shorthand property. As a result, it should be possible to serialize
+ // |declarations| as a single declaration. However, we only want to return the *value* from
+ // that single declaration. For now, we just manually strip the property name, colon,
+ // leading spacing, and trailing space. In future we should find a more robust way to do
+ // this.
+ //
+ // See https://github.com/servo/servo/issues/13423
+ debug_assert!(string.find(':').is_some());
+ let position = string.find(':').unwrap();
+ // Get the value after the first colon and any following whitespace.
+ let value = &string[(position + 1)..].trim_left();
+ debug_assert!(value.ends_with(';'));
+ let length = value.len() - 1; // Strip last semicolon.
+
+ // FIXME: Once we have nsString bindings for Servo (bug 1294742), we should be able to drop
+ // this and fill in |buffer| directly.
+ unsafe {
+ Gecko_Utf8SliceToString(buffer, value.as_ptr(), length);
+ }
+ }
+}
+
+#[no_mangle]
pub extern "C" fn Servo_CSSSupports(property: *const u8, property_length: u32,
value: *const u8, value_length: u32) -> bool {
let property = unsafe { from_utf8_unchecked(slice::from_raw_parts(property, property_length as usize)) };
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;