Bug 1339711 - Part 5: stylo: Support background presentation attribute; r?emilio draft
authorManish Goregaokar <manishearth@gmail.com>
Mon, 10 Apr 2017 15:28:48 +0800
changeset 561226 259732617f7ebedaca5a57d1013469d19b1f60e4
parent 561225 39a5c950a11624f5c131408817fe6709171dab81
child 623904 9742f2d76d85b28434a51035f7e8042146ede3e9
push id53654
push userbmo:manishearth@gmail.com
push dateWed, 12 Apr 2017 09:22:24 +0000
reviewersemilio
bugs1339711
milestone55.0a1
Bug 1339711 - Part 5: stylo: Support background presentation attribute; r?emilio MozReview-Commit-ID: LU6ETeH8lxn
dom/html/nsGenericHTMLElement.cpp
layout/reftests/backgrounds/reftest-stylo.list
layout/reftests/bugs/reftest-stylo.list
layout/style/GenericSpecifiedValues.h
layout/style/GenericSpecifiedValuesInlines.h
layout/style/ServoBindingList.h
layout/style/ServoSpecifiedValues.cpp
layout/style/ServoSpecifiedValues.h
layout/style/nsRuleData.cpp
layout/style/nsRuleData.h
servo/ports/geckolib/glue.rs
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1517,46 +1517,23 @@ nsGenericHTMLElement::MapImageBorderAttr
 void
 nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
                                         GenericSpecifiedValues* aData)
 {
 
   if (!aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Background)))
     return;
 
-  if (aData->IsServo()) {
-    // FIXME(bug 1339711)
-    NS_WARNING("stylo: cannot handle background presentation attribute");
-    return;
-  }
-
-  nsPresContext* presContext = aData->PresContext();
-
   if (!aData->PropertyIsSet(eCSSProperty_background_image) &&
-      presContext->UseDocumentColors()) {
+      aData->PresContext()->UseDocumentColors()) {
     // background
     nsAttrValue* value =
       const_cast<nsAttrValue*>(aAttributes->GetAttr(nsGkAtoms::background));
     if (value) {
-      nsRuleData* aRuleData = aData->AsGecko();
-      // Gecko-specific code
-      // Gecko caches the image on the attr directly, but we need not
-      // do the same thing for Servo.
-      if (aRuleData) {
-        nsCSSValue* backImage = aRuleData->ValueForBackgroundImage();
-        // If the value is an image, or it is a URL and we attempted a load,
-        // put it in the style tree.
-        if (value->Type() == nsAttrValue::eURL) {
-          value->LoadImage(presContext->Document());
-        }
-        if (value->Type() == nsAttrValue::eImage) {
-          nsCSSValueList* list = backImage->SetListValue();
-          list->mValue.SetImageValue(value->GetImageValue());
-        }
-      }
+      aData->SetBackgroundImage(*value);
     }
   }
 }
 
 void
 nsGenericHTMLElement::MapBGColorInto(const nsMappedAttributes* aAttributes,
                                      GenericSpecifiedValues* aData)
 {
--- a/layout/reftests/backgrounds/reftest-stylo.list
+++ b/layout/reftests/backgrounds/reftest-stylo.list
@@ -134,26 +134,26 @@ fails == background-size-monster-rem.htm
 
 fails == fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-1.html
 fuzzy(2,83) == fixed-bg-border-radius.html fixed-bg-border-radius.html
 
 HTTP == root-background-1.html root-background-1.html
 HTTP == root-background-1.html root-background-1.html
 
 fails == really-big-background.html really-big-background.html # Bug 1341690
-fails == body-background.html body-background.html # Bug 1339711
-fails == table-background.html table-background.html # Bug 1339711
-fails == table-background-print.html table-background-print.html
+== body-background.html body-background.html # Bug 1339711
+== table-background.html table-background.html # Bug 1339711
+== table-background-print.html table-background-print.html
 == div-background.html div-background.html
 
 == background-repeat-1-ref.html background-repeat-1-ref.html
 
 == multi-background-clip-content-border.html multi-background-clip-content-border.html
 
-fails HTTP == background-referrer.html background-referrer.html
+HTTP == background-referrer.html background-referrer.html
 
 == attachment-scroll-positioning-1.html attachment-scroll-positioning-1.html
 == attachment-local-positioning-1.html attachment-local-positioning-1.html
 == attachment-local-positioning-2.html attachment-local-positioning-2.html
 == attachment-local-positioning-3.html attachment-local-positioning-3.html
 == attachment-local-positioning-4.html attachment-local-positioning-4.html
 == attachment-local-positioning-5.html attachment-local-positioning-5.html
 
--- a/layout/reftests/bugs/reftest-stylo.list
+++ b/layout/reftests/bugs/reftest-stylo.list
@@ -1389,17 +1389,17 @@ pref(dom.use_xbl_scopes_for_remote_xul,t
 fails == 495385-5.html 495385-5.html
 fails == 496032-1.html 496032-1.html
 == 496840-1.html 496840-1.html
 fuzzy-if(skiaContent,1,17000) == 498228-1.xul 498228-1.xul
 == 501037.html 501037.html
 == 501257-1a.html 501257-1a.html
 == 501257-1b.html 501257-1b.html
 == 501257-1.xhtml 501257-1.xhtml
-fails == 501627-1.html 501627-1.html
+== 501627-1.html 501627-1.html
 == 502288-1.html 502288-1.html
 fails == 502447-1.html 502447-1.html
 == 502795-1.html 502795-1.html
 == 502942-1.html 502942-1.html
 == 503364-1a.html 503364-1a.html
 == 503364-1b.html 503364-1b.html
 # Reftest for bug 503531 marked as failing; should be re-enabled when
 # bug 607548 gets resolved.
@@ -1752,17 +1752,17 @@ fails == 776265-2d.html 776265-2d.html
 == 804323-1.html 804323-1.html
 == 811301-1.html 811301-1.html
 == 812824-1.html 812824-1.html
 == 814677.html 814677.html
 fails == 814952-1.html 814952-1.html
 fails == 815593-1.html 815593-1.html
 == 816359-1.html 816359-1.html
 == 816458-1.html 816458-1.html
-fails == 816948-1.html 816948-1.html
+== 816948-1.html 816948-1.html
 == 817019-1.html 817019-1.html
 fails == 818276-1.html 818276-1.html
 fails == 825999.html 825999.html
 == 827577-1a.html 827577-1a.html
 == 827577-1b.html 827577-1b.html
 == 827799-1.html 827799-1.html
 == 829958.html 829958.html
 == 836844-1.html 836844-1.html
--- a/layout/style/GenericSpecifiedValues.h
+++ b/layout/style/GenericSpecifiedValues.h
@@ -98,16 +98,17 @@ public:
     // Set a property to an RGBA nscolor value
     inline void SetColorValue(nsCSSPropertyID aId, nscolor aValue);
     inline void SetColorValueIfUnset(nsCSSPropertyID aId, nscolor aValue);
 
     // Set font-family to a string
     inline void SetFontFamily(const nsString& aValue);
     // Add a quirks-mode override to the decoration color of elements nested in <a>
     inline void SetTextDecorationColorOverride();
+    inline void SetBackgroundImage(nsAttrValue& value);
 
     const mozilla::StyleBackendType mType;
     nsPresContext* const mPresContext;
     const uint32_t mSIDs;
 };
 
 } // namespace mozilla
 
--- a/layout/style/GenericSpecifiedValuesInlines.h
+++ b/layout/style/GenericSpecifiedValuesInlines.h
@@ -165,11 +165,17 @@ GenericSpecifiedValues::SetFontFamily(co
 }
 
 void
 GenericSpecifiedValues::SetTextDecorationColorOverride()
 {
   MOZ_STYLO_FORWARD(SetTextDecorationColorOverride, ())
 }
 
+void
+GenericSpecifiedValues::SetBackgroundImage(nsAttrValue& aValue)
+{
+  MOZ_STYLO_FORWARD(SetBackgroundImage, (aValue))
+}
+
 } // namespace mozilla
 
 #endif // mozilla_GenericSpecifiedValuesInlines_h
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -263,16 +263,20 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property,
                    nscolor value)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetFontFamily, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    const nsAString& value)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetTextDecorationColorOverride, void,
                    RawServoDeclarationBlockBorrowed declarations)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetBackgroundImage, void,
+                   RawServoDeclarationBlockBorrowed declarations,
+                   const nsAString& value,
+                   RawGeckoURLExtraData* extra_data)
 
 // MediaList
 SERVO_BINDING_FUNC(Servo_MediaList_GetText, void,
                    RawServoMediaListBorrowed list, nsAString* result)
 SERVO_BINDING_FUNC(Servo_MediaList_SetText, void,
                    RawServoMediaListBorrowed list, const nsACString* text)
 SERVO_BINDING_FUNC(Servo_MediaList_GetLength, uint32_t,
                    RawServoMediaListBorrowed list)
--- a/layout/style/ServoSpecifiedValues.cpp
+++ b/layout/style/ServoSpecifiedValues.cpp
@@ -111,8 +111,19 @@ ServoSpecifiedValues::SetFontFamily(cons
   Servo_DeclarationBlock_SetFontFamily(mDecl, aValue);
 }
 
 void
 ServoSpecifiedValues::SetTextDecorationColorOverride()
 {
   Servo_DeclarationBlock_SetTextDecorationColorOverride(mDecl);
 }
+
+void
+ServoSpecifiedValues::SetBackgroundImage(nsAttrValue& aValue)
+{
+  // FIXME (bug 1310885) this should store resolved images directly on the servo
+  // side.
+  nsAutoString str;
+  aValue.ToString(str);
+  Servo_DeclarationBlock_SetBackgroundImage(mDecl, str,
+        mPresContext->Document()->DefaultStyleAttrURLData());
+}
\ No newline at end of file
--- a/layout/style/ServoSpecifiedValues.h
+++ b/layout/style/ServoSpecifiedValues.h
@@ -99,16 +99,17 @@ public:
                             nscolor aValue) {
     if (!PropertyIsSet(aId)) {
       SetColorValue(aId, aValue);
     }
   }
 
   void SetFontFamily(const nsString& aValue);
   void SetTextDecorationColorOverride();
+  void SetBackgroundImage(nsAttrValue& aValue);
 
 private:
   RefPtr<RawServoDeclarationBlock> mDecl;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ServoSpecifiedValues_h
--- a/layout/style/nsRuleData.cpp
+++ b/layout/style/nsRuleData.cpp
@@ -56,16 +56,31 @@ nsRuleData::SetTextDecorationColorOverri
   nsCSSValue* decoration = ValueForTextDecorationLine();
   int32_t newValue = NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
   if (decoration->GetUnit() == eCSSUnit_Enumerated) {
     newValue |= decoration->GetIntValue();
   }
   decoration->SetIntValue(newValue, eCSSUnit_Enumerated);
 }
 
+void
+nsRuleData::SetBackgroundImage(nsAttrValue& aValue)
+{
+  nsCSSValue* backImage = ValueForBackgroundImage();
+  // If the value is an image, or it is a URL and we attempted a load,
+  // put it in the style tree.
+  if (aValue.Type() == nsAttrValue::eURL) {
+    aValue.LoadImage(mPresContext->Document());
+  }
+  if (aValue.Type() == nsAttrValue::eImage) {
+    nsCSSValueList* list = backImage->SetListValue();
+    list->mValue.SetImageValue(aValue.GetImageValue());
+  }
+}
+
 #ifdef DEBUG
 nsRuleData::~nsRuleData()
 {
 #ifndef MOZ_VALGRIND
   // assert nothing in mSIDs has poison value
   size_t framePoisonOffset = GetPoisonOffset();
   for (size_t i = 0; i < nsStyleStructID_Length; ++i) {
     MOZ_ASSERT(!(mSIDs & (1 << i)) || mValueOffsets[i] != framePoisonOffset,
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -218,15 +218,16 @@ struct nsRuleData final: mozilla::Generi
                             nscolor aValue) {
     if (!PropertyIsSet(aId)) {
       SetColorValue(aId, aValue);
     }
   }
 
   void SetFontFamily(const nsString& aValue);
   void SetTextDecorationColorOverride();
+  void SetBackgroundImage(nsAttrValue& aValue);
 
 private:
   inline size_t GetPoisonOffset();
 
 };
 
 #endif
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1534,16 +1534,43 @@ pub extern "C" fn Servo_DeclarationBlock
             write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
                 decls.push(decl, Importance::Normal);
             })
         }
     }
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(declarations:
+                                                            RawServoDeclarationBlockBorrowed,
+                                                            value: *const nsAString,
+                                                            raw_extra_data: *mut URLExtraData) {
+    use style::properties::PropertyDeclaration;
+    use style::properties::longhands::background_image::SpecifiedValue as BackgroundImage;
+    use style::properties::longhands::background_image::single_value::SpecifiedValue as SingleBackgroundImage;
+    use style::values::specified::image::Image;
+    use style::values::specified::url::SpecifiedUrl;
+
+    let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
+    let string = unsafe { (*value).to_string() };
+    let error_reporter = StdoutErrorReporter;
+    let context = ParserContext::new(Origin::Author, url_data, &error_reporter);
+    if let Ok(url) = SpecifiedUrl::parse_from_string(string.into(), &context) {
+        let decl = PropertyDeclaration::BackgroundImage(BackgroundImage(
+            vec![SingleBackgroundImage(
+                Some(Image::Url(url))
+            )]
+        ));
+        write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
+            decls.push(decl, Importance::Normal);
+        })
+    }
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarations:
                                                                 RawServoDeclarationBlockBorrowed) {
     use style::properties::PropertyDeclaration;
     use style::properties::longhands::text_decoration_line;
 
     let mut decoration = text_decoration_line::computed_value::none;
     decoration |= text_decoration_line::COLOR_OVERRIDE;
     let decl = PropertyDeclaration::TextDecorationLine(decoration);