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 "nsImageFrame.h"
7 #include "nsIFormControlFrame.h"
8 #include "nsPresContext.h"
10 #include "nsStyleConsts.h"
11 #include "nsFormControlFrame.h"
12 #include "nsLayoutUtils.h"
13 #include "mozilla/MouseEvents.h"
14 #include "nsIContent.h"
16 using namespace mozilla
;
18 typedef nsImageFrame nsImageControlFrameSuper
;
19 class nsImageControlFrame
: public nsImageControlFrameSuper
,
20 public nsIFormControlFrame
23 explicit nsImageControlFrame(nsStyleContext
* aContext
);
24 ~nsImageControlFrame();
26 virtual void DestroyFrom(nsIFrame
* aDestructRoot
) MOZ_OVERRIDE
;
27 virtual void Init(nsIContent
* aContent
,
28 nsContainerFrame
* aParent
,
29 nsIFrame
* aPrevInFlow
) MOZ_OVERRIDE
;
32 NS_DECL_FRAMEARENA_HELPERS
34 virtual void Reflow(nsPresContext
* aPresContext
,
35 nsHTMLReflowMetrics
& aDesiredSize
,
36 const nsHTMLReflowState
& aReflowState
,
37 nsReflowStatus
& aStatus
) MOZ_OVERRIDE
;
39 virtual nsresult
HandleEvent(nsPresContext
* aPresContext
,
40 WidgetGUIEvent
* aEvent
,
41 nsEventStatus
* aEventStatus
) MOZ_OVERRIDE
;
43 virtual nsIAtom
* GetType() const MOZ_OVERRIDE
;
46 virtual mozilla::a11y::AccType
AccessibleType() MOZ_OVERRIDE
;
49 #ifdef DEBUG_FRAME_DUMP
50 virtual nsresult
GetFrameName(nsAString
& aResult
) const MOZ_OVERRIDE
{
51 return MakeFrameName(NS_LITERAL_STRING("ImageControl"), aResult
);
55 virtual nsresult
GetCursor(const nsPoint
& aPoint
,
56 nsIFrame::Cursor
& aCursor
) MOZ_OVERRIDE
;
57 // nsIFormContromFrame
58 virtual void SetFocus(bool aOn
, bool aRepaint
) MOZ_OVERRIDE
;
59 virtual nsresult
SetFormProperty(nsIAtom
* aName
,
60 const nsAString
& aValue
) MOZ_OVERRIDE
;
64 nsImageControlFrame::nsImageControlFrame(nsStyleContext
* aContext
):
65 nsImageControlFrameSuper(aContext
)
69 nsImageControlFrame::~nsImageControlFrame()
74 nsImageControlFrame::DestroyFrom(nsIFrame
* aDestructRoot
)
76 if (!GetPrevInFlow()) {
77 nsFormControlFrame::RegUnRegAccessKey(this, false);
79 nsImageControlFrameSuper::DestroyFrom(aDestructRoot
);
83 NS_NewImageControlFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
85 return new (aPresShell
) nsImageControlFrame(aContext
);
88 NS_IMPL_FRAMEARENA_HELPERS(nsImageControlFrame
)
91 nsImageControlFrame::Init(nsIContent
* aContent
,
92 nsContainerFrame
* aParent
,
93 nsIFrame
* aPrevInFlow
)
95 nsImageControlFrameSuper::Init(aContent
, aParent
, aPrevInFlow
);
101 mContent
->SetProperty(nsGkAtoms::imageClickedPoint
,
102 new nsIntPoint(0, 0),
103 nsINode::DeleteProperty
<nsIntPoint
>);
106 NS_QUERYFRAME_HEAD(nsImageControlFrame
)
107 NS_QUERYFRAME_ENTRY(nsIFormControlFrame
)
108 NS_QUERYFRAME_TAIL_INHERITING(nsImageControlFrameSuper
)
112 nsImageControlFrame::AccessibleType()
114 if (mContent
->Tag() == nsGkAtoms::button
||
115 mContent
->Tag() == nsGkAtoms::input
) {
116 return a11y::eHTMLButtonType
;
119 return a11y::eNoType
;
124 nsImageControlFrame::GetType() const
126 return nsGkAtoms::imageControlFrame
;
130 nsImageControlFrame::Reflow(nsPresContext
* aPresContext
,
131 nsHTMLReflowMetrics
& aDesiredSize
,
132 const nsHTMLReflowState
& aReflowState
,
133 nsReflowStatus
& aStatus
)
135 DO_GLOBAL_REFLOW_COUNT("nsImageControlFrame");
136 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
137 if (!GetPrevInFlow() && (mState
& NS_FRAME_FIRST_REFLOW
)) {
138 nsFormControlFrame::RegUnRegAccessKey(this, true);
140 return nsImageControlFrameSuper::Reflow(aPresContext
, aDesiredSize
, aReflowState
, aStatus
);
144 nsImageControlFrame::HandleEvent(nsPresContext
* aPresContext
,
145 WidgetGUIEvent
* aEvent
,
146 nsEventStatus
* aEventStatus
)
148 NS_ENSURE_ARG_POINTER(aEventStatus
);
150 // Don't do anything if the event has already been handled by someone
151 if (nsEventStatus_eConsumeNoDefault
== *aEventStatus
) {
155 // do we have user-input style?
156 const nsStyleUserInterface
* uiStyle
= StyleUserInterface();
157 if (uiStyle
->mUserInput
== NS_STYLE_USER_INPUT_NONE
|| uiStyle
->mUserInput
== NS_STYLE_USER_INPUT_DISABLED
)
158 return nsFrame::HandleEvent(aPresContext
, aEvent
, aEventStatus
);
160 if (mContent
->HasAttr(kNameSpaceID_None
, nsGkAtoms::disabled
)) { // XXX cache disabled
164 *aEventStatus
= nsEventStatus_eIgnore
;
166 if (aEvent
->message
== NS_MOUSE_BUTTON_UP
&&
167 aEvent
->AsMouseEvent()->button
== WidgetMouseEvent::eLeftButton
) {
168 // Store click point for HTMLInputElement::SubmitNamesValues
169 // Do this on MouseUp because the specs don't say and that's what IE does
170 nsIntPoint
* lastClickPoint
=
171 static_cast<nsIntPoint
*>
172 (mContent
->GetProperty(nsGkAtoms::imageClickedPoint
));
173 if (lastClickPoint
) {
174 // normally lastClickedPoint is not null, as it's allocated in Init()
175 nsPoint pt
= nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent
, this);
176 TranslateEventCoords(pt
, *lastClickPoint
);
179 return nsImageControlFrameSuper::HandleEvent(aPresContext
, aEvent
,
184 nsImageControlFrame::SetFocus(bool aOn
, bool aRepaint
)
189 nsImageControlFrame::GetCursor(const nsPoint
& aPoint
,
190 nsIFrame::Cursor
& aCursor
)
192 // Use style defined cursor if one is provided, otherwise when
193 // the cursor style is "auto" we use the pointer cursor.
194 FillCursorInformationFromStyle(StyleUserInterface(), aCursor
);
196 if (NS_STYLE_CURSOR_AUTO
== aCursor
.mCursor
) {
197 aCursor
.mCursor
= NS_STYLE_CURSOR_POINTER
;
204 nsImageControlFrame::SetFormProperty(nsIAtom
* aName
,
205 const nsAString
& aValue
)