Bug 741216 - Allow dropping files into the file picker control; r=bzbarsky a=akeybl
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 02 Apr 2012 16:25:09 -0400
changeset 95887 ff0d77a6196385a2d95b396b1cb1d0b5c0e5b630
parent 95886 192b18bb4d24dfaa0d5b249cec866fa8ec10aaeb
child 95888 769754742698b2bd0c56df41a4dcb83a7c591a5e
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, akeybl
bugs741216
milestone14.0a2
Bug 741216 - Allow dropping files into the file picker control; r=bzbarsky a=akeybl
editor/libeditor/base/nsEditorEventListener.cpp
editor/libeditor/base/nsEditorEventListener.h
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -66,16 +66,18 @@
 #include "nsIDOMRange.h"
 #include "nsEditorUtils.h"
 #include "nsISelectionPrivate.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIFocusManager.h"
 #include "nsIDOMWindow.h"
 #include "nsContentUtils.h"
 #include "nsIBidiKeyboard.h"
+#include "mozilla/dom/Element.h"
+#include "nsIFormControl.h"
 
 using namespace mozilla;
 
 nsEditorEventListener::nsEditorEventListener() :
   mEditor(nsnull), mCommitText(false),
   mInTransaction(false)
 #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
   , mHaveBidiKeyboards(false)
@@ -675,19 +677,21 @@ nsEditorEventListener::DragOver(nsIDOMDr
         mCaret->EraseCaret();
       
       //mCaret->SetCaretVisible(true);   // make sure it's visible
       mCaret->DrawAtPosition(parent, offset);
     }
   }
   else
   {
-    // This is needed when dropping on an input, to prevent the editor for
-    // the editable parent from receiving the event.
-    aDragEvent->StopPropagation();
+    if (!IsFileControlTextBox()) {
+      // This is needed when dropping on an input, to prevent the editor for
+      // the editable parent from receiving the event.
+      aDragEvent->StopPropagation();
+    }
 
     if (mCaret)
     {
       mCaret->EraseCaret();
     }
   }
 
   return NS_OK;
@@ -733,18 +737,18 @@ nsEditorEventListener::Drop(nsIDOMDragEv
 
   nsCOMPtr<nsIDOMNode> parent;
   aMouseEvent->GetRangeParent(getter_AddRefs(parent));
   nsCOMPtr<nsIContent> dropParent = do_QueryInterface(parent);
   NS_ENSURE_TRUE(dropParent, NS_ERROR_FAILURE);
 
   if (!dropParent->IsEditable() || !CanDrop(aMouseEvent)) {
     // was it because we're read-only?
-    if (mEditor->IsReadonly() || mEditor->IsDisabled())
-    {
+    if ((mEditor->IsReadonly() || mEditor->IsDisabled()) &&
+        !IsFileControlTextBox()) {
       // it was decided to "eat" the event as this is the "least surprise"
       // since someone else handling it might be unintentional and the 
       // user could probably re-drag to be not over the disabled/readonly 
       // editfields if that is what is desired.
       return aMouseEvent->StopPropagation();
     }
     return NS_OK;
   }
@@ -990,8 +994,23 @@ nsEditorEventListener::SpellCheckIfNeede
   mEditor->GetFlags(&currentFlags);
   if(currentFlags & nsIPlaintextEditor::eEditorSkipSpellCheck)
   {
     currentFlags ^= nsIPlaintextEditor::eEditorSkipSpellCheck;
     mEditor->SetFlags(currentFlags);
   }
 }
 
+bool
+nsEditorEventListener::IsFileControlTextBox()
+{
+  dom::Element* root = mEditor->GetRoot();
+  if (root && root->IsInNativeAnonymousSubtree()) {
+    nsIContent* parent = root->FindFirstNonNativeAnonymous();
+    if (parent && parent->IsHTML(nsGkAtoms::input)) {
+      nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(parent);
+      MOZ_ASSERT(formControl);
+      return formControl->GetType() == NS_FORM_INPUT_FILE;
+    }
+  }
+  return false;
+}
+
--- a/editor/libeditor/base/nsEditorEventListener.h
+++ b/editor/libeditor/base/nsEditorEventListener.h
@@ -95,16 +95,17 @@ protected:
   bool CanDrop(nsIDOMDragEvent* aEvent);
   nsresult DragEnter(nsIDOMDragEvent* aDragEvent);
   nsresult DragOver(nsIDOMDragEvent* aDragEvent);
   nsresult DragExit(nsIDOMDragEvent* aDragEvent);
   nsresult Drop(nsIDOMDragEvent* aDragEvent);
   nsresult DragGesture(nsIDOMDragEvent* aDragEvent);
   void CleanupDragDropCaret();
   already_AddRefed<nsIPresShell> GetPresShell();
+  bool IsFileControlTextBox();
 
 protected:
   nsEditor* mEditor; // weak
   nsRefPtr<nsCaret> mCaret;
   bool mCommitText;
   bool mInTransaction;
 #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
   bool mHaveBidiKeyboards;