LCOV - code coverage report
Current view: top level - layout/xul - nsScrollbarButtonFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 8 128 6.2 %
Date: 2017-07-14 16:53:18 Functions: 1 10 10.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : //
       7             : // Eric Vaughan
       8             : // Netscape Communications
       9             : //
      10             : // See documentation in associated header file
      11             : //
      12             : 
      13             : #include "nsScrollbarButtonFrame.h"
      14             : #include "nsPresContext.h"
      15             : #include "nsIContent.h"
      16             : #include "nsCOMPtr.h"
      17             : #include "nsNameSpaceManager.h"
      18             : #include "nsGkAtoms.h"
      19             : #include "nsSliderFrame.h"
      20             : #include "nsScrollbarFrame.h"
      21             : #include "nsIScrollbarMediator.h"
      22             : #include "nsRepeatService.h"
      23             : #include "mozilla/LookAndFeel.h"
      24             : #include "mozilla/MouseEvents.h"
      25             : #include "mozilla/Telemetry.h"
      26             : #include "mozilla/layers/ScrollInputMethods.h"
      27             : 
      28             : using namespace mozilla;
      29             : using mozilla::layers::ScrollInputMethod;
      30             : 
      31             : //
      32             : // NS_NewToolbarFrame
      33             : //
      34             : // Creates a new Toolbar frame and returns it
      35             : //
      36             : nsIFrame*
      37           0 : NS_NewScrollbarButtonFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
      38             : {
      39           0 :   return new (aPresShell) nsScrollbarButtonFrame(aContext);
      40             : }
      41             : 
      42           0 : NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
      43             : 
      44             : nsresult
      45           0 : nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
      46             :                                     WidgetGUIEvent* aEvent,
      47             :                                     nsEventStatus* aEventStatus)
      48             : {
      49           0 :   NS_ENSURE_ARG_POINTER(aEventStatus);
      50             : 
      51             :   // If a web page calls event.preventDefault() we still want to
      52             :   // scroll when scroll arrow is clicked. See bug 511075.
      53           0 :   if (!mContent->IsInNativeAnonymousSubtree() &&
      54           0 :       nsEventStatus_eConsumeNoDefault == *aEventStatus) {
      55           0 :     return NS_OK;
      56             :   }
      57             : 
      58           0 :   switch (aEvent->mMessage) {
      59             :     case eMouseDown:
      60           0 :       mCursorOnThis = true;
      61             :       // if we didn't handle the press ourselves, pass it on to the superclass
      62           0 :       if (HandleButtonPress(aPresContext, aEvent, aEventStatus)) {
      63           0 :         return NS_OK;
      64             :       }
      65           0 :       break;
      66             :     case eMouseUp:
      67           0 :       HandleRelease(aPresContext, aEvent, aEventStatus);
      68           0 :       break;
      69             :     case eMouseOut:
      70           0 :       mCursorOnThis = false;
      71           0 :       break;
      72             :     case eMouseMove: {
      73             :       nsPoint cursor =
      74           0 :         nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
      75           0 :       nsRect frameRect(nsPoint(0, 0), GetSize());
      76           0 :       mCursorOnThis = frameRect.Contains(cursor);
      77           0 :       break;
      78             :     }
      79             :     default:
      80           0 :       break;
      81             :   }
      82             : 
      83           0 :   return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
      84             : }
      85             : 
      86             : bool
      87           0 : nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
      88             :                                           WidgetGUIEvent* aEvent,
      89             :                                           nsEventStatus* aEventStatus)
      90             : {
      91             :   // Get the desired action for the scrollbar button.
      92             :   LookAndFeel::IntID tmpAction;
      93           0 :   uint16_t button = aEvent->AsMouseEvent()->button;
      94           0 :   if (button == WidgetMouseEvent::eLeftButton) {
      95           0 :     tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
      96           0 :   } else if (button == WidgetMouseEvent::eMiddleButton) {
      97           0 :     tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
      98           0 :   } else if (button == WidgetMouseEvent::eRightButton) {
      99           0 :     tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
     100             :   } else {
     101           0 :     return false;
     102             :   }
     103             : 
     104             :   // Get the button action metric from the pres. shell.
     105             :   int32_t pressedButtonAction;
     106           0 :   if (NS_FAILED(LookAndFeel::GetInt(tmpAction, &pressedButtonAction))) {
     107           0 :     return false;
     108             :   }
     109             : 
     110             :   // get the scrollbar control
     111             :   nsIFrame* scrollbar;
     112           0 :   GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
     113             : 
     114           0 :   if (scrollbar == nullptr)
     115           0 :     return false;
     116             : 
     117             :   static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment,
     118             :                                                    &nsGkAtoms::decrement,
     119             :                                                    nullptr };
     120           0 :   int32_t index = mContent->FindAttrValueIn(kNameSpaceID_None,
     121             :                                             nsGkAtoms::type,
     122           0 :                                             strings, eCaseMatters);
     123             :   int32_t direction;
     124           0 :   if (index == 0)
     125           0 :     direction = 1;
     126           0 :   else if (index == 1)
     127           0 :     direction = -1;
     128             :   else
     129           0 :     return false;
     130             : 
     131           0 :   bool repeat = pressedButtonAction != 2;
     132             :   // set this attribute so we can style it later
     133           0 :   AutoWeakFrame weakFrame(this);
     134           0 :   mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
     135             : 
     136           0 :   nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED);
     137             : 
     138           0 :   if (!weakFrame.IsAlive()) {
     139           0 :     return false;
     140             :   }
     141             : 
     142           0 :   nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
     143           0 :   if (sb) {
     144           0 :     nsIScrollbarMediator* m = sb->GetScrollbarMediator();
     145           0 :     switch (pressedButtonAction) {
     146             :     case 0:
     147           0 :       sb->SetIncrementToLine(direction);
     148           0 :       if (m) {
     149           0 :         m->ScrollByLine(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
     150             :       }
     151           0 :       break;
     152             :     case 1:
     153           0 :       sb->SetIncrementToPage(direction);
     154           0 :       if (m) {
     155           0 :         m->ScrollByPage(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
     156             :       }
     157           0 :       break;
     158             :     case 2:
     159           0 :       sb->SetIncrementToWhole(direction);
     160           0 :       if (m) {
     161           0 :         m->ScrollByWhole(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
     162             :       }
     163           0 :       break;
     164             :     case 3:
     165             :     default:
     166             :       // We were told to ignore this click, or someone assigned a non-standard
     167             :       // value to the button's action.
     168           0 :       return false;
     169             :     }
     170           0 :     if (!weakFrame.IsAlive()) {
     171           0 :       return false;
     172             :     }
     173             : 
     174             :     mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
     175           0 :         (uint32_t) ScrollInputMethod::MainThreadScrollbarButtonClick);
     176             : 
     177           0 :     if (!m) {
     178           0 :       sb->MoveToNewPosition();
     179           0 :       if (!weakFrame.IsAlive()) {
     180           0 :         return false;
     181             :       }
     182             :     }
     183             :   }
     184           0 :   if (repeat) {
     185           0 :     StartRepeat();
     186             :   }
     187           0 :   return true;
     188             : }
     189             : 
     190             : NS_IMETHODIMP
     191           0 : nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext,
     192             :                                       WidgetGUIEvent* aEvent,
     193             :                                       nsEventStatus* aEventStatus)
     194             : {
     195           0 :   nsIPresShell::SetCapturingContent(nullptr, 0);
     196             :   // we're not active anymore
     197           0 :   mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
     198           0 :   StopRepeat();
     199             :   nsIFrame* scrollbar;
     200           0 :   GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
     201           0 :   nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
     202           0 :   if (sb) {
     203           0 :     nsIScrollbarMediator* m = sb->GetScrollbarMediator();
     204           0 :     if (m) {
     205           0 :       m->ScrollbarReleased(sb);
     206             :     }
     207             :   }
     208           0 :   return NS_OK;
     209             : }
     210             : 
     211           0 : void nsScrollbarButtonFrame::Notify()
     212             : {
     213           0 :   if (mCursorOnThis ||
     214           0 :       LookAndFeel::GetInt(
     215             :         LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) {
     216             :     // get the scrollbar control
     217             :     nsIFrame* scrollbar;
     218           0 :     GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
     219           0 :     nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
     220           0 :     if (sb) {
     221           0 :       nsIScrollbarMediator* m = sb->GetScrollbarMediator();
     222           0 :       if (m) {
     223           0 :         m->RepeatButtonScroll(sb);
     224             :       } else {
     225           0 :         sb->MoveToNewPosition();
     226             :       }
     227             :     }
     228             :   }
     229           0 : }
     230             : 
     231             : void
     232           0 : nsScrollbarButtonFrame::MouseClicked(WidgetGUIEvent* aEvent)
     233             : {
     234           0 :   nsButtonBoxFrame::MouseClicked(aEvent);
     235             :   //MouseClicked();
     236           0 : }
     237             : 
     238             : nsresult
     239           0 : nsScrollbarButtonFrame::GetChildWithTag(nsIAtom* atom, nsIFrame* start,
     240             :                                         nsIFrame*& result)
     241             : {
     242             :   // recursively search our children
     243           0 :   for (nsIFrame* childFrame : start->PrincipalChildList())
     244             :   {
     245             :     // get the content node
     246           0 :     nsIContent* child = childFrame->GetContent();
     247             : 
     248           0 :     if (child) {
     249             :       // see if it is the child
     250           0 :        if (child->IsXULElement(atom))
     251             :        {
     252           0 :          result = childFrame;
     253             : 
     254           0 :          return NS_OK;
     255             :        }
     256             :     }
     257             : 
     258             :      // recursive search the child
     259           0 :      GetChildWithTag(atom, childFrame, result);
     260           0 :      if (result != nullptr)
     261           0 :        return NS_OK;
     262             :   }
     263             : 
     264           0 :   result = nullptr;
     265           0 :   return NS_OK;
     266             : }
     267             : 
     268             : nsresult
     269          92 : nsScrollbarButtonFrame::GetParentWithTag(nsIAtom* toFind, nsIFrame* start,
     270             :                                          nsIFrame*& result)
     271             : {
     272          92 :    while (start)
     273             :    {
     274          92 :       start = start->GetParent();
     275             : 
     276          92 :       if (start) {
     277             :         // get the content node
     278          92 :         nsIContent* child = start->GetContent();
     279             : 
     280          92 :         if (child && child->IsXULElement(toFind)) {
     281          92 :           result = start;
     282          92 :           return NS_OK;
     283             :         }
     284             :       }
     285             :    }
     286             : 
     287           0 :    result = nullptr;
     288           0 :    return NS_OK;
     289             : }
     290             : 
     291             : void
     292           0 : nsScrollbarButtonFrame::DestroyFrom(nsIFrame* aDestructRoot)
     293             : {
     294             :   // Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
     295             :   // from under you while you're in the process of scrolling.
     296           0 :   StopRepeat();
     297           0 :   nsButtonBoxFrame::DestroyFrom(aDestructRoot);
     298           0 : }

Generated by: LCOV version 1.13