layout/xul/nsScrollBoxFrame.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsCOMPtr.h"
     7 #include "nsPresContext.h"
     8 #include "nsGkAtoms.h"
     9 #include "nsButtonBoxFrame.h"
    10 #include "nsITimer.h"
    11 #include "nsRepeatService.h"
    12 #include "mozilla/MouseEvents.h"
    13 #include "nsIContent.h"
    15 using namespace mozilla;
    17 class nsAutoRepeatBoxFrame : public nsButtonBoxFrame
    18 {
    19 public:
    20   NS_DECL_FRAMEARENA_HELPERS
    22   friend nsIFrame* NS_NewAutoRepeatBoxFrame(nsIPresShell* aPresShell,
    23                                             nsStyleContext* aContext);
    25   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
    27   virtual nsresult AttributeChanged(int32_t aNameSpaceID,
    28                                     nsIAtom* aAttribute,
    29                                     int32_t aModType) MOZ_OVERRIDE;
    31   virtual nsresult HandleEvent(nsPresContext* aPresContext,
    32                                WidgetGUIEvent* aEvent,
    33                                nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    35   NS_IMETHOD HandlePress(nsPresContext* aPresContext,
    36                          WidgetGUIEvent* aEvent,
    37                          nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    39   NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
    40                            WidgetGUIEvent* aEvent,
    41                            nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    43 protected:
    44   nsAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext):
    45     nsButtonBoxFrame(aPresShell, aContext) {}
    47   void StartRepeat() {
    48     if (IsActivatedOnHover()) {
    49       // No initial delay on hover.
    50       nsRepeatService::GetInstance()->Start(Notify, this, 0);
    51     } else {
    52       nsRepeatService::GetInstance()->Start(Notify, this);
    53     }
    54   }
    55   void StopRepeat() {
    56     nsRepeatService::GetInstance()->Stop(Notify, this);
    57   }
    58   void Notify();
    59   static void Notify(void* aData) {
    60     static_cast<nsAutoRepeatBoxFrame*>(aData)->Notify();
    61   }
    63   bool mTrustedEvent;
    65   bool IsActivatedOnHover();
    66 };
    68 nsIFrame*
    69 NS_NewAutoRepeatBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
    70 {
    71   return new (aPresShell) nsAutoRepeatBoxFrame (aPresShell, aContext);
    72 }
    74 NS_IMPL_FRAMEARENA_HELPERS(nsAutoRepeatBoxFrame)
    76 nsresult
    77 nsAutoRepeatBoxFrame::HandleEvent(nsPresContext* aPresContext,
    78                                   WidgetGUIEvent* aEvent,
    79                                   nsEventStatus* aEventStatus)
    80 {  
    81   NS_ENSURE_ARG_POINTER(aEventStatus);
    82   if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
    83     return NS_OK;
    84   }
    86   switch(aEvent->message)
    87   {
    88     // repeat mode may be "hover" for repeating while the mouse is hovering
    89     // over the element, otherwise repetition is done while the element is
    90     // active (pressed).
    91     case NS_MOUSE_ENTER:
    92     case NS_MOUSE_ENTER_SYNTH:
    93       if (IsActivatedOnHover()) {
    94         StartRepeat();
    95         mTrustedEvent = aEvent->mFlags.mIsTrusted;
    96       }
    97       break;
    99     case NS_MOUSE_EXIT:
   100     case NS_MOUSE_EXIT_SYNTH:
   101       // always stop on mouse exit
   102       StopRepeat();
   103       // Not really necessary but do this to be safe
   104       mTrustedEvent = false;
   105       break;
   107     case NS_MOUSE_CLICK: {
   108       WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   109       if (mouseEvent->IsLeftClickEvent()) {
   110         // skip button frame handling to prevent click handling
   111         return nsBoxFrame::HandleEvent(aPresContext, mouseEvent, aEventStatus);
   112       }
   113       break;
   114     }
   115   }
   117   return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   118 }
   120 NS_IMETHODIMP
   121 nsAutoRepeatBoxFrame::HandlePress(nsPresContext* aPresContext,
   122                                   WidgetGUIEvent* aEvent,
   123                                   nsEventStatus* aEventStatus)
   124 {
   125   if (!IsActivatedOnHover()) {
   126     StartRepeat();
   127     mTrustedEvent = aEvent->mFlags.mIsTrusted;
   128     DoMouseClick(aEvent, mTrustedEvent);
   129   }
   131   return NS_OK;
   132 }
   134 NS_IMETHODIMP 
   135 nsAutoRepeatBoxFrame::HandleRelease(nsPresContext* aPresContext,
   136                                     WidgetGUIEvent* aEvent,
   137                                     nsEventStatus* aEventStatus)
   138 {
   139   if (!IsActivatedOnHover()) {
   140     StopRepeat();
   141   }
   142   return NS_OK;
   143 }
   145 nsresult
   146 nsAutoRepeatBoxFrame::AttributeChanged(int32_t aNameSpaceID,
   147                                        nsIAtom* aAttribute,
   148                                        int32_t aModType)
   149 {
   150   if (aAttribute == nsGkAtoms::type) {
   151     StopRepeat();
   152   }
   153   return NS_OK;
   154 }
   156 void
   157 nsAutoRepeatBoxFrame::Notify()
   158 {
   159   DoMouseClick(nullptr, mTrustedEvent);
   160 }
   162 void
   163 nsAutoRepeatBoxFrame::DestroyFrom(nsIFrame* aDestructRoot)
   164 {
   165   // Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
   166   // from under you while you're in the process of scrolling.
   167   StopRepeat();
   168   nsButtonBoxFrame::DestroyFrom(aDestructRoot);
   169 }
   171 bool
   172 nsAutoRepeatBoxFrame::IsActivatedOnHover()
   173 {
   174   return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::repeat,
   175                                nsGkAtoms::hover, eCaseMatters);
   176 }

mercurial