tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsImageControlFrame.cpp (4605B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/MouseEvents.h"
      8 #include "mozilla/PresShell.h"
      9 #include "nsGkAtoms.h"
     10 #include "nsIContent.h"
     11 #include "nsImageFrame.h"
     12 #include "nsLayoutUtils.h"
     13 #include "nsPresContext.h"
     14 #include "nsStyleConsts.h"
     15 
     16 using namespace mozilla;
     17 
     18 class nsImageControlFrame final : public nsImageFrame {
     19 public:
     20  explicit nsImageControlFrame(ComputedStyle* aStyle,
     21                               nsPresContext* aPresContext);
     22  ~nsImageControlFrame() final;
     23 
     24  void Init(nsIContent* aContent, nsContainerFrame* aParent,
     25            nsIFrame* aPrevInFlow) final;
     26 
     27  NS_DECL_QUERYFRAME
     28  NS_DECL_FRAMEARENA_HELPERS(nsImageControlFrame)
     29 
     30  void Reflow(nsPresContext*, ReflowOutput&, const ReflowInput&,
     31              nsReflowStatus&) final;
     32 
     33  nsresult HandleEvent(nsPresContext*, WidgetGUIEvent*, nsEventStatus*) final;
     34 
     35 #ifdef ACCESSIBILITY
     36  mozilla::a11y::AccType AccessibleType() final;
     37 #endif
     38 
     39 #ifdef DEBUG_FRAME_DUMP
     40  nsresult GetFrameName(nsAString& aResult) const final {
     41    return MakeFrameName(u"ImageControl"_ns, aResult);
     42  }
     43 #endif
     44 
     45  Cursor GetCursor(const nsPoint&) final;
     46 };
     47 
     48 nsImageControlFrame::nsImageControlFrame(ComputedStyle* aStyle,
     49                                         nsPresContext* aPresContext)
     50    : nsImageFrame(aStyle, aPresContext, kClassID) {}
     51 
     52 nsImageControlFrame::~nsImageControlFrame() = default;
     53 
     54 nsIFrame* NS_NewImageControlFrame(PresShell* aPresShell,
     55                                  ComputedStyle* aStyle) {
     56  return new (aPresShell)
     57      nsImageControlFrame(aStyle, aPresShell->GetPresContext());
     58 }
     59 
     60 NS_IMPL_FRAMEARENA_HELPERS(nsImageControlFrame)
     61 
     62 void nsImageControlFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
     63                               nsIFrame* aPrevInFlow) {
     64  nsImageFrame::Init(aContent, aParent, aPrevInFlow);
     65 
     66  if (aPrevInFlow) {
     67    return;
     68  }
     69 
     70  mContent->SetProperty(nsGkAtoms::imageClickedPoint, new CSSIntPoint(0, 0),
     71                        nsINode::DeleteProperty<CSSIntPoint>);
     72 }
     73 
     74 NS_QUERYFRAME_HEAD(nsImageControlFrame)
     75 NS_QUERYFRAME_TAIL_INHERITING(nsImageFrame)
     76 
     77 #ifdef ACCESSIBILITY
     78 a11y::AccType nsImageControlFrame::AccessibleType() {
     79  if (mContent->IsAnyOfHTMLElements(nsGkAtoms::button, nsGkAtoms::input)) {
     80    return a11y::eHTMLButtonType;
     81  }
     82 
     83  return a11y::eNoType;
     84 }
     85 #endif
     86 
     87 void nsImageControlFrame::Reflow(nsPresContext* aPresContext,
     88                                 ReflowOutput& aDesiredSize,
     89                                 const ReflowInput& aReflowInput,
     90                                 nsReflowStatus& aStatus) {
     91  DO_GLOBAL_REFLOW_COUNT("nsImageControlFrame");
     92  MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
     93  return nsImageFrame::Reflow(aPresContext, aDesiredSize, aReflowInput,
     94                              aStatus);
     95 }
     96 
     97 nsresult nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
     98                                          WidgetGUIEvent* aEvent,
     99                                          nsEventStatus* aEventStatus) {
    100  NS_ENSURE_ARG_POINTER(aEventStatus);
    101 
    102  // Don't do anything if the event has already been handled by someone
    103  if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
    104    return NS_OK;
    105  }
    106 
    107  if (IsContentDisabled()) {
    108    return nsIFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
    109  }
    110 
    111  *aEventStatus = nsEventStatus_eIgnore;
    112 
    113  if (aEvent->mMessage == eMouseUp &&
    114      aEvent->AsMouseEvent()->mButton == MouseButton::ePrimary) {
    115    // Store click point for HTMLInputElement::SubmitNamesValues
    116    // Do this on MouseUp because the specs don't say and that's what IE does
    117    auto* lastClickedPoint = static_cast<CSSIntPoint*>(
    118        mContent->GetProperty(nsGkAtoms::imageClickedPoint));
    119    if (lastClickedPoint) {
    120      // normally lastClickedPoint is not null, as it's allocated in Init()
    121      nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(
    122          aEvent, RelativeTo{this});
    123      *lastClickedPoint = TranslateEventCoords(pt);
    124    }
    125  }
    126  return nsImageFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
    127 }
    128 
    129 nsIFrame::Cursor nsImageControlFrame::GetCursor(const nsPoint&) {
    130  StyleCursorKind kind = StyleUI()->Cursor().keyword;
    131  if (kind == StyleCursorKind::Auto) {
    132    kind = StyleCursorKind::Pointer;
    133  }
    134  return Cursor{kind, AllowCustomCursorImage::Yes};
    135 }