Bug 1205027 - Only size <img> to broken-image size if it's actually broken. r=dholbert
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 03 Jun 2016 07:05:46 +0900
changeset 375007 4353662915021fe5da16a9df0bf4ab4efee426c5
parent 375006 192969a0735a5973a3f5234b6ccd3c2bc4a5a48f
child 375008 901aee13bd76c45d6d0c31c7b65e99988ade774b
push id20149
push userdhunt@mozilla.com
push dateFri, 03 Jun 2016 10:07:55 +0000
reviewersdholbert
bugs1205027
milestone49.0a1
Bug 1205027 - Only size <img> to broken-image size if it's actually broken. r=dholbert
caps/tests/mochitest/test_bug995943.xul
caps/tests/mochitest/test_principal_jarprefix_origin_appid_appstatus.html
layout/generic/nsImageFrame.cpp
layout/generic/test/file_SlowImage.sjs
layout/generic/test/mochitest.ini
layout/generic/test/test_intrinsic_size_on_loading.html
testing/web-platform/meta/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html.ini
--- a/caps/tests/mochitest/test_bug995943.xul
+++ b/caps/tests/mochitest/test_bug995943.xul
@@ -22,17 +22,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   const Ci = Components.interfaces;
   Cu.import("resource://gre/modules/Services.jsm");
   function debug(msg) { info(msg); }
 
   /** Test for CAPS file:// URI prefs. **/
   SimpleTest.waitForExplicitFinish();
   SimpleTest.requestCompleteLog();
   if (navigator.userAgent.indexOf("Mac OS X 10.10") != -1)
-    SimpleTest.expectAssertions(5); // See bug 1067022
+    SimpleTest.expectAssertions(6, 9); // See bug 1067022
   else if (Services.appinfo.OS == "WINNT")
     SimpleTest.expectAssertions(0, 1); // See bug 1067022
 
   var rootdir = Services.appinfo.OS == "WINNT" ? "file:///C:" : "file:///";
 
   function checkLoadFileURI(domain, shouldLoad) {
     debug("Invoking checkLoadFileURI with domain: " + domain + ", shouldLoad: " + shouldLoad);
     return new Promise(function(resolve, reject) {
--- a/caps/tests/mochitest/test_principal_jarprefix_origin_appid_appstatus.html
+++ b/caps/tests/mochitest/test_principal_jarprefix_origin_appid_appstatus.html
@@ -17,16 +17,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script type="application/javascript;version=1.7">
 
 /** Test for Bug 758258 **/
 
 var Ci = Components.interfaces;
 SimpleTest.waitForExplicitFinish();
+if (navigator.userAgent.indexOf("Mac OS X 10.10") != -1) {
+  SimpleTest.expectAssertions(0, 4);
+}
 
 /*
  * gData is an array of objects. Each object represents a test case.
  * - app: gives the app manifest URL, will set mozapp to it on the iframe;
  * - origin: gives the origin of the iframe. This is the URL thas is going to
  *           to be passed as iframe.src but also the expected principal's
  *           origin.
  * - isapp: tells if the iframe is really a mozapp. If the manifest url isn't
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -785,25 +785,40 @@ nsImageFrame::EnsureIntrinsicSizeAndRati
       mIntrinsicSize.height.GetCoordValue() == 0) {
 
     if (mImage) {
       UpdateIntrinsicSize(mImage);
       UpdateIntrinsicRatio(mImage);
     } else {
       // image request is null or image size not known, probably an
       // invalid image specified
-      // - make the image big enough for the icon (it may not be
-      // used if inline alt expansion is used instead)
       if (!(GetStateBits() & NS_FRAME_GENERATED_CONTENT)) {
-        nscoord edgeLengthToUse =
-          nsPresContext::CSSPixelsToAppUnits(
-            ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
-        mIntrinsicSize.width.SetCoordValue(edgeLengthToUse);
-        mIntrinsicSize.height.SetCoordValue(edgeLengthToUse);
-        mIntrinsicRatio.SizeTo(1, 1);
+        bool imageBroken = false;
+        // check for broken images. valid null images (eg. img src="") are
+        // not considered broken because they have no image requests
+        nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
+        if (imageLoader) {
+          nsCOMPtr<imgIRequest> currentRequest;
+          imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
+                                  getter_AddRefs(currentRequest));
+          uint32_t imageStatus;
+          imageBroken =
+            currentRequest &&
+            NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) &&
+            (imageStatus & imgIRequest::STATUS_ERROR);
+        }
+        // invalid image specified. make the image big enough for the "broken" icon
+        if (imageBroken) {
+          nscoord edgeLengthToUse =
+            nsPresContext::CSSPixelsToAppUnits(
+              ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
+          mIntrinsicSize.width.SetCoordValue(edgeLengthToUse);
+          mIntrinsicSize.height.SetCoordValue(edgeLengthToUse);
+          mIntrinsicRatio.SizeTo(1, 1);
+        }
       }
     }
   }
 }
 
 /* virtual */
 LogicalSize
 nsImageFrame::ComputeSize(nsRenderingContext *aRenderingContext,
new file mode 100644
--- /dev/null
+++ b/layout/generic/test/file_SlowImage.sjs
@@ -0,0 +1,45 @@
+"use strict";
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const IMG_BYTES = atob(
+  "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA" +
+  "DUlEQVQImWNgY2P7DwABOgESJhRQtgAAAABJRU5ErkJggg==");
+
+function handleRequest(request, response) {
+  response.processAsync();
+  getObjectState("context", function(obj) {
+    let ctx;
+    if (obj == null) {
+      ctx = {
+        QueryInterface: function(iid) {
+          if (iid.equals(Components.interfaces.nsISupports))
+            return this;
+          throw Components.results.NS_ERROR_NO_INTERFACE;
+        }
+      };
+      ctx.wrappedJSObject = ctx;
+
+      ctx.promise = new Promise(resolve => {
+        ctx.resolve = resolve;
+      });
+
+      setObjectState("context", ctx);
+    } else {
+      ctx = obj.wrappedJSObject;
+    }
+    Promise.resolve(ctx).then(next);
+  });
+
+  function next(ctx) {
+    if (request.queryString.indexOf("continue") >= 0) {
+      ctx.resolve();
+    }
+
+    ctx.promise.then(() => {
+      response.setHeader("Content-Type", "image/png");
+      response.write(IMG_BYTES);
+      response.finish();
+    });
+  }
+}
--- a/layout/generic/test/mochitest.ini
+++ b/layout/generic/test/mochitest.ini
@@ -9,16 +9,17 @@ support-files =
   plugin_clipping_helper_transformed.xhtml
   plugin_clipping_helper_table.xhtml
   plugin_clipping_lib.js
   plugin_focus_helper.html
   file_BrokenImageReference.png
   file_Dolske.png
   file_IconTestServer.sjs
   file_LoadingImageReference.png
+  file_SlowImage.sjs
   bug1174521.html
 
 [test_bug240933.html]
 [test_bug263683.html]
 [test_bug288789.html]
 [test_bug290397.html]
 [test_bug323656.html]
 [test_bug344830.html]
@@ -101,16 +102,17 @@ skip-if = buildapp == 'b2g' # b2g(Target
 [test_bug1062406.html]
 [test_bug1174521.html]
 [test_contained_plugin_transplant.html]
 skip-if = os=='win'
 [test_image_selection.html]
 [test_image_selection_2.html]
 [test_invalidate_during_plugin_paint.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # b2g(plugins not supported) b2g-debug(plugins not supported) b2g-desktop(plugins not supported)
+[test_intrinsic_size_on_loading.html]
 [test_movement_by_characters.html]
 [test_movement_by_words.html]
 # Disable the caret movement by word test on Linux because the shortcut keys
 # are defined in system level.  So, it depends on the environment.
 # Disable on Windows for too many intermittent failures (bug 916143).
 skip-if = (toolkit == "gtk2") || (toolkit == "gtk3") || (os == "win")
 [test_overflow_event.html]
 [test_page_scroll_with_fixed_pos.html]
new file mode 100644
--- /dev/null
+++ b/layout/generic/test/test_intrinsic_size_on_loading.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1205027
+-->
+<head>
+  <title>Test for images intrinsic size while load is pending</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <style>
+    body { margin: 0; }
+    img { display: block; }
+  </style>
+  <script>
+    SimpleTest.waitForExplicitFinish();
+    var initialOffsetTop;
+    var finalOffsetTop;
+
+    function report() {
+      finalOffsetTop = marker.offsetTop;
+      is(initialOffsetTop, 0, "initial offsetTop: " + initialOffsetTop);
+      is(finalOffsetTop, 8, "final offsetTop: " + finalOffsetTop);
+      ok(initialOffsetTop < finalOffsetTop, "offsetTop should get larger.");
+      SimpleTest.finish();
+    }
+
+    function fail() {
+      ok(false, "image loading should not fail.");
+    }
+  </script>
+</head>
+<body onload="report();">
+  <!-- Bunch of tiny images: -->
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+  <img src="file_SlowImage.sjs" onerror="fail();">
+
+  <div id="marker">Marker div</div>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1205027">Mozilla Bug 1205027</a>
+  <script>
+    initialOffsetTop = marker.offsetTop;
+    // prompt the sjs "server" to proceed to serve data to our <img> elements
+    var img = new Image();
+    img.onerror = fail;
+    img.src = "file_SlowImage.sjs?continue";
+  </script>
+</body>
+</html>
--- a/testing/web-platform/meta/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html.ini
+++ b/testing/web-platform/meta/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html.ini
@@ -167,17 +167,29 @@
       if debug and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): TIMEOUT
       if debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
       if debug and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): TIMEOUT
       if debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
       if debug and (os == "win") and (version == "10.0.10240") and (processor == "x86_64") and (bits == 64): TIMEOUT
       if not debug and (os == "win") and (version == "10.0.10240") and (processor == "x86_64") and (bits == 64): TIMEOUT
 
   [loading image <video poster>]
-    expected: FAIL
+    expected:
+      if not debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
+      if not debug and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): TIMEOUT
+      if not debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if not debug and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): TIMEOUT
+      if not debug and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): TIMEOUT
+      if debug and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): TIMEOUT
+      if debug and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): TIMEOUT
+      if debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
+      if debug and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): TIMEOUT
+      if debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
+      if debug and (os == "win") and (version == "10.0.10240") and (processor == "x86_64") and (bits == 64): TIMEOUT
+      if not debug and (os == "win") and (version == "10.0.10240") and (processor == "x86_64") and (bits == 64): TIMEOUT
 
   [loading video <video>]
     expected:
       if not debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
       if not debug and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): TIMEOUT
       if not debug and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
       if not debug and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): TIMEOUT
       if not debug and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): TIMEOUT