|
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 #include "nsImageFrame.h" |
|
6 #include "nsIFormControlFrame.h" |
|
7 #include "nsPresContext.h" |
|
8 #include "nsGkAtoms.h" |
|
9 #include "nsStyleConsts.h" |
|
10 #include "nsFormControlFrame.h" |
|
11 #include "nsLayoutUtils.h" |
|
12 #include "mozilla/MouseEvents.h" |
|
13 |
|
14 using namespace mozilla; |
|
15 |
|
16 typedef nsImageFrame nsImageControlFrameSuper; |
|
17 class nsImageControlFrame : public nsImageControlFrameSuper, |
|
18 public nsIFormControlFrame |
|
19 { |
|
20 public: |
|
21 nsImageControlFrame(nsStyleContext* aContext); |
|
22 ~nsImageControlFrame(); |
|
23 |
|
24 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; |
|
25 virtual void Init(nsIContent* aContent, |
|
26 nsIFrame* aParent, |
|
27 nsIFrame* aPrevInFlow) MOZ_OVERRIDE; |
|
28 |
|
29 NS_DECL_QUERYFRAME |
|
30 NS_DECL_FRAMEARENA_HELPERS |
|
31 |
|
32 virtual nsresult Reflow(nsPresContext* aPresContext, |
|
33 nsHTMLReflowMetrics& aDesiredSize, |
|
34 const nsHTMLReflowState& aReflowState, |
|
35 nsReflowStatus& aStatus) MOZ_OVERRIDE; |
|
36 |
|
37 virtual nsresult HandleEvent(nsPresContext* aPresContext, |
|
38 WidgetGUIEvent* aEvent, |
|
39 nsEventStatus* aEventStatus) MOZ_OVERRIDE; |
|
40 |
|
41 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
42 |
|
43 #ifdef ACCESSIBILITY |
|
44 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; |
|
45 #endif |
|
46 |
|
47 #ifdef DEBUG_FRAME_DUMP |
|
48 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { |
|
49 return MakeFrameName(NS_LITERAL_STRING("ImageControl"), aResult); |
|
50 } |
|
51 #endif |
|
52 |
|
53 virtual nsresult GetCursor(const nsPoint& aPoint, |
|
54 nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; |
|
55 // nsIFormContromFrame |
|
56 virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE; |
|
57 virtual nsresult SetFormProperty(nsIAtom* aName, |
|
58 const nsAString& aValue) MOZ_OVERRIDE; |
|
59 }; |
|
60 |
|
61 |
|
62 nsImageControlFrame::nsImageControlFrame(nsStyleContext* aContext): |
|
63 nsImageControlFrameSuper(aContext) |
|
64 { |
|
65 } |
|
66 |
|
67 nsImageControlFrame::~nsImageControlFrame() |
|
68 { |
|
69 } |
|
70 |
|
71 void |
|
72 nsImageControlFrame::DestroyFrom(nsIFrame* aDestructRoot) |
|
73 { |
|
74 if (!GetPrevInFlow()) { |
|
75 nsFormControlFrame::RegUnRegAccessKey(this, false); |
|
76 } |
|
77 nsImageControlFrameSuper::DestroyFrom(aDestructRoot); |
|
78 } |
|
79 |
|
80 nsIFrame* |
|
81 NS_NewImageControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) |
|
82 { |
|
83 return new (aPresShell) nsImageControlFrame(aContext); |
|
84 } |
|
85 |
|
86 NS_IMPL_FRAMEARENA_HELPERS(nsImageControlFrame) |
|
87 |
|
88 void |
|
89 nsImageControlFrame::Init(nsIContent* aContent, |
|
90 nsIFrame* aParent, |
|
91 nsIFrame* aPrevInFlow) |
|
92 { |
|
93 nsImageControlFrameSuper::Init(aContent, aParent, aPrevInFlow); |
|
94 |
|
95 if (aPrevInFlow) { |
|
96 return; |
|
97 } |
|
98 |
|
99 mContent->SetProperty(nsGkAtoms::imageClickedPoint, |
|
100 new nsIntPoint(0, 0), |
|
101 nsINode::DeleteProperty<nsIntPoint>); |
|
102 } |
|
103 |
|
104 NS_QUERYFRAME_HEAD(nsImageControlFrame) |
|
105 NS_QUERYFRAME_ENTRY(nsIFormControlFrame) |
|
106 NS_QUERYFRAME_TAIL_INHERITING(nsImageControlFrameSuper) |
|
107 |
|
108 #ifdef ACCESSIBILITY |
|
109 a11y::AccType |
|
110 nsImageControlFrame::AccessibleType() |
|
111 { |
|
112 if (mContent->Tag() == nsGkAtoms::button || |
|
113 mContent->Tag() == nsGkAtoms::input) { |
|
114 return a11y::eHTMLButtonType; |
|
115 } |
|
116 |
|
117 return a11y::eNoType; |
|
118 } |
|
119 #endif |
|
120 |
|
121 nsIAtom* |
|
122 nsImageControlFrame::GetType() const |
|
123 { |
|
124 return nsGkAtoms::imageControlFrame; |
|
125 } |
|
126 |
|
127 nsresult |
|
128 nsImageControlFrame::Reflow(nsPresContext* aPresContext, |
|
129 nsHTMLReflowMetrics& aDesiredSize, |
|
130 const nsHTMLReflowState& aReflowState, |
|
131 nsReflowStatus& aStatus) |
|
132 { |
|
133 DO_GLOBAL_REFLOW_COUNT("nsImageControlFrame"); |
|
134 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); |
|
135 if (!GetPrevInFlow() && (mState & NS_FRAME_FIRST_REFLOW)) { |
|
136 nsFormControlFrame::RegUnRegAccessKey(this, true); |
|
137 } |
|
138 return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); |
|
139 } |
|
140 |
|
141 nsresult |
|
142 nsImageControlFrame::HandleEvent(nsPresContext* aPresContext, |
|
143 WidgetGUIEvent* aEvent, |
|
144 nsEventStatus* aEventStatus) |
|
145 { |
|
146 NS_ENSURE_ARG_POINTER(aEventStatus); |
|
147 |
|
148 // Don't do anything if the event has already been handled by someone |
|
149 if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { |
|
150 return NS_OK; |
|
151 } |
|
152 |
|
153 // do we have user-input style? |
|
154 const nsStyleUserInterface* uiStyle = StyleUserInterface(); |
|
155 if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE || uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) |
|
156 return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); |
|
157 |
|
158 if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) { // XXX cache disabled |
|
159 return NS_OK; |
|
160 } |
|
161 |
|
162 *aEventStatus = nsEventStatus_eIgnore; |
|
163 |
|
164 if (aEvent->message == NS_MOUSE_BUTTON_UP && |
|
165 aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { |
|
166 // Store click point for HTMLInputElement::SubmitNamesValues |
|
167 // Do this on MouseUp because the specs don't say and that's what IE does |
|
168 nsIntPoint* lastClickPoint = |
|
169 static_cast<nsIntPoint*> |
|
170 (mContent->GetProperty(nsGkAtoms::imageClickedPoint)); |
|
171 if (lastClickPoint) { |
|
172 // normally lastClickedPoint is not null, as it's allocated in Init() |
|
173 nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this); |
|
174 TranslateEventCoords(pt, *lastClickPoint); |
|
175 } |
|
176 } |
|
177 return nsImageControlFrameSuper::HandleEvent(aPresContext, aEvent, |
|
178 aEventStatus); |
|
179 } |
|
180 |
|
181 void |
|
182 nsImageControlFrame::SetFocus(bool aOn, bool aRepaint) |
|
183 { |
|
184 } |
|
185 |
|
186 nsresult |
|
187 nsImageControlFrame::GetCursor(const nsPoint& aPoint, |
|
188 nsIFrame::Cursor& aCursor) |
|
189 { |
|
190 // Use style defined cursor if one is provided, otherwise when |
|
191 // the cursor style is "auto" we use the pointer cursor. |
|
192 FillCursorInformationFromStyle(StyleUserInterface(), aCursor); |
|
193 |
|
194 if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) { |
|
195 aCursor.mCursor = NS_STYLE_CURSOR_POINTER; |
|
196 } |
|
197 |
|
198 return NS_OK; |
|
199 } |
|
200 |
|
201 nsresult |
|
202 nsImageControlFrame::SetFormProperty(nsIAtom* aName, |
|
203 const nsAString& aValue) |
|
204 { |
|
205 return NS_OK; |
|
206 } |