Bug 696451 - Reload <img> when crossOrigin attribute is set. r=bz
authorMina Almasry <almasry.mina@gmail.com>
Thu, 10 Oct 2013 10:54:02 -0400
changeset 164184 41e7e41afe1f1470198d75f6b81c32b3cef4fe21
parent 164183 5436d332c9691b6c9aa835e88b4aa341bfe604d0
child 164185 774d6d582f4060aebda8611d99f54ced97f02e2c
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs696451
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 696451 - Reload <img> when crossOrigin attribute is set. r=bz
content/html/content/src/HTMLImageElement.cpp
content/html/content/test/image-allow-credentials.png
content/html/content/test/image-allow-credentials.png^headers^
content/html/content/test/mochitest.ini
content/html/content/test/test_change_crossorigin.html
--- a/content/html/content/src/HTMLImageElement.cpp
+++ b/content/html/content/src/HTMLImageElement.cpp
@@ -313,16 +313,59 @@ HTMLImageElement::AfterSetAttr(int32_t a
       aValue && !aValue->IsEmptyString()) {
     // add the image to the hashtable as needed
     NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eAtom,
       "Expected atom value for name/id");
     mForm->AddImageElementToTable(this,
       nsDependentAtomString(aValue->GetAtomValue()));
   }
 
+  if (aNameSpaceID == kNameSpaceID_None &&
+      aName == nsGkAtoms::src &&
+      !aValue) {
+    CancelImageRequests(aNotify);
+  }
+
+  // If we plan to call LoadImage, we want to do it first so that the image load
+  // kicks off. But if aNotify is false, we are coming from the parser or some
+  // such place; we'll get bound after all the attributes have been set, so
+  // we'll do the image load from BindToTree. Skip the LoadImage call in that case.
+  if (aNotify &&
+      aNameSpaceID == kNameSpaceID_None &&
+      aName == nsGkAtoms::crossorigin) {
+    // We want aForce == true in this LoadImage call, because we want to force
+    // a new load of the image with the new cross origin policy.
+    nsAutoString uri;
+    GetAttr(kNameSpaceID_None, nsGkAtoms::src, uri);
+    LoadImage(uri, true, aNotify);
+  }
+
+  if (aNotify &&
+      aNameSpaceID == kNameSpaceID_None &&
+      aName == nsGkAtoms::src &&
+      aValue) {
+
+    // Prevent setting image.src by exiting early
+    if (nsContentUtils::IsImageSrcSetDisabled()) {
+      return NS_OK;
+    }
+
+    // A hack to get animations to reset. See bug 594771.
+    mNewRequestsWillNeedAnimationReset = true;
+
+    // Force image loading here, so that we'll try to load the image from
+    // network if it's set to be not cacheable...  If we change things so that
+    // the state gets in Element's attr-setting happen around this
+    // LoadImage call, we could start passing false instead of aNotify
+    // here.
+    LoadImage(aValue->GetStringValue(), true, aNotify);
+
+    mNewRequestsWillNeedAnimationReset = false;
+  }
+
   return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
                                             aValue, aNotify);
 }
 
 
 nsresult
 HTMLImageElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
@@ -382,54 +425,24 @@ HTMLImageElement::IsHTMLFocusable(bool a
   return false;
 }
 
 nsresult
 HTMLImageElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                           nsIAtom* aPrefix, const nsAString& aValue,
                           bool aNotify)
 {
-  // If we plan to call LoadImage, we want to do it first so that the
-  // image load kicks off _before_ the reflow triggered by the SetAttr.  But if
-  // aNotify is false, we are coming from the parser or some such place; we'll
-  // get bound after all the attributes have been set, so we'll do the
-  // image load from BindToTree.  Skip the LoadImage call in that case.
-  if (aNotify &&
-      aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
-
-    // Prevent setting image.src by exiting early
-    if (nsContentUtils::IsImageSrcSetDisabled()) {
-      return NS_OK;
-    }
-
-    // A hack to get animations to reset. See bug 594771.
-    mNewRequestsWillNeedAnimationReset = true;
-
-    // Force image loading here, so that we'll try to load the image from
-    // network if it's set to be not cacheable...  If we change things so that
-    // the state gets in Element's attr-setting happen around this
-    // LoadImage call, we could start passing false instead of aNotify
-    // here.
-    LoadImage(aValue, true, aNotify);
-
-    mNewRequestsWillNeedAnimationReset = false;
-  }
-    
   return nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
                                        aNotify);
 }
 
 nsresult
 HTMLImageElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                             bool aNotify)
 {
-  if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::src) {
-    CancelImageRequests(aNotify);
-  }
-
   return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
 }
 
 nsresult
 HTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                              nsIContent* aBindingParent,
                              bool aCompileEventHandlers)
 {
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..df24ac6d3404325e473981930ade85065cf7fb9a
GIT binary patch
literal 844
zc$@)D1GD^zP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000j<000lL0ajJ30{{R5?ny*JR5*=wlU-<Abr{Bf|C4iak|t@k
znyz1_UD|b9CpwyStJbl)wOETfHyJ}l1+P@RQUvu%@X{{?1uq7I;FT95IyVX`Q#a>W
zH*l4W#u<{PNz9VwG#}^W<0L1?t5qG#bM^8*@B6!Y9%v)~sZWR7dH<ET*YfDQ-@UD+
zw7tRIec8-L-Mt*iY#7<fwOXnA4VT_5w*{yN-Ve=&dp<aHa{PEAtBZKDNbK(-ZdJzT
zQE|zVCdrO>&b>bO@tq&Xo#Dw37Y`VD<Kh#CN5=CNOJw5(mJ@jtVdL&l@%vOP8+RtJ
z&-?ctbLE%5`f(HR;<r~jN?H9E>*5zZgOd|P&R*cpRtL#MfnqdAF}{lF@u3x}h-M2d
zU7YIQ_0*!aayBIc)N=ZX)vMQouRK=b_uDDdE|ux^&sgX-sRT#)>9+`tv>+u9Av<NN
zH&!Lt?|m7#A_FWft?lnDrFrzFXYnVh40Oei?E%6Er;(c#UOh3uYp1VZ$RV^?8d?IO
zDEj~*0VGy(s>c)Hp(D?+Cny*kpJ8n71zf|E=pEaMtqb<=?8Ppd$Yvc+rx&+J-U2uz
z01;V>&4(3AT8;+~%~LWAvbi!#=YJ*{T_H3YWP0WZTfGgoZNHzEaIlfcn1GN0gvI&w
zN*BH@U5I9l(LEzH^a4Bj2BEHF*LCd5I_~5-jNVg74nf&4Qh?<EFpbN})LQ@3xyYIR
zPFdqVpMu9JgK1#b%Gh-smzibpQk|8wO3N~-=l=MzS&e?b86;Qt!jxiGerS~A%I*=R
z@yu+m{`kRAU~H&cxUnde8-y2rWyAE+vdmhoa`|B>T>oDZ72o0K<(7D_Y2>a+IG1f<
z1;P(F$7ZLt?Xv8?z$c&I5RxR>Mm_V9#b0j#*4<qY;N0P0I3(fi5l8`OIrdGA%|vgd
z<`k!+naSNcZ4rM9(A$>jU)YfP$i(Ean>QmzT`s3}TZ?`T+8Lm6&oZ?KZQix+Hva+S
WQ#UA?9#7r?0000<MNUMnLSTYXW|E5l
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/image-allow-credentials.png^headers^
@@ -0,0 +1,2 @@
+Access-Control-Allow-Origin: http://mochi.test:8888
+Access-Control-Allow-Credentials: true
--- a/content/html/content/test/mochitest.ini
+++ b/content/html/content/test/mochitest.ini
@@ -122,16 +122,18 @@ support-files =
   file_iframe_sandbox_top_navigation_fail.html
   file_iframe_sandbox_top_navigation_pass.html
   file_iframe_sandbox_window_navigation_fail.html
   file_iframe_sandbox_worker.js
   file_srcdoc-2.html
   file_srcdoc.html
   form_submit_server.sjs
   image.png
+  image-allow-credentials.png
+  image-allow-credentials.png^headers^
   nnc_lockup.gif
   reflect.js
   wakelock.ogg
   wakelock.ogv
 
 [test_a_text.html]
 [test_anchor_href_cache_invalidation.html]
 [test_applet_attributes_reflection.html]
@@ -338,16 +340,17 @@ support-files =
 [test_bug840877.html]
 [test_bug841466.html]
 [test_bug869040.html]
 [test_bug870787.html]
 [test_bug874758.html]
 [test_bug879319.html]
 [test_bug885024.html]
 [test_bug893537.html]
+[test_change_crossorigin.html]
 [test_checked.html]
 [test_dir_attributes_reflection.html]
 [test_dl_attributes_reflection.html]
 [test_element_prototype.html]
 [test_embed_attributes_reflection.html]
 [test_formData.html]
 [test_formSubmission.html]
 [test_formSubmission2.html]
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_change_crossorigin.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=696451
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 696451</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 696451 **/
+
+  SimpleTest.waitForExplicitFinish();
+
+  var img = new Image,
+      canvas = document.createElement("canvas"),
+      ctx = canvas.getContext("2d"),
+      src = "http://example.com/tests/content/html/content/test/image-allow-credentials.png",
+      imgDone = false,
+      imgNotAllowedToLoadDone = false;
+
+  img.src = src;
+  img.crossOrigin = "Anonymous";
+
+  img.addEventListener("load", function() {
+    canvas.width = img.width;
+    canvas.height = img.height;
+    ctx.drawImage( img, 0, 0 );
+    try {
+      canvas.toDataURL("image/png");
+      ok(true, "Image was refetched with setting crossOrigin.");
+    } catch (e) {
+      ok(false, "Image was not refetched after setting crossOrigin.");
+    }
+
+    imgDone = true;
+    if (imgDone && imgNotAllowedToLoadDone) {
+      SimpleTest.finish();
+    }
+  });
+
+  img.addEventListener("error", function (event) {
+    ok(false, "Should be able to load cross origin image with proper headers.");
+
+    imgDone = true;
+    if (imgDone && imgNotAllowedToLoadDone) {
+      SimpleTest.finish();
+    }
+  });
+
+  var imgNotAllowedToLoad = new Image;
+
+  imgNotAllowedToLoad.src = "http://example.com/tests/content/html/content/test/image.png";
+
+  imgNotAllowedToLoad.crossOrigin = "Anonymous";
+
+  imgNotAllowedToLoad.addEventListener("load", function() {
+      ok(false, "Image should not be allowed to load without " +
+                "allow-cross-origin-access headers.");
+
+      imgNotAllowedToLoadDone = true;
+      if (imgDone && imgNotAllowedToLoadDone) {
+        SimpleTest.finish();
+      }
+  });
+
+  imgNotAllowedToLoad.addEventListener("error", function() {
+      ok(true, "Image should not be allowed to load without " +
+               "allow-cross-origin-access headers.");
+      imgNotAllowedToLoadDone = true;
+      if (imgDone && imgNotAllowedToLoadDone) {
+        SimpleTest.finish();
+      }
+  });
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696451">Mozilla Bug 696451</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>