Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp

Issue 2815263002: Move form-related files in core/html/shadow to core/html/forms. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "core/html/shadow/SpinButtonElement.h"
28
29 #include "core/HTMLNames.h"
30 #include "core/dom/TaskRunnerHelper.h"
31 #include "core/events/MouseEvent.h"
32 #include "core/events/WheelEvent.h"
33 #include "core/frame/LocalFrame.h"
34 #include "core/html/shadow/ShadowElementNames.h"
35 #include "core/input/EventHandler.h"
36 #include "core/layout/LayoutBox.h"
37 #include "core/page/ChromeClient.h"
38 #include "core/page/Page.h"
39 #include "platform/scroll/ScrollbarTheme.h"
40
41 namespace blink {
42
43 using namespace HTMLNames;
44
45 inline SpinButtonElement::SpinButtonElement(Document& document,
46 SpinButtonOwner& spin_button_owner)
47 : HTMLDivElement(document),
48 spin_button_owner_(&spin_button_owner),
49 capturing_(false),
50 up_down_state_(kIndeterminate),
51 press_starting_state_(kIndeterminate),
52 repeating_timer_(
53 TaskRunnerHelper::Get(TaskType::kUnspecedTimer, &document),
54 this,
55 &SpinButtonElement::RepeatingTimerFired) {}
56
57 SpinButtonElement* SpinButtonElement::Create(
58 Document& document,
59 SpinButtonOwner& spin_button_owner) {
60 SpinButtonElement* element =
61 new SpinButtonElement(document, spin_button_owner);
62 element->SetShadowPseudoId(AtomicString("-webkit-inner-spin-button"));
63 element->setAttribute(idAttr, ShadowElementNames::SpinButton());
64 return element;
65 }
66
67 void SpinButtonElement::DetachLayoutTree(const AttachContext& context) {
68 ReleaseCapture(kEventDispatchDisallowed);
69 HTMLDivElement::DetachLayoutTree(context);
70 }
71
72 void SpinButtonElement::DefaultEventHandler(Event* event) {
73 if (!event->IsMouseEvent()) {
74 if (!event->DefaultHandled())
75 HTMLDivElement::DefaultEventHandler(event);
76 return;
77 }
78
79 LayoutBox* box = GetLayoutBox();
80 if (!box) {
81 if (!event->DefaultHandled())
82 HTMLDivElement::DefaultEventHandler(event);
83 return;
84 }
85
86 if (!ShouldRespondToMouseEvents()) {
87 if (!event->DefaultHandled())
88 HTMLDivElement::DefaultEventHandler(event);
89 return;
90 }
91
92 MouseEvent* mouse_event = ToMouseEvent(event);
93 IntPoint local = RoundedIntPoint(box->AbsoluteToLocal(
94 FloatPoint(mouse_event->AbsoluteLocation()), kUseTransforms));
95 if (mouse_event->type() == EventTypeNames::mousedown &&
96 mouse_event->button() ==
97 static_cast<short>(WebPointerProperties::Button::kLeft)) {
98 if (box->PixelSnappedBorderBoxRect().Contains(local)) {
99 if (spin_button_owner_)
100 spin_button_owner_->FocusAndSelectSpinButtonOwner();
101 if (GetLayoutObject()) {
102 if (up_down_state_ != kIndeterminate) {
103 // A JavaScript event handler called in doStepAction() below
104 // might change the element state and we might need to
105 // cancel the repeating timer by the state change. If we
106 // started the timer after doStepAction(), we would have no
107 // chance to cancel the timer.
108 StartRepeatingTimer();
109 DoStepAction(up_down_state_ == kUp ? 1 : -1);
110 }
111 }
112 event->SetDefaultHandled();
113 }
114 } else if (mouse_event->type() == EventTypeNames::mouseup &&
115 mouse_event->button() ==
116 static_cast<short>(WebPointerProperties::Button::kLeft)) {
117 ReleaseCapture();
118 } else if (event->type() == EventTypeNames::mousemove) {
119 if (box->PixelSnappedBorderBoxRect().Contains(local)) {
120 if (!capturing_) {
121 if (LocalFrame* frame = GetDocument().GetFrame()) {
122 frame->GetEventHandler().SetCapturingMouseEventsNode(this);
123 capturing_ = true;
124 if (Page* page = GetDocument().GetPage())
125 page->GetChromeClient().RegisterPopupOpeningObserver(this);
126 }
127 }
128 UpDownState old_up_down_state = up_down_state_;
129 up_down_state_ = (local.Y() < box->Size().Height() / 2) ? kUp : kDown;
130 if (up_down_state_ != old_up_down_state)
131 GetLayoutObject()->SetShouldDoFullPaintInvalidation();
132 } else {
133 ReleaseCapture();
134 up_down_state_ = kIndeterminate;
135 }
136 }
137
138 if (!event->DefaultHandled())
139 HTMLDivElement::DefaultEventHandler(event);
140 }
141
142 void SpinButtonElement::WillOpenPopup() {
143 ReleaseCapture();
144 up_down_state_ = kIndeterminate;
145 }
146
147 void SpinButtonElement::ForwardEvent(Event* event) {
148 if (!GetLayoutBox())
149 return;
150
151 if (!event->HasInterface(EventNames::WheelEvent))
152 return;
153
154 if (!spin_button_owner_)
155 return;
156
157 if (!spin_button_owner_->ShouldSpinButtonRespondToWheelEvents())
158 return;
159
160 DoStepAction(ToWheelEvent(event)->wheelDeltaY());
161 event->SetDefaultHandled();
162 }
163
164 bool SpinButtonElement::WillRespondToMouseMoveEvents() {
165 if (GetLayoutBox() && ShouldRespondToMouseEvents())
166 return true;
167
168 return HTMLDivElement::WillRespondToMouseMoveEvents();
169 }
170
171 bool SpinButtonElement::WillRespondToMouseClickEvents() {
172 if (GetLayoutBox() && ShouldRespondToMouseEvents())
173 return true;
174
175 return HTMLDivElement::WillRespondToMouseClickEvents();
176 }
177
178 void SpinButtonElement::DoStepAction(int amount) {
179 if (!spin_button_owner_)
180 return;
181
182 if (amount > 0)
183 spin_button_owner_->SpinButtonStepUp();
184 else if (amount < 0)
185 spin_button_owner_->SpinButtonStepDown();
186 }
187
188 void SpinButtonElement::ReleaseCapture(EventDispatch event_dispatch) {
189 StopRepeatingTimer();
190 if (!capturing_)
191 return;
192 if (LocalFrame* frame = GetDocument().GetFrame()) {
193 frame->GetEventHandler().SetCapturingMouseEventsNode(nullptr);
194 capturing_ = false;
195 if (Page* page = GetDocument().GetPage())
196 page->GetChromeClient().UnregisterPopupOpeningObserver(this);
197 }
198 if (spin_button_owner_)
199 spin_button_owner_->SpinButtonDidReleaseMouseCapture(event_dispatch);
200 }
201
202 bool SpinButtonElement::MatchesReadOnlyPseudoClass() const {
203 return OwnerShadowHost()->MatchesReadOnlyPseudoClass();
204 }
205
206 bool SpinButtonElement::MatchesReadWritePseudoClass() const {
207 return OwnerShadowHost()->MatchesReadWritePseudoClass();
208 }
209
210 void SpinButtonElement::StartRepeatingTimer() {
211 press_starting_state_ = up_down_state_;
212 ScrollbarTheme& theme = ScrollbarTheme::GetTheme();
213 repeating_timer_.Start(theme.InitialAutoscrollTimerDelay(),
214 theme.AutoscrollTimerDelay(), BLINK_FROM_HERE);
215 }
216
217 void SpinButtonElement::StopRepeatingTimer() {
218 repeating_timer_.Stop();
219 }
220
221 void SpinButtonElement::Step(int amount) {
222 if (!ShouldRespondToMouseEvents())
223 return;
224 // On Mac OS, NSStepper updates the value for the button under the mouse
225 // cursor regardless of the button pressed at the beginning. So the
226 // following check is not needed for Mac OS.
227 #if !OS(MACOSX)
228 if (up_down_state_ != press_starting_state_)
229 return;
230 #endif
231 DoStepAction(amount);
232 }
233
234 void SpinButtonElement::RepeatingTimerFired(TimerBase*) {
235 if (up_down_state_ != kIndeterminate)
236 Step(up_down_state_ == kUp ? 1 : -1);
237 }
238
239 void SpinButtonElement::SetHovered(bool flag) {
240 if (!flag)
241 up_down_state_ = kIndeterminate;
242 HTMLDivElement::SetHovered(flag);
243 }
244
245 bool SpinButtonElement::ShouldRespondToMouseEvents() {
246 return !spin_button_owner_ ||
247 spin_button_owner_->ShouldSpinButtonRespondToMouseEvents();
248 }
249
250 DEFINE_TRACE(SpinButtonElement) {
251 visitor->Trace(spin_button_owner_);
252 HTMLDivElement::Trace(visitor);
253 }
254
255 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698