Bug 813445 part.6 Remove NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Sun, 16 Dec 2012 10:26:04 +0900
changeset 125278 1047c6f74ab9a5c8b060062567ec9ed4423316c1
parent 125277 d5dcc27a64d19fa48008bba6bff79c66c6d5c6a9
child 125279 ee42ea2e903992efa0bc118a08d236bac4551d9a
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs813445
milestone20.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 813445 part.6 Remove NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS r=smaug
content/base/public/Element.h
content/base/src/Element.cpp
content/html/content/src/nsHTMLButtonElement.cpp
content/html/content/src/nsHTMLLabelElement.cpp
widget/nsGUIEvent.h
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -40,16 +40,17 @@
 #include "nsContentUtils.h"
 #include "nsINodeList.h"
 #include "mozilla/ErrorResult.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMAttr.h"
 #include "nsISMILAttr.h"
 #include "nsClientRect.h"
 #include "nsIDOMDOMTokenList.h"
+#include "nsEvent.h"
 
 class nsIDOMEventListener;
 class nsIFrame;
 class nsIDOMNamedNodeMap;
 class nsIDOMCSSStyleDeclaration;
 class nsIURI;
 class nsINodeInfo;
 class nsIControllers;
@@ -717,22 +718,25 @@ public:
   static bool ShouldBlur(nsIContent *aContent);
 
   /**
    * Method to create and dispatch a left-click event loosely based on
    * aSourceEvent. If aFullDispatch is true, the event will be dispatched
    * through the full dispatching of the presshell of the aPresContext; if it's
    * false the event will be dispatched only as a DOM event.
    * If aPresContext is nullptr, this does nothing.
+   *
+   * @param aFlags      Extra flags for the dispatching event.  The true flags
+   *                    will be respected.
    */
   static nsresult DispatchClickEvent(nsPresContext* aPresContext,
                                      nsInputEvent* aSourceEvent,
                                      nsIContent* aTarget,
                                      bool aFullDispatch,
-                                     uint32_t aFlags,
+                                     const mozilla::widget::EventFlags* aFlags,
                                      nsEventStatus* aStatus);
 
   /**
    * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event
    * will be dispatched through the full dispatching of the presshell of the
    * aPresContext; if it's false the event will be dispatched only as a DOM
    * event.
    * If aPresContext is nullptr, this does nothing.
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -1583,17 +1583,17 @@ Element::DispatchEvent(nsPresContext* aP
 }
 
 /* static */
 nsresult
 Element::DispatchClickEvent(nsPresContext* aPresContext,
                             nsInputEvent* aSourceEvent,
                             nsIContent* aTarget,
                             bool aFullDispatch,
-                            uint32_t aFlags,
+                            const widget::EventFlags* aExtraEventFlags,
                             nsEventStatus* aStatus)
 {
   NS_PRECONDITION(aTarget, "Must have target");
   NS_PRECONDITION(aSourceEvent, "Must have source event");
   NS_PRECONDITION(aStatus, "Null out param?");
 
   nsMouseEvent event(aSourceEvent->mFlags.mIsTrusted, NS_MOUSE_CLICK,
                      aSourceEvent->widget, nsMouseEvent::eReal);
@@ -1607,17 +1607,20 @@ Element::DispatchClickEvent(nsPresContex
     inputSource = static_cast<nsMouseEvent*>(aSourceEvent)->inputSource;
   } else if (aSourceEvent->eventStructType == NS_KEY_EVENT) {
     inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
   }
   event.pressure = pressure;
   event.clickCount = clickCount;
   event.inputSource = inputSource;
   event.modifiers = aSourceEvent->modifiers;
-  event.flags |= aFlags; // Be careful not to overwrite existing flags!
+  if (aExtraEventFlags) {
+    // Be careful not to overwrite existing flags!
+    event.mFlags |= *aExtraEventFlags;
+  }
 
   return DispatchEvent(aPresContext, &event, aTarget, aFullDispatch, aStatus);
 }
 
 nsIFrame*
 Element::GetPrimaryFrame(mozFlushType aType)
 {
   nsIDocument* doc = GetCurrentDoc();
@@ -2311,17 +2314,17 @@ Element::CheckHandleEventForLinksPrecond
                                               nsIURI** aURI) const
 {
   if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
       (!aVisitor.mEvent->mFlags.mIsTrusted &&
        (aVisitor.mEvent->message != NS_MOUSE_CLICK) &&
        (aVisitor.mEvent->message != NS_KEY_PRESS) &&
        (aVisitor.mEvent->message != NS_UI_ACTIVATE)) ||
       !aVisitor.mPresContext ||
-      (aVisitor.mEvent->flags & NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS)) {
+      aVisitor.mEvent->mFlags.mMultipleActionsPrevented) {
     return false;
   }
 
   // Make sure we actually are a link
   return IsLink(aURI);
 }
 
 nsresult
@@ -2357,27 +2360,27 @@ Element::PreHandleEventForLinks(nsEventC
   case NS_FOCUS_CONTENT:
     if (aVisitor.mEvent->eventStructType != NS_FOCUS_EVENT ||
         !static_cast<nsFocusEvent*>(aVisitor.mEvent)->isRefocus) {
       nsAutoString target;
       GetLinkTarget(target);
       nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
                                   false, true, true);
       // Make sure any ancestor links don't also TriggerLink
-      aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
+      aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
     }
     break;
 
   case NS_MOUSE_EXIT_SYNTH:
     aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
     // FALL THROUGH
   case NS_BLUR_CONTENT:
     rv = LeaveLink(aVisitor.mPresContext);
     if (NS_SUCCEEDED(rv)) {
-      aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
+      aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
     }
     break;
 
   default:
     // switch not in sync with the optimization switch earlier in this function
     NS_NOTREACHED("switch statements not in sync");
     return NS_ERROR_UNEXPECTED;
   }
@@ -2415,17 +2418,17 @@ Element::PostHandleEventForLinks(nsEvent
           static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
           nsMouseEvent::eLeftButton) {
         // don't make the link grab the focus if there is no link handler
         nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler();
         nsIDocument *document = GetCurrentDoc();
         if (handler && document) {
           nsIFocusManager* fm = nsFocusManager::GetFocusManager();
           if (fm) {
-            aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
+            aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
             nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
             fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOUSE |
                                nsIFocusManager::FLAG_NOSCROLL);
           }
 
           nsEventStateManager::SetActiveManager(
             aVisitor.mPresContext->EventStateManager(), this);
         }
@@ -2472,17 +2475,17 @@ Element::PostHandleEventForLinks(nsEvent
 
   case NS_KEY_PRESS:
     {
       if (aVisitor.mEvent->eventStructType == NS_KEY_EVENT) {
         nsKeyEvent* keyEvent = static_cast<nsKeyEvent*>(aVisitor.mEvent);
         if (keyEvent->keyCode == NS_VK_RETURN) {
           nsEventStatus status = nsEventStatus_eIgnore;
           rv = DispatchClickEvent(aVisitor.mPresContext, keyEvent, this,
-                                  false, 0, &status);
+                                  false, nullptr, &status);
           if (NS_SUCCEEDED(rv)) {
             aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
           }
         }
       }
     }
     break;
 
--- a/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/content/html/content/src/nsHTMLButtonElement.cpp
@@ -359,17 +359,17 @@ nsHTMLButtonElement::PostHandleEvent(nsE
                   aVisitor.mPresContext->EventStateManager();
                 nsEventStateManager::SetActiveManager(
                   static_cast<nsEventStateManager*>(esm), this);
               }
               nsIFocusManager* fm = nsFocusManager::GetFocusManager();
               if (fm)
                 fm->SetFocus(this, nsIFocusManager::FLAG_BYMOUSE |
                                    nsIFocusManager::FLAG_NOSCROLL);
-              aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
+              aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
             } else if (static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
                          nsMouseEvent::eMiddleButton ||
                        static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
                          nsMouseEvent::eRightButton) {
               // cancel all of these events for buttons
               //XXXsmaug What to do with these events? Why these should be cancelled?
               if (aVisitor.mDOMEvent) {
                 aVisitor.mDOMEvent->StopPropagation();
--- a/content/html/content/src/nsHTMLLabelElement.cpp
+++ b/content/html/content/src/nsHTMLLabelElement.cpp
@@ -142,17 +142,17 @@ nsresult
 nsHTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   if (mHandlingEvent ||
       (!NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent) &&
        aVisitor.mEvent->message != NS_MOUSE_BUTTON_DOWN) ||
       aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
       !aVisitor.mPresContext ||
       // Don't handle the event if it's already been handled by another label
-      (aVisitor.mEvent->flags & NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS)) {
+      aVisitor.mEvent->mFlags.mMultipleActionsPrevented) {
     return NS_OK;
   }
 
   // Strong ref because event dispatch is going to happen.
   nsRefPtr<Element> content = GetLabeledElement();
 
   if (content && !EventTargetIn(aVisitor.mEvent, content, this)) {
     mHandlingEvent = true;
@@ -215,23 +215,25 @@ nsHTMLLabelElement::PostHandleEvent(nsEv
           //    (For compatibility with IE, we do only left click.  If
           //    we wanted to interpret the HTML spec very narrowly, we
           //    would do nothing.  If we wanted to do something
           //    sensible, we might send more events through like
           //    this.)  See bug 7554, bug 49897, and bug 96813.
           nsEventStatus status = aVisitor.mEventStatus;
           // Ok to use aVisitor.mEvent as parameter because DispatchClickEvent
           // will actually create a new event.
+          widget::EventFlags eventFlags;
+          eventFlags.Clear();
+          eventFlags.mMultipleActionsPrevented = true;
           DispatchClickEvent(aVisitor.mPresContext,
                              static_cast<nsInputEvent*>(aVisitor.mEvent),
-                             content, false,
-                             NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS, &status);
+                             content, false, &eventFlags, &status);
           // Do we care about the status this returned?  I don't think we do...
           // Don't run another <label> off of this click
-          aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
+          aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
         }
         break;
     }
     mHandlingEvent = false;
   }
   return NS_OK;
 }
 
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -125,18 +125,16 @@ enum nsEventStructType {
 
 // Use this flag if the event should be dispatched only to chrome.
 #define NS_EVENT_FLAG_ONLY_CHROME_DISPATCH 0x2000
 
 #define NS_PRIV_EVENT_UNTRUSTED_PERMITTED 0x8000
 
 #define NS_EVENT_FLAG_EXCEPTION_THROWN    0x10000
 
-#define NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS 0x20000
-
 #define NS_EVENT_RETARGET_TO_NON_NATIVE_ANONYMOUS 0x40000
 
 #define NS_EVENT_FLAG_DONT_FORWARD_CROSS_PROCESS 0x100000
 
 #define NS_EVENT_CAPTURE_MASK             (~(NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))
 #define NS_EVENT_BUBBLE_MASK              (~(NS_EVENT_FLAG_CAPTURE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))
 
 #define NS_EVENT_TYPE_NULL                   0
@@ -529,16 +527,22 @@ public:
   // If mDefaultPrevented is true, the event has been consumed.
   // E.g., nsDOMEvent::PreventDefault() has been called or
   // the default action has been performed.
   bool    mDefaultPrevented : 1;
   // If mDefaultPreventedByContent is true, the event has been
   // consumed by content.
   // Note that mDefaultPrevented must be true when this is true.
   bool    mDefaultPreventedByContent : 1;
+  // mMultipleActionsPrevented may be used when default handling don't want to
+  // be prevented, but only one of the event targets should handle the event.
+  // For example, when a <label> element is in another <label> element and
+  // the first <label> element is clicked, that one may set this true.
+  // Then, the second <label> element won't handle the event.
+  bool    mMultipleActionsPrevented : 1;
 
   // If the event is being handled in target phase, returns true.
   bool InTargetPhase() const
   {
     return (mInBubblingPhase && mInCapturePhase);
   }
 
   EventFlags()