LCOV - code coverage report
Current view: top level - layout/xul - PopupBoxObject.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 25 182 13.7 %
Date: 2017-07-14 16:53:18 Functions: 9 30 30.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             : #include "nsCOMPtr.h"
       7             : #include "nsIRootBox.h"
       8             : #include "nsIPresShell.h"
       9             : #include "nsIContent.h"
      10             : #include "nsNameSpaceManager.h"
      11             : #include "nsGkAtoms.h"
      12             : #include "nsMenuPopupFrame.h"
      13             : #include "nsView.h"
      14             : #include "mozilla/AppUnits.h"
      15             : #include "mozilla/dom/DOMRect.h"
      16             : #include "mozilla/dom/PopupBoxObject.h"
      17             : #include "mozilla/dom/Element.h"
      18             : #include "mozilla/dom/Event.h"
      19             : #include "mozilla/dom/PopupBoxObjectBinding.h"
      20             : 
      21             : namespace mozilla {
      22             : namespace dom {
      23             : 
      24          18 : NS_IMPL_ADDREF_INHERITED(PopupBoxObject, BoxObject)
      25           6 : NS_IMPL_RELEASE_INHERITED(PopupBoxObject, BoxObject)
      26          60 : NS_INTERFACE_MAP_BEGIN(PopupBoxObject)
      27          60 : NS_INTERFACE_MAP_END_INHERITING(BoxObject)
      28             : 
      29           6 : PopupBoxObject::PopupBoxObject()
      30             : {
      31           6 : }
      32             : 
      33           0 : PopupBoxObject::~PopupBoxObject()
      34             : {
      35           0 : }
      36             : 
      37           6 : nsIContent* PopupBoxObject::GetParentObject() const
      38             : {
      39           6 :   return BoxObject::GetParentObject();
      40             : }
      41             : 
      42           6 : JSObject* PopupBoxObject::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
      43             : {
      44           6 :   return PopupBoxObjectBinding::Wrap(aCx, this, aGivenProto);
      45             : }
      46             : 
      47             : nsPopupSetFrame*
      48           0 : PopupBoxObject::GetPopupSetFrame()
      49             : {
      50           0 :   nsIRootBox* rootBox = nsIRootBox::GetRootBox(GetPresShell(false));
      51           0 :   if (!rootBox)
      52           0 :     return nullptr;
      53             : 
      54           0 :   return rootBox->GetPopupSetFrame();
      55             : }
      56             : 
      57             : void
      58           1 : PopupBoxObject::HidePopup(bool aCancel)
      59             : {
      60           1 :   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
      61           1 :   if (pm && mContent) {
      62           1 :     pm->HidePopup(mContent, false, true, false, aCancel);
      63             :   }
      64           1 : }
      65             : 
      66             : void
      67           0 : PopupBoxObject::ShowPopup(Element* aAnchorElement,
      68             :                           Element& aPopupElement,
      69             :                           int32_t aXPos, int32_t aYPos,
      70             :                           const nsAString& aPopupType,
      71             :                           const nsAString& aAnchorAlignment,
      72             :                           const nsAString& aPopupAlignment)
      73             : {
      74           0 :   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
      75           0 :   if (pm && mContent) {
      76           0 :     nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
      77           0 :     nsAutoString popupType(aPopupType);
      78           0 :     nsAutoString anchor(aAnchorAlignment);
      79           0 :     nsAutoString align(aPopupAlignment);
      80           0 :     pm->ShowPopupWithAnchorAlign(mContent, anchorContent, anchor, align,
      81             :                                  aXPos, aYPos,
      82           0 :                                  popupType.EqualsLiteral("context"));
      83             :   }
      84           0 : }
      85             : 
      86             : void
      87           0 : PopupBoxObject::OpenPopup(Element* aAnchorElement,
      88             :                           const nsAString& aPosition,
      89             :                           int32_t aXPos, int32_t aYPos,
      90             :                           bool aIsContextMenu,
      91             :                           bool aAttributesOverride,
      92             :                           Event* aTriggerEvent)
      93             : {
      94           0 :   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
      95           0 :   if (pm && mContent) {
      96           0 :     nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
      97           0 :     pm->ShowPopup(mContent, anchorContent, aPosition, aXPos, aYPos,
      98           0 :                   aIsContextMenu, aAttributesOverride, false, aTriggerEvent);
      99             :   }
     100           0 : }
     101             : 
     102             : void
     103           0 : PopupBoxObject::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos,
     104             :                                   bool aIsContextMenu,
     105             :                                   Event* aTriggerEvent)
     106             : {
     107           0 :   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     108           0 :   if (pm && mContent)
     109           0 :     pm->ShowPopupAtScreen(mContent, aXPos, aYPos, aIsContextMenu, aTriggerEvent);
     110           0 : }
     111             : 
     112             : void
     113           0 : PopupBoxObject::OpenPopupAtScreenRect(const nsAString& aPosition,
     114             :                                       int32_t aXPos, int32_t aYPos,
     115             :                                       int32_t aWidth, int32_t aHeight,
     116             :                                       bool aIsContextMenu,
     117             :                                       bool aAttributesOverride,
     118             :                                       Event* aTriggerEvent)
     119             : {
     120           0 :   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     121           0 :   if (pm && mContent) {
     122           0 :     pm->ShowPopupAtScreenRect(mContent, aPosition,
     123           0 :                               nsIntRect(aXPos, aYPos, aWidth, aHeight),
     124           0 :                               aIsContextMenu, aAttributesOverride, aTriggerEvent);
     125             :   }
     126           0 : }
     127             : 
     128             : void
     129           0 : PopupBoxObject::MoveTo(int32_t aLeft, int32_t aTop)
     130             : {
     131           0 :   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
     132           0 :   if (menuPopupFrame) {
     133           0 :     menuPopupFrame->MoveTo(CSSIntPoint(aLeft, aTop), true);
     134             :   }
     135           0 : }
     136             : 
     137             : void
     138           0 : PopupBoxObject::MoveToAnchor(Element* aAnchorElement,
     139             :                              const nsAString& aPosition,
     140             :                              int32_t aXPos, int32_t aYPos,
     141             :                              bool aAttributesOverride)
     142             : {
     143           0 :   if (mContent) {
     144           0 :     nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
     145             : 
     146           0 :     nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(mContent->GetPrimaryFrame());
     147           0 :     if (menuPopupFrame && menuPopupFrame->IsVisible()) {
     148           0 :       menuPopupFrame->MoveToAnchor(anchorContent, aPosition, aXPos, aYPos, aAttributesOverride);
     149             :     }
     150             :   }
     151           0 : }
     152             : 
     153             : void
     154           0 : PopupBoxObject::SizeTo(int32_t aWidth, int32_t aHeight)
     155             : {
     156           0 :   if (!mContent)
     157           0 :     return;
     158             : 
     159           0 :   nsAutoString width, height;
     160           0 :   width.AppendInt(aWidth);
     161           0 :   height.AppendInt(aHeight);
     162             : 
     163           0 :   nsCOMPtr<nsIContent> content = mContent;
     164             : 
     165             :   // We only want to pass aNotify=true to SetAttr once, but must make sure
     166             :   // we pass it when a value is being changed.  Thus, we check if the height
     167             :   // is the same and if so, pass true when setting the width.
     168           0 :   bool heightSame = content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::height, height, eCaseMatters);
     169             : 
     170           0 :   content->SetAttr(kNameSpaceID_None, nsGkAtoms::width, width, heightSame);
     171           0 :   content->SetAttr(kNameSpaceID_None, nsGkAtoms::height, height, true);
     172             : }
     173             : 
     174             : bool
     175           0 : PopupBoxObject::AutoPosition()
     176             : {
     177           0 :   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
     178           0 :   if (menuPopupFrame) {
     179           0 :     return menuPopupFrame->GetAutoPosition();
     180             :   }
     181           0 :   return true;
     182             : }
     183             : 
     184             : void
     185           0 : PopupBoxObject::SetAutoPosition(bool aShouldAutoPosition)
     186             : {
     187           0 :   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
     188           0 :   if (menuPopupFrame) {
     189           0 :     menuPopupFrame->SetAutoPosition(aShouldAutoPosition);
     190             :   }
     191           0 : }
     192             : 
     193             : void
     194           0 : PopupBoxObject::EnableRollup(bool aShouldRollup)
     195             : {
     196             :   // this does nothing now
     197           0 : }
     198             : 
     199             : void
     200           0 : PopupBoxObject::SetConsumeRollupEvent(uint32_t aConsume)
     201             : {
     202           0 :   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
     203           0 :   if (menuPopupFrame) {
     204           0 :     menuPopupFrame->SetConsumeRollupEvent(aConsume);
     205             :   }
     206           0 : }
     207             : 
     208             : void
     209           0 : PopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator)
     210             : {
     211           0 :   if (!mContent)
     212           0 :     return;
     213             : 
     214             :   // Use ignorekeys="true" on the popup instead of using this function.
     215           0 :   if (aEnableKeyboardNavigator)
     216           0 :     mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys, true);
     217             :   else
     218           0 :     mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys,
     219           0 :                       NS_LITERAL_STRING("true"), true);
     220             : }
     221             : 
     222             : void
     223           4 : PopupBoxObject::GetPopupState(nsString& aState)
     224             : {
     225             :   // set this here in case there's no frame for the popup
     226           4 :   aState.AssignLiteral("closed");
     227             : 
     228           4 :   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
     229           4 :   if (menuPopupFrame) {
     230           3 :     switch (menuPopupFrame->PopupState()) {
     231             :       case ePopupShown:
     232           0 :         aState.AssignLiteral("open");
     233           0 :         break;
     234             :       case ePopupShowing:
     235             :       case ePopupPositioning:
     236             :       case ePopupOpening:
     237             :       case ePopupVisible:
     238           0 :         aState.AssignLiteral("showing");
     239           0 :         break;
     240             :       case ePopupHiding:
     241             :       case ePopupInvisible:
     242           0 :         aState.AssignLiteral("hiding");
     243           0 :         break;
     244             :       case ePopupClosed:
     245           3 :         break;
     246             :       default:
     247           0 :         NS_NOTREACHED("Bad popup state");
     248           0 :         break;
     249             :     }
     250             :   }
     251           4 : }
     252             : 
     253             : nsINode*
     254           1 : PopupBoxObject::GetTriggerNode() const
     255             : {
     256           1 :   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
     257           1 :   return nsMenuPopupFrame::GetTriggerContent(menuPopupFrame);
     258             : }
     259             : 
     260             : Element*
     261           0 : PopupBoxObject::GetAnchorNode() const
     262             : {
     263           0 :   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
     264           0 :   if (!menuPopupFrame) {
     265           0 :     return nullptr;
     266             :   }
     267             : 
     268           0 :   nsIContent* anchor = menuPopupFrame->GetAnchor();
     269           0 :   return anchor && anchor->IsElement() ? anchor->AsElement() : nullptr;
     270             : }
     271             : 
     272             : already_AddRefed<DOMRect>
     273           0 : PopupBoxObject::GetOuterScreenRect()
     274             : {
     275           0 :   RefPtr<DOMRect> rect = new DOMRect(mContent);
     276             : 
     277             :   // Return an empty rectangle if the popup is not open.
     278           0 :   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
     279           0 :   if (!menuPopupFrame || !menuPopupFrame->IsOpen()) {
     280           0 :     return rect.forget();
     281             :   }
     282             : 
     283           0 :   nsView* view = menuPopupFrame->GetView();
     284           0 :   if (view) {
     285           0 :     nsIWidget* widget = view->GetWidget();
     286           0 :     if (widget) {
     287           0 :       LayoutDeviceIntRect screenRect = widget->GetScreenBounds();
     288             : 
     289           0 :       int32_t pp = menuPopupFrame->PresContext()->AppUnitsPerDevPixel();
     290           0 :       rect->SetLayoutRect(LayoutDeviceIntRect::ToAppUnits(screenRect, pp));
     291             :     }
     292             :   }
     293           0 :   return rect.forget();
     294             : }
     295             : 
     296             : void
     297           0 : PopupBoxObject::GetAlignmentPosition(nsString& positionStr)
     298             : {
     299           0 :   positionStr.Truncate();
     300             : 
     301             :   // This needs to flush layout.
     302           0 :   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(true));
     303           0 :   if (!menuPopupFrame)
     304           0 :     return;
     305             : 
     306           0 :   int8_t position = menuPopupFrame->GetAlignmentPosition();
     307           0 :   switch (position) {
     308             :     case POPUPPOSITION_AFTERSTART:
     309           0 :       positionStr.AssignLiteral("after_start");
     310           0 :       break;
     311             :     case POPUPPOSITION_AFTEREND:
     312           0 :       positionStr.AssignLiteral("after_end");
     313           0 :       break;
     314             :     case POPUPPOSITION_BEFORESTART:
     315           0 :       positionStr.AssignLiteral("before_start");
     316           0 :       break;
     317             :     case POPUPPOSITION_BEFOREEND:
     318           0 :       positionStr.AssignLiteral("before_end");
     319           0 :       break;
     320             :     case POPUPPOSITION_STARTBEFORE:
     321           0 :       positionStr.AssignLiteral("start_before");
     322           0 :       break;
     323             :     case POPUPPOSITION_ENDBEFORE:
     324           0 :       positionStr.AssignLiteral("end_before");
     325           0 :       break;
     326             :     case POPUPPOSITION_STARTAFTER:
     327           0 :       positionStr.AssignLiteral("start_after");
     328           0 :       break;
     329             :     case POPUPPOSITION_ENDAFTER:
     330           0 :       positionStr.AssignLiteral("end_after");
     331           0 :       break;
     332             :     case POPUPPOSITION_OVERLAP:
     333           0 :       positionStr.AssignLiteral("overlap");
     334           0 :       break;
     335             :     case POPUPPOSITION_AFTERPOINTER:
     336           0 :       positionStr.AssignLiteral("after_pointer");
     337           0 :       break;
     338             :     case POPUPPOSITION_SELECTION:
     339           0 :       positionStr.AssignLiteral("selection");
     340           0 :       break;
     341             :     default:
     342             :       // Leave as an empty string.
     343           0 :       break;
     344             :   }
     345             : }
     346             : 
     347             : int32_t
     348           0 : PopupBoxObject::AlignmentOffset()
     349             : {
     350           0 :   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
     351           0 :   if (!menuPopupFrame)
     352           0 :     return 0;
     353             : 
     354           0 :   int32_t pp = mozilla::AppUnitsPerCSSPixel();
     355             :   // Note that the offset might be along either the X or Y axis, but for the
     356             :   // sake of simplicity we use a point with only the X axis set so we can
     357             :   // use ToNearestPixels().
     358           0 :   nsPoint appOffset(menuPopupFrame->GetAlignmentOffset(), 0);
     359           0 :   nsIntPoint popupOffset = appOffset.ToNearestPixels(pp);
     360           0 :   return popupOffset.x;
     361             : }
     362             : 
     363             : void
     364           0 : PopupBoxObject::SetConstraintRect(dom::DOMRectReadOnly& aRect)
     365             : {
     366           0 :   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
     367           0 :   if (menuPopupFrame) {
     368           0 :     menuPopupFrame->SetOverrideConstraintRect(
     369           0 :       LayoutDeviceIntRect::Truncate(aRect.Left(), aRect.Top(), aRect.Width(), aRect.Height()));
     370             :   }
     371           0 : }
     372             : 
     373             : } // namespace dom
     374             : } // namespace mozilla
     375             : 
     376             : // Creation Routine ///////////////////////////////////////////////////////////////////////
     377             : 
     378             : nsresult
     379           0 : NS_NewPopupBoxObject(nsIBoxObject** aResult)
     380             : {
     381           0 :   *aResult = new mozilla::dom::PopupBoxObject();
     382           0 :   NS_ADDREF(*aResult);
     383           0 :   return NS_OK;
     384             : }

Generated by: LCOV version 1.13