Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/forms/nsNumberControlFrame.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef nsNumberControlFrame_h__
8
#define nsNumberControlFrame_h__
9
10
#include "mozilla/Attributes.h"
11
#include "nsContainerFrame.h"
12
#include "nsIFormControlFrame.h"
13
#include "nsIAnonymousContentCreator.h"
14
#include "nsCOMPtr.h"
15
16
class nsITextControlFrame;
17
class nsPresContext;
18
19
namespace mozilla {
20
enum class CSSPseudoElementType : uint8_t;
21
class WidgetEvent;
22
class WidgetGUIEvent;
23
namespace dom {
24
class HTMLInputElement;
25
} // namespace dom
26
} // namespace mozilla
27
28
/**
29
 * This frame type is used for <input type=number>.
30
 */
31
class nsNumberControlFrame final : public nsContainerFrame
32
                                 , public nsIAnonymousContentCreator
33
                                 , public nsIFormControlFrame
34
{
35
  friend nsIFrame*
36
  NS_NewNumberControlFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle);
37
38
  typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
39
  typedef mozilla::dom::Element Element;
40
  typedef mozilla::dom::HTMLInputElement HTMLInputElement;
41
  typedef mozilla::WidgetEvent WidgetEvent;
42
  typedef mozilla::WidgetGUIEvent WidgetGUIEvent;
43
44
  explicit nsNumberControlFrame(ComputedStyle* aStyle);
45
46
public:
47
  NS_DECL_QUERYFRAME
48
  NS_DECL_FRAMEARENA_HELPERS(nsNumberControlFrame)
49
50
  virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
51
  virtual void ContentStatesChanged(mozilla::EventStates aStates) override;
52
53
#ifdef ACCESSIBILITY
54
  virtual mozilla::a11y::AccType AccessibleType() override;
55
#endif
56
57
  virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
58
59
  virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
60
61
  virtual void Reflow(nsPresContext*           aPresContext,
62
                      ReflowOutput&     aDesiredSize,
63
                      const ReflowInput& aReflowInput,
64
                      nsReflowStatus&          aStatus) override;
65
66
  virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
67
                                    nsAtom* aAttribute,
68
                                    int32_t  aModType) override;
69
70
  // nsIAnonymousContentCreator
71
  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
72
  virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
73
                                        uint32_t aFilter) override;
74
75
#ifdef DEBUG_FRAME_DUMP
76
  virtual nsresult GetFrameName(nsAString& aResult) const override {
77
    return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult);
78
  }
79
#endif
80
81
  virtual bool IsFrameOfType(uint32_t aFlags) const override
82
0
  {
83
0
    return nsContainerFrame::IsFrameOfType(aFlags &
84
0
      ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
85
0
  }
86
87
  // nsIFormControlFrame
88
  virtual void SetFocus(bool aOn, bool aRepaint) override;
89
  virtual nsresult SetFormProperty(nsAtom* aName, const nsAString& aValue) override;
90
91
  /**
92
   * This method attempts to localizes aValue and then sets the result as the
93
   * value of our anonymous text control. It's called when our
94
   * HTMLInputElement's value changes, when we need to sync up the value
95
   * displayed in our anonymous text control.
96
   */
97
  void SetValueOfAnonTextControl(const nsAString& aValue);
98
99
  /**
100
   * This method gets the string value of our anonymous text control,
101
   * attempts to normalizes (de-localizes) it, then sets the outparam aValue to
102
   * the result. It's called when user input changes the text value of our
103
   * anonymous text control so that we can sync up the internal value of our
104
   * HTMLInputElement.
105
   */
106
  void GetValueOfAnonTextControl(nsAString& aValue);
107
108
  bool AnonTextControlIsEmpty();
109
110
  /**
111
   * Called to notify this frame that its HTMLInputElement is currently
112
   * processing a DOM 'input' event.
113
   */
114
  void HandlingInputEvent(bool aHandlingEvent)
115
0
  {
116
0
    mHandlingInputEvent = aHandlingEvent;
117
0
  }
118
119
  HTMLInputElement* GetAnonTextControl();
120
121
  /**
122
   * If the frame is the frame for an nsNumberControlFrame's anonymous text
123
   * field, returns the nsNumberControlFrame. Else returns nullptr.
124
   */
125
  static nsNumberControlFrame* GetNumberControlFrameForTextField(nsIFrame* aFrame);
126
127
  /**
128
   * If the frame is the frame for an nsNumberControlFrame's up or down spin
129
   * button, returns the nsNumberControlFrame. Else returns nullptr.
130
   */
131
  static nsNumberControlFrame* GetNumberControlFrameForSpinButton(nsIFrame* aFrame);
132
133
  enum SpinButtonEnum {
134
    eSpinButtonNone,
135
    eSpinButtonUp,
136
    eSpinButtonDown
137
  };
138
139
  /**
140
   * Returns one of the SpinButtonEnum values to depending on whether the
141
   * pointer event is over the spin-up button, the spin-down button, or
142
   * neither.
143
   */
144
  int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const;
145
146
  void SpinnerStateChanged() const;
147
148
  bool SpinnerUpButtonIsDepressed() const;
149
  bool SpinnerDownButtonIsDepressed() const;
150
151
  bool IsFocused() const;
152
153
  void HandleFocusEvent(WidgetEvent* aEvent);
154
155
  /**
156
   * Our element had HTMLInputElement::Select() called on it.
157
   */
158
  void HandleSelectCall();
159
160
  bool ShouldUseNativeStyleForSpinner() const;
161
162
private:
163
164
  nsITextControlFrame* GetTextFieldFrame();
165
  already_AddRefed<Element> MakeAnonymousElement(Element* aParent,
166
                                                 nsAtom* aTagName,
167
                                                 CSSPseudoElementType aPseudoType);
168
169
  class SyncDisabledStateEvent;
170
  friend class SyncDisabledStateEvent;
171
  class SyncDisabledStateEvent : public mozilla::Runnable
172
  {
173
  public:
174
    explicit SyncDisabledStateEvent(nsNumberControlFrame* aFrame)
175
      : mozilla::Runnable("nsNumberControlFrame::SyncDisabledStateEvent")
176
      , mFrame(aFrame)
177
0
    {}
178
179
    NS_IMETHOD Run() override
180
0
    {
181
0
      nsNumberControlFrame* frame =
182
0
        static_cast<nsNumberControlFrame*>(mFrame.GetFrame());
183
0
      NS_ENSURE_STATE(frame);
184
0
185
0
      frame->SyncDisabledState();
186
0
      return NS_OK;
187
0
    }
188
189
  private:
190
    WeakFrame mFrame;
191
  };
192
193
  /**
194
   * Sync the disabled state of the anonymous children up with our content's.
195
   */
196
  void SyncDisabledState();
197
198
  /**
199
   * The text field used to edit and show the number.
200
   * @see nsNumberControlFrame::CreateAnonymousContent.
201
   */
202
  nsCOMPtr<Element> mOuterWrapper;
203
  nsCOMPtr<Element> mTextField;
204
  nsCOMPtr<Element> mSpinBox;
205
  nsCOMPtr<Element> mSpinUp;
206
  nsCOMPtr<Element> mSpinDown;
207
  bool mHandlingInputEvent;
208
};
209
210
#endif // nsNumberControlFrame_h__