Auto merge of #13553 - birtles:animvalues, r=Manishearth

Support creating StyleAnimationValue objects from Servo

These are the servo-side changes for [bug 1302949](https://bugzilla.mozilla.org/show_bug.cgi?id=1302949#c59). @Manishearth has already reviewed them there.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix [bug 1302949](https://bugzilla.mozilla.org/show_bug.cgi?id=1302949#c59)
- [X] These changes do not require tests because there are existing tests for this in mozilla-central

<!-- 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/13553)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-09 08:53:28 -05:00 committed by GitHub
commit 804317c885
8 changed files with 170 additions and 2 deletions

View file

@ -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;
}

View file

@ -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;
@ -399,6 +400,11 @@ extern "C" {
*const ::std::os::raw::c_char,
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);
}
@ -847,6 +853,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)
@ -860,6 +878,11 @@ extern "C" {
pub fn Servo_DeclarationBlock_Release(declarations:
ServoDeclarationBlockBorrowed);
}
extern "C" {
pub fn Servo_DeclarationBlock_Equals(a: ServoDeclarationBlockBorrowed,
b: ServoDeclarationBlockBorrowed)
-> bool;
}
extern "C" {
pub fn Servo_DeclarationBlock_GetCache(declarations:
ServoDeclarationBlockBorrowed)
@ -929,6 +952,11 @@ extern "C" {
pub fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed,
set: RawServoStyleSetBorrowedMut);
}
extern "C" {
pub fn Servo_RestyleWithAddedDeclaration(declarations: ServoDeclarationBlockBorrowed,
previous_style: ServoComputedValuesBorrowed)
-> ServoComputedValuesStrong;
}
extern "C" {
pub fn Servo_GetStyleFont(computed_values:
ServoComputedValuesBorrowedOrNull)

View file

@ -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",

View file

@ -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"

View file

@ -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,
@ -120,6 +127,35 @@ pub extern "C" fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed,
restyle_subtree(node, raw_data);
}
#[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)
@ -362,6 +446,13 @@ pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationB
unsafe { GeckoDeclarationBlock::release(declarations) };
}
#[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 {
@ -378,6 +469,39 @@ pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDe
GeckoDeclarationBlock::as_arc(&declarations).cache.store(ptr::null_mut(), Ordering::Relaxed)
}
#[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 {

View file

@ -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;

View file

@ -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"

View file

@ -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;