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/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "content/public/common/page_zoom.h"
12 #include "content/shell/renderer/test_runner/mock_spell_check.h"
13 #include "content/shell/renderer/test_runner/test_interfaces.h"
14 #include "content/shell/renderer/test_runner/web_test_delegate.h"
15 #include "content/shell/renderer/test_runner/web_test_proxy.h"
16 #include "gin/handle.h"
17 #include "gin/object_template_builder.h"
18 #include "gin/wrappable.h"
19 #include "third_party/WebKit/public/platform/WebString.h"
20 #include "third_party/WebKit/public/platform/WebVector.h"
21 #include "third_party/WebKit/public/web/WebContextMenuData.h"
22 #include "third_party/WebKit/public/web/WebFrame.h"
23 #include "third_party/WebKit/public/web/WebKit.h"
24 #include "third_party/WebKit/public/web/WebPagePopup.h"
25 #include "third_party/WebKit/public/web/WebView.h"
26 #include "ui/events/keycodes/dom4/keycode_converter.h"
27 #include "ui/events/keycodes/keyboard_codes.h"
28 #include "v8/include/v8.h"
30 using blink::WebContextMenuData
;
31 using blink::WebDragData
;
32 using blink::WebDragOperationsMask
;
33 using blink::WebFloatPoint
;
34 using blink::WebFrame
;
35 using blink::WebGestureEvent
;
36 using blink::WebInputEvent
;
37 using blink::WebKeyboardEvent
;
38 using blink::WebMenuItemInfo
;
39 using blink::WebMouseEvent
;
40 using blink::WebMouseWheelEvent
;
41 using blink::WebPagePopup
;
42 using blink::WebPoint
;
43 using blink::WebString
;
44 using blink::WebTouchEvent
;
45 using blink::WebTouchPoint
;
46 using blink::WebVector
;
53 void InitMouseEvent(WebInputEvent::Type t
,
54 WebMouseEvent::Button b
,
62 e
->modifiers
= modifiers
;
67 e
->timeStampSeconds
= time_stamp
;
68 e
->clickCount
= click_count
;
71 int GetKeyModifier(const std::string
& modifier_name
) {
72 const char* characters
= modifier_name
.c_str();
73 if (!strcmp(characters
, "ctrlKey")
75 || !strcmp(characters
, "addSelectionKey")
78 return WebInputEvent::ControlKey
;
79 } else if (!strcmp(characters
, "shiftKey") ||
80 !strcmp(characters
, "rangeSelectionKey")) {
81 return WebInputEvent::ShiftKey
;
82 } else if (!strcmp(characters
, "altKey")) {
83 return WebInputEvent::AltKey
;
85 } else if (!strcmp(characters
, "metaKey") ||
86 !strcmp(characters
, "addSelectionKey")) {
87 return WebInputEvent::MetaKey
;
89 } else if (!strcmp(characters
, "metaKey")) {
90 return WebInputEvent::MetaKey
;
92 } else if (!strcmp(characters
, "autoRepeat")) {
93 return WebInputEvent::IsAutoRepeat
;
94 } else if (!strcmp(characters
, "copyKey")) {
96 return WebInputEvent::AltKey
;
98 return WebInputEvent::ControlKey
;
100 } else if (!strcmp(characters
, "leftButton")) {
101 return WebInputEvent::LeftButtonDown
;
102 } else if (!strcmp(characters
, "middleButton")) {
103 return WebInputEvent::MiddleButtonDown
;
104 } else if (!strcmp(characters
, "rightButton")) {
105 return WebInputEvent::RightButtonDown
;
111 int GetKeyModifiers(const std::vector
<std::string
>& modifier_names
) {
113 for (std::vector
<std::string
>::const_iterator it
= modifier_names
.begin();
114 it
!= modifier_names
.end(); ++it
) {
115 modifiers
|= GetKeyModifier(*it
);
120 int GetKeyModifiersFromV8(v8::Handle
<v8::Value
> value
) {
121 std::vector
<std::string
> modifier_names
;
122 if (value
->IsString()) {
123 modifier_names
.push_back(gin::V8ToString(value
));
124 } else if (value
->IsArray()) {
125 gin::Converter
<std::vector
<std::string
> >::FromV8(
126 NULL
, value
, &modifier_names
);
128 return GetKeyModifiers(modifier_names
);
131 // Maximum distance (in space and time) for a mouse click to register as a
132 // double or triple click.
133 const double kMultipleClickTimeSec
= 1;
134 const int kMultipleClickRadiusPixels
= 5;
135 const char kSubMenuDepthIdentifier
[] = "_";
136 const char kSubMenuIdentifier
[] = " >";
137 const char kSeparatorIdentifier
[] = "---------";
138 const char kDisabledIdentifier
[] = "#";
139 const char kCheckedIdentifier
[] = "*";
141 bool OutsideMultiClickRadius(const WebPoint
& a
, const WebPoint
& b
) {
142 return ((a
.x
- b
.x
) * (a
.x
- b
.x
) + (a
.y
- b
.y
) * (a
.y
- b
.y
)) >
143 kMultipleClickRadiusPixels
* kMultipleClickRadiusPixels
;
146 void PopulateCustomItems(const WebVector
<WebMenuItemInfo
>& customItems
,
147 const std::string
& prefix
, std::vector
<std::string
>* strings
) {
148 for (size_t i
= 0; i
< customItems
.size(); ++i
) {
149 std::string prefixCopy
= prefix
;
150 if (!customItems
[i
].enabled
)
151 prefixCopy
= kDisabledIdentifier
+ prefix
;
152 if (customItems
[i
].checked
)
153 prefixCopy
= kCheckedIdentifier
+ prefix
;
154 if (customItems
[i
].type
== blink::WebMenuItemInfo::Separator
) {
155 strings
->push_back(prefixCopy
+ kSeparatorIdentifier
);
156 } else if (customItems
[i
].type
== blink::WebMenuItemInfo::SubMenu
) {
157 strings
->push_back(prefixCopy
+ customItems
[i
].label
.utf8() +
158 customItems
[i
].icon
.utf8() + kSubMenuIdentifier
);
159 PopulateCustomItems(customItems
[i
].subMenuItems
, prefixCopy
+
160 kSubMenuDepthIdentifier
, strings
);
162 strings
->push_back(prefixCopy
+ customItems
[i
].label
.utf8() +
163 customItems
[i
].icon
.utf8());
168 // Because actual context menu is implemented by the browser side,
169 // this function does only what LayoutTests are expecting:
170 // - Many test checks the count of items. So returning non-zero value makes
172 // - Some test compares the count before and after some action. So changing the
173 // count based on flags also makes sense. This function is doing such for some
175 // - Some test even checks actual string content. So providing it would be also
177 std::vector
<std::string
> MakeMenuItemStringsFor(
178 WebContextMenuData
* context_menu
,
179 WebTestDelegate
* delegate
) {
180 // These constants are based on Safari's context menu because tests are made
182 static const char* kNonEditableMenuStrings
[] = {
193 static const char* kEditableMenuStrings
[] = {
198 "Spelling and Grammar",
199 "Substitutions, Transformations",
202 "Paragraph Direction",
207 // This is possible because mouse events are cancelleable.
209 return std::vector
<std::string
>();
211 std::vector
<std::string
> strings
;
213 // Populate custom menu items if provided by blink.
214 PopulateCustomItems(context_menu
->customItems
, "", &strings
);
216 if (context_menu
->isEditable
) {
217 for (const char** item
= kEditableMenuStrings
; *item
; ++item
) {
218 strings
.push_back(*item
);
220 WebVector
<WebString
> suggestions
;
221 MockSpellCheck::FillSuggestionList(context_menu
->misspelledWord
,
223 for (size_t i
= 0; i
< suggestions
.size(); ++i
) {
224 strings
.push_back(suggestions
[i
].utf8());
227 for (const char** item
= kNonEditableMenuStrings
; *item
; ++item
) {
228 strings
.push_back(*item
);
235 // How much we should scroll per event - the value here is chosen to match the
236 // WebKit impl and layout test results.
237 const float kScrollbarPixelsPerTick
= 40.0f
;
239 WebMouseEvent::Button
GetButtonTypeFromButtonNumber(int button_code
) {
241 return WebMouseEvent::ButtonLeft
;
242 if (button_code
== 2)
243 return WebMouseEvent::ButtonRight
;
244 return WebMouseEvent::ButtonMiddle
;
247 class MouseDownTask
: public WebMethodTask
<EventSender
> {
249 MouseDownTask(EventSender
* obj
, int button_number
, int modifiers
)
250 : WebMethodTask
<EventSender
>(obj
),
251 button_number_(button_number
),
252 modifiers_(modifiers
) {}
254 void RunIfValid() override
{ object_
->MouseDown(button_number_
, modifiers_
); }
261 class MouseUpTask
: public WebMethodTask
<EventSender
> {
263 MouseUpTask(EventSender
* obj
, int button_number
, int modifiers
)
264 : WebMethodTask
<EventSender
>(obj
),
265 button_number_(button_number
),
266 modifiers_(modifiers
) {}
268 void RunIfValid() override
{ object_
->MouseUp(button_number_
, modifiers_
); }
275 class KeyDownTask
: public WebMethodTask
<EventSender
> {
277 KeyDownTask(EventSender
* obj
,
278 const std::string code_str
,
280 KeyLocationCode location
)
281 : WebMethodTask
<EventSender
>(obj
),
283 modifiers_(modifiers
),
284 location_(location
) {}
286 void RunIfValid() override
{
287 object_
->KeyDown(code_str_
, modifiers_
, location_
);
291 std::string code_str_
;
293 KeyLocationCode location_
;
296 bool NeedsShiftModifier(int keyCode
) {
297 // If code is an uppercase letter, assign a SHIFT key to eventDown.modifier.
298 return (keyCode
& 0xFF) >= 'A' && (keyCode
& 0xFF) <= 'Z';
301 // Get the edit command corresponding to a keyboard event.
302 // Returns true if the specified event corresponds to an edit command, the name
303 // of the edit command will be stored in |*name|.
304 bool GetEditCommand(const WebKeyboardEvent
& event
, std::string
* name
) {
305 #if defined(OS_MACOSX)
306 // We only cares about Left,Right,Up,Down keys with Command or Command+Shift
307 // modifiers. These key events correspond to some special movement and
308 // selection editor commands. These keys will be marked as system key, which
309 // prevents them from being handled. Thus they must be handled specially.
310 if ((event
.modifiers
& ~WebKeyboardEvent::ShiftKey
) !=
311 WebKeyboardEvent::MetaKey
)
314 switch (event
.windowsKeyCode
) {
316 *name
= "MoveToBeginningOfLine";
319 *name
= "MoveToEndOfLine";
322 *name
= "MoveToBeginningOfDocument";
325 *name
= "MoveToEndOfDocument";
331 if (event
.modifiers
& WebKeyboardEvent::ShiftKey
)
332 name
->append("AndModifySelection");
340 bool IsSystemKeyEvent(const WebKeyboardEvent
& event
) {
341 #if defined(OS_MACOSX)
342 return event
.modifiers
& WebInputEvent::MetaKey
&&
343 event
.windowsKeyCode
!= ui::VKEY_B
&&
344 event
.windowsKeyCode
!= ui::VKEY_I
;
346 return !!(event
.modifiers
& WebInputEvent::AltKey
);
350 const char* kSourceDeviceStringTouchpad
= "touchpad";
351 const char* kSourceDeviceStringTouchscreen
= "touchscreen";
355 class EventSenderBindings
: public gin::Wrappable
<EventSenderBindings
> {
357 static gin::WrapperInfo kWrapperInfo
;
359 static void Install(base::WeakPtr
<EventSender
> sender
,
360 blink::WebFrame
* frame
);
363 explicit EventSenderBindings(base::WeakPtr
<EventSender
> sender
);
364 ~EventSenderBindings() override
;
367 gin::ObjectTemplateBuilder
GetObjectTemplateBuilder(
368 v8::Isolate
* isolate
) override
;
371 void EnableDOMUIEventLogging();
372 void FireKeyboardEventsToElement();
373 void ClearKillRing();
374 std::vector
<std::string
> ContextClick();
379 void SetPageZoomFactor(double factor
);
380 void SetPageScaleFactor(gin::Arguments
* args
);
381 void SetPageScaleFactorLimits(gin::Arguments
* args
);
382 void ClearTouchPoints();
383 void ReleaseTouchPoint(unsigned index
);
384 void UpdateTouchPoint(unsigned index
, double x
, double y
);
385 void CancelTouchPoint(unsigned index
);
386 void SetTouchModifier(const std::string
& key_name
, bool set_mask
);
387 void SetTouchCancelable(bool cancelable
);
388 void DumpFilenameBeingDragged();
389 void GestureFlingCancel();
390 void GestureFlingStart(float x
,
394 gin::Arguments
* args
);
395 void GestureScrollFirstPoint(int x
, int y
);
400 void LeapForward(int milliseconds
);
401 void BeginDragWithFiles(const std::vector
<std::string
>& files
);
402 void AddTouchPoint(gin::Arguments
* args
);
403 void MouseDragBegin();
405 void GestureScrollBegin(gin::Arguments
* args
);
406 void GestureScrollEnd(gin::Arguments
* args
);
407 void GestureScrollUpdate(gin::Arguments
* args
);
408 void GesturePinchBegin(gin::Arguments
* args
);
409 void GesturePinchEnd(gin::Arguments
* args
);
410 void GesturePinchUpdate(gin::Arguments
* args
);
411 void GestureTap(gin::Arguments
* args
);
412 void GestureTapDown(gin::Arguments
* args
);
413 void GestureShowPress(gin::Arguments
* args
);
414 void GestureTapCancel(gin::Arguments
* args
);
415 void GestureLongPress(gin::Arguments
* args
);
416 void GestureLongTap(gin::Arguments
* args
);
417 void GestureTwoFingerTap(gin::Arguments
* args
);
418 void ContinuousMouseScrollBy(gin::Arguments
* args
);
419 void MouseMoveTo(gin::Arguments
* args
);
420 void TrackpadScrollBegin();
421 void TrackpadScroll(gin::Arguments
* args
);
422 void TrackpadScrollEnd();
423 void MouseScrollBy(gin::Arguments
* args
);
424 // TODO(erikchen): Remove MouseMomentumBegin once CL 282743002 has landed.
425 void MouseMomentumBegin();
426 void MouseMomentumBegin2(gin::Arguments
* args
);
427 void MouseMomentumScrollBy(gin::Arguments
* args
);
428 void MouseMomentumEnd();
429 void ScheduleAsynchronousClick(gin::Arguments
* args
);
430 void ScheduleAsynchronousKeyDown(gin::Arguments
* args
);
431 void MouseDown(gin::Arguments
* args
);
432 void MouseUp(gin::Arguments
* args
);
433 void KeyDown(gin::Arguments
* args
);
435 // Binding properties:
436 bool ForceLayoutOnEvents() const;
437 void SetForceLayoutOnEvents(bool force
);
438 bool IsDragMode() const;
439 void SetIsDragMode(bool drag_mode
);
442 int WmKeyDown() const;
443 void SetWmKeyDown(int key_down
);
446 void SetWmKeyUp(int key_up
);
449 void SetWmChar(int wm_char
);
451 int WmDeadChar() const;
452 void SetWmDeadChar(int dead_char
);
454 int WmSysKeyDown() const;
455 void SetWmSysKeyDown(int key_down
);
457 int WmSysKeyUp() const;
458 void SetWmSysKeyUp(int key_up
);
460 int WmSysChar() const;
461 void SetWmSysChar(int sys_char
);
463 int WmSysDeadChar() const;
464 void SetWmSysDeadChar(int sys_dead_char
);
467 base::WeakPtr
<EventSender
> sender_
;
469 DISALLOW_COPY_AND_ASSIGN(EventSenderBindings
);
472 gin::WrapperInfo
EventSenderBindings::kWrapperInfo
= {gin::kEmbedderNativeGin
};
474 EventSenderBindings::EventSenderBindings(base::WeakPtr
<EventSender
> sender
)
478 EventSenderBindings::~EventSenderBindings() {}
481 void EventSenderBindings::Install(base::WeakPtr
<EventSender
> sender
,
483 v8::Isolate
* isolate
= blink::mainThreadIsolate();
484 v8::HandleScope
handle_scope(isolate
);
485 v8::Handle
<v8::Context
> context
= frame
->mainWorldScriptContext();
486 if (context
.IsEmpty())
489 v8::Context::Scope
context_scope(context
);
491 gin::Handle
<EventSenderBindings
> bindings
=
492 gin::CreateHandle(isolate
, new EventSenderBindings(sender
));
493 if (bindings
.IsEmpty())
495 v8::Handle
<v8::Object
> global
= context
->Global();
496 global
->Set(gin::StringToV8(isolate
, "eventSender"), bindings
.ToV8());
499 gin::ObjectTemplateBuilder
500 EventSenderBindings::GetObjectTemplateBuilder(v8::Isolate
* isolate
) {
501 return gin::Wrappable
<EventSenderBindings
>::GetObjectTemplateBuilder(isolate
)
502 .SetMethod("enableDOMUIEventLogging",
503 &EventSenderBindings::EnableDOMUIEventLogging
)
504 .SetMethod("fireKeyboardEventsToElement",
505 &EventSenderBindings::FireKeyboardEventsToElement
)
506 .SetMethod("clearKillRing", &EventSenderBindings::ClearKillRing
)
507 .SetMethod("contextClick", &EventSenderBindings::ContextClick
)
508 .SetMethod("textZoomIn", &EventSenderBindings::TextZoomIn
)
509 .SetMethod("textZoomOut", &EventSenderBindings::TextZoomOut
)
510 .SetMethod("zoomPageIn", &EventSenderBindings::ZoomPageIn
)
511 .SetMethod("zoomPageOut", &EventSenderBindings::ZoomPageOut
)
512 .SetMethod("setPageZoomFactor", &EventSenderBindings::SetPageZoomFactor
)
513 .SetMethod("setPageScaleFactor", &EventSenderBindings::SetPageScaleFactor
)
514 .SetMethod("setPageScaleFactorLimits",
515 &EventSenderBindings::SetPageScaleFactorLimits
)
516 .SetMethod("clearTouchPoints", &EventSenderBindings::ClearTouchPoints
)
517 .SetMethod("releaseTouchPoint", &EventSenderBindings::ReleaseTouchPoint
)
518 .SetMethod("updateTouchPoint", &EventSenderBindings::UpdateTouchPoint
)
519 .SetMethod("cancelTouchPoint", &EventSenderBindings::CancelTouchPoint
)
520 .SetMethod("setTouchModifier", &EventSenderBindings::SetTouchModifier
)
521 .SetMethod("setTouchCancelable", &EventSenderBindings::SetTouchCancelable
)
522 .SetMethod("dumpFilenameBeingDragged",
523 &EventSenderBindings::DumpFilenameBeingDragged
)
524 .SetMethod("gestureFlingCancel", &EventSenderBindings::GestureFlingCancel
)
525 .SetMethod("gestureFlingStart", &EventSenderBindings::GestureFlingStart
)
526 .SetMethod("gestureScrollFirstPoint",
527 &EventSenderBindings::GestureScrollFirstPoint
)
528 .SetMethod("touchStart", &EventSenderBindings::TouchStart
)
529 .SetMethod("touchMove", &EventSenderBindings::TouchMove
)
530 .SetMethod("touchCancel", &EventSenderBindings::TouchCancel
)
531 .SetMethod("touchEnd", &EventSenderBindings::TouchEnd
)
532 .SetMethod("leapForward", &EventSenderBindings::LeapForward
)
533 .SetMethod("beginDragWithFiles", &EventSenderBindings::BeginDragWithFiles
)
534 .SetMethod("addTouchPoint", &EventSenderBindings::AddTouchPoint
)
535 .SetMethod("mouseDragBegin", &EventSenderBindings::MouseDragBegin
)
536 .SetMethod("mouseDragEnd", &EventSenderBindings::MouseDragEnd
)
537 .SetMethod("gestureScrollBegin", &EventSenderBindings::GestureScrollBegin
)
538 .SetMethod("gestureScrollEnd", &EventSenderBindings::GestureScrollEnd
)
539 .SetMethod("gestureScrollUpdate",
540 &EventSenderBindings::GestureScrollUpdate
)
541 .SetMethod("gesturePinchBegin", &EventSenderBindings::GesturePinchBegin
)
542 .SetMethod("gesturePinchEnd", &EventSenderBindings::GesturePinchEnd
)
543 .SetMethod("gesturePinchUpdate", &EventSenderBindings::GesturePinchUpdate
)
544 .SetMethod("gestureTap", &EventSenderBindings::GestureTap
)
545 .SetMethod("gestureTapDown", &EventSenderBindings::GestureTapDown
)
546 .SetMethod("gestureShowPress", &EventSenderBindings::GestureShowPress
)
547 .SetMethod("gestureTapCancel", &EventSenderBindings::GestureTapCancel
)
548 .SetMethod("gestureLongPress", &EventSenderBindings::GestureLongPress
)
549 .SetMethod("gestureLongTap", &EventSenderBindings::GestureLongTap
)
550 .SetMethod("gestureTwoFingerTap",
551 &EventSenderBindings::GestureTwoFingerTap
)
552 .SetMethod("continuousMouseScrollBy",
553 &EventSenderBindings::ContinuousMouseScrollBy
)
554 .SetMethod("keyDown", &EventSenderBindings::KeyDown
)
555 .SetMethod("mouseDown", &EventSenderBindings::MouseDown
)
556 .SetMethod("mouseMoveTo", &EventSenderBindings::MouseMoveTo
)
557 .SetMethod("trackpadScrollBegin",
558 &EventSenderBindings::TrackpadScrollBegin
)
559 .SetMethod("trackpadScroll", &EventSenderBindings::TrackpadScroll
)
560 .SetMethod("trackpadScrollEnd", &EventSenderBindings::TrackpadScrollEnd
)
561 .SetMethod("mouseScrollBy", &EventSenderBindings::MouseScrollBy
)
562 .SetMethod("mouseUp", &EventSenderBindings::MouseUp
)
563 .SetMethod("mouseMomentumBegin", &EventSenderBindings::MouseMomentumBegin
)
564 .SetMethod("mouseMomentumBegin2",
565 &EventSenderBindings::MouseMomentumBegin2
)
566 .SetMethod("mouseMomentumScrollBy",
567 &EventSenderBindings::MouseMomentumScrollBy
)
568 .SetMethod("mouseMomentumEnd", &EventSenderBindings::MouseMomentumEnd
)
569 .SetMethod("scheduleAsynchronousClick",
570 &EventSenderBindings::ScheduleAsynchronousClick
)
571 .SetMethod("scheduleAsynchronousKeyDown",
572 &EventSenderBindings::ScheduleAsynchronousKeyDown
)
573 .SetProperty("forceLayoutOnEvents",
574 &EventSenderBindings::ForceLayoutOnEvents
,
575 &EventSenderBindings::SetForceLayoutOnEvents
)
576 .SetProperty("dragMode",
577 &EventSenderBindings::IsDragMode
,
578 &EventSenderBindings::SetIsDragMode
)
580 .SetProperty("WM_KEYDOWN",
581 &EventSenderBindings::WmKeyDown
,
582 &EventSenderBindings::SetWmKeyDown
)
583 .SetProperty("WM_KEYUP",
584 &EventSenderBindings::WmKeyUp
,
585 &EventSenderBindings::SetWmKeyUp
)
586 .SetProperty("WM_CHAR",
587 &EventSenderBindings::WmChar
,
588 &EventSenderBindings::SetWmChar
)
589 .SetProperty("WM_DEADCHAR",
590 &EventSenderBindings::WmDeadChar
,
591 &EventSenderBindings::SetWmDeadChar
)
592 .SetProperty("WM_SYSKEYDOWN",
593 &EventSenderBindings::WmSysKeyDown
,
594 &EventSenderBindings::SetWmSysKeyDown
)
595 .SetProperty("WM_SYSKEYUP",
596 &EventSenderBindings::WmSysKeyUp
,
597 &EventSenderBindings::SetWmSysKeyUp
)
598 .SetProperty("WM_SYSCHAR",
599 &EventSenderBindings::WmSysChar
,
600 &EventSenderBindings::SetWmSysChar
)
601 .SetProperty("WM_SYSDEADCHAR",
602 &EventSenderBindings::WmSysDeadChar
,
603 &EventSenderBindings::SetWmSysDeadChar
);
609 void EventSenderBindings::EnableDOMUIEventLogging() {
611 sender_
->EnableDOMUIEventLogging();
614 void EventSenderBindings::FireKeyboardEventsToElement() {
616 sender_
->FireKeyboardEventsToElement();
619 void EventSenderBindings::ClearKillRing() {
621 sender_
->ClearKillRing();
624 std::vector
<std::string
> EventSenderBindings::ContextClick() {
626 return sender_
->ContextClick();
627 return std::vector
<std::string
>();
630 void EventSenderBindings::TextZoomIn() {
632 sender_
->TextZoomIn();
635 void EventSenderBindings::TextZoomOut() {
637 sender_
->TextZoomOut();
640 void EventSenderBindings::ZoomPageIn() {
642 sender_
->ZoomPageIn();
645 void EventSenderBindings::ZoomPageOut() {
647 sender_
->ZoomPageOut();
650 void EventSenderBindings::SetPageZoomFactor(double factor
) {
652 sender_
->SetPageZoomFactor(factor
);
655 void EventSenderBindings::SetPageScaleFactor(gin::Arguments
* args
) {
661 if (args
->PeekNext().IsEmpty())
663 args
->GetNext(&scale_factor
);
664 if (args
->PeekNext().IsEmpty())
667 if (args
->PeekNext().IsEmpty())
670 sender_
->SetPageScaleFactor(scale_factor
,
671 static_cast<int>(x
), static_cast<int>(y
));
674 void EventSenderBindings::SetPageScaleFactorLimits(gin::Arguments
* args
) {
677 float min_scale_factor
;
678 float max_scale_factor
;
679 if (args
->PeekNext().IsEmpty())
681 args
->GetNext(&min_scale_factor
);
682 if (args
->PeekNext().IsEmpty())
684 args
->GetNext(&max_scale_factor
);
685 sender_
->SetPageScaleFactorLimits(min_scale_factor
, max_scale_factor
);
688 void EventSenderBindings::ClearTouchPoints() {
690 sender_
->ClearTouchPoints();
693 void EventSenderBindings::ReleaseTouchPoint(unsigned index
) {
695 sender_
->ReleaseTouchPoint(index
);
698 void EventSenderBindings::UpdateTouchPoint(unsigned index
, double x
, double y
) {
700 sender_
->UpdateTouchPoint(index
, static_cast<float>(x
), static_cast<float>(y
));
703 void EventSenderBindings::CancelTouchPoint(unsigned index
) {
705 sender_
->CancelTouchPoint(index
);
708 void EventSenderBindings::SetTouchModifier(const std::string
& key_name
,
711 sender_
->SetTouchModifier(key_name
, set_mask
);
714 void EventSenderBindings::SetTouchCancelable(bool cancelable
) {
716 sender_
->SetTouchCancelable(cancelable
);
719 void EventSenderBindings::DumpFilenameBeingDragged() {
721 sender_
->DumpFilenameBeingDragged();
724 void EventSenderBindings::GestureFlingCancel() {
726 sender_
->GestureFlingCancel();
729 void EventSenderBindings::GestureFlingStart(float x
,
733 gin::Arguments
* args
) {
735 sender_
->GestureFlingStart(x
, y
, velocity_x
, velocity_y
, args
);
738 void EventSenderBindings::GestureScrollFirstPoint(int x
, int y
) {
740 sender_
->GestureScrollFirstPoint(x
, y
);
743 void EventSenderBindings::TouchStart() {
745 sender_
->TouchStart();
748 void EventSenderBindings::TouchMove() {
750 sender_
->TouchMove();
753 void EventSenderBindings::TouchCancel() {
755 sender_
->TouchCancel();
758 void EventSenderBindings::TouchEnd() {
763 void EventSenderBindings::LeapForward(int milliseconds
) {
765 sender_
->LeapForward(milliseconds
);
768 void EventSenderBindings::BeginDragWithFiles(
769 const std::vector
<std::string
>& files
) {
771 sender_
->BeginDragWithFiles(files
);
774 void EventSenderBindings::AddTouchPoint(gin::Arguments
* args
) {
776 sender_
->AddTouchPoint(args
);
779 void EventSenderBindings::MouseDragBegin() {
781 sender_
->MouseDragBegin();
784 void EventSenderBindings::MouseDragEnd() {
786 sender_
->MouseDragEnd();
789 void EventSenderBindings::GestureScrollBegin(gin::Arguments
* args
) {
791 sender_
->GestureScrollBegin(args
);
794 void EventSenderBindings::GestureScrollEnd(gin::Arguments
* args
) {
796 sender_
->GestureScrollEnd(args
);
799 void EventSenderBindings::GestureScrollUpdate(gin::Arguments
* args
) {
801 sender_
->GestureScrollUpdate(args
);
804 void EventSenderBindings::GesturePinchBegin(gin::Arguments
* args
) {
806 sender_
->GesturePinchBegin(args
);
809 void EventSenderBindings::GesturePinchEnd(gin::Arguments
* args
) {
811 sender_
->GesturePinchEnd(args
);
814 void EventSenderBindings::GesturePinchUpdate(gin::Arguments
* args
) {
816 sender_
->GesturePinchUpdate(args
);
819 void EventSenderBindings::GestureTap(gin::Arguments
* args
) {
821 sender_
->GestureTap(args
);
824 void EventSenderBindings::GestureTapDown(gin::Arguments
* args
) {
826 sender_
->GestureTapDown(args
);
829 void EventSenderBindings::GestureShowPress(gin::Arguments
* args
) {
831 sender_
->GestureShowPress(args
);
834 void EventSenderBindings::GestureTapCancel(gin::Arguments
* args
) {
836 sender_
->GestureTapCancel(args
);
839 void EventSenderBindings::GestureLongPress(gin::Arguments
* args
) {
841 sender_
->GestureLongPress(args
);
844 void EventSenderBindings::GestureLongTap(gin::Arguments
* args
) {
846 sender_
->GestureLongTap(args
);
849 void EventSenderBindings::GestureTwoFingerTap(gin::Arguments
* args
) {
851 sender_
->GestureTwoFingerTap(args
);
854 void EventSenderBindings::ContinuousMouseScrollBy(gin::Arguments
* args
) {
856 sender_
->ContinuousMouseScrollBy(args
);
859 void EventSenderBindings::MouseMoveTo(gin::Arguments
* args
) {
861 sender_
->MouseMoveTo(args
);
864 void EventSenderBindings::TrackpadScrollBegin() {
866 sender_
->TrackpadScrollBegin();
869 void EventSenderBindings::TrackpadScroll(gin::Arguments
* args
) {
871 sender_
->TrackpadScroll(args
);
874 void EventSenderBindings::TrackpadScrollEnd() {
876 sender_
->TrackpadScrollEnd();
879 void EventSenderBindings::MouseScrollBy(gin::Arguments
* args
) {
881 sender_
->MouseScrollBy(args
);
884 void EventSenderBindings::MouseMomentumBegin() {
886 sender_
->MouseMomentumBegin();
889 void EventSenderBindings::MouseMomentumBegin2(gin::Arguments
* args
) {
891 sender_
->MouseMomentumBegin2(args
);
894 void EventSenderBindings::MouseMomentumScrollBy(gin::Arguments
* args
) {
896 sender_
->MouseMomentumScrollBy(args
);
899 void EventSenderBindings::MouseMomentumEnd() {
901 sender_
->MouseMomentumEnd();
904 void EventSenderBindings::ScheduleAsynchronousClick(gin::Arguments
* args
) {
908 int button_number
= 0;
910 if (!args
->PeekNext().IsEmpty()) {
911 args
->GetNext(&button_number
);
912 if (!args
->PeekNext().IsEmpty())
913 modifiers
= GetKeyModifiersFromV8(args
->PeekNext());
915 sender_
->ScheduleAsynchronousClick(button_number
, modifiers
);
918 void EventSenderBindings::ScheduleAsynchronousKeyDown(gin::Arguments
* args
) {
922 std::string code_str
;
924 int location
= DOMKeyLocationStandard
;
925 args
->GetNext(&code_str
);
926 if (!args
->PeekNext().IsEmpty()) {
927 v8::Handle
<v8::Value
> value
;
928 args
->GetNext(&value
);
929 modifiers
= GetKeyModifiersFromV8(value
);
930 if (!args
->PeekNext().IsEmpty())
931 args
->GetNext(&location
);
933 sender_
->ScheduleAsynchronousKeyDown(code_str
, modifiers
,
934 static_cast<KeyLocationCode
>(location
));
937 void EventSenderBindings::MouseDown(gin::Arguments
* args
) {
941 int button_number
= 0;
943 if (!args
->PeekNext().IsEmpty()) {
944 args
->GetNext(&button_number
);
945 if (!args
->PeekNext().IsEmpty())
946 modifiers
= GetKeyModifiersFromV8(args
->PeekNext());
948 sender_
->MouseDown(button_number
, modifiers
);
951 void EventSenderBindings::MouseUp(gin::Arguments
* args
) {
955 int button_number
= 0;
957 if (!args
->PeekNext().IsEmpty()) {
958 args
->GetNext(&button_number
);
959 if (!args
->PeekNext().IsEmpty())
960 modifiers
= GetKeyModifiersFromV8(args
->PeekNext());
962 sender_
->MouseUp(button_number
, modifiers
);
965 void EventSenderBindings::KeyDown(gin::Arguments
* args
) {
969 std::string code_str
;
971 int location
= DOMKeyLocationStandard
;
972 args
->GetNext(&code_str
);
973 if (!args
->PeekNext().IsEmpty()) {
974 v8::Handle
<v8::Value
> value
;
975 args
->GetNext(&value
);
976 modifiers
= GetKeyModifiersFromV8(value
);
977 if (!args
->PeekNext().IsEmpty())
978 args
->GetNext(&location
);
980 sender_
->KeyDown(code_str
, modifiers
, static_cast<KeyLocationCode
>(location
));
983 bool EventSenderBindings::ForceLayoutOnEvents() const {
985 return sender_
->force_layout_on_events();
989 void EventSenderBindings::SetForceLayoutOnEvents(bool force
) {
991 sender_
->set_force_layout_on_events(force
);
994 bool EventSenderBindings::IsDragMode() const {
996 return sender_
->is_drag_mode();
1000 void EventSenderBindings::SetIsDragMode(bool drag_mode
) {
1002 sender_
->set_is_drag_mode(drag_mode
);
1006 int EventSenderBindings::WmKeyDown() const {
1008 return sender_
->wm_key_down();
1012 void EventSenderBindings::SetWmKeyDown(int key_down
) {
1014 sender_
->set_wm_key_down(key_down
);
1017 int EventSenderBindings::WmKeyUp() const {
1019 return sender_
->wm_key_up();
1023 void EventSenderBindings::SetWmKeyUp(int key_up
) {
1025 sender_
->set_wm_key_up(key_up
);
1028 int EventSenderBindings::WmChar() const {
1030 return sender_
->wm_char();
1034 void EventSenderBindings::SetWmChar(int wm_char
) {
1036 sender_
->set_wm_char(wm_char
);
1039 int EventSenderBindings::WmDeadChar() const {
1041 return sender_
->wm_dead_char();
1045 void EventSenderBindings::SetWmDeadChar(int dead_char
) {
1047 sender_
->set_wm_dead_char(dead_char
);
1050 int EventSenderBindings::WmSysKeyDown() const {
1052 return sender_
->wm_sys_key_down();
1056 void EventSenderBindings::SetWmSysKeyDown(int key_down
) {
1058 sender_
->set_wm_sys_key_down(key_down
);
1061 int EventSenderBindings::WmSysKeyUp() const {
1063 return sender_
->wm_sys_key_up();
1067 void EventSenderBindings::SetWmSysKeyUp(int key_up
) {
1069 sender_
->set_wm_sys_key_up(key_up
);
1072 int EventSenderBindings::WmSysChar() const {
1074 return sender_
->wm_sys_char();
1078 void EventSenderBindings::SetWmSysChar(int sys_char
) {
1080 sender_
->set_wm_sys_char(sys_char
);
1083 int EventSenderBindings::WmSysDeadChar() const {
1085 return sender_
->wm_sys_dead_char();
1089 void EventSenderBindings::SetWmSysDeadChar(int sys_dead_char
) {
1091 sender_
->set_wm_sys_dead_char(sys_dead_char
);
1095 // EventSender -----------------------------------------------------------------
1097 WebMouseEvent::Button
EventSender::pressed_button_
= WebMouseEvent::ButtonNone
;
1099 WebPoint
EventSender::last_mouse_pos_
;
1101 WebMouseEvent::Button
EventSender::last_button_type_
=
1102 WebMouseEvent::ButtonNone
;
1104 EventSender::SavedEvent::SavedEvent()
1105 : type(TYPE_UNSPECIFIED
),
1106 button_type(WebMouseEvent::ButtonNone
),
1110 EventSender::EventSender(TestInterfaces
* interfaces
)
1111 : interfaces_(interfaces
),
1114 force_layout_on_events_(false),
1115 is_drag_mode_(true),
1116 touch_modifiers_(0),
1117 touch_cancelable_(true),
1118 replaying_saved_events_(false),
1119 current_drag_effects_allowed_(blink::WebDragOperationNone
),
1120 last_click_time_sec_(0),
1121 current_drag_effect_(blink::WebDragOperationNone
),
1129 wm_sys_key_down_(0),
1132 wm_sys_dead_char_(0),
1134 weak_factory_(this) {}
1136 EventSender::~EventSender() {}
1138 void EventSender::Reset() {
1139 DCHECK(current_drag_data_
.isNull());
1140 current_drag_data_
.reset();
1141 current_drag_effect_
= blink::WebDragOperationNone
;
1142 current_drag_effects_allowed_
= blink::WebDragOperationNone
;
1143 if (view_
&& pressed_button_
!= WebMouseEvent::ButtonNone
)
1144 view_
->mouseCaptureLost();
1145 pressed_button_
= WebMouseEvent::ButtonNone
;
1146 is_drag_mode_
= true;
1147 force_layout_on_events_
= true;
1150 wm_key_down_
= WM_KEYDOWN
;
1151 wm_key_up_
= WM_KEYUP
;
1153 wm_dead_char_
= WM_DEADCHAR
;
1154 wm_sys_key_down_
= WM_SYSKEYDOWN
;
1155 wm_sys_key_up_
= WM_SYSKEYUP
;
1156 wm_sys_char_
= WM_SYSCHAR
;
1157 wm_sys_dead_char_
= WM_SYSDEADCHAR
;
1160 last_mouse_pos_
= WebPoint(0, 0);
1161 last_click_time_sec_
= 0;
1162 last_click_pos_
= WebPoint(0, 0);
1163 last_button_type_
= WebMouseEvent::ButtonNone
;
1164 touch_points_
.clear();
1165 last_context_menu_data_
.reset();
1166 task_list_
.RevokeAll();
1167 current_gesture_location_
= WebPoint(0, 0);
1168 mouse_event_queue_
.clear();
1170 time_offset_ms_
= 0;
1173 touch_modifiers_
= 0;
1174 touch_cancelable_
= true;
1175 touch_points_
.clear();
1178 void EventSender::Install(WebFrame
* frame
) {
1179 EventSenderBindings::Install(weak_factory_
.GetWeakPtr(), frame
);
1182 void EventSender::SetDelegate(WebTestDelegate
* delegate
) {
1183 delegate_
= delegate
;
1186 void EventSender::SetWebView(WebView
* view
) {
1190 void EventSender::SetContextMenuData(const WebContextMenuData
& data
) {
1191 last_context_menu_data_
.reset(new WebContextMenuData(data
));
1194 void EventSender::DoDragDrop(const WebDragData
& drag_data
,
1195 WebDragOperationsMask mask
) {
1196 WebMouseEvent event
;
1197 InitMouseEvent(WebInputEvent::MouseDown
,
1200 GetCurrentEventTimeSec(),
1204 WebPoint
client_point(event
.x
, event
.y
);
1205 WebPoint
screen_point(event
.globalX
, event
.globalY
);
1206 current_drag_data_
= drag_data
;
1207 current_drag_effects_allowed_
= mask
;
1208 current_drag_effect_
= view_
->dragTargetDragEnter(
1209 drag_data
, client_point
, screen_point
, current_drag_effects_allowed_
, 0);
1211 // Finish processing events.
1212 ReplaySavedEvents();
1215 void EventSender::MouseDown(int button_number
, int modifiers
) {
1216 if (force_layout_on_events_
)
1219 DCHECK_NE(-1, button_number
);
1221 WebMouseEvent::Button button_type
=
1222 GetButtonTypeFromButtonNumber(button_number
);
1224 UpdateClickCountForButton(button_type
);
1226 pressed_button_
= button_type
;
1228 WebMouseEvent event
;
1229 InitMouseEvent(WebInputEvent::MouseDown
,
1232 GetCurrentEventTimeSec(),
1236 HandleInputEventOnViewOrPopup(event
);
1239 void EventSender::MouseUp(int button_number
, int modifiers
) {
1240 if (force_layout_on_events_
)
1243 DCHECK_NE(-1, button_number
);
1245 WebMouseEvent::Button button_type
=
1246 GetButtonTypeFromButtonNumber(button_number
);
1248 if (is_drag_mode_
&& !replaying_saved_events_
) {
1249 SavedEvent saved_event
;
1250 saved_event
.type
= SavedEvent::TYPE_MOUSE_UP
;
1251 saved_event
.button_type
= button_type
;
1252 saved_event
.modifiers
= modifiers
;
1253 mouse_event_queue_
.push_back(saved_event
);
1254 ReplaySavedEvents();
1256 WebMouseEvent event
;
1257 InitMouseEvent(WebInputEvent::MouseUp
,
1260 GetCurrentEventTimeSec(),
1268 void EventSender::KeyDown(const std::string
& code_str
,
1270 KeyLocationCode location
) {
1271 // FIXME: I'm not exactly sure how we should convert the string to a key
1272 // event. This seems to work in the cases I tested.
1273 // FIXME: Should we also generate a KEY_UP?
1275 bool generate_char
= false;
1277 // Convert \n -> VK_RETURN. Some layout tests use \n to mean "Enter", when
1278 // Windows uses \r for "Enter".
1281 bool needs_shift_key_modifier
= false;
1282 std::string domString
;
1284 if ("\n" == code_str
) {
1285 generate_char
= true;
1286 text
= code
= ui::VKEY_RETURN
;
1287 domString
.assign("Enter");
1288 } else if ("rightArrow" == code_str
) {
1289 code
= ui::VKEY_RIGHT
;
1290 domString
.assign("ArrowRight");
1291 } else if ("downArrow" == code_str
) {
1292 code
= ui::VKEY_DOWN
;
1293 domString
.assign("ArrowDown");
1294 } else if ("leftArrow" == code_str
) {
1295 code
= ui::VKEY_LEFT
;
1296 domString
.assign("ArrowLeft");
1297 } else if ("upArrow" == code_str
) {
1299 domString
.assign("ArrowUp");
1300 } else if ("insert" == code_str
) {
1301 code
= ui::VKEY_INSERT
;
1302 domString
.assign("Insert");
1303 } else if ("delete" == code_str
) {
1304 code
= ui::VKEY_DELETE
;
1305 domString
.assign("Delete");
1306 } else if ("pageUp" == code_str
) {
1307 code
= ui::VKEY_PRIOR
;
1308 domString
.assign("PageUp");
1309 } else if ("pageDown" == code_str
) {
1310 code
= ui::VKEY_NEXT
;
1311 domString
.assign("PageDown");
1312 } else if ("home" == code_str
) {
1313 code
= ui::VKEY_HOME
;
1314 domString
.assign("Home");
1315 } else if ("end" == code_str
) {
1316 code
= ui::VKEY_END
;
1317 domString
.assign("End");
1318 } else if ("printScreen" == code_str
) {
1319 code
= ui::VKEY_SNAPSHOT
;
1320 domString
.assign("PrintScreen");
1321 } else if ("menu" == code_str
) {
1322 code
= ui::VKEY_APPS
;
1323 domString
.assign("ContextMenu");
1324 } else if ("leftControl" == code_str
) {
1325 code
= ui::VKEY_LCONTROL
;
1326 domString
.assign("ControlLeft");
1327 } else if ("rightControl" == code_str
) {
1328 code
= ui::VKEY_RCONTROL
;
1329 domString
.assign("ControlRight");
1330 } else if ("leftShift" == code_str
) {
1331 code
= ui::VKEY_LSHIFT
;
1332 domString
.assign("ShiftLeft");
1333 } else if ("rightShift" == code_str
) {
1334 code
= ui::VKEY_RSHIFT
;
1335 domString
.assign("ShiftRight");
1336 } else if ("leftAlt" == code_str
) {
1337 code
= ui::VKEY_LMENU
;
1338 domString
.assign("AltLeft");
1339 } else if ("rightAlt" == code_str
) {
1340 code
= ui::VKEY_RMENU
;
1341 domString
.assign("AltRight");
1342 } else if ("numLock" == code_str
) {
1343 code
= ui::VKEY_NUMLOCK
;
1344 domString
.assign("NumLock");
1345 } else if ("backspace" == code_str
) {
1346 code
= ui::VKEY_BACK
;
1347 domString
.assign("Backspace");
1348 } else if ("escape" == code_str
) {
1349 code
= ui::VKEY_ESCAPE
;
1350 domString
.assign("Escape");
1352 // Compare the input string with the function-key names defined by the
1353 // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key
1354 // name, set its key code.
1355 for (int i
= 1; i
<= 24; ++i
) {
1356 std::string function_key_name
= base::StringPrintf("F%d", i
);
1357 if (function_key_name
== code_str
) {
1358 code
= ui::VKEY_F1
+ (i
- 1);
1359 domString
= function_key_name
;
1364 WebString web_code_str
=
1365 WebString::fromUTF8(code_str
.data(), code_str
.size());
1366 DCHECK_EQ(1u, web_code_str
.length());
1367 text
= code
= web_code_str
.at(0);
1368 needs_shift_key_modifier
= NeedsShiftModifier(code
);
1369 if ((code
& 0xFF) >= 'a' && (code
& 0xFF) <= 'z')
1371 if ((code
>= 'A' && code
<= 'Z') || (code
>= 'a' && code
<= 'z')) {
1372 domString
.assign("Key");
1373 domString
.push_back(base::ToUpperASCII(code
));
1374 } else if (code
>= '0' && code
<= '9') {
1375 domString
.assign("Digit");
1376 domString
.push_back(code
);
1377 } else if (code
== ' ') {
1378 domString
.assign("Space");
1379 } else if (code
== 9) {
1380 domString
.assign("Tab");
1382 generate_char
= true;
1385 if ("(" == code_str
) {
1387 needs_shift_key_modifier
= true;
1391 // For one generated keyboard event, we need to generate a keyDown/keyUp
1393 // On Windows, we might also need to generate a char event to mimic the
1394 // Windows event flow; on other platforms we create a merged event and test
1395 // the event flow that that platform provides.
1396 WebKeyboardEvent event_down
;
1397 event_down
.type
= WebInputEvent::RawKeyDown
;
1398 event_down
.modifiers
= modifiers
;
1399 event_down
.windowsKeyCode
= code
;
1400 event_down
.domCode
= static_cast<int>(
1401 ui::KeycodeConverter::CodeStringToDomCode(domString
.c_str()));
1403 if (generate_char
) {
1404 event_down
.text
[0] = text
;
1405 event_down
.unmodifiedText
[0] = text
;
1408 event_down
.setKeyIdentifierFromWindowsKeyCode();
1410 if (event_down
.modifiers
!= 0)
1411 event_down
.isSystemKey
= IsSystemKeyEvent(event_down
);
1413 if (needs_shift_key_modifier
)
1414 event_down
.modifiers
|= WebInputEvent::ShiftKey
;
1416 // See if KeyLocation argument is given.
1417 if (location
== DOMKeyLocationNumpad
)
1418 event_down
.modifiers
|= WebInputEvent::IsKeyPad
;
1420 WebKeyboardEvent event_up
;
1421 event_up
= event_down
;
1422 event_up
.type
= WebInputEvent::KeyUp
;
1423 // EventSender.m forces a layout here, with at least one
1424 // test (fast/forms/focus-control-to-page.html) relying on this.
1425 if (force_layout_on_events_
)
1428 // In the browser, if a keyboard event corresponds to an editor command,
1429 // the command will be dispatched to the renderer just before dispatching
1430 // the keyboard event, and then it will be executed in the
1431 // RenderView::handleCurrentKeyboardEvent() method.
1432 // We just simulate the same behavior here.
1433 std::string edit_command
;
1434 if (GetEditCommand(event_down
, &edit_command
))
1435 delegate_
->SetEditCommand(edit_command
, "");
1437 HandleInputEventOnViewOrPopup(event_down
);
1439 if (code
== ui::VKEY_ESCAPE
&& !current_drag_data_
.isNull()) {
1440 WebMouseEvent event
;
1441 InitMouseEvent(WebInputEvent::MouseDown
,
1444 GetCurrentEventTimeSec(),
1448 FinishDragAndDrop(event
, blink::WebDragOperationNone
);
1451 delegate_
->ClearEditCommand();
1453 if (generate_char
) {
1454 WebKeyboardEvent event_char
= event_up
;
1455 event_char
.type
= WebInputEvent::Char
;
1456 // keyIdentifier is an empty string, unless the Enter key was pressed.
1457 // This behavior is not standard (keyIdentifier itself is not even a
1458 // standard any more), but it matches the actual behavior in Blink.
1459 if (code
!= ui::VKEY_RETURN
)
1460 event_char
.keyIdentifier
[0] = '\0';
1461 HandleInputEventOnViewOrPopup(event_char
);
1464 HandleInputEventOnViewOrPopup(event_up
);
1467 void EventSender::EnableDOMUIEventLogging() {}
1469 void EventSender::FireKeyboardEventsToElement() {}
1471 void EventSender::ClearKillRing() {}
1473 std::vector
<std::string
> EventSender::ContextClick() {
1474 if (force_layout_on_events_
) {
1478 UpdateClickCountForButton(WebMouseEvent::ButtonRight
);
1480 // Clears last context menu data because we need to know if the context menu
1481 // be requested after following mouse events.
1482 last_context_menu_data_
.reset();
1484 // Generate right mouse down and up.
1485 WebMouseEvent event
;
1486 // This is a hack to work around only allowing a single pressed button since
1487 // we want to test the case where both the left and right mouse buttons are
1489 if (pressed_button_
== WebMouseEvent::ButtonNone
) {
1490 pressed_button_
= WebMouseEvent::ButtonRight
;
1492 InitMouseEvent(WebInputEvent::MouseDown
,
1493 WebMouseEvent::ButtonRight
,
1495 GetCurrentEventTimeSec(),
1499 HandleInputEventOnViewOrPopup(event
);
1502 InitMouseEvent(WebInputEvent::MouseUp
,
1503 WebMouseEvent::ButtonRight
,
1505 GetCurrentEventTimeSec(),
1509 HandleInputEventOnViewOrPopup(event
);
1511 pressed_button_
= WebMouseEvent::ButtonNone
;
1514 std::vector
<std::string
> menu_items
= MakeMenuItemStringsFor(last_context_menu_data_
.get(), delegate_
);
1515 last_context_menu_data_
.reset();
1519 void EventSender::TextZoomIn() {
1520 view_
->setTextZoomFactor(view_
->textZoomFactor() * 1.2f
);
1523 void EventSender::TextZoomOut() {
1524 view_
->setTextZoomFactor(view_
->textZoomFactor() / 1.2f
);
1527 void EventSender::ZoomPageIn() {
1528 const std::vector
<WebTestProxyBase
*>& window_list
=
1529 interfaces_
->GetWindowList();
1531 for (size_t i
= 0; i
< window_list
.size(); ++i
) {
1532 window_list
.at(i
)->GetWebView()->setZoomLevel(
1533 window_list
.at(i
)->GetWebView()->zoomLevel() + 1);
1537 void EventSender::ZoomPageOut() {
1538 const std::vector
<WebTestProxyBase
*>& window_list
=
1539 interfaces_
->GetWindowList();
1541 for (size_t i
= 0; i
< window_list
.size(); ++i
) {
1542 window_list
.at(i
)->GetWebView()->setZoomLevel(
1543 window_list
.at(i
)->GetWebView()->zoomLevel() - 1);
1547 void EventSender::SetPageZoomFactor(double zoom_factor
) {
1548 const std::vector
<WebTestProxyBase
*>& window_list
=
1549 interfaces_
->GetWindowList();
1551 for (size_t i
= 0; i
< window_list
.size(); ++i
) {
1552 window_list
.at(i
)->GetWebView()->setZoomLevel(
1553 ZoomFactorToZoomLevel(zoom_factor
));
1557 void EventSender::SetPageScaleFactor(float scale_factor
, int x
, int y
) {
1558 view_
->setPageScaleFactor(scale_factor
, WebPoint(x
, y
));
1561 void EventSender::SetPageScaleFactorLimits(float min_scale
, float max_scale
) {
1562 view_
->setDefaultPageScaleLimits(min_scale
, max_scale
);
1565 void EventSender::ClearTouchPoints() {
1566 touch_points_
.clear();
1569 void EventSender::ThrowTouchPointError() {
1570 v8::Isolate
* isolate
= blink::mainThreadIsolate();
1571 isolate
->ThrowException(v8::Exception::TypeError(
1572 gin::StringToV8(isolate
, "Invalid touch point.")));
1575 void EventSender::ReleaseTouchPoint(unsigned index
) {
1576 if (index
>= touch_points_
.size()) {
1577 ThrowTouchPointError();
1581 WebTouchPoint
* touch_point
= &touch_points_
[index
];
1582 touch_point
->state
= WebTouchPoint::StateReleased
;
1585 void EventSender::UpdateTouchPoint(unsigned index
, float x
, float y
) {
1586 if (index
>= touch_points_
.size()) {
1587 ThrowTouchPointError();
1591 WebTouchPoint
* touch_point
= &touch_points_
[index
];
1592 touch_point
->state
= WebTouchPoint::StateMoved
;
1593 touch_point
->position
= WebFloatPoint(x
, y
);
1594 touch_point
->screenPosition
= touch_point
->position
;
1597 void EventSender::CancelTouchPoint(unsigned index
) {
1598 if (index
>= touch_points_
.size()) {
1599 ThrowTouchPointError();
1603 WebTouchPoint
* touch_point
= &touch_points_
[index
];
1604 touch_point
->state
= WebTouchPoint::StateCancelled
;
1607 void EventSender::SetTouchModifier(const std::string
& key_name
,
1610 if (key_name
== "shift")
1611 mask
= WebInputEvent::ShiftKey
;
1612 else if (key_name
== "alt")
1613 mask
= WebInputEvent::AltKey
;
1614 else if (key_name
== "ctrl")
1615 mask
= WebInputEvent::ControlKey
;
1616 else if (key_name
== "meta")
1617 mask
= WebInputEvent::MetaKey
;
1620 touch_modifiers_
|= mask
;
1622 touch_modifiers_
&= ~mask
;
1625 void EventSender::SetTouchCancelable(bool cancelable
) {
1626 touch_cancelable_
= cancelable
;
1629 void EventSender::DumpFilenameBeingDragged() {
1630 if (current_drag_data_
.isNull())
1634 WebVector
<WebDragData::Item
> items
= current_drag_data_
.items();
1635 for (size_t i
= 0; i
< items
.size(); ++i
) {
1636 if (items
[i
].storageType
== WebDragData::Item::StorageTypeBinaryData
) {
1637 filename
= items
[i
].title
;
1641 delegate_
->PrintMessage(std::string("Filename being dragged: ") +
1642 filename
.utf8().data() + "\n");
1645 void EventSender::GestureFlingCancel() {
1646 WebGestureEvent event
;
1647 event
.type
= WebInputEvent::GestureFlingCancel
;
1648 event
.timeStampSeconds
= GetCurrentEventTimeSec();
1650 if (force_layout_on_events_
)
1653 HandleInputEventOnViewOrPopup(event
);
1656 void EventSender::GestureFlingStart(float x
,
1660 gin::Arguments
* args
) {
1661 WebGestureEvent event
;
1662 event
.type
= WebInputEvent::GestureFlingStart
;
1664 std::string device_string
;
1665 if (!args
->PeekNext().IsEmpty() && args
->PeekNext()->IsString())
1666 args
->GetNext(&device_string
);
1668 if (device_string
== kSourceDeviceStringTouchpad
) {
1669 event
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
1670 } else if (device_string
== kSourceDeviceStringTouchscreen
) {
1671 event
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
1679 event
.globalX
= event
.x
;
1680 event
.globalY
= event
.y
;
1682 event
.data
.flingStart
.velocityX
= velocity_x
;
1683 event
.data
.flingStart
.velocityY
= velocity_y
;
1684 event
.timeStampSeconds
= GetCurrentEventTimeSec();
1686 if (force_layout_on_events_
)
1689 HandleInputEventOnViewOrPopup(event
);
1692 void EventSender::GestureScrollFirstPoint(int x
, int y
) {
1693 current_gesture_location_
= WebPoint(x
, y
);
1696 void EventSender::TouchStart() {
1697 SendCurrentTouchEvent(WebInputEvent::TouchStart
);
1700 void EventSender::TouchMove() {
1701 SendCurrentTouchEvent(WebInputEvent::TouchMove
);
1704 void EventSender::TouchCancel() {
1705 SendCurrentTouchEvent(WebInputEvent::TouchCancel
);
1708 void EventSender::TouchEnd() {
1709 SendCurrentTouchEvent(WebInputEvent::TouchEnd
);
1712 void EventSender::LeapForward(int milliseconds
) {
1713 if (is_drag_mode_
&& pressed_button_
== WebMouseEvent::ButtonLeft
&&
1714 !replaying_saved_events_
) {
1715 SavedEvent saved_event
;
1716 saved_event
.type
= SavedEvent::TYPE_LEAP_FORWARD
;
1717 saved_event
.milliseconds
= milliseconds
;
1718 mouse_event_queue_
.push_back(saved_event
);
1720 DoLeapForward(milliseconds
);
1724 void EventSender::BeginDragWithFiles(const std::vector
<std::string
>& files
) {
1725 current_drag_data_
.initialize();
1726 WebVector
<WebString
> absolute_filenames(files
.size());
1727 for (size_t i
= 0; i
< files
.size(); ++i
) {
1728 WebDragData::Item item
;
1729 item
.storageType
= WebDragData::Item::StorageTypeFilename
;
1730 item
.filenameData
= delegate_
->GetAbsoluteWebStringFromUTF8Path(files
[i
]);
1731 current_drag_data_
.addItem(item
);
1732 absolute_filenames
[i
] = item
.filenameData
;
1734 current_drag_data_
.setFilesystemId(
1735 delegate_
->RegisterIsolatedFileSystem(absolute_filenames
));
1736 current_drag_effects_allowed_
= blink::WebDragOperationCopy
;
1738 // Provide a drag source.
1739 view_
->dragTargetDragEnter(current_drag_data_
,
1742 current_drag_effects_allowed_
,
1744 // |is_drag_mode_| saves events and then replays them later. We don't
1746 is_drag_mode_
= false;
1748 // Make the rest of eventSender think a drag is in progress.
1749 pressed_button_
= WebMouseEvent::ButtonLeft
;
1752 void EventSender::AddTouchPoint(gin::Arguments
* args
) {
1755 if (!args
->GetNext(&x
) || !args
->GetNext(&y
)) {
1760 WebTouchPoint touch_point
;
1761 touch_point
.state
= WebTouchPoint::StatePressed
;
1762 touch_point
.position
= WebFloatPoint(static_cast<float>(x
),
1763 static_cast<float>(y
));
1764 touch_point
.screenPosition
= touch_point
.position
;
1766 if (!args
->PeekNext().IsEmpty()) {
1768 if (!args
->GetNext(&radius_x
)) {
1773 double radius_y
= radius_x
;
1774 if (!args
->PeekNext().IsEmpty()) {
1775 if (!args
->GetNext(&radius_y
)) {
1781 touch_point
.radiusX
= static_cast<float>(radius_x
);
1782 touch_point
.radiusY
= static_cast<float>(radius_y
);
1786 for (size_t i
= 0; i
< touch_points_
.size(); i
++) {
1787 if (touch_points_
[i
].id
== lowest_id
)
1790 touch_point
.id
= lowest_id
;
1791 touch_points_
.push_back(touch_point
);
1794 void EventSender::MouseDragBegin() {
1795 WebMouseWheelEvent event
;
1796 InitMouseEvent(WebInputEvent::MouseWheel
,
1797 WebMouseEvent::ButtonNone
,
1799 GetCurrentEventTimeSec(),
1803 event
.phase
= WebMouseWheelEvent::PhaseBegan
;
1804 event
.hasPreciseScrollingDeltas
= true;
1805 HandleInputEventOnViewOrPopup(event
);
1808 void EventSender::MouseDragEnd() {
1809 WebMouseWheelEvent event
;
1810 InitMouseEvent(WebInputEvent::MouseWheel
,
1811 WebMouseEvent::ButtonNone
,
1813 GetCurrentEventTimeSec(),
1817 event
.phase
= WebMouseWheelEvent::PhaseEnded
;
1818 event
.hasPreciseScrollingDeltas
= true;
1819 HandleInputEventOnViewOrPopup(event
);
1822 void EventSender::GestureScrollBegin(gin::Arguments
* args
) {
1823 GestureEvent(WebInputEvent::GestureScrollBegin
, args
);
1826 void EventSender::GestureScrollEnd(gin::Arguments
* args
) {
1827 GestureEvent(WebInputEvent::GestureScrollEnd
, args
);
1830 void EventSender::GestureScrollUpdate(gin::Arguments
* args
) {
1831 GestureEvent(WebInputEvent::GestureScrollUpdate
, args
);
1834 void EventSender::GesturePinchBegin(gin::Arguments
* args
) {
1835 GestureEvent(WebInputEvent::GesturePinchBegin
, args
);
1838 void EventSender::GesturePinchEnd(gin::Arguments
* args
) {
1839 GestureEvent(WebInputEvent::GesturePinchEnd
, args
);
1842 void EventSender::GesturePinchUpdate(gin::Arguments
* args
) {
1843 GestureEvent(WebInputEvent::GesturePinchUpdate
, args
);
1846 void EventSender::GestureTap(gin::Arguments
* args
) {
1847 GestureEvent(WebInputEvent::GestureTap
, args
);
1850 void EventSender::GestureTapDown(gin::Arguments
* args
) {
1851 GestureEvent(WebInputEvent::GestureTapDown
, args
);
1854 void EventSender::GestureShowPress(gin::Arguments
* args
) {
1855 GestureEvent(WebInputEvent::GestureShowPress
, args
);
1858 void EventSender::GestureTapCancel(gin::Arguments
* args
) {
1859 GestureEvent(WebInputEvent::GestureTapCancel
, args
);
1862 void EventSender::GestureLongPress(gin::Arguments
* args
) {
1863 GestureEvent(WebInputEvent::GestureLongPress
, args
);
1866 void EventSender::GestureLongTap(gin::Arguments
* args
) {
1867 GestureEvent(WebInputEvent::GestureLongTap
, args
);
1870 void EventSender::GestureTwoFingerTap(gin::Arguments
* args
) {
1871 GestureEvent(WebInputEvent::GestureTwoFingerTap
, args
);
1874 void EventSender::ContinuousMouseScrollBy(gin::Arguments
* args
) {
1875 WebMouseWheelEvent event
;
1876 InitMouseWheelEvent(args
, true, &event
);
1877 HandleInputEventOnViewOrPopup(event
);
1880 void EventSender::MouseMoveTo(gin::Arguments
* args
) {
1881 if (force_layout_on_events_
)
1886 if (!args
->GetNext(&x
) || !args
->GetNext(&y
)) {
1890 WebPoint
mouse_pos(static_cast<int>(x
), static_cast<int>(y
));
1893 if (!args
->PeekNext().IsEmpty())
1894 modifiers
= GetKeyModifiersFromV8(args
->PeekNext());
1896 if (is_drag_mode_
&& pressed_button_
== WebMouseEvent::ButtonLeft
&&
1897 !replaying_saved_events_
) {
1898 SavedEvent saved_event
;
1899 saved_event
.type
= SavedEvent::TYPE_MOUSE_MOVE
;
1900 saved_event
.pos
= mouse_pos
;
1901 saved_event
.modifiers
= modifiers
;
1902 mouse_event_queue_
.push_back(saved_event
);
1904 WebMouseEvent event
;
1905 InitMouseEvent(WebInputEvent::MouseMove
,
1908 GetCurrentEventTimeSec(),
1916 void EventSender::TrackpadScrollBegin() {
1917 WebMouseWheelEvent event
;
1918 InitMouseEvent(WebInputEvent::MouseWheel
,
1919 WebMouseEvent::ButtonNone
,
1921 GetCurrentEventTimeSec(),
1925 event
.phase
= blink::WebMouseWheelEvent::PhaseBegan
;
1926 event
.hasPreciseScrollingDeltas
= true;
1927 HandleInputEventOnViewOrPopup(event
);
1930 void EventSender::TrackpadScroll(gin::Arguments
* args
) {
1931 WebMouseWheelEvent event
;
1932 InitMouseWheelEvent(args
, true, &event
);
1933 event
.phase
= blink::WebMouseWheelEvent::PhaseChanged
;
1934 event
.hasPreciseScrollingDeltas
= true;
1935 HandleInputEventOnViewOrPopup(event
);
1938 void EventSender::TrackpadScrollEnd() {
1939 WebMouseWheelEvent event
;
1940 InitMouseEvent(WebInputEvent::MouseWheel
,
1941 WebMouseEvent::ButtonNone
,
1943 GetCurrentEventTimeSec(),
1947 event
.phase
= WebMouseWheelEvent::PhaseEnded
;
1948 event
.hasPreciseScrollingDeltas
= true;
1949 HandleInputEventOnViewOrPopup(event
);
1952 void EventSender::MouseScrollBy(gin::Arguments
* args
) {
1953 WebMouseWheelEvent event
;
1954 InitMouseWheelEvent(args
, false, &event
);
1955 HandleInputEventOnViewOrPopup(event
);
1958 void EventSender::MouseMomentumBegin() {
1959 WebMouseWheelEvent event
;
1960 InitMouseEvent(WebInputEvent::MouseWheel
,
1961 WebMouseEvent::ButtonNone
,
1963 GetCurrentEventTimeSec(),
1967 event
.momentumPhase
= WebMouseWheelEvent::PhaseBegan
;
1968 event
.hasPreciseScrollingDeltas
= true;
1969 HandleInputEventOnViewOrPopup(event
);
1972 void EventSender::MouseMomentumBegin2(gin::Arguments
* args
) {
1973 WebMouseWheelEvent event
;
1974 InitMouseWheelEvent(args
, true, &event
);
1975 event
.momentumPhase
= WebMouseWheelEvent::PhaseBegan
;
1976 event
.hasPreciseScrollingDeltas
= true;
1977 HandleInputEventOnViewOrPopup(event
);
1980 void EventSender::MouseMomentumScrollBy(gin::Arguments
* args
) {
1981 WebMouseWheelEvent event
;
1982 InitMouseWheelEvent(args
, true, &event
);
1983 event
.momentumPhase
= WebMouseWheelEvent::PhaseChanged
;
1984 event
.hasPreciseScrollingDeltas
= true;
1985 HandleInputEventOnViewOrPopup(event
);
1988 void EventSender::MouseMomentumEnd() {
1989 WebMouseWheelEvent event
;
1990 InitMouseEvent(WebInputEvent::MouseWheel
,
1991 WebMouseEvent::ButtonNone
,
1993 GetCurrentEventTimeSec(),
1997 event
.momentumPhase
= WebMouseWheelEvent::PhaseEnded
;
1998 event
.hasPreciseScrollingDeltas
= true;
1999 HandleInputEventOnViewOrPopup(event
);
2002 void EventSender::ScheduleAsynchronousClick(int button_number
, int modifiers
) {
2003 delegate_
->PostTask(new MouseDownTask(this, button_number
, modifiers
));
2004 delegate_
->PostTask(new MouseUpTask(this, button_number
, modifiers
));
2007 void EventSender::ScheduleAsynchronousKeyDown(const std::string
& code_str
,
2009 KeyLocationCode location
) {
2010 delegate_
->PostTask(new KeyDownTask(this, code_str
, modifiers
, location
));
2013 double EventSender::GetCurrentEventTimeSec() {
2014 return (delegate_
->GetCurrentTimeInMillisecond() + time_offset_ms_
) / 1000.0;
2017 void EventSender::DoLeapForward(int milliseconds
) {
2018 time_offset_ms_
+= milliseconds
;
2021 void EventSender::SendCurrentTouchEvent(WebInputEvent::Type type
) {
2022 DCHECK_GT(static_cast<unsigned>(WebTouchEvent::touchesLengthCap
),
2023 touch_points_
.size());
2024 if (force_layout_on_events_
)
2027 WebTouchEvent touch_event
;
2028 touch_event
.type
= type
;
2029 touch_event
.modifiers
= touch_modifiers_
;
2030 touch_event
.cancelable
= touch_cancelable_
;
2031 touch_event
.timeStampSeconds
= GetCurrentEventTimeSec();
2032 touch_event
.touchesLength
= touch_points_
.size();
2033 for (size_t i
= 0; i
< touch_points_
.size(); ++i
)
2034 touch_event
.touches
[i
] = touch_points_
[i
];
2035 HandleInputEventOnViewOrPopup(touch_event
);
2037 for (size_t i
= 0; i
< touch_points_
.size(); ++i
) {
2038 WebTouchPoint
* touch_point
= &touch_points_
[i
];
2039 if (touch_point
->state
== WebTouchPoint::StateReleased
) {
2040 touch_points_
.erase(touch_points_
.begin() + i
);
2043 touch_point
->state
= WebTouchPoint::StateStationary
;
2047 void EventSender::GestureEvent(WebInputEvent::Type type
,
2048 gin::Arguments
* args
) {
2049 WebGestureEvent event
;
2052 // If the first argument is a string, it is to specify the device, otherwise
2053 // the device is assumed to be a touchscreen (since most tests were written
2055 event
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
2056 if (args
->PeekNext()->IsString()) {
2057 std::string device_string
;
2058 if (!args
->GetNext(&device_string
)) {
2062 if (device_string
== kSourceDeviceStringTouchpad
) {
2063 event
.sourceDevice
= blink::WebGestureDeviceTouchpad
;
2064 } else if (device_string
== kSourceDeviceStringTouchscreen
) {
2065 event
.sourceDevice
= blink::WebGestureDeviceTouchscreen
;
2074 if (!args
->GetNext(&x
) || !args
->GetNext(&y
)) {
2080 case WebInputEvent::GestureScrollUpdate
:
2082 bool preventPropagation
= false;
2083 if (!args
->PeekNext().IsEmpty()) {
2084 if (!args
->GetNext(&preventPropagation
)) {
2090 event
.data
.scrollUpdate
.deltaX
= static_cast<float>(x
);
2091 event
.data
.scrollUpdate
.deltaY
= static_cast<float>(y
);
2092 event
.data
.scrollUpdate
.preventPropagation
= preventPropagation
;
2093 event
.x
= current_gesture_location_
.x
;
2094 event
.y
= current_gesture_location_
.y
;
2095 current_gesture_location_
.x
=
2096 current_gesture_location_
.x
+ event
.data
.scrollUpdate
.deltaX
;
2097 current_gesture_location_
.y
=
2098 current_gesture_location_
.y
+ event
.data
.scrollUpdate
.deltaY
;
2101 case WebInputEvent::GestureScrollBegin
:
2102 current_gesture_location_
= WebPoint(x
, y
);
2103 event
.x
= current_gesture_location_
.x
;
2104 event
.y
= current_gesture_location_
.y
;
2106 case WebInputEvent::GestureScrollEnd
:
2107 case WebInputEvent::GestureFlingStart
:
2108 event
.x
= current_gesture_location_
.x
;
2109 event
.y
= current_gesture_location_
.y
;
2111 case WebInputEvent::GesturePinchBegin
:
2112 case WebInputEvent::GesturePinchEnd
:
2113 current_gesture_location_
= WebPoint(x
, y
);
2114 event
.x
= current_gesture_location_
.x
;
2115 event
.y
= current_gesture_location_
.y
;
2117 case WebInputEvent::GesturePinchUpdate
:
2120 if (!args
->PeekNext().IsEmpty()) {
2121 if (!args
->GetNext(&scale
)) {
2126 event
.data
.pinchUpdate
.scale
= scale
;
2127 current_gesture_location_
= WebPoint(x
, y
);
2128 event
.x
= current_gesture_location_
.x
;
2129 event
.y
= current_gesture_location_
.y
;
2132 case WebInputEvent::GestureTap
:
2134 float tap_count
= 1;
2137 if (!args
->PeekNext().IsEmpty()) {
2138 if (!args
->GetNext(&tap_count
)) {
2143 if (!args
->PeekNext().IsEmpty()) {
2144 if (!args
->GetNext(&width
)) {
2149 if (!args
->PeekNext().IsEmpty()) {
2150 if (!args
->GetNext(&height
)) {
2155 event
.data
.tap
.tapCount
= tap_count
;
2156 event
.data
.tap
.width
= width
;
2157 event
.data
.tap
.height
= height
;
2162 case WebInputEvent::GestureTapUnconfirmed
:
2163 if (!args
->PeekNext().IsEmpty()) {
2165 if (!args
->GetNext(&tap_count
)) {
2169 event
.data
.tap
.tapCount
= tap_count
;
2171 event
.data
.tap
.tapCount
= 1;
2176 case WebInputEvent::GestureTapDown
:
2180 if (!args
->PeekNext().IsEmpty()) {
2181 if (!args
->GetNext(&width
)) {
2186 if (!args
->PeekNext().IsEmpty()) {
2187 if (!args
->GetNext(&height
)) {
2194 event
.data
.tapDown
.width
= width
;
2195 event
.data
.tapDown
.height
= height
;
2198 case WebInputEvent::GestureShowPress
:
2202 if (!args
->PeekNext().IsEmpty()) {
2203 if (!args
->GetNext(&width
)) {
2207 if (!args
->PeekNext().IsEmpty()) {
2208 if (!args
->GetNext(&height
)) {
2216 event
.data
.showPress
.width
= width
;
2217 event
.data
.showPress
.height
= height
;
2220 case WebInputEvent::GestureTapCancel
:
2224 case WebInputEvent::GestureLongPress
:
2227 if (!args
->PeekNext().IsEmpty()) {
2229 if (!args
->GetNext(&width
)) {
2233 event
.data
.longPress
.width
= width
;
2234 if (!args
->PeekNext().IsEmpty()) {
2236 if (!args
->GetNext(&height
)) {
2240 event
.data
.longPress
.height
= height
;
2244 case WebInputEvent::GestureLongTap
:
2247 if (!args
->PeekNext().IsEmpty()) {
2249 if (!args
->GetNext(&width
)) {
2253 event
.data
.longPress
.width
= width
;
2254 if (!args
->PeekNext().IsEmpty()) {
2256 if (!args
->GetNext(&height
)) {
2260 event
.data
.longPress
.height
= height
;
2264 case WebInputEvent::GestureTwoFingerTap
:
2267 if (!args
->PeekNext().IsEmpty()) {
2268 float first_finger_width
;
2269 if (!args
->GetNext(&first_finger_width
)) {
2273 event
.data
.twoFingerTap
.firstFingerWidth
= first_finger_width
;
2274 if (!args
->PeekNext().IsEmpty()) {
2275 float first_finger_height
;
2276 if (!args
->GetNext(&first_finger_height
)) {
2280 event
.data
.twoFingerTap
.firstFingerHeight
= first_finger_height
;
2288 event
.globalX
= event
.x
;
2289 event
.globalY
= event
.y
;
2290 event
.timeStampSeconds
= GetCurrentEventTimeSec();
2292 if (force_layout_on_events_
)
2295 bool result
= HandleInputEventOnViewOrPopup(event
);
2297 // Long press might start a drag drop session. Complete it if so.
2298 if (type
== WebInputEvent::GestureLongPress
&& !current_drag_data_
.isNull()) {
2299 WebMouseEvent mouse_event
;
2300 InitMouseEvent(WebInputEvent::MouseDown
,
2303 GetCurrentEventTimeSec(),
2308 FinishDragAndDrop(mouse_event
, blink::WebDragOperationNone
);
2310 args
->Return(result
);
2313 void EventSender::UpdateClickCountForButton(
2314 WebMouseEvent::Button button_type
) {
2315 if ((GetCurrentEventTimeSec() - last_click_time_sec_
<
2316 kMultipleClickTimeSec
) &&
2317 (!OutsideMultiClickRadius(last_mouse_pos_
, last_click_pos_
)) &&
2318 (button_type
== last_button_type_
)) {
2322 last_button_type_
= button_type
;
2326 void EventSender::InitMouseWheelEvent(gin::Arguments
* args
,
2328 WebMouseWheelEvent
* event
) {
2329 // Force a layout here just to make sure every position has been
2330 // determined before we send events (as well as all the other methods
2331 // that send an event do).
2332 if (force_layout_on_events_
)
2336 if (!args
->GetNext(&horizontal
)) {
2341 if (!args
->GetNext(&vertical
)) {
2347 bool has_precise_scrolling_deltas
= false;
2349 bool can_scroll
= true;
2350 if (!args
->PeekNext().IsEmpty()) {
2351 args
->GetNext(&paged
);
2352 if (!args
->PeekNext().IsEmpty()) {
2353 args
->GetNext(&has_precise_scrolling_deltas
);
2354 if (!args
->PeekNext().IsEmpty()) {
2355 v8::Handle
<v8::Value
> value
;
2356 args
->GetNext(&value
);
2357 modifiers
= GetKeyModifiersFromV8(value
);
2358 if (!args
->PeekNext().IsEmpty())
2359 args
->GetNext(&can_scroll
);
2364 InitMouseEvent(WebInputEvent::MouseWheel
,
2367 GetCurrentEventTimeSec(),
2371 event
->wheelTicksX
= static_cast<float>(horizontal
);
2372 event
->wheelTicksY
= static_cast<float>(vertical
);
2373 event
->deltaX
= event
->wheelTicksX
;
2374 event
->deltaY
= event
->wheelTicksY
;
2375 event
->scrollByPage
= paged
;
2376 event
->hasPreciseScrollingDeltas
= has_precise_scrolling_deltas
;
2377 event
->canScroll
= can_scroll
;
2379 event
->wheelTicksX
/= kScrollbarPixelsPerTick
;
2380 event
->wheelTicksY
/= kScrollbarPixelsPerTick
;
2382 event
->deltaX
*= kScrollbarPixelsPerTick
;
2383 event
->deltaY
*= kScrollbarPixelsPerTick
;
2387 void EventSender::FinishDragAndDrop(const WebMouseEvent
& e
,
2388 blink::WebDragOperation drag_effect
) {
2389 WebPoint
client_point(e
.x
, e
.y
);
2390 WebPoint
screen_point(e
.globalX
, e
.globalY
);
2391 current_drag_effect_
= drag_effect
;
2392 if (current_drag_effect_
) {
2393 // Specifically pass any keyboard modifiers to the drop method. This allows
2394 // tests to control the drop type (i.e. copy or move).
2395 view_
->dragTargetDrop(client_point
, screen_point
, e
.modifiers
);
2397 view_
->dragTargetDragLeave();
2399 view_
->dragSourceEndedAt(client_point
, screen_point
, current_drag_effect_
);
2400 view_
->dragSourceSystemDragEnded();
2402 current_drag_data_
.reset();
2405 void EventSender::DoMouseUp(const WebMouseEvent
& e
) {
2406 HandleInputEventOnViewOrPopup(e
);
2408 pressed_button_
= WebMouseEvent::ButtonNone
;
2409 last_click_time_sec_
= e
.timeStampSeconds
;
2410 last_click_pos_
= last_mouse_pos_
;
2412 // If we're in a drag operation, complete it.
2413 if (current_drag_data_
.isNull())
2416 WebPoint
client_point(e
.x
, e
.y
);
2417 WebPoint
screen_point(e
.globalX
, e
.globalY
);
2420 view_
->dragTargetDragOver(
2421 client_point
, screen_point
, current_drag_effects_allowed_
, 0));
2424 void EventSender::DoMouseMove(const WebMouseEvent
& e
) {
2425 last_mouse_pos_
= WebPoint(e
.x
, e
.y
);
2427 HandleInputEventOnViewOrPopup(e
);
2429 if (pressed_button_
== WebMouseEvent::ButtonNone
||
2430 current_drag_data_
.isNull()) {
2434 WebPoint
client_point(e
.x
, e
.y
);
2435 WebPoint
screen_point(e
.globalX
, e
.globalY
);
2436 current_drag_effect_
= view_
->dragTargetDragOver(
2437 client_point
, screen_point
, current_drag_effects_allowed_
, 0);
2440 void EventSender::ReplaySavedEvents() {
2441 replaying_saved_events_
= true;
2442 while (!mouse_event_queue_
.empty()) {
2443 SavedEvent e
= mouse_event_queue_
.front();
2444 mouse_event_queue_
.pop_front();
2447 case SavedEvent::TYPE_MOUSE_MOVE
: {
2448 WebMouseEvent event
;
2449 InitMouseEvent(WebInputEvent::MouseMove
,
2452 GetCurrentEventTimeSec(),
2459 case SavedEvent::TYPE_LEAP_FORWARD
:
2460 DoLeapForward(e
.milliseconds
);
2462 case SavedEvent::TYPE_MOUSE_UP
: {
2463 WebMouseEvent event
;
2464 InitMouseEvent(WebInputEvent::MouseUp
,
2467 GetCurrentEventTimeSec(),
2479 replaying_saved_events_
= false;
2482 bool EventSender::HandleInputEventOnViewOrPopup(const WebInputEvent
& event
) {
2483 if (WebPagePopup
* popup
= view_
->pagePopup()) {
2484 if (!WebInputEvent::isKeyboardEventType(event
.type
))
2485 return popup
->handleInputEvent(event
);
2487 return view_
->handleInputEvent(event
);
2490 } // namespace content