Bug 1110950 - Trigger a reflow (as well as a repaint) for changes to 'object-fit' and 'object-position', so subdocuments can be repositioned/resized. r=roc, a=sledru
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 15 Jan 2015 14:39:52 -0800
changeset 242924 2b2b697613eb
parent 242923 be5eee20bba5
child 242925 595835cd60a0
push id4341
push userryanvm@gmail.com
push date2015-01-20 15:33 +0000
treeherdermozilla-beta@595835cd60a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sledru
bugs1110950
milestone36.0
Bug 1110950 - Trigger a reflow (as well as a repaint) for changes to 'object-fit' and 'object-position', so subdocuments can be repositioned/resized. r=roc, a=sledru
layout/reftests/image/image-object-fit-dyn-1-ref.html
layout/reftests/image/image-object-fit-dyn-1.html
layout/reftests/image/image-object-position-dyn-1-ref.html
layout/reftests/image/image-object-position-dyn-1.html
layout/reftests/image/reftest.list
layout/style/nsStyleStruct.cpp
new file mode 100644
--- /dev/null
+++ b/layout/reftests/image/image-object-fit-dyn-1-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+  <head>
+    <meta charset="utf-8">
+    <style type="text/css">
+      embed, img, object, video {
+        object-fit: cover;
+        background: red;
+        width: 50px;
+        height: 30px;
+      }
+    </style>
+  </head>
+  <body>
+    <embed src="500.svg">
+    <img src="500.svg">
+    <object data="500.svg"></object>
+    <video poster="500.svg"></video>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/image/image-object-fit-dyn-1.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!--
+     This testcase ensures that we repaint correctly when "object-fit" is
+     adjusted on a replaced element with SVG content.  We start with
+     "object-fit: contain", which lets some of the red background show through
+     as we fit the SVG's square aspect-ratio into the wide rectangular
+     container elements. We then change dynamically to "object-fit: cover",
+     which should scale our SVG content to cover each replaced element's
+     content-box. No red should ultimately be visible in the reftest snapshot.
+-->
+<html class="reftest-wait">
+  <head>
+    <meta charset="utf-8">
+    <style type="text/css">
+      embed, img, object, video {
+        object-fit: contain;
+        background: red;
+        width: 50px;
+        height: 30px;
+      }
+    </style>
+    <script>
+      function go() {
+        var elemsToTweak = ["embed", "img", "object", "video"];
+        elemsToTweak.forEach(tweakElemObjectFit);
+        document.documentElement.removeAttribute("class");
+      }
+      function tweakElemObjectFit(tagName) {
+        var elem = document.getElementsByTagName(tagName)[0];
+        elem.style.objectFit = "cover";
+      }
+      document.addEventListener("MozReftestInvalidate", go);
+    </script>
+  </head>
+  <body>
+    <embed src="500.svg">
+    <img src="500.svg">
+    <object data="500.svg"></object>
+    <video poster="500.svg"></video>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/image/image-object-position-dyn-1-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+  <head>
+    <meta charset="utf-8">
+    <style type="text/css">
+      embed, img, object, video {
+        object-fit: fill;
+        object-position: 0 0;
+        background: red;
+        width: 50px;
+        height: 30px;
+      }
+    </style>
+  </head>
+  <body>
+    <embed src="500.svg">
+    <img src="500.svg">
+    <object data="500.svg"></object>
+    <video poster="500.svg"></video>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/image/image-object-position-dyn-1.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!--
+     This testcase ensures that we repaint correctly when "object-position" is
+     adjusted on a replaced element with SVG content.  We start with
+     "object-position: 10px 15px", which lets a strip of the red background
+     show through on the top and left edges. We then change dynamically to
+     "object-position: 0 0", which (given our "object-fit: fill" value) lets
+     the SVG image fill each replaced element without any uncovered edges.
+-->
+<html class="reftest-wait">
+  <head>
+    <meta charset="utf-8">
+    <style type="text/css">
+      embed, img, object, video {
+        object-fit: fill;
+        object-position: 10px 15px;
+        background: red;
+        width: 50px;
+        height: 30px;
+      }
+    </style>
+    <script>
+      function go() {
+        var elemsToTweak = ["embed", "img", "object", "video"];
+        elemsToTweak.forEach(tweakElemObjectFit);
+        document.documentElement.removeAttribute("class");
+      }
+      function tweakElemObjectFit(tagName) {
+        var elem = document.getElementsByTagName(tagName)[0];
+        elem.style.objectPosition = "0 0";
+      }
+      document.addEventListener("MozReftestInvalidate", go);
+    </script>
+  </head>
+  <body>
+    <embed src="500.svg">
+    <img src="500.svg">
+    <object data="500.svg"></object>
+    <video poster="500.svg"></video>
+  </body>
+</html>
--- a/layout/reftests/image/reftest.list
+++ b/layout/reftests/image/reftest.list
@@ -7,18 +7,20 @@ skip-if(B2G&&browserIsRemote) == image-z
 skip-if(B2G&&browserIsRemote) == image-zoom-2.html image-zoom-1-ref.html
 == invalid-url-image-1.html invalid-url-image-1-ref.html
 random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == sync-image-switch-1a.html sync-image-switch-1-ref.html # bug 855050 for WinXP
 random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == sync-image-switch-1b.html sync-image-switch-1-ref.html # bug 855050 for WinXP
 random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == sync-image-switch-1c.html sync-image-switch-1-ref.html # bug 855050 for WinXP
 random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == sync-image-switch-1d.html sync-image-switch-1-ref.html # bug 855050 for WinXP
 
 # Tests for "object-fit" & "object-position"
+test-pref(layout.css.object-fit-and-position.enabled,true) == image-object-fit-dyn-1.html image-object-fit-dyn-1-ref.html
 test-pref(layout.css.object-fit-and-position.enabled,true) == image-object-fit-with-background-1.html image-object-fit-with-background-1-ref.html
 test-pref(layout.css.object-fit-and-position.enabled,true) == image-object-fit-with-background-2.html image-object-fit-with-background-2-ref.html
+test-pref(layout.css.object-fit-and-position.enabled,true) == image-object-position-dyn-1.html image-object-position-dyn-1-ref.html
 test-pref(layout.css.object-fit-and-position.enabled,true) == image-object-position-with-background-1.html image-object-position-with-background-1-ref.html
 test-pref(layout.css.object-fit-and-position.enabled,true) == image-object-position-with-background-2.html image-object-position-with-background-2-ref.html
 
 # Tests for image-orientation used with 'from-image' (note that all
 # image-orientation tests are fuzzy because the JPEG images do not perfectly
 # reproduce blocks of solid color, even at maximum quality):
 fuzzy(2,5) == image-orientation-from-image.html?none     image-orientation-ref.html?0
 fuzzy(1,1) == image-orientation-from-image.html?0        image-orientation-ref.html?0
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1484,21 +1484,28 @@ IsAutonessEqual(const nsStyleSides& aSid
   }
   return true;
 }
 
 nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) const
 {
   nsChangeHint hint = nsChangeHint(0);
 
-  // Changes to "z-index", "object-fit", & "object-position" require a repaint.
-  if (mZIndex != aOther.mZIndex ||
-      mObjectFit != aOther.mObjectFit ||
+  // Changes to "z-index" require a repaint.
+  if (mZIndex != aOther.mZIndex) {
+    NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
+  }
+
+  // Changes to "object-fit" & "object-position" require a repaint.  They
+  // may also require a reflow, if we have a nsSubDocumentFrame, so that we
+  // can adjust the size & position of the subdocument.
+  if (mObjectFit != aOther.mObjectFit ||
       mObjectPosition != aOther.mObjectPosition) {
-    NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
+    NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_RepaintFrame,
+                                       nsChangeHint_NeedReflow));
   }
 
   if (mOrder != aOther.mOrder) {
     // "order" impacts both layout order and stacking order, so we need both a
     // reflow and a repaint when it changes.  (Technically, we only need a
     // reflow if we're in a multi-line flexbox (which we can't be sure about,
     // since that's determined by styling on our parent) -- there, "order" can
     // affect which flex line we end up on, & hence can affect our sizing by