diff options
-rw-r--r-- | components/script/dom/htmlfontelement.rs | 21 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 16 | ||||
-rw-r--r-- | components/style/gecko_bindings/bindings.rs | 13 | ||||
-rw-r--r-- | components/style/gecko_bindings/sugar/ns_css_value.rs | 24 | ||||
-rw-r--r-- | components/style/values/specified/length.rs | 19 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 57 |
6 files changed, 126 insertions, 24 deletions
diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs index 0eca01a47f9..80a0266595c 100644 --- a/components/script/dom/htmlfontelement.rs +++ b/components/script/dom/htmlfontelement.rs @@ -123,7 +123,7 @@ impl HTMLFontElementLayoutHelpers for LayoutJS<HTMLFontElement> { } /// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size -pub fn parse_legacy_font_size(mut input: &str) -> Option<&'static str> { +fn parse_length(mut input: &str) -> Option<specified::Length> { // Steps 1 & 2 are not relevant // Step 3 @@ -153,8 +153,8 @@ pub fn parse_legacy_font_size(mut input: &str) -> Option<&'static str> { // Steps 6, 7, 8 let mut value = match read_numbers(input_chars) { - (Some(v), _) => v, - (None, _) => return None, + (Some(v), _) if v >= 0 => v, + _ => return None, }; // Step 9 @@ -165,18 +165,5 @@ pub fn parse_legacy_font_size(mut input: &str) -> Option<&'static str> { } // Steps 10, 11, 12 - Some(match value { - n if n >= 7 => "xxx-large", - 6 => "xx-large", - 5 => "x-large", - 4 => "large", - 3 => "medium", - 2 => "small", - n if n <= 1 => "x-small", - _ => unreachable!(), - }) -} - -fn parse_length(value: &str) -> Option<specified::Length> { - parse_legacy_font_size(&value).and_then(|parsed| specified::Length::from_str(&parsed)) + Some(specified::Length::from_font_size_int(value as u8)) } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index b73db50a50b..872fc06486c 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -30,7 +30,8 @@ use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink, Gecko use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use gecko_bindings::bindings::Gecko_ClassOrClassList; use gecko_bindings::bindings::Gecko_GetAnimationRule; -use gecko_bindings::bindings::Gecko_GetServoDeclarationBlock; +use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock; +use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock; use gecko_bindings::bindings::Gecko_GetStyleContext; use gecko_bindings::structs; use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode}; @@ -42,6 +43,7 @@ use parking_lot::RwLock; use parser::ParserContextExtraData; use properties::{ComputedValues, parse_style_attribute}; use properties::PropertyDeclarationBlock; +use rule_tree::CascadeLevel as ServoCascadeLevel; use selector_parser::{ElementExt, Snapshot}; use selectors::Element; use selectors::parser::{AttrSelector, NamespaceConstraint}; @@ -385,7 +387,7 @@ impl<'le> TElement for GeckoElement<'le> { } fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>> { - let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.0) }; + let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) }; declarations.map(|s| s.as_arc_opt()).unwrap_or(None) } @@ -483,10 +485,16 @@ impl<'le> PartialEq for GeckoElement<'le> { } impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { - fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, _hints: &mut V) + fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V) where V: Push<ApplicableDeclarationBlock>, { - // FIXME(bholley) - Need to implement this. + let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; + let declarations = declarations.and_then(|s| s.as_arc_opt()); + if let Some(decl) = declarations { + hints.push( + ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints) + ); + } } } diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index eafce93ea25..b16d0a442b3 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -499,7 +499,11 @@ extern "C" { -> u32; } extern "C" { - pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed) + pub fn Gecko_GetStyleAttrDeclarationBlock(element: RawGeckoElementBorrowed) + -> RawServoDeclarationBlockStrongBorrowedOrNull; +} +extern "C" { + pub fn Gecko_GetHTMLPresentationAttrDeclarationBlock(element: RawGeckoElementBorrowed) -> RawServoDeclarationBlockStrongBorrowedOrNull; } extern "C" { @@ -1392,6 +1396,13 @@ extern "C" { nsCSSPropertyID); } extern "C" { + pub fn Servo_DeclarationBlock_AddPresValue(declarations: + RawServoDeclarationBlockBorrowed, + property: nsCSSPropertyID, + css_value: + nsCSSValueBorrowedMut); +} +extern "C" { pub fn Servo_CSSSupports2(name: *const nsACString_internal, value: *const nsACString_internal) -> bool; } diff --git a/components/style/gecko_bindings/sugar/ns_css_value.rs b/components/style/gecko_bindings/sugar/ns_css_value.rs index 3f125b13311..0eb9dc5c90c 100644 --- a/components/style/gecko_bindings/sugar/ns_css_value.rs +++ b/components/style/gecko_bindings/sugar/ns_css_value.rs @@ -12,7 +12,7 @@ use gecko_bindings::bindings::Gecko_CSSValue_GetPercentage; use gecko_bindings::bindings::Gecko_CSSValue_SetAbsoluteLength; use gecko_bindings::bindings::Gecko_CSSValue_SetCalc; use gecko_bindings::bindings::Gecko_CSSValue_SetPercentage; -use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array}; +use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array, nscolor}; use std::mem; use std::ops::Index; use std::slice; @@ -34,6 +34,28 @@ impl nsCSSValue { unsafe { *self.mValue.mInt.as_ref() } } + /// Checks if it is an integer and returns it if so + pub fn integer(&self) -> Option<i32> { + if self.mUnit == nsCSSUnit::eCSSUnit_Integer || + self.mUnit == nsCSSUnit::eCSSUnit_Enumerated || + self.mUnit == nsCSSUnit::eCSSUnit_EnumColor { + Some(unsafe { *self.mValue.mInt.as_ref() }) + } else { + None + } + } + + /// Checks if it is an RGBA color, returning it if so + /// Only use it with colors set by SetColorValue(), + /// which always sets RGBA colors + pub fn color_value(&self) -> Option<nscolor> { + if self.mUnit == nsCSSUnit::eCSSUnit_RGBAColor { + Some(unsafe { *self.mValue.mColor.as_ref() }) + } else { + None + } + } + /// Returns this nsCSSValue value as a floating point value, unchecked in /// release builds. pub fn float_unchecked(&self) -> f32 { diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 9cc284fd774..351c692cc9a 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -293,6 +293,20 @@ impl NoCalcLength { }) } + /// https://drafts.csswg.org/css-fonts-3/#font-size-prop + pub fn from_font_size_int(i: u8) -> Self { + let au = match i { + 0 | 1 => Au::from_px(FONT_MEDIUM_PX) * 3 / 4, + 2 => Au::from_px(FONT_MEDIUM_PX) * 8 / 9, + 3 => Au::from_px(FONT_MEDIUM_PX), + 4 => Au::from_px(FONT_MEDIUM_PX) * 6 / 5, + 5 => Au::from_px(FONT_MEDIUM_PX) * 3 / 2, + 6 => Au::from_px(FONT_MEDIUM_PX) * 2, + _ => Au::from_px(FONT_MEDIUM_PX) * 3, + }; + NoCalcLength::Absolute(au) + } + /// Parse a given absolute or relative dimension. pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<NoCalcLength, ()> { match_ignore_ascii_case! { unit, @@ -429,6 +443,11 @@ impl Length { NoCalcLength::parse_dimension(value, unit).map(Length::NoCalc) } + /// https://drafts.csswg.org/css-fonts-3/#font-size-prop + pub fn from_font_size_int(i: u8) -> Self { + Length::NoCalc(NoCalcLength::from_font_size_int(i)) + } + #[inline] fn parse_internal(input: &mut Parser, context: AllowedNumericType) -> Result<Length, ()> { match try!(input.next()) { diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 5de30623403..e075843a114 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -34,7 +34,7 @@ use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSet use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong}; -use style::gecko_bindings::bindings::{nsACString, nsAString}; +use style::gecko_bindings::bindings::{nsACString, nsCSSValueBorrowedMut, nsAString}; use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe; use style::gecko_bindings::bindings::RawGeckoAnimationValueListBorrowedMut; use style::gecko_bindings::bindings::RawGeckoElementBorrowed; @@ -947,6 +947,61 @@ pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawSer } #[no_mangle] +pub extern "C" fn Servo_DeclarationBlock_AddPresValue(declarations: RawServoDeclarationBlockBorrowed, + property: nsCSSPropertyID, + css_value: nsCSSValueBorrowedMut) { + use style::gecko::values::convert_nscolor_to_rgba; + use style::properties::{DeclaredValue, LonghandId, PropertyDeclaration, PropertyId, longhands}; + use style::values::specified; + + let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); + let prop = PropertyId::from_nscsspropertyid(property); + + let long = match prop { + Ok(PropertyId::Longhand(long)) => long, + _ => { + error!("stylo: unknown presentation property with id {:?}", property); + return + } + }; + let decl = match long { + LonghandId::FontSize => { + if let Some(int) = css_value.integer() { + PropertyDeclaration::FontSize(DeclaredValue::Value( + longhands::font_size::SpecifiedValue( + specified::LengthOrPercentage::Length( + specified::NoCalcLength::from_font_size_int(int as u8) + ) + ) + )) + } else { + error!("stylo: got unexpected non-integer value for font-size presentation attribute"); + return + } + } + LonghandId::Color => { + if let Some(color) = css_value.color_value() { + PropertyDeclaration::Color(DeclaredValue::Value( + specified::CSSRGBA { + parsed: convert_nscolor_to_rgba(color), + authored: None + } + )) + } else { + error!("stylo: got unexpected non-integer value for color presentation attribute"); + return + } + } + _ => { + error!("stylo: cannot handle longhand {:?} from presentation attribute", long); + return + } + }; + declarations.write().declarations.push((decl, Importance::Normal)); + +} + +#[no_mangle] pub extern "C" fn Servo_CSSSupports2(property: *const nsACString, value: *const nsACString) -> bool { let property = unsafe { property.as_ref().unwrap().as_str_unchecked() }; let id = if let Ok(id) = PropertyId::parse(property.into()) { |