[safe-browsing] Database full hash matches like prefix match.
[chromium-blink-merge.git] / content / shell / renderer / test_runner / event_sender.cc
blob5285d0369dfec165a4042d355f5a5e56bc76dcff
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/shell/renderer/test_runner/event_sender.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
10 #include "content/public/common/page_zoom.h"
11 #include "content/shell/renderer/test_runner/MockSpellCheck.h"
12 #include "content/shell/renderer/test_runner/TestInterfaces.h"
13 #include "content/shell/renderer/test_runner/WebTestDelegate.h"
14 #include "content/shell/renderer/test_runner/WebTestProxy.h"
15 #include "gin/handle.h"
16 #include "gin/object_template_builder.h"
17 #include "gin/wrappable.h"
18 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "third_party/WebKit/public/platform/WebVector.h"
20 #include "third_party/WebKit/public/web/WebContextMenuData.h"
21 #include "third_party/WebKit/public/web/WebFrame.h"
22 #include "third_party/WebKit/public/web/WebKit.h"
23 #include "third_party/WebKit/public/web/WebView.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
25 #include "v8/include/v8.h"
27 using blink::WebContextMenuData;
28 using blink::WebDragData;
29 using blink::WebDragOperationsMask;
30 using blink::WebFloatPoint;
31 using blink::WebFrame;
32 using blink::WebGestureEvent;
33 using blink::WebInputEvent;
34 using blink::WebKeyboardEvent;
35 using blink::WebMouseEvent;
36 using blink::WebMouseWheelEvent;
37 using blink::WebPoint;
38 using blink::WebString;
39 using blink::WebTouchEvent;
40 using blink::WebTouchPoint;
41 using blink::WebVector;
42 using blink::WebView;
44 namespace content {
46 namespace {
48 void InitMouseEvent(WebInputEvent::Type t,
49 WebMouseEvent::Button b,
50 const WebPoint& pos,
51 double time_stamp,
52 int click_count,
53 int modifiers,
54 WebMouseEvent* e) {
55 e->type = t;
56 e->button = b;
57 e->modifiers = modifiers;
58 e->x = pos.x;
59 e->y = pos.y;
60 e->globalX = pos.x;
61 e->globalY = pos.y;
62 e->timeStampSeconds = time_stamp;
63 e->clickCount = click_count;
66 int GetKeyModifier(const std::string& modifier_name) {
67 const char* characters = modifier_name.c_str();
68 if (!strcmp(characters, "ctrlKey")
69 #ifndef __APPLE__
70 || !strcmp(characters, "addSelectionKey")
71 #endif
72 ) {
73 return WebInputEvent::ControlKey;
74 } else if (!strcmp(characters, "shiftKey") ||
75 !strcmp(characters, "rangeSelectionKey")) {
76 return WebInputEvent::ShiftKey;
77 } else if (!strcmp(characters, "altKey")) {
78 return WebInputEvent::AltKey;
79 #ifdef __APPLE__
80 } else if (!strcmp(characters, "metaKey") ||
81 !strcmp(characters, "addSelectionKey")) {
82 return WebInputEvent::MetaKey;
83 #else
84 } else if (!strcmp(characters, "metaKey")) {
85 return WebInputEvent::MetaKey;
86 #endif
87 } else if (!strcmp(characters, "autoRepeat")) {
88 return WebInputEvent::IsAutoRepeat;
89 } else if (!strcmp(characters, "copyKey")) {
90 #ifdef __APPLE__
91 return WebInputEvent::AltKey;
92 #else
93 return WebInputEvent::ControlKey;
94 #endif
97 return 0;
100 int GetKeyModifiers(const std::vector<std::string>& modifier_names) {
101 int modifiers = 0;
102 for (std::vector<std::string>::const_iterator it = modifier_names.begin();
103 it != modifier_names.end(); ++it) {
104 modifiers |= GetKeyModifier(*it);
106 return modifiers;
109 int GetKeyModifiersFromV8(v8::Handle<v8::Value> value) {
110 std::vector<std::string> modifier_names;
111 if (value->IsString()) {
112 modifier_names.push_back(gin::V8ToString(value));
113 } else if (value->IsArray()) {
114 gin::Converter<std::vector<std::string> >::FromV8(
115 NULL, value, &modifier_names);
117 return GetKeyModifiers(modifier_names);
120 // Maximum distance (in space and time) for a mouse click to register as a
121 // double or triple click.
122 const double kMultipleClickTimeSec = 1;
123 const int kMultipleClickRadiusPixels = 5;
125 bool OutsideMultiClickRadius(const WebPoint& a, const WebPoint& b) {
126 return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) >
127 kMultipleClickRadiusPixels * kMultipleClickRadiusPixels;
130 // Because actual context menu is implemented by the browser side,
131 // this function does only what LayoutTests are expecting:
132 // - Many test checks the count of items. So returning non-zero value makes
133 // sense.
134 // - Some test compares the count before and after some action. So changing the
135 // count based on flags also makes sense. This function is doing such for some
136 // flags.
137 // - Some test even checks actual string content. So providing it would be also
138 // helpful.
139 std::vector<std::string> MakeMenuItemStringsFor(
140 WebContextMenuData* context_menu,
141 WebTestRunner::WebTestDelegate* delegate) {
142 // These constants are based on Safari's context menu because tests are made
143 // for it.
144 static const char* kNonEditableMenuStrings[] = {
145 "Back",
146 "Reload Page",
147 "Open in Dashbaord",
148 "<separator>",
149 "View Source",
150 "Save Page As",
151 "Print Page",
152 "Inspect Element",
155 static const char* kEditableMenuStrings[] = {
156 "Cut",
157 "Copy",
158 "<separator>",
159 "Paste",
160 "Spelling and Grammar",
161 "Substitutions, Transformations",
162 "Font",
163 "Speech",
164 "Paragraph Direction",
165 "<separator>",
169 // This is possible because mouse events are cancelleable.
170 if (!context_menu)
171 return std::vector<std::string>();
173 std::vector<std::string> strings;
175 if (context_menu->isEditable) {
176 for (const char** item = kEditableMenuStrings; *item; ++item) {
177 strings.push_back(*item);
179 WebVector<WebString> suggestions;
180 WebTestRunner::MockSpellCheck::fillSuggestionList(
181 context_menu->misspelledWord, &suggestions);
182 for (size_t i = 0; i < suggestions.size(); ++i) {
183 strings.push_back(suggestions[i].utf8());
185 } else {
186 for (const char** item = kNonEditableMenuStrings; *item; ++item) {
187 strings.push_back(*item);
191 return strings;
194 // How much we should scroll per event - the value here is chosen to match the
195 // WebKit impl and layout test results.
196 const float kScrollbarPixelsPerTick = 40.0f;
198 WebMouseEvent::Button GetButtonTypeFromButtonNumber(int button_code) {
199 if (!button_code)
200 return WebMouseEvent::ButtonLeft;
201 if (button_code == 2)
202 return WebMouseEvent::ButtonRight;
203 return WebMouseEvent::ButtonMiddle;
206 class MouseDownTask : public WebTestRunner::WebMethodTask<EventSender> {
207 public:
208 MouseDownTask(EventSender* obj, int button_number, int modifiers)
209 : WebMethodTask<EventSender>(obj),
210 button_number_(button_number),
211 modifiers_(modifiers) {}
213 virtual void runIfValid() OVERRIDE {
214 m_object->MouseDown(button_number_, modifiers_);
217 private:
218 int button_number_;
219 int modifiers_;
222 class MouseUpTask : public WebTestRunner::WebMethodTask<EventSender> {
223 public:
224 MouseUpTask(EventSender* obj, int button_number, int modifiers)
225 : WebMethodTask<EventSender>(obj),
226 button_number_(button_number),
227 modifiers_(modifiers) {}
229 virtual void runIfValid() OVERRIDE {
230 m_object->MouseUp(button_number_, modifiers_);
233 private:
234 int button_number_;
235 int modifiers_;
238 class KeyDownTask : public WebTestRunner::WebMethodTask<EventSender> {
239 public:
240 KeyDownTask(EventSender* obj,
241 const std::string code_str,
242 int modifiers,
243 KeyLocationCode location)
244 : WebMethodTask<EventSender>(obj),
245 code_str_(code_str),
246 modifiers_(modifiers),
247 location_(location) {}
249 virtual void runIfValid() OVERRIDE {
250 m_object->KeyDown(code_str_, modifiers_, location_);
253 private:
254 std::string code_str_;
255 int modifiers_;
256 KeyLocationCode location_;
259 bool NeedsShiftModifier(int keyCode) {
260 // If code is an uppercase letter, assign a SHIFT key to eventDown.modifier.
261 return (keyCode & 0xFF) >= 'A' && (keyCode & 0xFF) <= 'Z';
264 // Get the edit command corresponding to a keyboard event.
265 // Returns true if the specified event corresponds to an edit command, the name
266 // of the edit command will be stored in |*name|.
267 bool GetEditCommand(const WebKeyboardEvent& event, std::string* name) {
268 #if defined(OS_MACOSX)
269 // We only cares about Left,Right,Up,Down keys with Command or Command+Shift
270 // modifiers. These key events correspond to some special movement and
271 // selection editor commands. These keys will be marked as system key, which
272 // prevents them from being handled. Thus they must be handled specially.
273 if ((event.modifiers & ~WebKeyboardEvent::ShiftKey) !=
274 WebKeyboardEvent::MetaKey)
275 return false;
277 switch (event.windowsKeyCode) {
278 case ui::VKEY_LEFT:
279 *name = "MoveToBeginningOfLine";
280 break;
281 case ui::VKEY_RIGHT:
282 *name = "MoveToEndOfLine";
283 break;
284 case ui::VKEY_UP:
285 *name = "MoveToBeginningOfDocument";
286 break;
287 case ui::VKEY_DOWN:
288 *name = "MoveToEndOfDocument";
289 break;
290 default:
291 return false;
294 if (event.modifiers & WebKeyboardEvent::ShiftKey)
295 name->append("AndModifySelection");
297 return true;
298 #else
299 return false;
300 #endif
303 bool IsSystemKeyEvent(const WebKeyboardEvent& event) {
304 #if defined(OS_MACOSX)
305 return event.modifiers & WebInputEvent::MetaKey &&
306 event.windowsKeyCode != ui::VKEY_B &&
307 event.windowsKeyCode != ui::VKEY_I;
308 #else
309 return !!(event.modifiers & WebInputEvent::AltKey);
310 #endif
313 } // namespace
315 class EventSenderBindings : public gin::Wrappable<EventSenderBindings> {
316 public:
317 static gin::WrapperInfo kWrapperInfo;
319 static void Install(base::WeakPtr<EventSender> sender,
320 blink::WebFrame* frame);
322 private:
323 explicit EventSenderBindings(base::WeakPtr<EventSender> sender);
324 virtual ~EventSenderBindings();
326 // gin::Wrappable:
327 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
328 v8::Isolate* isolate) OVERRIDE;
330 // Bound methods:
331 void EnableDOMUIEventLogging();
332 void FireKeyboardEventsToElement();
333 void ClearKillRing();
334 std::vector<std::string> ContextClick();
335 void TextZoomIn();
336 void TextZoomOut();
337 void ZoomPageIn();
338 void ZoomPageOut();
339 void SetPageZoomFactor(gin::Arguments* args);
340 void SetPageScaleFactor(gin::Arguments* args);
341 void ClearTouchPoints();
342 void ReleaseTouchPoint(unsigned index);
343 void UpdateTouchPoint(unsigned index, double x, double y);
344 void CancelTouchPoint(unsigned index);
345 void SetTouchModifier(const std::string& key_name, bool set_mask);
346 void SetTouchCancelable(bool cancelable);
347 void DumpFilenameBeingDragged();
348 void GestureFlingCancel();
349 void GestureFlingStart(float x, float y, float velocity_x, float velocity_y);
350 void GestureScrollFirstPoint(int x, int y);
351 void TouchStart();
352 void TouchMove();
353 void TouchCancel();
354 void TouchEnd();
355 void LeapForward(int milliseconds);
356 void BeginDragWithFiles(const std::vector<std::string>& files);
357 void AddTouchPoint(gin::Arguments* args);
358 void MouseDragBegin();
359 void MouseDragEnd();
360 void MouseMomentumBegin();
361 void GestureScrollBegin(gin::Arguments* args);
362 void GestureScrollEnd(gin::Arguments* args);
363 void GestureScrollUpdate(gin::Arguments* args);
364 void GestureScrollUpdateWithoutPropagation(gin::Arguments* args);
365 void GestureTap(gin::Arguments* args);
366 void GestureTapDown(gin::Arguments* args);
367 void GestureShowPress(gin::Arguments* args);
368 void GestureTapCancel(gin::Arguments* args);
369 void GestureLongPress(gin::Arguments* args);
370 void GestureLongTap(gin::Arguments* args);
371 void GestureTwoFingerTap(gin::Arguments* args);
372 void ContinuousMouseScrollBy(gin::Arguments* args);
373 void MouseMoveTo(gin::Arguments* args);
374 void MouseScrollBy(gin::Arguments* args);
375 void MouseMomentumScrollBy(gin::Arguments* args);
376 void MouseMomentumEnd();
377 void ScheduleAsynchronousClick(gin::Arguments* args);
378 void ScheduleAsynchronousKeyDown(gin::Arguments* args);
379 void MouseDown(gin::Arguments* args);
380 void MouseUp(gin::Arguments* args);
381 void KeyDown(gin::Arguments* args);
383 // Binding properties:
384 bool ForceLayoutOnEvents() const;
385 void SetForceLayoutOnEvents(bool force);
386 bool IsDragMode() const;
387 void SetIsDragMode(bool drag_mode);
389 #if defined(OS_WIN)
390 int WmKeyDown() const;
391 void SetWmKeyDown(int key_down);
393 int WmKeyUp() const;
394 void SetWmKeyUp(int key_up);
396 int WmChar() const;
397 void SetWmChar(int wm_char);
399 int WmDeadChar() const;
400 void SetWmDeadChar(int dead_char);
402 int WmSysKeyDown() const;
403 void SetWmSysKeyDown(int key_down);
405 int WmSysKeyUp() const;
406 void SetWmSysKeyUp(int key_up);
408 int WmSysChar() const;
409 void SetWmSysChar(int sys_char);
411 int WmSysDeadChar() const;
412 void SetWmSysDeadChar(int sys_dead_char);
413 #endif
415 base::WeakPtr<EventSender> sender_;
417 DISALLOW_COPY_AND_ASSIGN(EventSenderBindings);
420 gin::WrapperInfo EventSenderBindings::kWrapperInfo = {gin::kEmbedderNativeGin};
422 EventSenderBindings::EventSenderBindings(base::WeakPtr<EventSender> sender)
423 : sender_(sender) {
426 EventSenderBindings::~EventSenderBindings() {}
428 // static
429 void EventSenderBindings::Install(base::WeakPtr<EventSender> sender,
430 WebFrame* frame) {
431 v8::Isolate* isolate = blink::mainThreadIsolate();
432 v8::HandleScope handle_scope(isolate);
433 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
434 if (context.IsEmpty())
435 return;
437 v8::Context::Scope context_scope(context);
439 gin::Handle<EventSenderBindings> bindings =
440 gin::CreateHandle(isolate, new EventSenderBindings(sender));
441 if (bindings.IsEmpty())
442 return;
443 v8::Handle<v8::Object> global = context->Global();
444 global->Set(gin::StringToV8(isolate, "eventSender"), bindings.ToV8());
447 gin::ObjectTemplateBuilder
448 EventSenderBindings::GetObjectTemplateBuilder(v8::Isolate* isolate) {
449 return gin::Wrappable<EventSenderBindings>::GetObjectTemplateBuilder(isolate)
450 .SetMethod("enableDOMUIEventLogging",
451 &EventSenderBindings::EnableDOMUIEventLogging)
452 .SetMethod("fireKeyboardEventsToElement",
453 &EventSenderBindings::FireKeyboardEventsToElement)
454 .SetMethod("clearKillRing", &EventSenderBindings::ClearKillRing)
455 .SetMethod("contextClick", &EventSenderBindings::ContextClick)
456 .SetMethod("textZoomIn", &EventSenderBindings::TextZoomIn)
457 .SetMethod("textZoomOut", &EventSenderBindings::TextZoomOut)
458 .SetMethod("zoomPageIn", &EventSenderBindings::ZoomPageIn)
459 .SetMethod("zoomPageOut", &EventSenderBindings::ZoomPageOut)
460 .SetMethod("setPageZoomFactor", &EventSenderBindings::SetPageZoomFactor)
461 .SetMethod("setPageScaleFactor", &EventSenderBindings::SetPageScaleFactor)
462 .SetMethod("clearTouchPoints", &EventSenderBindings::ClearTouchPoints)
463 .SetMethod("releaseTouchPoint", &EventSenderBindings::ReleaseTouchPoint)
464 .SetMethod("updateTouchPoint", &EventSenderBindings::UpdateTouchPoint)
465 .SetMethod("cancelTouchPoint", &EventSenderBindings::CancelTouchPoint)
466 .SetMethod("setTouchModifier", &EventSenderBindings::SetTouchModifier)
467 .SetMethod("setTouchCancelable", &EventSenderBindings::SetTouchCancelable)
468 .SetMethod("dumpFilenameBeingDragged",
469 &EventSenderBindings::DumpFilenameBeingDragged)
470 .SetMethod("gestureFlingCancel", &EventSenderBindings::GestureFlingCancel)
471 .SetMethod("gestureFlingStart", &EventSenderBindings::GestureFlingStart)
472 .SetMethod("gestureScrollFirstPoint",
473 &EventSenderBindings::GestureScrollFirstPoint)
474 .SetMethod("touchStart", &EventSenderBindings::TouchStart)
475 .SetMethod("touchMove", &EventSenderBindings::TouchMove)
476 .SetMethod("touchCancel", &EventSenderBindings::TouchCancel)
477 .SetMethod("touchEnd", &EventSenderBindings::TouchEnd)
478 .SetMethod("leapForward", &EventSenderBindings::LeapForward)
479 .SetMethod("beginDragWithFiles", &EventSenderBindings::BeginDragWithFiles)
480 .SetMethod("addTouchPoint", &EventSenderBindings::AddTouchPoint)
481 .SetMethod("mouseDragBegin", &EventSenderBindings::MouseDragBegin)
482 .SetMethod("mouseDragEnd", &EventSenderBindings::MouseDragEnd)
483 .SetMethod("mouseMomentumBegin", &EventSenderBindings::MouseMomentumBegin)
484 .SetMethod("gestureScrollBegin", &EventSenderBindings::GestureScrollBegin)
485 .SetMethod("gestureScrollEnd", &EventSenderBindings::GestureScrollEnd)
486 .SetMethod("gestureScrollUpdate",
487 &EventSenderBindings::GestureScrollUpdate)
488 .SetMethod("gestureScrollUpdateWithoutPropagation",
489 &EventSenderBindings::GestureScrollUpdateWithoutPropagation)
490 .SetMethod("gestureTap", &EventSenderBindings::GestureTap)
491 .SetMethod("gestureTapDown", &EventSenderBindings::GestureTapDown)
492 .SetMethod("gestureShowPress", &EventSenderBindings::GestureShowPress)
493 .SetMethod("gestureTapCancel", &EventSenderBindings::GestureTapCancel)
494 .SetMethod("gestureLongPress", &EventSenderBindings::GestureLongPress)
495 .SetMethod("gestureLongTap", &EventSenderBindings::GestureLongTap)
496 .SetMethod("gestureTwoFingerTap",
497 &EventSenderBindings::GestureTwoFingerTap)
498 .SetMethod("continuousMouseScrollBy",
499 &EventSenderBindings::ContinuousMouseScrollBy)
500 .SetMethod("keyDown", &EventSenderBindings::KeyDown)
501 .SetMethod("mouseDown", &EventSenderBindings::MouseDown)
502 .SetMethod("mouseMoveTo", &EventSenderBindings::MouseMoveTo)
503 .SetMethod("mouseScrollBy", &EventSenderBindings::MouseScrollBy)
504 .SetMethod("mouseUp", &EventSenderBindings::MouseUp)
505 .SetMethod("mouseMomentumScrollBy",
506 &EventSenderBindings::MouseMomentumScrollBy)
507 .SetMethod("mouseMomentumEnd", &EventSenderBindings::MouseMomentumEnd)
508 .SetMethod("scheduleAsynchronousClick",
509 &EventSenderBindings::ScheduleAsynchronousClick)
510 .SetMethod("scheduleAsynchronousKeyDown",
511 &EventSenderBindings::ScheduleAsynchronousKeyDown)
512 .SetProperty("forceLayoutOnEvents",
513 &EventSenderBindings::ForceLayoutOnEvents,
514 &EventSenderBindings::SetForceLayoutOnEvents)
515 .SetProperty("dragMode",
516 &EventSenderBindings::IsDragMode,
517 &EventSenderBindings::SetIsDragMode)
518 #if defined(OS_WIN)
519 .SetProperty("WM_KEYDOWN",
520 &EventSenderBindings::WmKeyDown,
521 &EventSenderBindings::SetWmKeyDown)
522 .SetProperty("WM_KEYUP",
523 &EventSenderBindings::WmKeyUp,
524 &EventSenderBindings::SetWmKeyUp)
525 .SetProperty("WM_CHAR",
526 &EventSenderBindings::WmChar,
527 &EventSenderBindings::SetWmChar)
528 .SetProperty("WM_DEADCHAR",
529 &EventSenderBindings::WmDeadChar,
530 &EventSenderBindings::SetWmDeadChar)
531 .SetProperty("WM_SYSKEYDOWN",
532 &EventSenderBindings::WmSysKeyDown,
533 &EventSenderBindings::SetWmSysKeyDown)
534 .SetProperty("WM_SYSKEYUP",
535 &EventSenderBindings::WmSysKeyUp,
536 &EventSenderBindings::SetWmSysKeyUp)
537 .SetProperty("WM_SYSCHAR",
538 &EventSenderBindings::WmSysChar,
539 &EventSenderBindings::SetWmSysChar)
540 .SetProperty("WM_SYSDEADCHAR",
541 &EventSenderBindings::WmSysDeadChar,
542 &EventSenderBindings::SetWmSysDeadChar);
543 #else
545 #endif
548 void EventSenderBindings::EnableDOMUIEventLogging() {
549 if (sender_)
550 sender_->EnableDOMUIEventLogging();
553 void EventSenderBindings::FireKeyboardEventsToElement() {
554 if (sender_)
555 sender_->FireKeyboardEventsToElement();
558 void EventSenderBindings::ClearKillRing() {
559 if (sender_)
560 sender_->ClearKillRing();
563 std::vector<std::string> EventSenderBindings::ContextClick() {
564 if (sender_)
565 return sender_->ContextClick();
566 return std::vector<std::string>();
569 void EventSenderBindings::TextZoomIn() {
570 if (sender_)
571 sender_->TextZoomIn();
574 void EventSenderBindings::TextZoomOut() {
575 if (sender_)
576 sender_->TextZoomOut();
579 void EventSenderBindings::ZoomPageIn() {
580 if (sender_)
581 sender_->ZoomPageIn();
584 void EventSenderBindings::ZoomPageOut() {
585 if (sender_)
586 sender_->ZoomPageOut();
589 void EventSenderBindings::SetPageZoomFactor(gin::Arguments* args) {
590 if (!sender_)
591 return;
592 double zoom_factor;
593 if (args->PeekNext().IsEmpty())
594 return;
595 args->GetNext(&zoom_factor);
596 sender_->SetPageZoomFactor(zoom_factor);
599 void EventSenderBindings::SetPageScaleFactor(gin::Arguments* args) {
600 if (!sender_)
601 return;
602 float scale_factor;
603 double x;
604 double y;
605 if (args->PeekNext().IsEmpty())
606 return;
607 args->GetNext(&scale_factor);
608 if (args->PeekNext().IsEmpty())
609 return;
610 args->GetNext(&x);
611 if (args->PeekNext().IsEmpty())
612 return;
613 args->GetNext(&y);
614 sender_->SetPageScaleFactor(scale_factor,
615 static_cast<int>(x), static_cast<int>(y));
618 void EventSenderBindings::ClearTouchPoints() {
619 if (sender_)
620 sender_->ClearTouchPoints();
623 void EventSenderBindings::ReleaseTouchPoint(unsigned index) {
624 if (sender_)
625 sender_->ReleaseTouchPoint(index);
628 void EventSenderBindings::UpdateTouchPoint(unsigned index, double x, double y) {
629 if (sender_)
630 sender_->UpdateTouchPoint(index, static_cast<int>(x), static_cast<int>(y));
633 void EventSenderBindings::CancelTouchPoint(unsigned index) {
634 if (sender_)
635 sender_->CancelTouchPoint(index);
638 void EventSenderBindings::SetTouchModifier(const std::string& key_name,
639 bool set_mask) {
640 if (sender_)
641 sender_->SetTouchModifier(key_name, set_mask);
644 void EventSenderBindings::SetTouchCancelable(bool cancelable) {
645 if (sender_)
646 sender_->SetTouchCancelable(cancelable);
649 void EventSenderBindings::DumpFilenameBeingDragged() {
650 if (sender_)
651 sender_->DumpFilenameBeingDragged();
654 void EventSenderBindings::GestureFlingCancel() {
655 if (sender_)
656 sender_->GestureFlingCancel();
659 void EventSenderBindings::GestureFlingStart(float x,
660 float y,
661 float velocity_x,
662 float velocity_y) {
663 if (sender_)
664 sender_->GestureFlingStart(x, y, velocity_x, velocity_y);
667 void EventSenderBindings::GestureScrollFirstPoint(int x, int y) {
668 if (sender_)
669 sender_->GestureScrollFirstPoint(x, y);
672 void EventSenderBindings::TouchStart() {
673 if (sender_)
674 sender_->TouchStart();
677 void EventSenderBindings::TouchMove() {
678 if (sender_)
679 sender_->TouchMove();
682 void EventSenderBindings::TouchCancel() {
683 if (sender_)
684 sender_->TouchCancel();
687 void EventSenderBindings::TouchEnd() {
688 if (sender_)
689 sender_->TouchEnd();
692 void EventSenderBindings::LeapForward(int milliseconds) {
693 if (sender_)
694 sender_->LeapForward(milliseconds);
697 void EventSenderBindings::BeginDragWithFiles(
698 const std::vector<std::string>& files) {
699 if (sender_)
700 sender_->BeginDragWithFiles(files);
703 void EventSenderBindings::AddTouchPoint(gin::Arguments* args) {
704 if (sender_)
705 sender_->AddTouchPoint(args);
708 void EventSenderBindings::MouseDragBegin() {
709 if (sender_)
710 sender_->MouseDragBegin();
713 void EventSenderBindings::MouseDragEnd() {
714 if (sender_)
715 sender_->MouseDragEnd();
718 void EventSenderBindings::MouseMomentumBegin() {
719 if (sender_)
720 sender_->MouseMomentumBegin();
723 void EventSenderBindings::GestureScrollBegin(gin::Arguments* args) {
724 if (sender_)
725 sender_->GestureScrollBegin(args);
728 void EventSenderBindings::GestureScrollEnd(gin::Arguments* args) {
729 if (sender_)
730 sender_->GestureScrollEnd(args);
733 void EventSenderBindings::GestureScrollUpdate(gin::Arguments* args) {
734 if (sender_)
735 sender_->GestureScrollUpdate(args);
738 void EventSenderBindings::GestureScrollUpdateWithoutPropagation(
739 gin::Arguments* args) {
740 if (sender_)
741 sender_->GestureScrollUpdateWithoutPropagation(args);
744 void EventSenderBindings::GestureTap(gin::Arguments* args) {
745 if (sender_)
746 sender_->GestureTap(args);
749 void EventSenderBindings::GestureTapDown(gin::Arguments* args) {
750 if (sender_)
751 sender_->GestureTapDown(args);
754 void EventSenderBindings::GestureShowPress(gin::Arguments* args) {
755 if (sender_)
756 sender_->GestureShowPress(args);
759 void EventSenderBindings::GestureTapCancel(gin::Arguments* args) {
760 if (sender_)
761 sender_->GestureTapCancel(args);
764 void EventSenderBindings::GestureLongPress(gin::Arguments* args) {
765 if (sender_)
766 sender_->GestureLongPress(args);
769 void EventSenderBindings::GestureLongTap(gin::Arguments* args) {
770 if (sender_)
771 sender_->GestureLongTap(args);
774 void EventSenderBindings::GestureTwoFingerTap(gin::Arguments* args) {
775 if (sender_)
776 sender_->GestureTwoFingerTap(args);
779 void EventSenderBindings::ContinuousMouseScrollBy(gin::Arguments* args) {
780 if (sender_)
781 sender_->ContinuousMouseScrollBy(args);
784 void EventSenderBindings::MouseMoveTo(gin::Arguments* args) {
785 if (sender_)
786 sender_->MouseMoveTo(args);
789 void EventSenderBindings::MouseScrollBy(gin::Arguments* args) {
790 if (sender_)
791 sender_->MouseScrollBy(args);
794 void EventSenderBindings::MouseMomentumScrollBy(gin::Arguments* args) {
795 if (sender_)
796 sender_->MouseMomentumScrollBy(args);
799 void EventSenderBindings::MouseMomentumEnd() {
800 if (sender_)
801 sender_->MouseMomentumEnd();
804 void EventSenderBindings::ScheduleAsynchronousClick(gin::Arguments* args) {
805 if (!sender_)
806 return;
808 int button_number = 0;
809 int modifiers = 0;
810 if (!args->PeekNext().IsEmpty()) {
811 args->GetNext(&button_number);
812 if (!args->PeekNext().IsEmpty())
813 modifiers = GetKeyModifiersFromV8(args->PeekNext());
815 sender_->ScheduleAsynchronousClick(button_number, modifiers);
818 void EventSenderBindings::ScheduleAsynchronousKeyDown(gin::Arguments* args) {
819 if (!sender_)
820 return;
822 std::string code_str;
823 int modifiers = 0;
824 int location = DOMKeyLocationStandard;
825 args->GetNext(&code_str);
826 if (!args->PeekNext().IsEmpty()) {
827 v8::Handle<v8::Value> value;
828 args->GetNext(&value);
829 modifiers = GetKeyModifiersFromV8(value);
830 if (!args->PeekNext().IsEmpty())
831 args->GetNext(&location);
833 sender_->ScheduleAsynchronousKeyDown(code_str, modifiers,
834 static_cast<KeyLocationCode>(location));
837 void EventSenderBindings::MouseDown(gin::Arguments* args) {
838 if (!sender_)
839 return;
841 int button_number = 0;
842 int modifiers = 0;
843 if (!args->PeekNext().IsEmpty()) {
844 args->GetNext(&button_number);
845 if (!args->PeekNext().IsEmpty())
846 modifiers = GetKeyModifiersFromV8(args->PeekNext());
848 sender_->MouseDown(button_number, modifiers);
851 void EventSenderBindings::MouseUp(gin::Arguments* args) {
852 if (!sender_)
853 return;
855 int button_number = 0;
856 int modifiers = 0;
857 if (!args->PeekNext().IsEmpty()) {
858 args->GetNext(&button_number);
859 if (!args->PeekNext().IsEmpty())
860 modifiers = GetKeyModifiersFromV8(args->PeekNext());
862 sender_->MouseUp(button_number, modifiers);
865 void EventSenderBindings::KeyDown(gin::Arguments* args) {
866 if (!sender_)
867 return;
869 std::string code_str;
870 int modifiers = 0;
871 int location = DOMKeyLocationStandard;
872 args->GetNext(&code_str);
873 if (!args->PeekNext().IsEmpty()) {
874 v8::Handle<v8::Value> value;
875 args->GetNext(&value);
876 modifiers = GetKeyModifiersFromV8(value);
877 if (!args->PeekNext().IsEmpty())
878 args->GetNext(&location);
880 sender_->KeyDown(code_str, modifiers, static_cast<KeyLocationCode>(location));
883 bool EventSenderBindings::ForceLayoutOnEvents() const {
884 if (sender_)
885 return sender_->force_layout_on_events();
886 return false;
889 void EventSenderBindings::SetForceLayoutOnEvents(bool force) {
890 if (sender_)
891 sender_->set_force_layout_on_events(force);
894 bool EventSenderBindings::IsDragMode() const {
895 if (sender_)
896 return sender_->is_drag_mode();
897 return true;
900 void EventSenderBindings::SetIsDragMode(bool drag_mode) {
901 if (sender_)
902 sender_->set_is_drag_mode(drag_mode);
905 #if defined(OS_WIN)
906 int EventSenderBindings::WmKeyDown() const {
907 if (sender_)
908 return sender_->wm_key_down();
909 return 0;
912 void EventSenderBindings::SetWmKeyDown(int key_down) {
913 if (sender_)
914 sender_->set_wm_key_down(key_down);
917 int EventSenderBindings::WmKeyUp() const {
918 if (sender_)
919 return sender_->wm_key_up();
920 return 0;
923 void EventSenderBindings::SetWmKeyUp(int key_up) {
924 if (sender_)
925 sender_->set_wm_key_up(key_up);
928 int EventSenderBindings::WmChar() const {
929 if (sender_)
930 return sender_->wm_char();
931 return 0;
934 void EventSenderBindings::SetWmChar(int wm_char) {
935 if (sender_)
936 sender_->set_wm_char(wm_char);
939 int EventSenderBindings::WmDeadChar() const {
940 if (sender_)
941 return sender_->wm_dead_char();
942 return 0;
945 void EventSenderBindings::SetWmDeadChar(int dead_char) {
946 if (sender_)
947 sender_->set_wm_dead_char(dead_char);
950 int EventSenderBindings::WmSysKeyDown() const {
951 if (sender_)
952 return sender_->wm_sys_key_down();
953 return 0;
956 void EventSenderBindings::SetWmSysKeyDown(int key_down) {
957 if (sender_)
958 sender_->set_wm_sys_key_down(key_down);
961 int EventSenderBindings::WmSysKeyUp() const {
962 if (sender_)
963 return sender_->wm_sys_key_up();
964 return 0;
967 void EventSenderBindings::SetWmSysKeyUp(int key_up) {
968 if (sender_)
969 sender_->set_wm_sys_key_up(key_up);
972 int EventSenderBindings::WmSysChar() const {
973 if (sender_)
974 return sender_->wm_sys_char();
975 return 0;
978 void EventSenderBindings::SetWmSysChar(int sys_char) {
979 if (sender_)
980 sender_->set_wm_sys_char(sys_char);
983 int EventSenderBindings::WmSysDeadChar() const {
984 if (sender_)
985 return sender_->wm_sys_dead_char();
986 return 0;
989 void EventSenderBindings::SetWmSysDeadChar(int sys_dead_char) {
990 if (sender_)
991 sender_->set_wm_sys_dead_char(sys_dead_char);
993 #endif
995 // EventSender -----------------------------------------------------------------
997 WebMouseEvent::Button EventSender::pressed_button_ = WebMouseEvent::ButtonNone;
999 WebPoint EventSender::last_mouse_pos_;
1001 WebMouseEvent::Button EventSender::last_button_type_ =
1002 WebMouseEvent::ButtonNone;
1004 EventSender::SavedEvent::SavedEvent()
1005 : type(TYPE_UNSPECIFIED),
1006 button_type(WebMouseEvent::ButtonNone),
1007 milliseconds(0),
1008 modifiers(0) {}
1010 EventSender::EventSender(WebTestRunner::TestInterfaces* interfaces)
1011 : interfaces_(interfaces),
1012 delegate_(NULL),
1013 view_(NULL),
1014 force_layout_on_events_(false),
1015 is_drag_mode_(true),
1016 touch_modifiers_(0),
1017 touch_cancelable_(true),
1018 replaying_saved_events_(false),
1019 current_drag_effects_allowed_(blink::WebDragOperationNone),
1020 last_click_time_sec_(0),
1021 current_drag_effect_(blink::WebDragOperationNone),
1022 time_offset_ms_(0),
1023 click_count_(0),
1024 #if defined(OS_WIN)
1025 wm_key_down_(0),
1026 wm_key_up_(0),
1027 wm_char_(0),
1028 wm_dead_char_(0),
1029 wm_sys_key_down_(0),
1030 wm_sys_key_up_(0),
1031 wm_sys_char_(0),
1032 wm_sys_dead_char_(0),
1033 #endif
1034 weak_factory_(this) {}
1036 EventSender::~EventSender() {}
1038 void EventSender::Reset() {
1039 DCHECK(current_drag_data_.isNull());
1040 current_drag_data_.reset();
1041 current_drag_effect_ = blink::WebDragOperationNone;
1042 current_drag_effects_allowed_ = blink::WebDragOperationNone;
1043 if (view_ && pressed_button_ != WebMouseEvent::ButtonNone)
1044 view_->mouseCaptureLost();
1045 pressed_button_ = WebMouseEvent::ButtonNone;
1046 is_drag_mode_ = true;
1047 force_layout_on_events_ = true;
1049 #if defined(OS_WIN)
1050 wm_key_down_ = WM_KEYDOWN;
1051 wm_key_up_ = WM_KEYUP;
1052 wm_char_ = WM_CHAR;
1053 wm_dead_char_ = WM_DEADCHAR;
1054 wm_sys_key_down_ = WM_SYSKEYDOWN;
1055 wm_sys_key_up_ = WM_SYSKEYUP;
1056 wm_sys_char_ = WM_SYSCHAR;
1057 wm_sys_dead_char_ = WM_SYSDEADCHAR;
1058 #endif
1060 last_mouse_pos_ = WebPoint(0, 0);
1061 last_click_time_sec_ = 0;
1062 last_click_pos_ = WebPoint(0, 0);
1063 last_button_type_ = WebMouseEvent::ButtonNone;
1064 touch_points_.clear();
1065 last_context_menu_data_.reset();
1066 task_list_.revokeAll();
1067 current_gesture_location_ = WebPoint(0, 0);
1068 mouse_event_queue_.clear();
1070 time_offset_ms_ = 0;
1071 click_count_ = 0;
1073 touch_modifiers_ = 0;
1074 touch_cancelable_ = true;
1075 touch_points_.clear();
1078 void EventSender::Install(WebFrame* frame) {
1079 EventSenderBindings::Install(weak_factory_.GetWeakPtr(), frame);
1082 void EventSender::SetDelegate(WebTestRunner::WebTestDelegate* delegate) {
1083 delegate_ = delegate;
1086 void EventSender::SetWebView(WebView* view) {
1087 view_ = view;
1090 void EventSender::SetContextMenuData(const WebContextMenuData& data) {
1091 last_context_menu_data_.reset(new WebContextMenuData(data));
1094 void EventSender::DoDragDrop(const WebDragData& drag_data,
1095 WebDragOperationsMask mask) {
1096 WebMouseEvent event;
1097 InitMouseEvent(WebInputEvent::MouseDown,
1098 pressed_button_,
1099 last_mouse_pos_,
1100 GetCurrentEventTimeSec(),
1101 click_count_,
1103 &event);
1104 WebPoint client_point(event.x, event.y);
1105 WebPoint screen_point(event.globalX, event.globalY);
1106 current_drag_data_ = drag_data;
1107 current_drag_effects_allowed_ = mask;
1108 current_drag_effect_ = view_->dragTargetDragEnter(
1109 drag_data, client_point, screen_point, current_drag_effects_allowed_, 0);
1111 // Finish processing events.
1112 ReplaySavedEvents();
1115 void EventSender::MouseDown(int button_number, int modifiers) {
1116 if (force_layout_on_events_)
1117 view_->layout();
1119 DCHECK_NE(-1, button_number);
1121 WebMouseEvent::Button button_type =
1122 GetButtonTypeFromButtonNumber(button_number);
1124 UpdateClickCountForButton(button_type);
1126 pressed_button_ = button_type;
1128 WebMouseEvent event;
1129 InitMouseEvent(WebInputEvent::MouseDown,
1130 button_type,
1131 last_mouse_pos_,
1132 GetCurrentEventTimeSec(),
1133 click_count_,
1134 modifiers,
1135 &event);
1136 view_->handleInputEvent(event);
1139 void EventSender::MouseUp(int button_number, int modifiers) {
1140 if (force_layout_on_events_)
1141 view_->layout();
1143 DCHECK_NE(-1, button_number);
1145 WebMouseEvent::Button button_type =
1146 GetButtonTypeFromButtonNumber(button_number);
1148 if (is_drag_mode_ && !replaying_saved_events_) {
1149 SavedEvent saved_event;
1150 saved_event.type = SavedEvent::TYPE_MOUSE_UP;
1151 saved_event.button_type = button_type;
1152 saved_event.modifiers = modifiers;
1153 mouse_event_queue_.push_back(saved_event);
1154 ReplaySavedEvents();
1155 } else {
1156 WebMouseEvent event;
1157 InitMouseEvent(WebInputEvent::MouseUp,
1158 button_type,
1159 last_mouse_pos_,
1160 GetCurrentEventTimeSec(),
1161 click_count_,
1162 modifiers,
1163 &event);
1164 DoMouseUp(event);
1168 void EventSender::KeyDown(const std::string& code_str,
1169 int modifiers,
1170 KeyLocationCode location) {
1171 // FIXME: I'm not exactly sure how we should convert the string to a key
1172 // event. This seems to work in the cases I tested.
1173 // FIXME: Should we also generate a KEY_UP?
1175 bool generate_char = false;
1177 // Convert \n -> VK_RETURN. Some layout tests use \n to mean "Enter", when
1178 // Windows uses \r for "Enter".
1179 int code = 0;
1180 int text = 0;
1181 bool needs_shift_key_modifier = false;
1183 if ("\n" == code_str) {
1184 generate_char = true;
1185 text = code = ui::VKEY_RETURN;
1186 } else if ("rightArrow" == code_str) {
1187 code = ui::VKEY_RIGHT;
1188 } else if ("downArrow" == code_str) {
1189 code = ui::VKEY_DOWN;
1190 } else if ("leftArrow" == code_str) {
1191 code = ui::VKEY_LEFT;
1192 } else if ("upArrow" == code_str) {
1193 code = ui::VKEY_UP;
1194 } else if ("insert" == code_str) {
1195 code = ui::VKEY_INSERT;
1196 } else if ("delete" == code_str) {
1197 code = ui::VKEY_DELETE;
1198 } else if ("pageUp" == code_str) {
1199 code = ui::VKEY_PRIOR;
1200 } else if ("pageDown" == code_str) {
1201 code = ui::VKEY_NEXT;
1202 } else if ("home" == code_str) {
1203 code = ui::VKEY_HOME;
1204 } else if ("end" == code_str) {
1205 code = ui::VKEY_END;
1206 } else if ("printScreen" == code_str) {
1207 code = ui::VKEY_SNAPSHOT;
1208 } else if ("menu" == code_str) {
1209 code = ui::VKEY_APPS;
1210 } else if ("leftControl" == code_str) {
1211 code = ui::VKEY_LCONTROL;
1212 } else if ("rightControl" == code_str) {
1213 code = ui::VKEY_RCONTROL;
1214 } else if ("leftShift" == code_str) {
1215 code = ui::VKEY_LSHIFT;
1216 } else if ("rightShift" == code_str) {
1217 code = ui::VKEY_RSHIFT;
1218 } else if ("leftAlt" == code_str) {
1219 code = ui::VKEY_LMENU;
1220 } else if ("rightAlt" == code_str) {
1221 code = ui::VKEY_RMENU;
1222 } else if ("numLock" == code_str) {
1223 code = ui::VKEY_NUMLOCK;
1224 } else {
1225 // Compare the input string with the function-key names defined by the
1226 // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key
1227 // name, set its key code.
1228 for (int i = 1; i <= 24; ++i) {
1229 std::string function_key_name = base::StringPrintf("F%d", i);
1230 if (function_key_name == code_str) {
1231 code = ui::VKEY_F1 + (i - 1);
1232 break;
1235 if (!code) {
1236 WebString web_code_str =
1237 WebString::fromUTF8(code_str.data(), code_str.size());
1238 DCHECK_EQ(1u, web_code_str.length());
1239 text = code = web_code_str.at(0);
1240 needs_shift_key_modifier = NeedsShiftModifier(code);
1241 if ((code & 0xFF) >= 'a' && (code & 0xFF) <= 'z')
1242 code -= 'a' - 'A';
1243 generate_char = true;
1246 if ("(" == code_str) {
1247 code = '9';
1248 needs_shift_key_modifier = true;
1252 // For one generated keyboard event, we need to generate a keyDown/keyUp
1253 // pair;
1254 // On Windows, we might also need to generate a char event to mimic the
1255 // Windows event flow; on other platforms we create a merged event and test
1256 // the event flow that that platform provides.
1257 WebKeyboardEvent event_down;
1258 event_down.type = WebInputEvent::RawKeyDown;
1259 event_down.modifiers = modifiers;
1260 event_down.windowsKeyCode = code;
1262 if (generate_char) {
1263 event_down.text[0] = text;
1264 event_down.unmodifiedText[0] = text;
1267 event_down.setKeyIdentifierFromWindowsKeyCode();
1269 if (event_down.modifiers != 0)
1270 event_down.isSystemKey = IsSystemKeyEvent(event_down);
1272 if (needs_shift_key_modifier)
1273 event_down.modifiers |= WebInputEvent::ShiftKey;
1275 // See if KeyLocation argument is given.
1276 if (location == DOMKeyLocationNumpad)
1277 event_down.modifiers |= WebInputEvent::IsKeyPad;
1279 WebKeyboardEvent event_up;
1280 event_up = event_down;
1281 event_up.type = WebInputEvent::KeyUp;
1282 // EventSender.m forces a layout here, with at least one
1283 // test (fast/forms/focus-control-to-page.html) relying on this.
1284 if (force_layout_on_events_)
1285 view_->layout();
1287 // In the browser, if a keyboard event corresponds to an editor command,
1288 // the command will be dispatched to the renderer just before dispatching
1289 // the keyboard event, and then it will be executed in the
1290 // RenderView::handleCurrentKeyboardEvent() method.
1291 // We just simulate the same behavior here.
1292 std::string edit_command;
1293 if (GetEditCommand(event_down, &edit_command))
1294 delegate_->setEditCommand(edit_command, "");
1296 view_->handleInputEvent(event_down);
1298 if (code == ui::VKEY_ESCAPE && !current_drag_data_.isNull()) {
1299 WebMouseEvent event;
1300 InitMouseEvent(WebInputEvent::MouseDown,
1301 pressed_button_,
1302 last_mouse_pos_,
1303 GetCurrentEventTimeSec(),
1304 click_count_,
1306 &event);
1307 FinishDragAndDrop(event, blink::WebDragOperationNone);
1310 delegate_->clearEditCommand();
1312 if (generate_char) {
1313 WebKeyboardEvent event_char = event_up;
1314 event_char.type = WebInputEvent::Char;
1315 event_char.keyIdentifier[0] = '\0';
1316 view_->handleInputEvent(event_char);
1319 view_->handleInputEvent(event_up);
1322 void EventSender::EnableDOMUIEventLogging() {}
1324 void EventSender::FireKeyboardEventsToElement() {}
1326 void EventSender::ClearKillRing() {}
1328 std::vector<std::string> EventSender::ContextClick() {
1329 if (force_layout_on_events_) {
1330 view_->layout();
1333 UpdateClickCountForButton(WebMouseEvent::ButtonRight);
1335 // Clears last context menu data because we need to know if the context menu
1336 // be requested after following mouse events.
1337 last_context_menu_data_.reset();
1339 // Generate right mouse down and up.
1340 WebMouseEvent event;
1341 // This is a hack to work around only allowing a single pressed button since
1342 // we want to test the case where both the left and right mouse buttons are
1343 // pressed.
1344 if (pressed_button_ == WebMouseEvent::ButtonNone) {
1345 pressed_button_ = WebMouseEvent::ButtonRight;
1347 InitMouseEvent(WebInputEvent::MouseDown,
1348 WebMouseEvent::ButtonRight,
1349 last_mouse_pos_,
1350 GetCurrentEventTimeSec(),
1351 click_count_,
1353 &event);
1354 view_->handleInputEvent(event);
1356 #if defined(OS_WIN)
1357 InitMouseEvent(WebInputEvent::MouseUp,
1358 WebMouseEvent::ButtonRight,
1359 last_mouse_pos_,
1360 GetCurrentEventTimeSec(),
1361 click_count_,
1363 &event);
1364 view_->handleInputEvent(event);
1366 pressed_button_= WebMouseEvent::ButtonNone;
1367 #endif
1369 std::vector<std::string> menu_items = MakeMenuItemStringsFor(last_context_menu_data_.get(), delegate_);
1370 last_context_menu_data_.reset();
1371 return menu_items;
1374 void EventSender::TextZoomIn() {
1375 view_->setTextZoomFactor(view_->textZoomFactor() * 1.2f);
1378 void EventSender::TextZoomOut() {
1379 view_->setTextZoomFactor(view_->textZoomFactor() / 1.2f);
1382 void EventSender::ZoomPageIn() {
1383 const std::vector<WebTestProxyBase*>& window_list = interfaces_->windowList();
1385 for (size_t i = 0; i < window_list.size(); ++i) {
1386 window_list.at(i)->webView()->setZoomLevel(
1387 window_list.at(i)->webView()->zoomLevel() + 1);
1391 void EventSender::ZoomPageOut() {
1392 const std::vector<WebTestProxyBase*>& window_list = interfaces_->windowList();
1394 for (size_t i = 0; i < window_list.size(); ++i) {
1395 window_list.at(i)->webView()->setZoomLevel(
1396 window_list.at(i)->webView()->zoomLevel() - 1);
1400 void EventSender::SetPageZoomFactor(double zoom_factor) {
1401 const std::vector<WebTestProxyBase*>& window_list = interfaces_->windowList();
1403 for (size_t i = 0; i < window_list.size(); ++i) {
1404 window_list.at(i)->webView()->setZoomLevel(
1405 content::ZoomFactorToZoomLevel(zoom_factor));
1409 void EventSender::SetPageScaleFactor(float scale_factor, int x, int y) {
1410 view_->setPageScaleFactorLimits(scale_factor, scale_factor);
1411 view_->setPageScaleFactor(scale_factor, WebPoint(x, y));
1414 void EventSender::ClearTouchPoints() {
1415 touch_points_.clear();
1418 void EventSender::ThrowTouchPointError() {
1419 v8::Isolate* isolate = blink::mainThreadIsolate();
1420 isolate->ThrowException(v8::Exception::TypeError(
1421 gin::StringToV8(isolate, "Invalid touch point.")));
1424 void EventSender::ReleaseTouchPoint(unsigned index) {
1425 if (index >= touch_points_.size()) {
1426 ThrowTouchPointError();
1427 return;
1430 WebTouchPoint* touch_point = &touch_points_[index];
1431 touch_point->state = WebTouchPoint::StateReleased;
1434 void EventSender::UpdateTouchPoint(unsigned index, int x, int y) {
1435 if (index >= touch_points_.size()) {
1436 ThrowTouchPointError();
1437 return;
1440 WebTouchPoint* touch_point = &touch_points_[index];
1441 touch_point->state = WebTouchPoint::StateMoved;
1442 touch_point->position = WebFloatPoint(x, y);
1443 touch_point->screenPosition = touch_point->position;
1446 void EventSender::CancelTouchPoint(unsigned index) {
1447 if (index >= touch_points_.size()) {
1448 ThrowTouchPointError();
1449 return;
1452 WebTouchPoint* touch_point = &touch_points_[index];
1453 touch_point->state = WebTouchPoint::StateCancelled;
1456 void EventSender::SetTouchModifier(const std::string& key_name,
1457 bool set_mask) {
1458 int mask = 0;
1459 if (key_name == "shift")
1460 mask = WebInputEvent::ShiftKey;
1461 else if (key_name == "alt")
1462 mask = WebInputEvent::AltKey;
1463 else if (key_name == "ctrl")
1464 mask = WebInputEvent::ControlKey;
1465 else if (key_name == "meta")
1466 mask = WebInputEvent::MetaKey;
1468 if (set_mask)
1469 touch_modifiers_ |= mask;
1470 else
1471 touch_modifiers_ &= ~mask;
1474 void EventSender::SetTouchCancelable(bool cancelable) {
1475 touch_cancelable_ = cancelable;
1478 void EventSender::DumpFilenameBeingDragged() {
1479 WebString filename;
1480 WebVector<WebDragData::Item> items = current_drag_data_.items();
1481 for (size_t i = 0; i < items.size(); ++i) {
1482 if (items[i].storageType == WebDragData::Item::StorageTypeBinaryData) {
1483 filename = items[i].title;
1484 break;
1487 delegate_->printMessage(std::string("Filename being dragged: ") +
1488 filename.utf8().data() + "\n");
1491 void EventSender::GestureFlingCancel() {
1492 WebGestureEvent event;
1493 event.type = WebInputEvent::GestureFlingCancel;
1494 event.timeStampSeconds = GetCurrentEventTimeSec();
1496 if (force_layout_on_events_)
1497 view_->layout();
1499 view_->handleInputEvent(event);
1502 void EventSender::GestureFlingStart(float x,
1503 float y,
1504 float velocity_x,
1505 float velocity_y) {
1506 WebGestureEvent event;
1507 event.type = WebInputEvent::GestureFlingStart;
1509 event.x = x;
1510 event.y = y;
1511 event.globalX = event.x;
1512 event.globalY = event.y;
1514 event.data.flingStart.velocityX = velocity_x;
1515 event.data.flingStart.velocityY = velocity_y;
1516 event.timeStampSeconds = GetCurrentEventTimeSec();
1518 if (force_layout_on_events_)
1519 view_->layout();
1521 view_->handleInputEvent(event);
1524 void EventSender::GestureScrollFirstPoint(int x, int y) {
1525 current_gesture_location_ = WebPoint(x, y);
1528 void EventSender::TouchStart() {
1529 SendCurrentTouchEvent(WebInputEvent::TouchStart);
1532 void EventSender::TouchMove() {
1533 SendCurrentTouchEvent(WebInputEvent::TouchMove);
1536 void EventSender::TouchCancel() {
1537 SendCurrentTouchEvent(WebInputEvent::TouchCancel);
1540 void EventSender::TouchEnd() {
1541 SendCurrentTouchEvent(WebInputEvent::TouchEnd);
1544 void EventSender::LeapForward(int milliseconds) {
1545 if (is_drag_mode_ && pressed_button_ == WebMouseEvent::ButtonLeft &&
1546 !replaying_saved_events_) {
1547 SavedEvent saved_event;
1548 saved_event.type = SavedEvent::TYPE_LEAP_FORWARD;
1549 saved_event.milliseconds = milliseconds;
1550 mouse_event_queue_.push_back(saved_event);
1551 } else {
1552 DoLeapForward(milliseconds);
1556 void EventSender::BeginDragWithFiles(const std::vector<std::string>& files) {
1557 current_drag_data_.initialize();
1558 WebVector<WebString> absolute_filenames(files.size());
1559 for (size_t i = 0; i < files.size(); ++i) {
1560 WebDragData::Item item;
1561 item.storageType = WebDragData::Item::StorageTypeFilename;
1562 item.filenameData = delegate_->getAbsoluteWebStringFromUTF8Path(files[i]);
1563 current_drag_data_.addItem(item);
1564 absolute_filenames[i] = item.filenameData;
1566 current_drag_data_.setFilesystemId(
1567 delegate_->registerIsolatedFileSystem(absolute_filenames));
1568 current_drag_effects_allowed_ = blink::WebDragOperationCopy;
1570 // Provide a drag source.
1571 view_->dragTargetDragEnter(current_drag_data_,
1572 last_mouse_pos_,
1573 last_mouse_pos_,
1574 current_drag_effects_allowed_,
1576 // |is_drag_mode_| saves events and then replays them later. We don't
1577 // need/want that.
1578 is_drag_mode_ = false;
1580 // Make the rest of eventSender think a drag is in progress.
1581 pressed_button_ = WebMouseEvent::ButtonLeft;
1584 void EventSender::AddTouchPoint(gin::Arguments* args) {
1585 double x;
1586 double y;
1587 args->GetNext(&x);
1588 args->GetNext(&y);
1590 WebTouchPoint touch_point;
1591 touch_point.state = WebTouchPoint::StatePressed;
1592 touch_point.position = WebFloatPoint(static_cast<int>(x),
1593 static_cast<int>(y));
1594 touch_point.screenPosition = touch_point.position;
1596 if (!args->PeekNext().IsEmpty()) {
1597 double radius_x;
1598 if (!args->GetNext(&radius_x)) {
1599 args->ThrowError();
1600 return;
1603 double radius_y = radius_x;
1604 if (!args->PeekNext().IsEmpty()) {
1605 if (!args->GetNext(&radius_y)) {
1606 args->ThrowError();
1607 return;
1611 touch_point.radiusX = static_cast<int>(radius_x);
1612 touch_point.radiusY = static_cast<int>(radius_y);
1615 int lowest_id = 0;
1616 for (size_t i = 0; i < touch_points_.size(); i++) {
1617 if (touch_points_[i].id == lowest_id)
1618 lowest_id++;
1620 touch_point.id = lowest_id;
1621 touch_points_.push_back(touch_point);
1624 void EventSender::MouseDragBegin() {
1625 WebMouseWheelEvent event;
1626 InitMouseEvent(WebInputEvent::MouseWheel,
1627 WebMouseEvent::ButtonNone,
1628 last_mouse_pos_,
1629 GetCurrentEventTimeSec(),
1630 click_count_,
1632 &event);
1633 event.phase = WebMouseWheelEvent::PhaseBegan;
1634 event.hasPreciseScrollingDeltas = true;
1635 view_->handleInputEvent(event);
1638 void EventSender::MouseDragEnd() {
1639 WebMouseWheelEvent event;
1640 InitMouseEvent(WebInputEvent::MouseWheel,
1641 WebMouseEvent::ButtonNone,
1642 last_mouse_pos_,
1643 GetCurrentEventTimeSec(),
1644 click_count_,
1646 &event);
1647 event.phase = WebMouseWheelEvent::PhaseEnded;
1648 event.hasPreciseScrollingDeltas = true;
1649 view_->handleInputEvent(event);
1652 void EventSender::MouseMomentumBegin() {
1653 WebMouseWheelEvent event;
1654 InitMouseEvent(WebInputEvent::MouseWheel,
1655 WebMouseEvent::ButtonNone,
1656 last_mouse_pos_,
1657 GetCurrentEventTimeSec(),
1658 click_count_,
1660 &event);
1661 event.momentumPhase = WebMouseWheelEvent::PhaseBegan;
1662 event.hasPreciseScrollingDeltas = true;
1663 view_->handleInputEvent(event);
1666 void EventSender::GestureScrollBegin(gin::Arguments* args) {
1667 GestureEvent(WebInputEvent::GestureScrollBegin, args);
1670 void EventSender::GestureScrollEnd(gin::Arguments* args) {
1671 GestureEvent(WebInputEvent::GestureScrollEnd, args);
1674 void EventSender::GestureScrollUpdate(gin::Arguments* args) {
1675 GestureEvent(WebInputEvent::GestureScrollUpdate, args);
1678 void EventSender::GestureScrollUpdateWithoutPropagation(gin::Arguments* args) {
1679 GestureEvent(WebInputEvent::GestureScrollUpdateWithoutPropagation, args);
1682 void EventSender::GestureTap(gin::Arguments* args) {
1683 GestureEvent(WebInputEvent::GestureTap, args);
1686 void EventSender::GestureTapDown(gin::Arguments* args) {
1687 GestureEvent(WebInputEvent::GestureTapDown, args);
1690 void EventSender::GestureShowPress(gin::Arguments* args) {
1691 GestureEvent(WebInputEvent::GestureShowPress, args);
1694 void EventSender::GestureTapCancel(gin::Arguments* args) {
1695 GestureEvent(WebInputEvent::GestureTapCancel, args);
1698 void EventSender::GestureLongPress(gin::Arguments* args) {
1699 GestureEvent(WebInputEvent::GestureLongPress, args);
1702 void EventSender::GestureLongTap(gin::Arguments* args) {
1703 GestureEvent(WebInputEvent::GestureLongTap, args);
1706 void EventSender::GestureTwoFingerTap(gin::Arguments* args) {
1707 GestureEvent(WebInputEvent::GestureTwoFingerTap, args);
1710 void EventSender::ContinuousMouseScrollBy(gin::Arguments* args) {
1711 WebMouseWheelEvent event;
1712 InitMouseWheelEvent(args, true, &event);
1713 view_->handleInputEvent(event);
1716 void EventSender::MouseMoveTo(gin::Arguments* args) {
1717 if (force_layout_on_events_)
1718 view_->layout();
1720 double x;
1721 double y;
1722 args->GetNext(&x);
1723 args->GetNext(&y);
1724 WebPoint mouse_pos(static_cast<int>(x), static_cast<int>(y));
1726 int modifiers = 0;
1727 if (!args->PeekNext().IsEmpty())
1728 modifiers = GetKeyModifiersFromV8(args->PeekNext());
1730 if (is_drag_mode_ && pressed_button_ == WebMouseEvent::ButtonLeft &&
1731 !replaying_saved_events_) {
1732 SavedEvent saved_event;
1733 saved_event.type = SavedEvent::TYPE_MOUSE_MOVE;
1734 saved_event.pos = mouse_pos;
1735 saved_event.modifiers = modifiers;
1736 mouse_event_queue_.push_back(saved_event);
1737 } else {
1738 WebMouseEvent event;
1739 InitMouseEvent(WebInputEvent::MouseMove,
1740 pressed_button_,
1741 mouse_pos,
1742 GetCurrentEventTimeSec(),
1743 click_count_,
1744 modifiers,
1745 &event);
1746 DoMouseMove(event);
1750 void EventSender::MouseScrollBy(gin::Arguments* args) {
1751 WebMouseWheelEvent event;
1752 InitMouseWheelEvent(args, false, &event);
1753 view_->handleInputEvent(event);
1756 void EventSender::MouseMomentumScrollBy(gin::Arguments* args) {
1757 WebMouseWheelEvent event;
1758 InitMouseWheelEvent(args, true, &event);
1759 event.momentumPhase = WebMouseWheelEvent::PhaseChanged;
1760 event.hasPreciseScrollingDeltas = true;
1761 view_->handleInputEvent(event);
1764 void EventSender::MouseMomentumEnd() {
1765 WebMouseWheelEvent event;
1766 InitMouseEvent(WebInputEvent::MouseWheel,
1767 WebMouseEvent::ButtonNone,
1768 last_mouse_pos_,
1769 GetCurrentEventTimeSec(),
1770 click_count_,
1772 &event);
1773 event.momentumPhase = WebMouseWheelEvent::PhaseEnded;
1774 event.hasPreciseScrollingDeltas = true;
1775 view_->handleInputEvent(event);
1778 void EventSender::ScheduleAsynchronousClick(int button_number, int modifiers) {
1779 delegate_->postTask(new MouseDownTask(this, button_number, modifiers));
1780 delegate_->postTask(new MouseUpTask(this, button_number, modifiers));
1783 void EventSender::ScheduleAsynchronousKeyDown(const std::string& code_str,
1784 int modifiers,
1785 KeyLocationCode location) {
1786 delegate_->postTask(new KeyDownTask(this, code_str, modifiers, location));
1789 double EventSender::GetCurrentEventTimeSec() {
1790 return (delegate_->getCurrentTimeInMillisecond() + time_offset_ms_) / 1000.0;
1793 void EventSender::DoLeapForward(int milliseconds) {
1794 time_offset_ms_ += milliseconds;
1797 void EventSender::SendCurrentTouchEvent(WebInputEvent::Type type) {
1798 DCHECK_GT(static_cast<unsigned>(WebTouchEvent::touchesLengthCap),
1799 touch_points_.size());
1800 if (force_layout_on_events_)
1801 view_->layout();
1803 WebTouchEvent touch_event;
1804 touch_event.type = type;
1805 touch_event.modifiers = touch_modifiers_;
1806 touch_event.cancelable = touch_cancelable_;
1807 touch_event.timeStampSeconds = GetCurrentEventTimeSec();
1808 touch_event.touchesLength = touch_points_.size();
1809 for (size_t i = 0; i < touch_points_.size(); ++i)
1810 touch_event.touches[i] = touch_points_[i];
1811 view_->handleInputEvent(touch_event);
1813 for (size_t i = 0; i < touch_points_.size(); ++i) {
1814 WebTouchPoint* touch_point = &touch_points_[i];
1815 if (touch_point->state == WebTouchPoint::StateReleased) {
1816 touch_points_.erase(touch_points_.begin() + i);
1817 --i;
1818 } else
1819 touch_point->state = WebTouchPoint::StateStationary;
1823 void EventSender::GestureEvent(WebInputEvent::Type type,
1824 gin::Arguments* args) {
1825 double x;
1826 double y;
1827 args->GetNext(&x);
1828 args->GetNext(&y);
1829 WebPoint point(x, y);
1831 WebGestureEvent event;
1832 event.type = type;
1834 switch (type) {
1835 case WebInputEvent::GestureScrollUpdate:
1836 case WebInputEvent::GestureScrollUpdateWithoutPropagation:
1837 event.data.scrollUpdate.deltaX = static_cast<float>(x);
1838 event.data.scrollUpdate.deltaY = static_cast<float>(y);
1839 event.x = current_gesture_location_.x;
1840 event.y = current_gesture_location_.y;
1841 current_gesture_location_.x =
1842 current_gesture_location_.x + event.data.scrollUpdate.deltaX;
1843 current_gesture_location_.y =
1844 current_gesture_location_.y + event.data.scrollUpdate.deltaY;
1845 break;
1846 case WebInputEvent::GestureScrollBegin:
1847 current_gesture_location_ = WebPoint(point.x, point.y);
1848 event.x = current_gesture_location_.x;
1849 event.y = current_gesture_location_.y;
1850 break;
1851 case WebInputEvent::GestureScrollEnd:
1852 case WebInputEvent::GestureFlingStart:
1853 event.x = current_gesture_location_.x;
1854 event.y = current_gesture_location_.y;
1855 break;
1856 case WebInputEvent::GestureTap:
1857 if (!args->PeekNext().IsEmpty()) {
1858 float tap_count;
1859 if (!args->GetNext(&tap_count)) {
1860 args->ThrowError();
1861 return;
1863 event.data.tap.tapCount = tap_count;
1864 } else {
1865 event.data.tap.tapCount = 1;
1868 event.x = point.x;
1869 event.y = point.y;
1870 break;
1871 case WebInputEvent::GestureTapUnconfirmed:
1872 if (!args->PeekNext().IsEmpty()) {
1873 float tap_count;
1874 if (!args->GetNext(&tap_count)) {
1875 args->ThrowError();
1876 return;
1878 event.data.tap.tapCount = tap_count;
1879 } else {
1880 event.data.tap.tapCount = 1;
1882 event.x = point.x;
1883 event.y = point.y;
1884 break;
1885 case WebInputEvent::GestureTapDown:
1886 event.x = point.x;
1887 event.y = point.y;
1888 if (!args->PeekNext().IsEmpty()) {
1889 float width;
1890 if (!args->GetNext(&width)) {
1891 args->ThrowError();
1892 return;
1894 event.data.tapDown.width = width;
1896 if (!args->PeekNext().IsEmpty()) {
1897 float height;
1898 if (!args->GetNext(&height)) {
1899 args->ThrowError();
1900 return;
1902 event.data.tapDown.height = height;
1904 break;
1905 case WebInputEvent::GestureShowPress:
1906 event.x = point.x;
1907 event.y = point.y;
1908 if (!args->PeekNext().IsEmpty()) {
1909 float width;
1910 if (!args->GetNext(&width)) {
1911 args->ThrowError();
1912 return;
1914 event.data.showPress.width = width;
1915 if (!args->PeekNext().IsEmpty()) {
1916 float height;
1917 if (!args->GetNext(&height)) {
1918 args->ThrowError();
1919 return;
1921 event.data.showPress.height = height;
1924 break;
1925 case WebInputEvent::GestureTapCancel:
1926 event.x = point.x;
1927 event.y = point.y;
1928 break;
1929 case WebInputEvent::GestureLongPress:
1930 event.x = point.x;
1931 event.y = point.y;
1932 if (!args->PeekNext().IsEmpty()) {
1933 float width;
1934 if (!args->GetNext(&width)) {
1935 args->ThrowError();
1936 return;
1938 event.data.longPress.width = width;
1939 if (!args->PeekNext().IsEmpty()) {
1940 float height;
1941 if (!args->GetNext(&height)) {
1942 args->ThrowError();
1943 return;
1945 event.data.longPress.height = height;
1948 break;
1949 case WebInputEvent::GestureLongTap:
1950 event.x = point.x;
1951 event.y = point.y;
1952 if (!args->PeekNext().IsEmpty()) {
1953 float width;
1954 if (!args->GetNext(&width)) {
1955 args->ThrowError();
1956 return;
1958 event.data.longPress.width = width;
1959 if (!args->PeekNext().IsEmpty()) {
1960 float height;
1961 if (!args->GetNext(&height)) {
1962 args->ThrowError();
1963 return;
1965 event.data.longPress.height = height;
1968 break;
1969 case WebInputEvent::GestureTwoFingerTap:
1970 event.x = point.x;
1971 event.y = point.y;
1972 if (!args->PeekNext().IsEmpty()) {
1973 float first_finger_width;
1974 if (!args->GetNext(&first_finger_width)) {
1975 args->ThrowError();
1976 return;
1978 event.data.twoFingerTap.firstFingerWidth = first_finger_width;
1979 if (!args->PeekNext().IsEmpty()) {
1980 float first_finger_height;
1981 if (!args->GetNext(&first_finger_height)) {
1982 args->ThrowError();
1983 return;
1985 event.data.twoFingerTap.firstFingerHeight = first_finger_height;
1988 break;
1989 default:
1990 NOTREACHED();
1993 event.globalX = event.x;
1994 event.globalY = event.y;
1995 event.timeStampSeconds = GetCurrentEventTimeSec();
1997 if (force_layout_on_events_)
1998 view_->layout();
2000 view_->handleInputEvent(event);
2002 // Long press might start a drag drop session. Complete it if so.
2003 if (type == WebInputEvent::GestureLongPress && !current_drag_data_.isNull()) {
2004 WebMouseEvent mouse_event;
2005 InitMouseEvent(WebInputEvent::MouseDown,
2006 pressed_button_,
2007 point,
2008 GetCurrentEventTimeSec(),
2009 click_count_,
2011 &mouse_event);
2013 FinishDragAndDrop(mouse_event, blink::WebDragOperationNone);
2017 void EventSender::UpdateClickCountForButton(
2018 WebMouseEvent::Button button_type) {
2019 if ((GetCurrentEventTimeSec() - last_click_time_sec_ <
2020 kMultipleClickTimeSec) &&
2021 (!OutsideMultiClickRadius(last_mouse_pos_, last_click_pos_)) &&
2022 (button_type == last_button_type_)) {
2023 ++click_count_;
2024 } else {
2025 click_count_ = 1;
2026 last_button_type_ = button_type;
2030 void EventSender::InitMouseWheelEvent(gin::Arguments* args,
2031 bool continuous,
2032 WebMouseWheelEvent* event) {
2033 // Force a layout here just to make sure every position has been
2034 // determined before we send events (as well as all the other methods
2035 // that send an event do).
2036 if (force_layout_on_events_)
2037 view_->layout();
2039 double horizontal;
2040 if (!args->GetNext(&horizontal)) {
2041 args->ThrowError();
2042 return;
2044 double vertical;
2045 if (!args->GetNext(&vertical)) {
2046 args->ThrowError();
2047 return;
2050 bool paged = false;
2051 bool has_precise_scrolling_deltas = false;
2052 int modifiers = 0;
2053 if (!args->PeekNext().IsEmpty()) {
2054 args->GetNext(&paged);
2055 if (!args->PeekNext().IsEmpty()) {
2056 args->GetNext(&has_precise_scrolling_deltas);
2057 if (!args->PeekNext().IsEmpty())
2058 modifiers = GetKeyModifiersFromV8(args->PeekNext());
2062 InitMouseEvent(WebInputEvent::MouseWheel,
2063 pressed_button_,
2064 last_mouse_pos_,
2065 GetCurrentEventTimeSec(),
2066 click_count_,
2067 modifiers,
2068 event);
2069 event->wheelTicksX = static_cast<float>(horizontal);
2070 event->wheelTicksY = static_cast<float>(vertical);
2071 event->deltaX = event->wheelTicksX;
2072 event->deltaY = event->wheelTicksY;
2073 event->scrollByPage = paged;
2074 event->hasPreciseScrollingDeltas = has_precise_scrolling_deltas;
2076 if (continuous) {
2077 event->wheelTicksX /= kScrollbarPixelsPerTick;
2078 event->wheelTicksY /= kScrollbarPixelsPerTick;
2079 } else {
2080 event->deltaX *= kScrollbarPixelsPerTick;
2081 event->deltaY *= kScrollbarPixelsPerTick;
2085 void EventSender::FinishDragAndDrop(const WebMouseEvent& e,
2086 blink::WebDragOperation drag_effect) {
2087 WebPoint client_point(e.x, e.y);
2088 WebPoint screen_point(e.globalX, e.globalY);
2089 current_drag_effect_ = drag_effect;
2090 if (current_drag_effect_) {
2091 // Specifically pass any keyboard modifiers to the drop method. This allows
2092 // tests to control the drop type (i.e. copy or move).
2093 view_->dragTargetDrop(client_point, screen_point, e.modifiers);
2094 } else {
2095 view_->dragTargetDragLeave();
2097 view_->dragSourceEndedAt(client_point, screen_point, current_drag_effect_);
2098 view_->dragSourceSystemDragEnded();
2100 current_drag_data_.reset();
2103 void EventSender::DoMouseUp(const WebMouseEvent& e) {
2104 view_->handleInputEvent(e);
2106 pressed_button_ = WebMouseEvent::ButtonNone;
2107 last_click_time_sec_ = e.timeStampSeconds;
2108 last_click_pos_ = last_mouse_pos_;
2110 // If we're in a drag operation, complete it.
2111 if (current_drag_data_.isNull())
2112 return;
2114 WebPoint client_point(e.x, e.y);
2115 WebPoint screen_point(e.globalX, e.globalY);
2116 FinishDragAndDrop(
2118 view_->dragTargetDragOver(
2119 client_point, screen_point, current_drag_effects_allowed_, 0));
2122 void EventSender::DoMouseMove(const WebMouseEvent& e) {
2123 last_mouse_pos_ = WebPoint(e.x, e.y);
2125 view_->handleInputEvent(e);
2127 if (pressed_button_ == WebMouseEvent::ButtonNone ||
2128 current_drag_data_.isNull()) {
2129 return;
2132 WebPoint client_point(e.x, e.y);
2133 WebPoint screen_point(e.globalX, e.globalY);
2134 current_drag_effect_ = view_->dragTargetDragOver(
2135 client_point, screen_point, current_drag_effects_allowed_, 0);
2138 void EventSender::ReplaySavedEvents() {
2139 replaying_saved_events_ = true;
2140 while (!mouse_event_queue_.empty()) {
2141 SavedEvent e = mouse_event_queue_.front();
2142 mouse_event_queue_.pop_front();
2144 switch (e.type) {
2145 case SavedEvent::TYPE_MOUSE_MOVE: {
2146 WebMouseEvent event;
2147 InitMouseEvent(WebInputEvent::MouseMove,
2148 pressed_button_,
2149 e.pos,
2150 GetCurrentEventTimeSec(),
2151 click_count_,
2152 e.modifiers,
2153 &event);
2154 DoMouseMove(event);
2155 break;
2157 case SavedEvent::TYPE_LEAP_FORWARD:
2158 DoLeapForward(e.milliseconds);
2159 break;
2160 case SavedEvent::TYPE_MOUSE_UP: {
2161 WebMouseEvent event;
2162 InitMouseEvent(WebInputEvent::MouseUp,
2163 e.button_type,
2164 last_mouse_pos_,
2165 GetCurrentEventTimeSec(),
2166 click_count_,
2167 e.modifiers,
2168 &event);
2169 DoMouseUp(event);
2170 break;
2172 default:
2173 NOTREACHED();
2177 replaying_saved_events_ = false;
2180 } // namespace content