From 0392e58a2f523b7a93b459f30eda183ff5f2088b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 26 Mar 2017 13:53:34 -0700 Subject: [PATCH 1/4] stylo: Add support for text-align match-parent and the -moz-center-or-inherit behavior MozReview-Commit-ID: GEDM7JfJB8A --- components/style/gecko/wrapper.rs | 20 +++- components/style/properties/gecko.mako.rs | 6 +- .../longhand/inherited_text.mako.rs | 110 ++++++++++++++++-- 3 files changed, 123 insertions(+), 13 deletions(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 0666338058e..12a4c884336 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -51,7 +51,7 @@ use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS; use gecko_bindings::sugar::ownership::HasArcFFI; use parking_lot::RwLock; use properties::{ComputedValues, parse_style_attribute}; -use properties::PropertyDeclarationBlock; +use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; use properties::animated_properties::AnimationValueMap; use rule_tree::CascadeLevel as ServoCascadeLevel; use selector_parser::{ElementExt, Snapshot}; @@ -624,6 +624,24 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { fn synthesize_presentational_hints_for_legacy_attributes(&self, hints: &mut V) where V: Push, { + use properties::longhands::text_align::SpecifiedValue; + lazy_static! { + static ref TH_RULE: ApplicableDeclarationBlock = { + let global_style_data = &*GLOBAL_STYLE_DATA; + let pdb = PropertyDeclarationBlock::with_one( + PropertyDeclaration::TextAlign(SpecifiedValue::MozCenterOrInherit), + Importance::Normal + ); + let arc = Arc::new(global_style_data.shared_lock.wrap(pdb)); + ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints) + }; + }; + + // elements get a default MozCenterOrInherit which may get overridden + if self.get_namespace() == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) && + self.get_local_name().as_ptr() == atom!("th").as_ptr() { + hints.push(TH_RULE.clone()); + } let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; let declarations = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 78db1f0bd62..bc6d5471b0d 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -2797,8 +2797,12 @@ fn static_assert() { -webkit-text-stroke-width text-emphasis-position -moz-tab-size -moz-text-size-adjust"> <% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " + - "-moz-right match-parent char") %> + "-moz-right char") %> + <% text_align_reachable_keyword = Keyword("text-align", "start end left right center justify char") %> ${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)} + // Stable rust errors on unreachable patterns, and there is overlap, so we run with the overlapping + // constants removed + ${impl_keyword_clone('text_align', 'mTextAlign', text_align_reachable_keyword)} pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) { self.gecko.mTextShadow.replace_with_new(v.0.len() as u32); diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index b24cdbbcacf..37d58b07386 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -250,11 +250,10 @@ ${helpers.single_keyword("text-align-last", spec="https://drafts.csswg.org/css-text/#propdef-text-align-last")} // TODO make this a shorthand and implement text-align-last/text-align-all -<%helpers:longhand name="text-align" animatable="False" spec="https://drafts.csswg.org/css-text/#propdef-text-align"> - pub use self::computed_value::T as SpecifiedValue; +<%helpers:longhand name="text-align" animatable="False" need_clone="True" + spec="https://drafts.csswg.org/css-text/#propdef-text-align"> use values::computed::ComputedValueAsSpecified; use values::HasViewportPercentage; - impl ComputedValueAsSpecified for SpecifiedValue {} no_viewport_percentage!(SpecifiedValue); pub mod computed_value { use style_traits::ToCss; @@ -299,21 +298,110 @@ ${helpers.single_keyword("text-align-last", _moz_center("-moz-center") => 6, _moz_left("-moz-left") => 7, _moz_right("-moz-right") => 8, - match_parent("match-parent") => 9, char("char") => 10, % endif } + + ${helpers.gecko_keyword_conversion(Keyword('text-align', + """left right center justify -moz-left -moz-right + -moz-center char end""", + gecko_strip_moz_prefix=False), type="T")} } + #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T::start } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - computed_value::T::parse(input) - } - ${helpers.gecko_keyword_conversion(Keyword('text-align', - """left right center justify -moz-left -moz-right - -moz-center char end match-parent""", - gecko_strip_moz_prefix=False))} + + + % if product == "gecko": + use std::fmt; + use style_traits::ToCss; + + #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] + pub enum SpecifiedValue { + Keyword(computed_value::T), + MatchParent, + MozCenterOrInherit, + } + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + // MozCenterOrInherit cannot be parsed, only set directly on th elements + if let Ok(key) = input.try(computed_value::T::parse) { + Ok(SpecifiedValue::Keyword(key)) + } else { + input.expect_ident_matching("match-parent")?; + Ok(SpecifiedValue::MatchParent) + } + } + impl ToCss for SpecifiedValue { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + SpecifiedValue::Keyword(key) => key.to_css(dest), + SpecifiedValue::MatchParent => dest.write_str("match-parent"), + SpecifiedValue::MozCenterOrInherit => Ok(()), + } + } + } + + impl SpecifiedValue { + pub fn from_gecko_keyword(kw: u32) -> Self { + use gecko_bindings::structs::NS_STYLE_TEXT_ALIGN_MATCH_PARENT; + if kw == NS_STYLE_TEXT_ALIGN_MATCH_PARENT { + SpecifiedValue::MatchParent + } else { + SpecifiedValue::Keyword(computed_value::T::from_gecko_keyword(kw)) + } + } + } + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + #[inline] + fn to_computed_value(&self, context: &Context) -> computed_value::T { + match *self { + SpecifiedValue::Keyword(key) => key, + SpecifiedValue::MatchParent => { + // on the root element we should still respect the dir + // but the parent dir of that element is LTR even if it's + // and will only be RTL if certain prefs have been set. + // In that case, the default behavior here will set it to left, + // but we want to set it to right -- instead set it to the default (`start`), + // which will do the right thing in this case (but not the general case) + if context.is_root_element { + return get_initial_value(); + } + let parent = context.inherited_style().get_inheritedtext().clone_text_align(); + let ltr = context.inherited_style().writing_mode.is_bidi_ltr(); + match (parent, ltr) { + (computed_value::T::start, true) => computed_value::T::left, + (computed_value::T::start, false) => computed_value::T::right, + (computed_value::T::end, true) => computed_value::T::right, + (computed_value::T::end, false) => computed_value::T::left, + _ => parent + } + } + SpecifiedValue::MozCenterOrInherit => { + let parent = context.inherited_style().get_inheritedtext().clone_text_align(); + if parent == computed_value::T::start { + computed_value::T::center + } else { + parent + } + } + } + } + + #[inline] + fn from_computed_value(computed: &computed_value::T) -> Self { + SpecifiedValue::Keyword(*computed) + } + } + % else: + impl ComputedValueAsSpecified for SpecifiedValue {} + pub use self::computed_value::T as SpecifiedValue; + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + computed_value::T::parse(input) + } + % endif // FIXME: This prop should be animatable. From 1c23296d8af5299970e5affa48ecdcd0cbbac1f6 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 26 Mar 2017 13:53:34 -0700 Subject: [PATCH 2/4] stylo: Add support for color quirk MozReview-Commit-ID: 56IKARwfbhw --- components/style/gecko/wrapper.rs | 25 ++++++++++++---- components/style/gecko_bindings/bindings.rs | 4 +++ .../style/properties/longhand/color.mako.rs | 5 +--- components/style/values/computed/mod.rs | 29 ++++++++++++++----- components/style/values/specified/color.rs | 3 ++ components/style/values/specified/mod.rs | 21 ++++++++------ 6 files changed, 62 insertions(+), 25 deletions(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 12a4c884336..262e7f3018d 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -624,12 +624,23 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { fn synthesize_presentational_hints_for_legacy_attributes(&self, hints: &mut V) where V: Push, { - use properties::longhands::text_align::SpecifiedValue; + use properties::longhands::text_align::SpecifiedValue as SpecifiedTextAlign; + use properties::longhands::color::SpecifiedValue as SpecifiedColor; + use values::specified::color::Color; lazy_static! { static ref TH_RULE: ApplicableDeclarationBlock = { let global_style_data = &*GLOBAL_STYLE_DATA; let pdb = PropertyDeclarationBlock::with_one( - PropertyDeclaration::TextAlign(SpecifiedValue::MozCenterOrInherit), + PropertyDeclaration::TextAlign(SpecifiedTextAlign::MozCenterOrInherit), + Importance::Normal + ); + let arc = Arc::new(global_style_data.shared_lock.wrap(pdb)); + ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints) + }; + static ref TABLE_COLOR_RULE: ApplicableDeclarationBlock = { + let global_style_data = &*GLOBAL_STYLE_DATA; + let pdb = PropertyDeclarationBlock::with_one( + PropertyDeclaration::Color(SpecifiedColor(Color::InheritFromBodyQuirk.into())), Importance::Normal ); let arc = Arc::new(global_style_data.shared_lock.wrap(pdb)); @@ -638,9 +649,13 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { }; //
elements get a default MozCenterOrInherit which may get overridden - if self.get_namespace() == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) && - self.get_local_name().as_ptr() == atom!("th").as_ptr() { - hints.push(TH_RULE.clone()); + if self.get_namespace() == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) { + if self.get_local_name().as_ptr() == atom!("th").as_ptr() { + hints.push(TH_RULE.clone()); + } else if self.get_local_name().as_ptr() == atom!("table").as_ptr() && + self.as_node().owner_doc().mCompatMode == structs::nsCompatibility::eCompatibility_NavQuirks { + hints.push(TABLE_COLOR_RULE.clone()); + } } let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; let declarations = declarations.and_then(|s| s.as_arc_opt()); diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index c68b1294437..999beb32e0e 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -1050,6 +1050,10 @@ extern "C" { extern "C" { pub fn Gecko_CSSFontFaceRule_Release(aPtr: *mut nsCSSFontFaceRule); } +extern "C" { + pub fn Gecko_GetBody(pres_context: RawGeckoPresContextBorrowed) + -> RawGeckoElementBorrowedOrNull; +} extern "C" { pub fn Gecko_GetLookAndFeelSystemColor(color_id: i32, pres_context: diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 436012bf461..3825df7c128 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -26,10 +26,7 @@ #[inline] fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue(CSSColor { - parsed: Color::RGBA(*computed), - authored: None, - }) + SpecifiedValue(Color::RGBA(*computed).into()) } } diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 71eacc8bb8f..2cf46210317 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -209,6 +209,24 @@ impl ToComputedValue for specified::Color { specified::Color::MozHyperlinktext => to_rgba(pres_context.mLinkColor), specified::Color::MozActiveHyperlinktext => to_rgba(pres_context.mActiveLinkColor), specified::Color::MozVisitedHyperlinktext => to_rgba(pres_context.mVisitedLinkColor), + specified::Color::InheritFromBodyQuirk => { + use dom::TElement; + use gecko_bindings::bindings::Gecko_GetBody; + use gecko::wrapper::GeckoElement; + let body = unsafe { + Gecko_GetBody(pres_context) + }; + if let Some(body) = body { + let wrap = GeckoElement(body); + let borrow = wrap.borrow_data(); + borrow.as_ref().unwrap() + .styles().primary.values() + .get_color() + .clone_color() + } else { + to_rgba(pres_context.mDefaultColor) + } + }, } } @@ -239,13 +257,10 @@ impl ToComputedValue for specified::CSSColor { #[inline] fn from_computed_value(computed: &CSSColor) -> Self { - specified::CSSColor { - parsed: match *computed { - CSSColor::RGBA(rgba) => specified::Color::RGBA(rgba), - CSSColor::CurrentColor => specified::Color::CurrentColor, - }, - authored: None, - } + (match *computed { + CSSColor::RGBA(rgba) => specified::Color::RGBA(rgba), + CSSColor::CurrentColor => specified::Color::CurrentColor, + }).into() } } diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 4a3c5498716..fcd6c8be8d8 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -48,6 +48,8 @@ mod gecko { MozActiveHyperlinktext, /// -moz-visitedhyperlinktext MozVisitedHyperlinktext, + /// Quirksmode-only rule for inheriting color from the body + InheritFromBodyQuirk, } no_viewport_percentage!(Color); @@ -89,6 +91,7 @@ mod gecko { Color::MozHyperlinktext => dest.write_str("-moz-hyperlinktext"), Color::MozActiveHyperlinktext => dest.write_str("-moz-activehyperlinktext"), Color::MozVisitedHyperlinktext => dest.write_str("-moz-visitedhyperlinktext"), + Color::InheritFromBodyQuirk => Ok(()), } } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index e6317c6e570..f5ba7b7fb1d 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -107,24 +107,27 @@ impl ToCss for CSSColor { } } +impl From for CSSColor { + fn from(color: Color) -> Self { + CSSColor { + parsed: color, + authored: None, + } + } +} + impl CSSColor { #[inline] /// Returns currentcolor value. pub fn currentcolor() -> CSSColor { - CSSColor { - parsed: Color::CurrentColor, - authored: None, - } + Color::CurrentColor.into() } #[inline] /// Returns transparent value. pub fn transparent() -> CSSColor { - CSSColor { - parsed: Color::RGBA(cssparser::RGBA::transparent()), - // This should probably be "transparent", but maybe it doesn't matter. - authored: None, - } + // We should probably set authored to "transparent", but maybe it doesn't matter. + Color::RGBA(cssparser::RGBA::transparent()).into() } } From 8dea66e6f119d1d6eea35e200122534822d4b523 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 26 Mar 2017 13:53:34 -0700 Subject: [PATCH 3/4] stylo: Add support for default language MozReview-Commit-ID: LhhSBzYjow5 --- components/style/gecko/wrapper.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 262e7f3018d..cbfc8924e25 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -626,6 +626,7 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { { use properties::longhands::text_align::SpecifiedValue as SpecifiedTextAlign; use properties::longhands::color::SpecifiedValue as SpecifiedColor; + use properties::longhands::_x_lang::SpecifiedValue as SpecifiedLang; use values::specified::color::Color; lazy_static! { static ref TH_RULE: ApplicableDeclarationBlock = { @@ -646,16 +647,30 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { let arc = Arc::new(global_style_data.shared_lock.wrap(pdb)); ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints) }; + static ref MATHML_LANG_RULE: ApplicableDeclarationBlock = { + let global_style_data = &*GLOBAL_STYLE_DATA; + let pdb = PropertyDeclarationBlock::with_one( + PropertyDeclaration::XLang(SpecifiedLang(atom!("x-math"))), + Importance::Normal + ); + let arc = Arc::new(global_style_data.shared_lock.wrap(pdb)); + ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints) + }; }; + let ns = self.get_namespace(); // elements get a default MozCenterOrInherit which may get overridden - if self.get_namespace() == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) { + if ns == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) { if self.get_local_name().as_ptr() == atom!("th").as_ptr() { hints.push(TH_RULE.clone()); } else if self.get_local_name().as_ptr() == atom!("table").as_ptr() && self.as_node().owner_doc().mCompatMode == structs::nsCompatibility::eCompatibility_NavQuirks { hints.push(TABLE_COLOR_RULE.clone()); } + } else if ns == &*Namespace(atom!("http://www.w3.org/1998/Math/MathML")) { + if self.get_local_name().as_ptr() == atom!("math").as_ptr() { + hints.push(MATHML_LANG_RULE.clone()); + } } let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; let declarations = declarations.and_then(|s| s.as_arc_opt()); From 5d6bc8177e392d21675b7ca779b2be5bb66bf284 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 26 Mar 2017 13:53:34 -0700 Subject: [PATCH 4/4] stylo: Add support for xml:lang MozReview-Commit-ID: E0GpyPKES3k --- components/style/gecko/wrapper.rs | 32 +++++++++++++++++---- components/style/gecko_bindings/bindings.rs | 4 +++ components/style/values/computed/mod.rs | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index cbfc8924e25..9ec7ee3cf76 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -624,9 +624,9 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { fn synthesize_presentational_hints_for_legacy_attributes(&self, hints: &mut V) where V: Push, { - use properties::longhands::text_align::SpecifiedValue as SpecifiedTextAlign; - use properties::longhands::color::SpecifiedValue as SpecifiedColor; use properties::longhands::_x_lang::SpecifiedValue as SpecifiedLang; + use properties::longhands::color::SpecifiedValue as SpecifiedColor; + use properties::longhands::text_align::SpecifiedValue as SpecifiedTextAlign; use values::specified::color::Color; lazy_static! { static ref TH_RULE: ApplicableDeclarationBlock = { @@ -667,10 +667,6 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { self.as_node().owner_doc().mCompatMode == structs::nsCompatibility::eCompatibility_NavQuirks { hints.push(TABLE_COLOR_RULE.clone()); } - } else if ns == &*Namespace(atom!("http://www.w3.org/1998/Math/MathML")) { - if self.get_local_name().as_ptr() == atom!("math").as_ptr() { - hints.push(MATHML_LANG_RULE.clone()); - } } let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; let declarations = declarations.and_then(|s| s.as_arc_opt()); @@ -686,6 +682,30 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints) ); } + + // xml:lang has precedence over lang, which can be + // set by Gecko_GetHTMLPresentationAttrDeclarationBlock + // + // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#language + let ptr = unsafe { + bindings::Gecko_GetXMLLangValue(self.0) + }; + if !ptr.is_null() { + let global_style_data = &*GLOBAL_STYLE_DATA; + + let pdb = PropertyDeclarationBlock::with_one( + PropertyDeclaration::XLang(SpecifiedLang(Atom::from(ptr))), + Importance::Normal + ); + let arc = Arc::new(global_style_data.shared_lock.wrap(pdb)); + hints.push(ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints)) + } + // MathML's default lang has precedence over both `lang` and `xml:lang` + if ns == &*Namespace(atom!("http://www.w3.org/1998/Math/MathML")) { + if self.get_local_name().as_ptr() == atom!("math").as_ptr() { + hints.push(MATHML_LANG_RULE.clone()); + } + } } } diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index 999beb32e0e..f076001f46b 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -479,6 +479,10 @@ extern "C" { pub fn Gecko_GetElementId(element: RawGeckoElementBorrowed) -> *mut nsIAtom; } +extern "C" { + pub fn Gecko_GetXMLLangValue(element: RawGeckoElementBorrowed) + -> *mut nsIAtom; +} extern "C" { pub fn Gecko_AtomAttrValue(element: RawGeckoElementBorrowed, attribute: *mut nsIAtom) -> *mut nsIAtom; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 2cf46210317..b2b64e1c212 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -211,8 +211,8 @@ impl ToComputedValue for specified::Color { specified::Color::MozVisitedHyperlinktext => to_rgba(pres_context.mVisitedLinkColor), specified::Color::InheritFromBodyQuirk => { use dom::TElement; - use gecko_bindings::bindings::Gecko_GetBody; use gecko::wrapper::GeckoElement; + use gecko_bindings::bindings::Gecko_GetBody; let body = unsafe { Gecko_GetBody(pres_context) };