aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-02-03 17:36:04 -0800
committerGitHub <noreply@github.com>2017-02-03 17:36:04 -0800
commit57fb07e9c041750a82852ca8dde7364fc7083e5b (patch)
tree261c0c275f77ec901933f99204128d5efb9ccd2d
parentcd2dbd720bdffc87ec49fc4ad4e4aa0f5b2cb1f3 (diff)
parent34ba00e6d97973257f61adf6ecbb6a2205b88664 (diff)
downloadservo-57fb07e9c041750a82852ca8dde7364fc7083e5b.tar.gz
servo-57fb07e9c041750a82852ca8dde7364fc7083e5b.zip
Auto merge of #15331 - Manishearth:stylo-presattr, r=emilio,bz
Basic handling framework for presentation attributes in Stylo, with handling for font-size and color https://bugzilla.mozilla.org/show_bug.cgi?id=1330041 r=emilio,bz <!-- 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/15331) <!-- Reviewable:end -->
-rw-r--r--components/script/dom/htmlfontelement.rs21
-rw-r--r--components/style/gecko/wrapper.rs16
-rw-r--r--components/style/gecko_bindings/bindings.rs13
-rw-r--r--components/style/gecko_bindings/sugar/ns_css_value.rs24
-rw-r--r--components/style/values/specified/length.rs19
-rw-r--r--ports/geckolib/glue.rs57
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()) {