Bug 500885 - DOMActivate is fired twice for input[type=file] if user clicks on browse button, r=Olli.Pettay sr=jonas
authorGeoff Lankow <geoff@darktrojan.net>
Tue, 24 Nov 2009 18:12:00 -0800
changeset 35693 0db0a203473325dc764b6d489cc38d210ca6fdc4
parent 35692 1484f0779ccd57df9f00aba55a9331959ec6a7fc
child 35694 b259db01f88c05a4e91331b6a0f63367ec419fd0
push id10682
push userphilringnalda@gmail.com
push dateMon, 14 Dec 2009 02:11:07 +0000
treeherdermozilla-central@bc0849430750 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersOlli, jonas
bugs500885
milestone1.9.3a1pre
Bug 500885 - DOMActivate is fired twice for input[type=file] if user clicks on browse button, r=Olli.Pettay sr=jonas
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/test/Makefile.in
content/html/content/test/test_bug500885.html
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -1743,16 +1743,32 @@ SelectTextFieldOnFocus()
 }
 
 nsresult
 nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   if (!aVisitor.mPresContext) {
     return NS_OK;
   }
+
+  // ignore the activate event fired by the "Browse..." button
+  // (file input controls fire their own) (bug 500885)
+  if (mType == NS_FORM_INPUT_FILE) {
+    nsCOMPtr<nsIContent> maybeButton =
+      do_QueryInterface(aVisitor.mEvent->originalTarget);
+    if (maybeButton &&
+      maybeButton->IsRootOfNativeAnonymousSubtree() &&
+      maybeButton->AttrValueIs(kNameSpaceID_None,
+                               nsGkAtoms::type,
+                               nsGkAtoms::button,
+                               eCaseMatters)) {
+        return NS_OK;
+    }
+  }
+
   nsresult rv = NS_OK;
   PRBool outerActivateEvent = !!(aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT);
   PRBool originalCheckedValue =
     !!(aVisitor.mItemFlags & NS_ORIGINAL_CHECKED_VALUE);
   PRBool noContentDispatch = !!(aVisitor.mItemFlags & NS_NO_CONTENT_DISPATCH);
   PRInt8 oldType = NS_CONTROL_TYPE(aVisitor.mItemFlags);
   // Ideally we would make the default action for click and space just dispatch
   // DOMActivate, and the default action for DOMActivate flip the checkbox/
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -131,16 +131,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug460568.html \
 		test_bug347174.html \
 		test_bug347174_write.html \
 		test_bug347174_xsl.html \
 		test_bug347174_xslp.html \
 		347174transformable.xml \
 		347174transform.xsl \
 		test_bug481335.xhtml \
+		test_bug500885.html \
 		test_bug514856.html \
 		bug514856_iframe.html \
 		test_bug519987.html \
 		test_bug523771.html \
 		form_submit_server.sjs \
 		test_bug529819.html \
 		test_bug529859.html \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug500885.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=500885
+-->
+<head>
+  <title>Test for Bug 500885</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500885">Mozilla Bug 500885</a>
+<div>
+  <input id="file" type="file" />
+</div>
+<script type="text/javascript">
+
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cm = Components.manager;
+
+Cc["@mozilla.org/moz/jssubscript-loader;1"]
+  .getService(Ci.mozIJSSubScriptLoader)
+  .loadSubScript("chrome://mochikit/content/browser/toolkit/content/tests/browser/common/mockObjects.js", this);
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function MockFilePicker() { };
+MockFilePicker.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
+  init: function(aParent, aTitle, aMode) { },
+  appendFilters: function(aFilterMask) { },
+  appendFilter: function(aTitle, aFilter) { },
+  defaultString: "",
+  defaultExtension: "",
+  filterIndex: 0,
+  displayDirectory: null,
+  file: null,
+  get fileURL() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  get files() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  show: function MFP_show() {
+    return Ci.nsIFilePicker.returnOK;
+  }
+};
+
+var mockFilePickerRegisterer =
+  new MockObjectRegisterer("@mozilla.org/filepicker;1",MockFilePicker);
+
+
+function test() {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var wu = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                  .getInterface(Ci.nsIDOMWindowUtils);
+                  
+  mockFilePickerRegisterer.register();
+  try {
+    var domActivateEvents;
+    var fileInput = document.getElementById("file");
+    var rect = fileInput.getBoundingClientRect();
+
+    fileInput.addEventListener ("DOMActivate", function () {
+      domActivateEvents++;
+    }, false);
+
+    domActivateEvents = 0;
+    wu.sendMouseEvent("mousedown", rect.left + 5, rect.top + 5, 0, 1, 0);
+    wu.sendMouseEvent("mouseup", rect.left + 5, rect.top + 5, 0, 1, 0);
+    is(domActivateEvents, 1, "click on text field should only fire 1 DOMActivate event");
+
+    domActivateEvents = 0;
+    wu.sendMouseEvent("mousedown", rect.right - 5, rect.top + 5, 0, 1, 0);
+    wu.sendMouseEvent("mouseup", rect.right - 5, rect.top + 5, 0, 1, 0);
+    is(domActivateEvents, 1, "click on button should only fire 1 DOMActivate event");
+
+  } finally {
+    mockFilePickerRegisterer.unregister();
+  }
+  SimpleTest.finish();
+}
+
+window.onload = function() {
+  SimpleTest.waitForExplicitFinish();
+  setTimeout(test, 0);
+};
+
+</script>
+</body>
+
+</html>