Stop parsing style attributes during restyle in geckolib.

This commit is contained in:
Cameron McCormack 2016-06-07 11:23:13 +10:00
parent ba30d72679
commit 98a32a76df
3 changed files with 83 additions and 18 deletions

View file

@ -134,6 +134,8 @@ pub enum ServoNodeData { }
pub enum ServoComputedValues { }
pub enum RawServoStyleSheet { }
pub enum RawServoStyleSet { }
pub enum nsHTMLCSSStyleSheet { }
pub enum ServoDeclarationBlock { }
pub type ThreadSafePrincipalHolder = nsMainThreadPtrHolder<nsIPrincipal>;
pub type ThreadSafeURIHolder = nsMainThreadPtrHolder<nsIURI>;
extern "C" {
@ -170,6 +172,8 @@ extern "C" {
pub fn Gecko_ClassOrClassList(element: *mut RawGeckoElement,
class_: *mut *mut nsIAtom,
classList: *mut *mut *mut nsIAtom) -> u32;
pub fn Gecko_GetServoDeclarationBlock(element: *mut RawGeckoElement)
-> *mut ServoDeclarationBlock;
pub fn Gecko_GetNodeData(node: *mut RawGeckoNode) -> *mut ServoNodeData;
pub fn Gecko_SetNodeData(node: *mut RawGeckoNode,
data: *mut ServoNodeData);
@ -242,6 +246,18 @@ extern "C" {
pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool;
pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet;
pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet);
pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u8,
cache: *mut nsHTMLCSSStyleSheet)
-> *mut ServoDeclarationBlock;
pub fn Servo_DropDeclarationBlock(declarations:
*mut ServoDeclarationBlock);
pub fn Servo_GetDeclarationBlockCache(declarations:
*mut ServoDeclarationBlock)
-> *mut nsHTMLCSSStyleSheet;
pub fn Servo_SetDeclarationBlockImmutable(declarations:
*mut ServoDeclarationBlock);
pub fn Servo_ClearDeclarationBlockCachePointer(declarations:
*mut ServoDeclarationBlock);
pub fn Servo_GetComputedValues(node: *mut RawGeckoNode)
-> *mut ServoComputedValues;
pub fn Servo_GetComputedValuesForAnonymousBox(parentStyleOrNull:

View file

@ -9,8 +9,9 @@ use data::PerDocumentStyleData;
use env_logger;
use euclid::Size2D;
use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSheet, ServoComputedValues, ServoNodeData};
use gecko_bindings::bindings::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSheet, ServoComputedValues};
use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder};
use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet};
use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
use gecko_bindings::structs::{SheetParsingMode, nsIAtom};
use properties::GeckoComputedValues;
@ -26,7 +27,7 @@ use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
use style::parallel;
use style::parser::ParserContextExtraData;
use style::properties::ComputedValues;
use style::properties::{ComputedValues, PropertyDeclarationBlock};
use style::selector_impl::{SelectorImplExt, PseudoElementCascadeType};
use style::stylesheets::Origin;
use traversal::RecalcStyleOnly;
@ -410,3 +411,48 @@ pub extern "C" fn Servo_DropStyleSet(data: *mut RawServoStyleSet) -> () {
let _ = Box::<PerDocumentStyleData>::from_raw(data as *mut PerDocumentStyleData);
}
}
pub struct GeckoDeclarationBlock {
pub declarations: Option<PropertyDeclarationBlock>,
pub cache: *mut nsHTMLCSSStyleSheet,
pub immutable: bool,
}
#[no_mangle]
pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
cache: *mut nsHTMLCSSStyleSheet)
-> *mut ServoDeclarationBlock {
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
let declarations = Box::new(GeckoDeclarationBlock {
declarations: GeckoElement::parse_style_attribute(value),
cache: cache,
immutable: false,
});
Box::into_raw(declarations) as *mut ServoDeclarationBlock
}
#[no_mangle]
pub extern "C" fn Servo_DropDeclarationBlock(declarations: *mut ServoDeclarationBlock) {
unsafe {
let _ = Box::<GeckoDeclarationBlock>::from_raw(declarations as *mut GeckoDeclarationBlock);
}
}
#[no_mangle]
pub extern "C" fn Servo_GetDeclarationBlockCache(declarations: *mut ServoDeclarationBlock)
-> *mut nsHTMLCSSStyleSheet {
let declarations = unsafe { (declarations as *const GeckoDeclarationBlock).as_ref().unwrap() };
declarations.cache
}
#[no_mangle]
pub extern "C" fn Servo_SetDeclarationBlockImmutable(declarations: *mut ServoDeclarationBlock) {
let declarations = unsafe { (declarations as *mut GeckoDeclarationBlock).as_mut().unwrap() };
declarations.immutable = true;
}
#[no_mangle]
pub extern "C" fn Servo_ClearDeclarationBlockCachePointer(declarations: *mut ServoDeclarationBlock) {
let declarations = unsafe { (declarations as *mut GeckoDeclarationBlock).as_mut().unwrap() };
declarations.cache = ptr::null_mut();
}

View file

@ -15,12 +15,14 @@ use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetLastChildElement};
use gecko_bindings::bindings::{Gecko_GetNextSibling, Gecko_GetNextSiblingElement};
use gecko_bindings::bindings::{Gecko_GetParentElement, Gecko_GetParentNode};
use gecko_bindings::bindings::{Gecko_GetPrevSibling, Gecko_GetPrevSiblingElement};
use gecko_bindings::bindings::{Gecko_IsHTMLElementInHTMLDocument, Gecko_IsLink, Gecko_IsRootElement, Gecko_IsTextNode};
use gecko_bindings::bindings::{Gecko_GetServoDeclarationBlock, Gecko_IsHTMLElementInHTMLDocument};
use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_IsTextNode};
use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink};
#[allow(unused_imports)] // Used in commented-out code.
use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData};
use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use gecko_bindings::structs::nsIAtom;
use glue::GeckoDeclarationBlock;
use libc::uintptr_t;
use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData};
@ -317,6 +319,15 @@ impl<'le> GeckoElement<'le> {
unsafe fn from_ref(el: &RawGeckoElement) -> GeckoElement<'le> {
GeckoElement::from_raw(el as *const RawGeckoElement as *mut RawGeckoElement)
}
pub fn parse_style_attribute(value: &str) -> Option<PropertyDeclarationBlock> {
// FIXME(bholley): Real base URL and error reporter.
let base_url = &*DUMMY_BASE_URL;
// FIXME(heycam): Needs real ParserContextExtraData so that URLs parse
// properly.
let extra_data = ParserContextExtraData::default();
Some(parse_style_attribute(value, &base_url, Box::new(StdoutErrorReporter), extra_data))
}
}
lazy_static! {
@ -325,6 +336,8 @@ lazy_static! {
};
}
static NO_STYLE_ATTRIBUTE: Option<PropertyDeclarationBlock> = None;
impl<'le> TElement for GeckoElement<'le> {
type ConcreteNode = GeckoNode<'le>;
type ConcreteDocument = GeckoDocument<'le>;
@ -334,20 +347,10 @@ impl<'le> TElement for GeckoElement<'le> {
}
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> {
panic!("Requires signature modification - only implemented in stylo branch");
/*
// FIXME(bholley): We should do what Servo does here. Gecko needs to
// call into the Servo CSS parser and then cache the resulting block
// in the nsAttrValue. That will allow us to borrow it from here.
let attr = self.get_attr(&ns!(), &atom!("style"));
// FIXME(bholley): Real base URL and error reporter.
let base_url = &*DUMMY_BASE_URL;
// FIXME(heycam): Needs real ParserContextExtraData so that URLs parse
// properly.
let extra_data = ParserContextExtraData::default();
attr.map(|v| parse_style_attribute(&v, &base_url, Box::new(StdoutErrorReporter),
extra_data))
*/
unsafe {
let ptr = Gecko_GetServoDeclarationBlock(self.element) as *mut GeckoDeclarationBlock;
ptr.as_ref().map(|d| &d.declarations).unwrap_or(&NO_STYLE_ATTRIBUTE)
}
}
fn get_state(&self) -> ElementState {