diff --git a/ports/geckolib/bindings.rs b/ports/geckolib/bindings.rs index a3640f775bd..16724678a80 100644 --- a/ports/geckolib/bindings.rs +++ b/ports/geckolib/bindings.rs @@ -1,5 +1,6 @@ /* automatically generated by rust-bindgen */ +use gecko_style_structs::SheetParsingMode; use gecko_style_structs::nsStyleFont; use gecko_style_structs::nsStyleColor; use gecko_style_structs::nsStyleList; @@ -68,7 +69,8 @@ extern "C" { pub fn Gecko_SetNodeData(node: *mut RawGeckoNode, data: *mut ServoNodeData); pub fn Servo_DropNodeData(data: *mut ServoNodeData); - pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8, length: u32) + pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8, length: u32, + parsing_mode: SheetParsingMode) -> *mut RawServoStyleSheet; pub fn Servo_AddRefStyleSheet(sheet: *mut RawServoStyleSheet); pub fn Servo_ReleaseStyleSheet(sheet: *mut RawServoStyleSheet); @@ -96,6 +98,8 @@ extern "C" { pub fn Gecko_GetAttrAsUTF8(element: *mut RawGeckoElement, ns: *const u8, name: *const u8, length: *mut u32) -> *const ::std::os::raw::c_char; + pub fn Gecko_GetAtomAsUTF16(atom: *mut nsIAtom, length: *mut u32) + -> *const u16; pub fn Gecko_LocalName(element: *mut RawGeckoElement, length: *mut u32) -> *const u16; pub fn Gecko_Namespace(element: *mut RawGeckoElement, length: *mut u32) @@ -106,23 +110,33 @@ extern "C" { pub fn Gecko_CopyConstruct_nsStyleFont(ptr: *mut nsStyleFont, other: *const nsStyleFont); pub fn Gecko_Destroy_nsStyleFont(ptr: *mut nsStyleFont); + pub fn Servo_GetStyleFont(computedValues: *mut ServoComputedValues) + -> *const nsStyleFont; pub fn Gecko_Construct_nsStyleColor(ptr: *mut nsStyleColor); pub fn Gecko_CopyConstruct_nsStyleColor(ptr: *mut nsStyleColor, other: *const nsStyleColor); pub fn Gecko_Destroy_nsStyleColor(ptr: *mut nsStyleColor); + pub fn Servo_GetStyleColor(computedValues: *mut ServoComputedValues) + -> *const nsStyleColor; pub fn Gecko_Construct_nsStyleList(ptr: *mut nsStyleList); pub fn Gecko_CopyConstruct_nsStyleList(ptr: *mut nsStyleList, other: *const nsStyleList); pub fn Gecko_Destroy_nsStyleList(ptr: *mut nsStyleList); + pub fn Servo_GetStyleList(computedValues: *mut ServoComputedValues) + -> *const nsStyleList; pub fn Gecko_Construct_nsStyleText(ptr: *mut nsStyleText); pub fn Gecko_CopyConstruct_nsStyleText(ptr: *mut nsStyleText, other: *const nsStyleText); pub fn Gecko_Destroy_nsStyleText(ptr: *mut nsStyleText); + pub fn Servo_GetStyleText(computedValues: *mut ServoComputedValues) + -> *const nsStyleText; pub fn Gecko_Construct_nsStyleVisibility(ptr: *mut nsStyleVisibility); pub fn Gecko_CopyConstruct_nsStyleVisibility(ptr: *mut nsStyleVisibility, other: *const nsStyleVisibility); pub fn Gecko_Destroy_nsStyleVisibility(ptr: *mut nsStyleVisibility); + pub fn Servo_GetStyleVisibility(computedValues: *mut ServoComputedValues) + -> *const nsStyleVisibility; pub fn Gecko_Construct_nsStyleUserInterface(ptr: *mut nsStyleUserInterface); pub fn Gecko_CopyConstruct_nsStyleUserInterface(ptr: @@ -130,81 +144,120 @@ extern "C" { other: *const nsStyleUserInterface); pub fn Gecko_Destroy_nsStyleUserInterface(ptr: *mut nsStyleUserInterface); + pub fn Servo_GetStyleUserInterface(computedValues: + *mut ServoComputedValues) + -> *const nsStyleUserInterface; pub fn Gecko_Construct_nsStyleTableBorder(ptr: *mut nsStyleTableBorder); pub fn Gecko_CopyConstruct_nsStyleTableBorder(ptr: *mut nsStyleTableBorder, other: *const nsStyleTableBorder); pub fn Gecko_Destroy_nsStyleTableBorder(ptr: *mut nsStyleTableBorder); + pub fn Servo_GetStyleTableBorder(computedValues: *mut ServoComputedValues) + -> *const nsStyleTableBorder; pub fn Gecko_Construct_nsStyleSVG(ptr: *mut nsStyleSVG); pub fn Gecko_CopyConstruct_nsStyleSVG(ptr: *mut nsStyleSVG, other: *const nsStyleSVG); pub fn Gecko_Destroy_nsStyleSVG(ptr: *mut nsStyleSVG); + pub fn Servo_GetStyleSVG(computedValues: *mut ServoComputedValues) + -> *const nsStyleSVG; pub fn Gecko_Construct_nsStyleVariables(ptr: *mut nsStyleVariables); pub fn Gecko_CopyConstruct_nsStyleVariables(ptr: *mut nsStyleVariables, other: *const nsStyleVariables); pub fn Gecko_Destroy_nsStyleVariables(ptr: *mut nsStyleVariables); + pub fn Servo_GetStyleVariables(computedValues: *mut ServoComputedValues) + -> *const nsStyleVariables; pub fn Gecko_Construct_nsStyleBackground(ptr: *mut nsStyleBackground); pub fn Gecko_CopyConstruct_nsStyleBackground(ptr: *mut nsStyleBackground, other: *const nsStyleBackground); pub fn Gecko_Destroy_nsStyleBackground(ptr: *mut nsStyleBackground); + pub fn Servo_GetStyleBackground(computedValues: *mut ServoComputedValues) + -> *const nsStyleBackground; pub fn Gecko_Construct_nsStylePosition(ptr: *mut nsStylePosition); pub fn Gecko_CopyConstruct_nsStylePosition(ptr: *mut nsStylePosition, other: *const nsStylePosition); pub fn Gecko_Destroy_nsStylePosition(ptr: *mut nsStylePosition); + pub fn Servo_GetStylePosition(computedValues: *mut ServoComputedValues) + -> *const nsStylePosition; pub fn Gecko_Construct_nsStyleTextReset(ptr: *mut nsStyleTextReset); pub fn Gecko_CopyConstruct_nsStyleTextReset(ptr: *mut nsStyleTextReset, other: *const nsStyleTextReset); pub fn Gecko_Destroy_nsStyleTextReset(ptr: *mut nsStyleTextReset); + pub fn Servo_GetStyleTextReset(computedValues: *mut ServoComputedValues) + -> *const nsStyleTextReset; pub fn Gecko_Construct_nsStyleDisplay(ptr: *mut nsStyleDisplay); pub fn Gecko_CopyConstruct_nsStyleDisplay(ptr: *mut nsStyleDisplay, other: *const nsStyleDisplay); pub fn Gecko_Destroy_nsStyleDisplay(ptr: *mut nsStyleDisplay); + pub fn Servo_GetStyleDisplay(computedValues: *mut ServoComputedValues) + -> *const nsStyleDisplay; pub fn Gecko_Construct_nsStyleContent(ptr: *mut nsStyleContent); pub fn Gecko_CopyConstruct_nsStyleContent(ptr: *mut nsStyleContent, other: *const nsStyleContent); pub fn Gecko_Destroy_nsStyleContent(ptr: *mut nsStyleContent); + pub fn Servo_GetStyleContent(computedValues: *mut ServoComputedValues) + -> *const nsStyleContent; pub fn Gecko_Construct_nsStyleUIReset(ptr: *mut nsStyleUIReset); pub fn Gecko_CopyConstruct_nsStyleUIReset(ptr: *mut nsStyleUIReset, other: *const nsStyleUIReset); pub fn Gecko_Destroy_nsStyleUIReset(ptr: *mut nsStyleUIReset); + pub fn Servo_GetStyleUIReset(computedValues: *mut ServoComputedValues) + -> *const nsStyleUIReset; pub fn Gecko_Construct_nsStyleTable(ptr: *mut nsStyleTable); pub fn Gecko_CopyConstruct_nsStyleTable(ptr: *mut nsStyleTable, other: *const nsStyleTable); pub fn Gecko_Destroy_nsStyleTable(ptr: *mut nsStyleTable); + pub fn Servo_GetStyleTable(computedValues: *mut ServoComputedValues) + -> *const nsStyleTable; pub fn Gecko_Construct_nsStyleMargin(ptr: *mut nsStyleMargin); pub fn Gecko_CopyConstruct_nsStyleMargin(ptr: *mut nsStyleMargin, other: *const nsStyleMargin); pub fn Gecko_Destroy_nsStyleMargin(ptr: *mut nsStyleMargin); + pub fn Servo_GetStyleMargin(computedValues: *mut ServoComputedValues) + -> *const nsStyleMargin; pub fn Gecko_Construct_nsStylePadding(ptr: *mut nsStylePadding); pub fn Gecko_CopyConstruct_nsStylePadding(ptr: *mut nsStylePadding, other: *const nsStylePadding); pub fn Gecko_Destroy_nsStylePadding(ptr: *mut nsStylePadding); + pub fn Servo_GetStylePadding(computedValues: *mut ServoComputedValues) + -> *const nsStylePadding; pub fn Gecko_Construct_nsStyleBorder(ptr: *mut nsStyleBorder); pub fn Gecko_CopyConstruct_nsStyleBorder(ptr: *mut nsStyleBorder, other: *const nsStyleBorder); pub fn Gecko_Destroy_nsStyleBorder(ptr: *mut nsStyleBorder); + pub fn Servo_GetStyleBorder(computedValues: *mut ServoComputedValues) + -> *const nsStyleBorder; pub fn Gecko_Construct_nsStyleOutline(ptr: *mut nsStyleOutline); pub fn Gecko_CopyConstruct_nsStyleOutline(ptr: *mut nsStyleOutline, other: *const nsStyleOutline); pub fn Gecko_Destroy_nsStyleOutline(ptr: *mut nsStyleOutline); + pub fn Servo_GetStyleOutline(computedValues: *mut ServoComputedValues) + -> *const nsStyleOutline; pub fn Gecko_Construct_nsStyleXUL(ptr: *mut nsStyleXUL); pub fn Gecko_CopyConstruct_nsStyleXUL(ptr: *mut nsStyleXUL, other: *const nsStyleXUL); pub fn Gecko_Destroy_nsStyleXUL(ptr: *mut nsStyleXUL); + pub fn Servo_GetStyleXUL(computedValues: *mut ServoComputedValues) + -> *const nsStyleXUL; pub fn Gecko_Construct_nsStyleSVGReset(ptr: *mut nsStyleSVGReset); pub fn Gecko_CopyConstruct_nsStyleSVGReset(ptr: *mut nsStyleSVGReset, other: *const nsStyleSVGReset); pub fn Gecko_Destroy_nsStyleSVGReset(ptr: *mut nsStyleSVGReset); + pub fn Servo_GetStyleSVGReset(computedValues: *mut ServoComputedValues) + -> *const nsStyleSVGReset; pub fn Gecko_Construct_nsStyleColumn(ptr: *mut nsStyleColumn); pub fn Gecko_CopyConstruct_nsStyleColumn(ptr: *mut nsStyleColumn, other: *const nsStyleColumn); pub fn Gecko_Destroy_nsStyleColumn(ptr: *mut nsStyleColumn); + pub fn Servo_GetStyleColumn(computedValues: *mut ServoComputedValues) + -> *const nsStyleColumn; pub fn Gecko_Construct_nsStyleEffects(ptr: *mut nsStyleEffects); pub fn Gecko_CopyConstruct_nsStyleEffects(ptr: *mut nsStyleEffects, other: *const nsStyleEffects); pub fn Gecko_Destroy_nsStyleEffects(ptr: *mut nsStyleEffects); + pub fn Servo_GetStyleEffects(computedValues: *mut ServoComputedValues) + -> *const nsStyleEffects; } diff --git a/ports/geckolib/gecko_style_structs.rs b/ports/geckolib/gecko_style_structs.rs index 114fe03b2b6..f5807afd5e9 100644 --- a/ports/geckolib/gecko_style_structs.rs +++ b/ports/geckolib/gecko_style_structs.rs @@ -3986,6 +3986,34 @@ fn bindgen_test_layout_CounterStyleManager() { assert_eq!(::std::mem::size_of::() , 72usize); assert_eq!(::std::mem::align_of::() , 8usize); } +/** + * Enum defining the mode in which a sheet is to be parsed. This is + * usually, but not always, the same as the cascade level at which the + * sheet will apply (see nsStyleSet.h). Most of the Loader APIs only + * support loading of author sheets. + * + * Author sheets are the normal case: styles embedded in or linked + * from HTML pages. They are also the most restricted. + * + * User sheets can do anything author sheets can do, and also get + * access to a few CSS extensions that are not yet suitable for + * exposure on the public Web, but are very useful for expressing + * user style overrides, such as @-moz-document rules. + * + * Agent sheets have access to all author- and user-sheet features + * plus more extensions that are necessary for internal use but, + * again, not yet suitable for exposure on the public Web. Some of + * these are outright unsafe to expose; in particular, incorrect + * styling of anonymous box pseudo-elements can violate layout + * invariants. + */ +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum SheetParsingMode { + eAuthorSheetFeatures = 0, + eUserSheetFeatures = 1, + eAgentSheetFeatures = 2, +} pub type nsLoadFlags = u32; #[repr(C)] #[derive(Debug, Copy)] diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 4d7f2cdcb93..adf5a43ced6 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -10,8 +10,9 @@ use bindings::{RawServoStyleSet, RawServoStyleSheet, ServoComputedValues, ServoN use bindings::{nsIAtom}; use data::PerDocumentStyleData; use euclid::Size2D; +use gecko_style_structs::SheetParsingMode; use properties::GeckoComputedValues; -use selector_impl::{SharedStyleContext, Stylesheet}; +use selector_impl::{GeckoSelectorImpl, SharedStyleContext, Stylesheet}; use std::marker::PhantomData; use std::mem::{forget, transmute}; use std::ptr; @@ -81,13 +82,20 @@ pub extern "C" fn Servo_DropNodeData(data: *mut ServoNodeData) -> () { #[no_mangle] pub extern "C" fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8, - length: u32) -> *mut RawServoStyleSheet { + length: u32, + mode: SheetParsingMode) -> *mut RawServoStyleSheet { let input = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) }; - // FIXME(heycam): Pass in the real base URL and sheet origin to use. + let origin = match mode { + SheetParsingMode::eAuthorSheetFeatures => Origin::Author, + SheetParsingMode::eUserSheetFeatures => Origin::User, + SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, + }; + + // FIXME(heycam): Pass in the real base URL. let url = Url::parse("about:none").unwrap(); - let sheet = Arc::new(Stylesheet::from_str(input, url, Origin::Author, Box::new(StdoutErrorReporter))); + let sheet = Arc::new(Stylesheet::from_str(input, url, origin, Box::new(StdoutErrorReporter))); unsafe { transmute(sheet) } @@ -198,12 +206,48 @@ pub extern "C" fn Servo_GetComputedValues(node: *mut RawGeckoNode) } #[no_mangle] -pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(_parentStyleOrNull: *mut ServoComputedValues, - _pseudoTag: *mut nsIAtom, +pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(parent_style_or_null: *mut ServoComputedValues, + pseudo_tag: *mut nsIAtom, raw_data: *mut RawServoStyleSet) -> *mut ServoComputedValues { - let _data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - unimplemented!(); + use bindings::Gecko_GetAtomAsUTF16; + use selectors::parser::{ParserContext, SelectorImpl}; + + let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + + // TODO: This is ugly and should go away once we get an atom back-end. + let pseudo_string = unsafe { + let mut length = 0; + let buff = Gecko_GetAtomAsUTF16(pseudo_tag, &mut length); + String::from_utf16(slice::from_raw_parts(buff, length as usize)).unwrap() + }; + + let mut context = ParserContext::new(); + // Parse every pseudo-element possible. + context.in_user_agent_stylesheet = true; + + let pseudo = match GeckoSelectorImpl::parse_pseudo_element(&context, &pseudo_string) { + Ok(pseudo) => pseudo, + Err(_) => { + warn!("stylo: Unable to parse pseudo-element: {}", pseudo_string); + return ptr::null_mut(); + } + }; + + unsafe { + let parent: Option> = + if parent_style_or_null.is_null() { + None + } else { + Some(transmute(parent_style_or_null)) + }; + + let new_computed = data.stylist.computed_values_for_pseudo(&pseudo, parent.as_ref()); + + forget(parent); + + new_computed.map_or(ptr::null_mut(), |c| transmute(c)) + } } #[no_mangle] diff --git a/ports/geckolib/tools/regen_bindings.sh b/ports/geckolib/tools/regen_bindings.sh index 5529dd95234..cff58117d91 100755 --- a/ports/geckolib/tools/regen_bindings.sh +++ b/ports/geckolib/tools/regen_bindings.sh @@ -28,17 +28,17 @@ else LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib; fi -# Prevent bindgen from generating opaque types for the gecko style structs. -export MAP_GECKO_STRUCTS="" -for STRUCT in nsStyleFont nsStyleColor nsStyleList nsStyleText \ +# Prevent bindgen from generating opaque types for common gecko types +export MAP_GECKO_TYPES="" +for STRUCT in SheetParsingMode nsStyleFont nsStyleColor nsStyleList nsStyleText \ nsStyleVisibility nsStyleUserInterface nsStyleTableBorder \ nsStyleSVG nsStyleVariables nsStyleBackground nsStylePosition \ nsStyleTextReset nsStyleDisplay nsStyleContent nsStyleUIReset \ nsStyleTable nsStyleMargin nsStylePadding nsStyleBorder \ nsStyleOutline nsStyleXUL nsStyleSVGReset nsStyleColumn nsStyleEffects do - MAP_GECKO_STRUCTS=$MAP_GECKO_STRUCTS"-blacklist-type $STRUCT " - MAP_GECKO_STRUCTS=$MAP_GECKO_STRUCTS"-raw-line 'use gecko_style_structs::$STRUCT;' " + MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $STRUCT " + MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use gecko_style_structs::$STRUCT;' " done # Check for the include directory. @@ -50,7 +50,7 @@ fi export RUST_BACKTRACE=1 -# We need to use 'eval' here to make MAP_GECKO_STRUCTS evaluate properly as +# We need to use 'eval' here to make MAP_GECKO_TYPES evaluate properly as # multiple arguments. eval ./rust-bindgen/target/debug/bindgen \ -x c++ -std=gnu++0x \ @@ -61,4 +61,4 @@ eval ./rust-bindgen/target/debug/bindgen \ "$DIST_INCLUDE/mozilla/ServoBindings.h" \ -match "ServoBindings.h" \ -match "nsStyleStructList.h" \ - $MAP_GECKO_STRUCTS + $MAP_GECKO_TYPES diff --git a/ports/geckolib/tools/regen_style_structs.sh b/ports/geckolib/tools/regen_style_structs.sh index dc4690fc188..95833f88a16 100755 --- a/ports/geckolib/tools/regen_style_structs.sh +++ b/ports/geckolib/tools/regen_style_structs.sh @@ -95,6 +95,7 @@ export RUST_BACKTRACE=1 -match "nsDataHashtable.h" \ -match "nsCSSScanner.h" \ -match "Types.h" \ + -match "SheetParsingMode.h" \ -blacklist-type "IsDestructibleFallbackImpl" \ -blacklist-type "IsDestructibleFallback" \ -opaque-type "nsIntMargin" \