blob: 1960be99e20fa3f6a35c36f14288099ac31c78e5 [file] [log] [blame]
[email protected]3db130e2014-03-27 08:14:481// 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.
4
5#include "content/shell/renderer/test_runner/event_sender.h"
6
7#include "base/basictypes.h"
8#include "base/logging.h"
habib.virji565c80c2015-02-06 12:26:439#include "base/strings/string_util.h"
[email protected]3db130e2014-03-27 08:14:4810#include "base/strings/stringprintf.h"
[email protected]b32fe542014-04-30 08:42:0611#include "content/public/common/page_zoom.h"
[email protected]f656a652014-07-25 12:19:5212#include "content/shell/renderer/test_runner/mock_spell_check.h"
[email protected]8ed8bf432014-08-11 19:47:5513#include "content/shell/renderer/test_runner/test_interfaces.h"
abhishek.a21ca9b5602014-09-19 07:33:3314#include "content/shell/renderer/test_runner/web_test_delegate.h"
[email protected]a1640e42014-05-14 13:43:3215#include "content/shell/renderer/test_runner/web_test_proxy.h"
[email protected]3db130e2014-03-27 08:14:4816#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"
tkent588765612014-11-28 01:07:4824#include "third_party/WebKit/public/web/WebPagePopup.h"
[email protected]3db130e2014-03-27 08:14:4825#include "third_party/WebKit/public/web/WebView.h"
habib.virji565c80c2015-02-06 12:26:4326#include "ui/events/keycodes/dom4/keycode_converter.h"
[email protected]a731f1a92014-04-17 19:31:0627#include "ui/events/keycodes/keyboard_codes.h"
[email protected]3db130e2014-03-27 08:14:4828#include "v8/include/v8.h"
29
[email protected]3db130e2014-03-27 08:14:4830using blink::WebContextMenuData;
31using blink::WebDragData;
32using blink::WebDragOperationsMask;
33using blink::WebFloatPoint;
34using blink::WebFrame;
35using blink::WebGestureEvent;
36using blink::WebInputEvent;
37using blink::WebKeyboardEvent;
[email protected]f9634a82014-08-05 13:10:1938using blink::WebMenuItemInfo;
[email protected]3db130e2014-03-27 08:14:4839using blink::WebMouseEvent;
40using blink::WebMouseWheelEvent;
tkent588765612014-11-28 01:07:4841using blink::WebPagePopup;
[email protected]3db130e2014-03-27 08:14:4842using blink::WebPoint;
43using blink::WebString;
44using blink::WebTouchEvent;
45using blink::WebTouchPoint;
46using blink::WebVector;
47using blink::WebView;
48
[email protected]3db130e2014-03-27 08:14:4849namespace content {
50
51namespace {
52
53void InitMouseEvent(WebInputEvent::Type t,
54 WebMouseEvent::Button b,
55 const WebPoint& pos,
56 double time_stamp,
57 int click_count,
58 int modifiers,
59 WebMouseEvent* e) {
60 e->type = t;
61 e->button = b;
62 e->modifiers = modifiers;
63 e->x = pos.x;
64 e->y = pos.y;
65 e->globalX = pos.x;
66 e->globalY = pos.y;
67 e->timeStampSeconds = time_stamp;
68 e->clickCount = click_count;
69}
70
71int GetKeyModifier(const std::string& modifier_name) {
72 const char* characters = modifier_name.c_str();
73 if (!strcmp(characters, "ctrlKey")
74#ifndef __APPLE__
75 || !strcmp(characters, "addSelectionKey")
76#endif
77 ) {
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;
84#ifdef __APPLE__
85 } else if (!strcmp(characters, "metaKey") ||
86 !strcmp(characters, "addSelectionKey")) {
87 return WebInputEvent::MetaKey;
88#else
89 } else if (!strcmp(characters, "metaKey")) {
90 return WebInputEvent::MetaKey;
91#endif
92 } else if (!strcmp(characters, "autoRepeat")) {
93 return WebInputEvent::IsAutoRepeat;
94 } else if (!strcmp(characters, "copyKey")) {
95#ifdef __APPLE__
96 return WebInputEvent::AltKey;
97#else
98 return WebInputEvent::ControlKey;
99#endif
jinho.bangffc700e2014-11-17 04:05:26100 } 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;
[email protected]3db130e2014-03-27 08:14:48106 }
107
108 return 0;
109}
110
111int GetKeyModifiers(const std::vector<std::string>& modifier_names) {
112 int modifiers = 0;
113 for (std::vector<std::string>::const_iterator it = modifier_names.begin();
114 it != modifier_names.end(); ++it) {
115 modifiers |= GetKeyModifier(*it);
116 }
117 return modifiers;
118}
119
120int 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);
127 }
128 return GetKeyModifiers(modifier_names);
129}
130
131// Maximum distance (in space and time) for a mouse click to register as a
132// double or triple click.
133const double kMultipleClickTimeSec = 1;
134const int kMultipleClickRadiusPixels = 5;
[email protected]f9634a82014-08-05 13:10:19135const char kSubMenuDepthIdentifier[] = "_";
136const char kSubMenuIdentifier[] = " >";
sanjoy.pal362c3252014-08-26 08:07:08137const char kSeparatorIdentifier[] = "---------";
sanjoy.pala62675e2014-11-27 00:47:29138const char kDisabledIdentifier[] = "#";
139const char kCheckedIdentifier[] = "*";
[email protected]3db130e2014-03-27 08:14:48140
141bool 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;
144}
145
[email protected]f9634a82014-08-05 13:10:19146void 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) {
sanjoy.pala62675e2014-11-27 00:47:29149 std::string prefixCopy = prefix;
150 if (!customItems[i].enabled)
151 prefixCopy = kDisabledIdentifier + prefix;
152 if (customItems[i].checked)
153 prefixCopy = kCheckedIdentifier + prefix;
sanjoy.pal362c3252014-08-26 08:07:08154 if (customItems[i].type == blink::WebMenuItemInfo::Separator) {
sanjoy.pala62675e2014-11-27 00:47:29155 strings->push_back(prefixCopy + kSeparatorIdentifier);
sanjoy.pal362c3252014-08-26 08:07:08156 } else if (customItems[i].type == blink::WebMenuItemInfo::SubMenu) {
sanjoy.pala62675e2014-11-27 00:47:29157 strings->push_back(prefixCopy + customItems[i].label.utf8() +
sanjoy.pal2adb5c52015-01-13 11:26:49158 customItems[i].icon.utf8() + kSubMenuIdentifier);
sanjoy.pala62675e2014-11-27 00:47:29159 PopulateCustomItems(customItems[i].subMenuItems, prefixCopy +
[email protected]f9634a82014-08-05 13:10:19160 kSubMenuDepthIdentifier, strings);
161 } else {
sanjoy.pal2adb5c52015-01-13 11:26:49162 strings->push_back(prefixCopy + customItems[i].label.utf8() +
163 customItems[i].icon.utf8());
[email protected]f9634a82014-08-05 13:10:19164 }
165 }
166}
167
[email protected]3db130e2014-03-27 08:14:48168// 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
171// sense.
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
174// flags.
175// - Some test even checks actual string content. So providing it would be also
176// helpful.
177std::vector<std::string> MakeMenuItemStringsFor(
178 WebContextMenuData* context_menu,
[email protected]79ecada2014-05-04 05:16:16179 WebTestDelegate* delegate) {
[email protected]3db130e2014-03-27 08:14:48180 // These constants are based on Safari's context menu because tests are made
181 // for it.
182 static const char* kNonEditableMenuStrings[] = {
183 "Back",
184 "Reload Page",
185 "Open in Dashbaord",
186 "<separator>",
187 "View Source",
188 "Save Page As",
189 "Print Page",
190 "Inspect Element",
191 0
192 };
193 static const char* kEditableMenuStrings[] = {
194 "Cut",
195 "Copy",
196 "<separator>",
197 "Paste",
198 "Spelling and Grammar",
199 "Substitutions, Transformations",
200 "Font",
201 "Speech",
202 "Paragraph Direction",
203 "<separator>",
204 0
205 };
206
207 // This is possible because mouse events are cancelleable.
208 if (!context_menu)
209 return std::vector<std::string>();
210
211 std::vector<std::string> strings;
212
[email protected]f9634a82014-08-05 13:10:19213 // Populate custom menu items if provided by blink.
214 PopulateCustomItems(context_menu->customItems, "", &strings);
215
[email protected]3db130e2014-03-27 08:14:48216 if (context_menu->isEditable) {
217 for (const char** item = kEditableMenuStrings; *item; ++item) {
218 strings.push_back(*item);
219 }
220 WebVector<WebString> suggestions;
[email protected]f656a652014-07-25 12:19:52221 MockSpellCheck::FillSuggestionList(context_menu->misspelledWord,
222 &suggestions);
[email protected]3db130e2014-03-27 08:14:48223 for (size_t i = 0; i < suggestions.size(); ++i) {
224 strings.push_back(suggestions[i].utf8());
225 }
226 } else {
227 for (const char** item = kNonEditableMenuStrings; *item; ++item) {
228 strings.push_back(*item);
229 }
230 }
231
232 return strings;
233}
234
235// How much we should scroll per event - the value here is chosen to match the
236// WebKit impl and layout test results.
237const float kScrollbarPixelsPerTick = 40.0f;
238
239WebMouseEvent::Button GetButtonTypeFromButtonNumber(int button_code) {
240 if (!button_code)
241 return WebMouseEvent::ButtonLeft;
242 if (button_code == 2)
243 return WebMouseEvent::ButtonRight;
244 return WebMouseEvent::ButtonMiddle;
245}
246
[email protected]79ecada2014-05-04 05:16:16247class MouseDownTask : public WebMethodTask<EventSender> {
[email protected]3db130e2014-03-27 08:14:48248 public:
249 MouseDownTask(EventSender* obj, int button_number, int modifiers)
250 : WebMethodTask<EventSender>(obj),
251 button_number_(button_number),
252 modifiers_(modifiers) {}
253
dchenge933b3e2014-10-21 11:44:09254 void RunIfValid() override { object_->MouseDown(button_number_, modifiers_); }
[email protected]3db130e2014-03-27 08:14:48255
256 private:
257 int button_number_;
258 int modifiers_;
259};
260
[email protected]79ecada2014-05-04 05:16:16261class MouseUpTask : public WebMethodTask<EventSender> {
[email protected]3db130e2014-03-27 08:14:48262 public:
263 MouseUpTask(EventSender* obj, int button_number, int modifiers)
264 : WebMethodTask<EventSender>(obj),
265 button_number_(button_number),
266 modifiers_(modifiers) {}
267
dchenge933b3e2014-10-21 11:44:09268 void RunIfValid() override { object_->MouseUp(button_number_, modifiers_); }
[email protected]3db130e2014-03-27 08:14:48269
270 private:
271 int button_number_;
272 int modifiers_;
273};
274
[email protected]79ecada2014-05-04 05:16:16275class KeyDownTask : public WebMethodTask<EventSender> {
[email protected]3db130e2014-03-27 08:14:48276 public:
277 KeyDownTask(EventSender* obj,
278 const std::string code_str,
279 int modifiers,
280 KeyLocationCode location)
281 : WebMethodTask<EventSender>(obj),
282 code_str_(code_str),
283 modifiers_(modifiers),
284 location_(location) {}
285
dchenge933b3e2014-10-21 11:44:09286 void RunIfValid() override {
abhishek.a21ab71acb2014-09-12 16:46:31287 object_->KeyDown(code_str_, modifiers_, location_);
[email protected]3db130e2014-03-27 08:14:48288 }
289
290 private:
291 std::string code_str_;
292 int modifiers_;
293 KeyLocationCode location_;
294};
295
296bool 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';
299}
300
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|.
304bool 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)
312 return false;
313
314 switch (event.windowsKeyCode) {
[email protected]a731f1a92014-04-17 19:31:06315 case ui::VKEY_LEFT:
[email protected]3db130e2014-03-27 08:14:48316 *name = "MoveToBeginningOfLine";
317 break;
[email protected]a731f1a92014-04-17 19:31:06318 case ui::VKEY_RIGHT:
[email protected]3db130e2014-03-27 08:14:48319 *name = "MoveToEndOfLine";
320 break;
[email protected]a731f1a92014-04-17 19:31:06321 case ui::VKEY_UP:
[email protected]3db130e2014-03-27 08:14:48322 *name = "MoveToBeginningOfDocument";
323 break;
[email protected]a731f1a92014-04-17 19:31:06324 case ui::VKEY_DOWN:
[email protected]3db130e2014-03-27 08:14:48325 *name = "MoveToEndOfDocument";
326 break;
327 default:
328 return false;
329 }
330
331 if (event.modifiers & WebKeyboardEvent::ShiftKey)
332 name->append("AndModifySelection");
333
334 return true;
335#else
336 return false;
337#endif
338}
339
[email protected]a731f1a92014-04-17 19:31:06340bool 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;
345#else
346 return !!(event.modifiers & WebInputEvent::AltKey);
347#endif
348}
349
tdresser3a1c9722015-02-13 15:44:53350const char* kSourceDeviceStringTouchpad = "touchpad";
351const char* kSourceDeviceStringTouchscreen = "touchscreen";
352
[email protected]3db130e2014-03-27 08:14:48353} // namespace
354
355class EventSenderBindings : public gin::Wrappable<EventSenderBindings> {
356 public:
357 static gin::WrapperInfo kWrapperInfo;
358
359 static void Install(base::WeakPtr<EventSender> sender,
360 blink::WebFrame* frame);
361
362 private:
363 explicit EventSenderBindings(base::WeakPtr<EventSender> sender);
dchenge933b3e2014-10-21 11:44:09364 ~EventSenderBindings() override;
[email protected]3db130e2014-03-27 08:14:48365
366 // gin::Wrappable:
dchenge933b3e2014-10-21 11:44:09367 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
anand.ratn449f39a42014-10-06 13:45:57368 v8::Isolate* isolate) override;
[email protected]3db130e2014-03-27 08:14:48369
370 // Bound methods:
371 void EnableDOMUIEventLogging();
372 void FireKeyboardEventsToElement();
373 void ClearKillRing();
374 std::vector<std::string> ContextClick();
375 void TextZoomIn();
376 void TextZoomOut();
377 void ZoomPageIn();
378 void ZoomPageOut();
[email protected]d160488f2014-05-06 17:03:01379 void SetPageZoomFactor(double factor);
[email protected]3db130e2014-03-27 08:14:48380 void SetPageScaleFactor(gin::Arguments* args);
bokan798ccc52014-11-19 23:32:00381 void SetPageScaleFactorLimits(gin::Arguments* args);
[email protected]3db130e2014-03-27 08:14:48382 void ClearTouchPoints();
383 void ReleaseTouchPoint(unsigned index);
[email protected]f53eba122014-04-16 11:30:01384 void UpdateTouchPoint(unsigned index, double x, double y);
[email protected]3db130e2014-03-27 08:14:48385 void CancelTouchPoint(unsigned index);
386 void SetTouchModifier(const std::string& key_name, bool set_mask);
[email protected]ace1cd502014-04-24 21:05:30387 void SetTouchCancelable(bool cancelable);
[email protected]3db130e2014-03-27 08:14:48388 void DumpFilenameBeingDragged();
389 void GestureFlingCancel();
tdresser3a1c9722015-02-13 15:44:53390 void GestureFlingStart(float x,
391 float y,
392 float velocity_x,
393 float velocity_y,
394 gin::Arguments* args);
[email protected]3db130e2014-03-27 08:14:48395 void GestureScrollFirstPoint(int x, int y);
396 void TouchStart();
397 void TouchMove();
398 void TouchCancel();
399 void TouchEnd();
400 void LeapForward(int milliseconds);
401 void BeginDragWithFiles(const std::vector<std::string>& files);
402 void AddTouchPoint(gin::Arguments* args);
403 void MouseDragBegin();
404 void MouseDragEnd();
[email protected]3db130e2014-03-27 08:14:48405 void GestureScrollBegin(gin::Arguments* args);
406 void GestureScrollEnd(gin::Arguments* args);
407 void GestureScrollUpdate(gin::Arguments* args);
ccameronb81b8072015-01-30 00:54:49408 void GesturePinchBegin(gin::Arguments* args);
409 void GesturePinchEnd(gin::Arguments* args);
410 void GesturePinchUpdate(gin::Arguments* args);
[email protected]3db130e2014-03-27 08:14:48411 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);
[email protected]3db130e2014-03-27 08:14:48419 void MouseMoveTo(gin::Arguments* args);
[email protected]9d80c822014-05-19 19:07:12420 void TrackpadScrollBegin();
421 void TrackpadScroll(gin::Arguments* args);
422 void TrackpadScrollEnd();
[email protected]3db130e2014-03-27 08:14:48423 void MouseScrollBy(gin::Arguments* args);
[email protected]9d80c822014-05-19 19:07:12424 // TODO(erikchen): Remove MouseMomentumBegin once CL 282743002 has landed.
425 void MouseMomentumBegin();
426 void MouseMomentumBegin2(gin::Arguments* args);
[email protected]3db130e2014-03-27 08:14:48427 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);
434
435 // Binding properties:
436 bool ForceLayoutOnEvents() const;
437 void SetForceLayoutOnEvents(bool force);
438 bool IsDragMode() const;
439 void SetIsDragMode(bool drag_mode);
440
441#if defined(OS_WIN)
442 int WmKeyDown() const;
443 void SetWmKeyDown(int key_down);
444
445 int WmKeyUp() const;
446 void SetWmKeyUp(int key_up);
447
448 int WmChar() const;
449 void SetWmChar(int wm_char);
450
451 int WmDeadChar() const;
452 void SetWmDeadChar(int dead_char);
453
454 int WmSysKeyDown() const;
455 void SetWmSysKeyDown(int key_down);
456
457 int WmSysKeyUp() const;
458 void SetWmSysKeyUp(int key_up);
459
460 int WmSysChar() const;
461 void SetWmSysChar(int sys_char);
462
463 int WmSysDeadChar() const;
464 void SetWmSysDeadChar(int sys_dead_char);
465#endif
466
467 base::WeakPtr<EventSender> sender_;
468
469 DISALLOW_COPY_AND_ASSIGN(EventSenderBindings);
470};
471
472gin::WrapperInfo EventSenderBindings::kWrapperInfo = {gin::kEmbedderNativeGin};
473
474EventSenderBindings::EventSenderBindings(base::WeakPtr<EventSender> sender)
475 : sender_(sender) {
476}
477
478EventSenderBindings::~EventSenderBindings() {}
479
480// static
481void EventSenderBindings::Install(base::WeakPtr<EventSender> sender,
482 WebFrame* frame) {
483 v8::Isolate* isolate = blink::mainThreadIsolate();
484 v8::HandleScope handle_scope(isolate);
485 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
486 if (context.IsEmpty())
487 return;
488
489 v8::Context::Scope context_scope(context);
490
491 gin::Handle<EventSenderBindings> bindings =
492 gin::CreateHandle(isolate, new EventSenderBindings(sender));
[email protected]ad4d2032014-04-28 13:50:59493 if (bindings.IsEmpty())
494 return;
[email protected]3db130e2014-03-27 08:14:48495 v8::Handle<v8::Object> global = context->Global();
496 global->Set(gin::StringToV8(isolate, "eventSender"), bindings.ToV8());
497}
498
499gin::ObjectTemplateBuilder
500EventSenderBindings::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)
[email protected]b32fe542014-04-30 08:42:06512 .SetMethod("setPageZoomFactor", &EventSenderBindings::SetPageZoomFactor)
[email protected]3db130e2014-03-27 08:14:48513 .SetMethod("setPageScaleFactor", &EventSenderBindings::SetPageScaleFactor)
bokan798ccc52014-11-19 23:32:00514 .SetMethod("setPageScaleFactorLimits",
515 &EventSenderBindings::SetPageScaleFactorLimits)
[email protected]3db130e2014-03-27 08:14:48516 .SetMethod("clearTouchPoints", &EventSenderBindings::ClearTouchPoints)
517 .SetMethod("releaseTouchPoint", &EventSenderBindings::ReleaseTouchPoint)
518 .SetMethod("updateTouchPoint", &EventSenderBindings::UpdateTouchPoint)
519 .SetMethod("cancelTouchPoint", &EventSenderBindings::CancelTouchPoint)
520 .SetMethod("setTouchModifier", &EventSenderBindings::SetTouchModifier)
[email protected]ace1cd502014-04-24 21:05:30521 .SetMethod("setTouchCancelable", &EventSenderBindings::SetTouchCancelable)
[email protected]3db130e2014-03-27 08:14:48522 .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)
[email protected]3db130e2014-03-27 08:14:48537 .SetMethod("gestureScrollBegin", &EventSenderBindings::GestureScrollBegin)
538 .SetMethod("gestureScrollEnd", &EventSenderBindings::GestureScrollEnd)
539 .SetMethod("gestureScrollUpdate",
540 &EventSenderBindings::GestureScrollUpdate)
ccameronb81b8072015-01-30 00:54:49541 .SetMethod("gesturePinchBegin", &EventSenderBindings::GesturePinchBegin)
542 .SetMethod("gesturePinchEnd", &EventSenderBindings::GesturePinchEnd)
543 .SetMethod("gesturePinchUpdate", &EventSenderBindings::GesturePinchUpdate)
[email protected]3db130e2014-03-27 08:14:48544 .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)
[email protected]3db130e2014-03-27 08:14:48554 .SetMethod("keyDown", &EventSenderBindings::KeyDown)
555 .SetMethod("mouseDown", &EventSenderBindings::MouseDown)
556 .SetMethod("mouseMoveTo", &EventSenderBindings::MouseMoveTo)
[email protected]9d80c822014-05-19 19:07:12557 .SetMethod("trackpadScrollBegin",
558 &EventSenderBindings::TrackpadScrollBegin)
559 .SetMethod("trackpadScroll", &EventSenderBindings::TrackpadScroll)
560 .SetMethod("trackpadScrollEnd", &EventSenderBindings::TrackpadScrollEnd)
[email protected]3db130e2014-03-27 08:14:48561 .SetMethod("mouseScrollBy", &EventSenderBindings::MouseScrollBy)
562 .SetMethod("mouseUp", &EventSenderBindings::MouseUp)
[email protected]9d80c822014-05-19 19:07:12563 .SetMethod("mouseMomentumBegin", &EventSenderBindings::MouseMomentumBegin)
564 .SetMethod("mouseMomentumBegin2",
565 &EventSenderBindings::MouseMomentumBegin2)
[email protected]3db130e2014-03-27 08:14:48566 .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)
579#if defined(OS_WIN)
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);
604#else
605 ;
606#endif
607}
608
609void EventSenderBindings::EnableDOMUIEventLogging() {
610 if (sender_)
611 sender_->EnableDOMUIEventLogging();
612}
613
614void EventSenderBindings::FireKeyboardEventsToElement() {
615 if (sender_)
616 sender_->FireKeyboardEventsToElement();
617}
618
619void EventSenderBindings::ClearKillRing() {
620 if (sender_)
621 sender_->ClearKillRing();
622}
623
624std::vector<std::string> EventSenderBindings::ContextClick() {
625 if (sender_)
626 return sender_->ContextClick();
627 return std::vector<std::string>();
628}
629
630void EventSenderBindings::TextZoomIn() {
631 if (sender_)
632 sender_->TextZoomIn();
633}
634
635void EventSenderBindings::TextZoomOut() {
636 if (sender_)
637 sender_->TextZoomOut();
638}
639
640void EventSenderBindings::ZoomPageIn() {
641 if (sender_)
642 sender_->ZoomPageIn();
643}
644
645void EventSenderBindings::ZoomPageOut() {
646 if (sender_)
647 sender_->ZoomPageOut();
648}
649
[email protected]d160488f2014-05-06 17:03:01650void EventSenderBindings::SetPageZoomFactor(double factor) {
651 if (sender_)
652 sender_->SetPageZoomFactor(factor);
[email protected]b32fe542014-04-30 08:42:06653}
654
[email protected]3db130e2014-03-27 08:14:48655void EventSenderBindings::SetPageScaleFactor(gin::Arguments* args) {
656 if (!sender_)
657 return;
658 float scale_factor;
[email protected]f53eba122014-04-16 11:30:01659 double x;
660 double y;
[email protected]3db130e2014-03-27 08:14:48661 if (args->PeekNext().IsEmpty())
662 return;
663 args->GetNext(&scale_factor);
664 if (args->PeekNext().IsEmpty())
665 return;
666 args->GetNext(&x);
667 if (args->PeekNext().IsEmpty())
668 return;
669 args->GetNext(&y);
[email protected]f53eba122014-04-16 11:30:01670 sender_->SetPageScaleFactor(scale_factor,
671 static_cast<int>(x), static_cast<int>(y));
[email protected]3db130e2014-03-27 08:14:48672}
673
bokan798ccc52014-11-19 23:32:00674void EventSenderBindings::SetPageScaleFactorLimits(gin::Arguments* args) {
675 if (!sender_)
676 return;
677 float min_scale_factor;
678 float max_scale_factor;
679 if (args->PeekNext().IsEmpty())
680 return;
681 args->GetNext(&min_scale_factor);
682 if (args->PeekNext().IsEmpty())
683 return;
684 args->GetNext(&max_scale_factor);
685 sender_->SetPageScaleFactorLimits(min_scale_factor, max_scale_factor);
686}
687
[email protected]3db130e2014-03-27 08:14:48688void EventSenderBindings::ClearTouchPoints() {
689 if (sender_)
690 sender_->ClearTouchPoints();
691}
692
693void EventSenderBindings::ReleaseTouchPoint(unsigned index) {
694 if (sender_)
695 sender_->ReleaseTouchPoint(index);
696}
697
[email protected]f53eba122014-04-16 11:30:01698void EventSenderBindings::UpdateTouchPoint(unsigned index, double x, double y) {
[email protected]3db130e2014-03-27 08:14:48699 if (sender_)
[email protected]f3d5009d2014-06-06 05:24:57700 sender_->UpdateTouchPoint(index, static_cast<float>(x), static_cast<float>(y));
[email protected]3db130e2014-03-27 08:14:48701}
702
703void EventSenderBindings::CancelTouchPoint(unsigned index) {
704 if (sender_)
705 sender_->CancelTouchPoint(index);
706}
707
708void EventSenderBindings::SetTouchModifier(const std::string& key_name,
709 bool set_mask) {
710 if (sender_)
711 sender_->SetTouchModifier(key_name, set_mask);
712}
713
[email protected]ace1cd502014-04-24 21:05:30714void EventSenderBindings::SetTouchCancelable(bool cancelable) {
715 if (sender_)
716 sender_->SetTouchCancelable(cancelable);
717}
718
[email protected]3db130e2014-03-27 08:14:48719void EventSenderBindings::DumpFilenameBeingDragged() {
720 if (sender_)
721 sender_->DumpFilenameBeingDragged();
722}
723
724void EventSenderBindings::GestureFlingCancel() {
725 if (sender_)
726 sender_->GestureFlingCancel();
727}
728
729void EventSenderBindings::GestureFlingStart(float x,
730 float y,
731 float velocity_x,
tdresser3a1c9722015-02-13 15:44:53732 float velocity_y,
733 gin::Arguments* args) {
[email protected]3db130e2014-03-27 08:14:48734 if (sender_)
tdresser3a1c9722015-02-13 15:44:53735 sender_->GestureFlingStart(x, y, velocity_x, velocity_y, args);
[email protected]3db130e2014-03-27 08:14:48736}
737
738void EventSenderBindings::GestureScrollFirstPoint(int x, int y) {
739 if (sender_)
740 sender_->GestureScrollFirstPoint(x, y);
741}
742
743void EventSenderBindings::TouchStart() {
744 if (sender_)
745 sender_->TouchStart();
746}
747
748void EventSenderBindings::TouchMove() {
749 if (sender_)
750 sender_->TouchMove();
751}
752
753void EventSenderBindings::TouchCancel() {
754 if (sender_)
755 sender_->TouchCancel();
756}
757
758void EventSenderBindings::TouchEnd() {
759 if (sender_)
760 sender_->TouchEnd();
761}
762
763void EventSenderBindings::LeapForward(int milliseconds) {
764 if (sender_)
765 sender_->LeapForward(milliseconds);
766}
767
768void EventSenderBindings::BeginDragWithFiles(
769 const std::vector<std::string>& files) {
770 if (sender_)
771 sender_->BeginDragWithFiles(files);
772}
773
774void EventSenderBindings::AddTouchPoint(gin::Arguments* args) {
775 if (sender_)
776 sender_->AddTouchPoint(args);
777}
778
779void EventSenderBindings::MouseDragBegin() {
780 if (sender_)
781 sender_->MouseDragBegin();
782}
783
784void EventSenderBindings::MouseDragEnd() {
785 if (sender_)
786 sender_->MouseDragEnd();
787}
788
[email protected]3db130e2014-03-27 08:14:48789void EventSenderBindings::GestureScrollBegin(gin::Arguments* args) {
790 if (sender_)
791 sender_->GestureScrollBegin(args);
792}
793
794void EventSenderBindings::GestureScrollEnd(gin::Arguments* args) {
795 if (sender_)
796 sender_->GestureScrollEnd(args);
797}
798
799void EventSenderBindings::GestureScrollUpdate(gin::Arguments* args) {
800 if (sender_)
801 sender_->GestureScrollUpdate(args);
802}
803
ccameronb81b8072015-01-30 00:54:49804void EventSenderBindings::GesturePinchBegin(gin::Arguments* args) {
805 if (sender_)
806 sender_->GesturePinchBegin(args);
807}
808
809void EventSenderBindings::GesturePinchEnd(gin::Arguments* args) {
810 if (sender_)
811 sender_->GesturePinchEnd(args);
812}
813
814void EventSenderBindings::GesturePinchUpdate(gin::Arguments* args) {
815 if (sender_)
816 sender_->GesturePinchUpdate(args);
817}
818
[email protected]3db130e2014-03-27 08:14:48819void EventSenderBindings::GestureTap(gin::Arguments* args) {
820 if (sender_)
821 sender_->GestureTap(args);
822}
823
824void EventSenderBindings::GestureTapDown(gin::Arguments* args) {
825 if (sender_)
826 sender_->GestureTapDown(args);
827}
828
829void EventSenderBindings::GestureShowPress(gin::Arguments* args) {
830 if (sender_)
831 sender_->GestureShowPress(args);
832}
833
834void EventSenderBindings::GestureTapCancel(gin::Arguments* args) {
835 if (sender_)
836 sender_->GestureTapCancel(args);
837}
838
839void EventSenderBindings::GestureLongPress(gin::Arguments* args) {
840 if (sender_)
841 sender_->GestureLongPress(args);
842}
843
844void EventSenderBindings::GestureLongTap(gin::Arguments* args) {
845 if (sender_)
846 sender_->GestureLongTap(args);
847}
848
849void EventSenderBindings::GestureTwoFingerTap(gin::Arguments* args) {
850 if (sender_)
851 sender_->GestureTwoFingerTap(args);
852}
853
854void EventSenderBindings::ContinuousMouseScrollBy(gin::Arguments* args) {
855 if (sender_)
856 sender_->ContinuousMouseScrollBy(args);
857}
858
[email protected]3db130e2014-03-27 08:14:48859void EventSenderBindings::MouseMoveTo(gin::Arguments* args) {
860 if (sender_)
861 sender_->MouseMoveTo(args);
862}
863
[email protected]9d80c822014-05-19 19:07:12864void EventSenderBindings::TrackpadScrollBegin() {
865 if (sender_)
866 sender_->TrackpadScrollBegin();
867}
868
869void EventSenderBindings::TrackpadScroll(gin::Arguments* args) {
870 if (sender_)
871 sender_->TrackpadScroll(args);
872}
873
874void EventSenderBindings::TrackpadScrollEnd() {
875 if (sender_)
876 sender_->TrackpadScrollEnd();
877}
878
[email protected]3db130e2014-03-27 08:14:48879void EventSenderBindings::MouseScrollBy(gin::Arguments* args) {
880 if (sender_)
881 sender_->MouseScrollBy(args);
882}
883
[email protected]9d80c822014-05-19 19:07:12884void EventSenderBindings::MouseMomentumBegin() {
885 if (sender_)
886 sender_->MouseMomentumBegin();
887}
888
889void EventSenderBindings::MouseMomentumBegin2(gin::Arguments* args) {
890 if (sender_)
891 sender_->MouseMomentumBegin2(args);
892}
893
[email protected]3db130e2014-03-27 08:14:48894void EventSenderBindings::MouseMomentumScrollBy(gin::Arguments* args) {
895 if (sender_)
896 sender_->MouseMomentumScrollBy(args);
897}
898
899void EventSenderBindings::MouseMomentumEnd() {
900 if (sender_)
901 sender_->MouseMomentumEnd();
902}
903
904void EventSenderBindings::ScheduleAsynchronousClick(gin::Arguments* args) {
905 if (!sender_)
906 return;
907
908 int button_number = 0;
909 int modifiers = 0;
910 if (!args->PeekNext().IsEmpty()) {
911 args->GetNext(&button_number);
912 if (!args->PeekNext().IsEmpty())
913 modifiers = GetKeyModifiersFromV8(args->PeekNext());
914 }
915 sender_->ScheduleAsynchronousClick(button_number, modifiers);
916}
917
918void EventSenderBindings::ScheduleAsynchronousKeyDown(gin::Arguments* args) {
919 if (!sender_)
920 return;
921
922 std::string code_str;
923 int modifiers = 0;
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);
932 }
933 sender_->ScheduleAsynchronousKeyDown(code_str, modifiers,
934 static_cast<KeyLocationCode>(location));
935}
936
937void EventSenderBindings::MouseDown(gin::Arguments* args) {
938 if (!sender_)
939 return;
940
941 int button_number = 0;
942 int modifiers = 0;
943 if (!args->PeekNext().IsEmpty()) {
944 args->GetNext(&button_number);
945 if (!args->PeekNext().IsEmpty())
946 modifiers = GetKeyModifiersFromV8(args->PeekNext());
947 }
948 sender_->MouseDown(button_number, modifiers);
949}
950
951void EventSenderBindings::MouseUp(gin::Arguments* args) {
952 if (!sender_)
953 return;
954
955 int button_number = 0;
956 int modifiers = 0;
957 if (!args->PeekNext().IsEmpty()) {
958 args->GetNext(&button_number);
959 if (!args->PeekNext().IsEmpty())
960 modifiers = GetKeyModifiersFromV8(args->PeekNext());
961 }
962 sender_->MouseUp(button_number, modifiers);
963}
964
965void EventSenderBindings::KeyDown(gin::Arguments* args) {
966 if (!sender_)
967 return;
968
969 std::string code_str;
970 int modifiers = 0;
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);
979 }
980 sender_->KeyDown(code_str, modifiers, static_cast<KeyLocationCode>(location));
981}
982
983bool EventSenderBindings::ForceLayoutOnEvents() const {
984 if (sender_)
985 return sender_->force_layout_on_events();
986 return false;
987}
988
989void EventSenderBindings::SetForceLayoutOnEvents(bool force) {
990 if (sender_)
991 sender_->set_force_layout_on_events(force);
992}
993
994bool EventSenderBindings::IsDragMode() const {
995 if (sender_)
996 return sender_->is_drag_mode();
997 return true;
998}
999
1000void EventSenderBindings::SetIsDragMode(bool drag_mode) {
1001 if (sender_)
1002 sender_->set_is_drag_mode(drag_mode);
1003}
1004
1005#if defined(OS_WIN)
1006int EventSenderBindings::WmKeyDown() const {
1007 if (sender_)
1008 return sender_->wm_key_down();
1009 return 0;
1010}
1011
1012void EventSenderBindings::SetWmKeyDown(int key_down) {
1013 if (sender_)
1014 sender_->set_wm_key_down(key_down);
1015}
1016
1017int EventSenderBindings::WmKeyUp() const {
1018 if (sender_)
1019 return sender_->wm_key_up();
1020 return 0;
1021}
1022
1023void EventSenderBindings::SetWmKeyUp(int key_up) {
1024 if (sender_)
1025 sender_->set_wm_key_up(key_up);
1026}
1027
1028int EventSenderBindings::WmChar() const {
1029 if (sender_)
1030 return sender_->wm_char();
1031 return 0;
1032}
1033
1034void EventSenderBindings::SetWmChar(int wm_char) {
1035 if (sender_)
1036 sender_->set_wm_char(wm_char);
1037}
1038
1039int EventSenderBindings::WmDeadChar() const {
1040 if (sender_)
1041 return sender_->wm_dead_char();
1042 return 0;
1043}
1044
1045void EventSenderBindings::SetWmDeadChar(int dead_char) {
1046 if (sender_)
1047 sender_->set_wm_dead_char(dead_char);
1048}
1049
1050int EventSenderBindings::WmSysKeyDown() const {
1051 if (sender_)
1052 return sender_->wm_sys_key_down();
1053 return 0;
1054}
1055
1056void EventSenderBindings::SetWmSysKeyDown(int key_down) {
1057 if (sender_)
1058 sender_->set_wm_sys_key_down(key_down);
1059}
1060
1061int EventSenderBindings::WmSysKeyUp() const {
1062 if (sender_)
1063 return sender_->wm_sys_key_up();
1064 return 0;
1065}
1066
1067void EventSenderBindings::SetWmSysKeyUp(int key_up) {
1068 if (sender_)
1069 sender_->set_wm_sys_key_up(key_up);
1070}
1071
1072int EventSenderBindings::WmSysChar() const {
1073 if (sender_)
1074 return sender_->wm_sys_char();
1075 return 0;
1076}
1077
1078void EventSenderBindings::SetWmSysChar(int sys_char) {
1079 if (sender_)
1080 sender_->set_wm_sys_char(sys_char);
1081}
1082
1083int EventSenderBindings::WmSysDeadChar() const {
1084 if (sender_)
1085 return sender_->wm_sys_dead_char();
1086 return 0;
1087}
1088
1089void EventSenderBindings::SetWmSysDeadChar(int sys_dead_char) {
1090 if (sender_)
1091 sender_->set_wm_sys_dead_char(sys_dead_char);
1092}
1093#endif
1094
1095// EventSender -----------------------------------------------------------------
1096
1097WebMouseEvent::Button EventSender::pressed_button_ = WebMouseEvent::ButtonNone;
1098
1099WebPoint EventSender::last_mouse_pos_;
1100
1101WebMouseEvent::Button EventSender::last_button_type_ =
1102 WebMouseEvent::ButtonNone;
1103
1104EventSender::SavedEvent::SavedEvent()
1105 : type(TYPE_UNSPECIFIED),
1106 button_type(WebMouseEvent::ButtonNone),
1107 milliseconds(0),
1108 modifiers(0) {}
1109
[email protected]79ecada2014-05-04 05:16:161110EventSender::EventSender(TestInterfaces* interfaces)
[email protected]3db130e2014-03-27 08:14:481111 : interfaces_(interfaces),
1112 delegate_(NULL),
1113 view_(NULL),
1114 force_layout_on_events_(false),
1115 is_drag_mode_(true),
1116 touch_modifiers_(0),
[email protected]ace1cd502014-04-24 21:05:301117 touch_cancelable_(true),
[email protected]3db130e2014-03-27 08:14:481118 replaying_saved_events_(false),
1119 current_drag_effects_allowed_(blink::WebDragOperationNone),
1120 last_click_time_sec_(0),
1121 current_drag_effect_(blink::WebDragOperationNone),
1122 time_offset_ms_(0),
1123 click_count_(0),
1124#if defined(OS_WIN)
1125 wm_key_down_(0),
1126 wm_key_up_(0),
1127 wm_char_(0),
1128 wm_dead_char_(0),
1129 wm_sys_key_down_(0),
1130 wm_sys_key_up_(0),
1131 wm_sys_char_(0),
1132 wm_sys_dead_char_(0),
1133#endif
1134 weak_factory_(this) {}
1135
1136EventSender::~EventSender() {}
1137
1138void 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;
1148
1149#if defined(OS_WIN)
1150 wm_key_down_ = WM_KEYDOWN;
1151 wm_key_up_ = WM_KEYUP;
1152 wm_char_ = WM_CHAR;
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;
1158#endif
1159
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();
[email protected]644616d2014-03-27 16:14:471165 last_context_menu_data_.reset();
abhishek.a21ab71acb2014-09-12 16:46:311166 task_list_.RevokeAll();
[email protected]3db130e2014-03-27 08:14:481167 current_gesture_location_ = WebPoint(0, 0);
1168 mouse_event_queue_.clear();
1169
1170 time_offset_ms_ = 0;
1171 click_count_ = 0;
[email protected]ace1cd502014-04-24 21:05:301172
1173 touch_modifiers_ = 0;
1174 touch_cancelable_ = true;
1175 touch_points_.clear();
[email protected]3db130e2014-03-27 08:14:481176}
1177
1178void EventSender::Install(WebFrame* frame) {
1179 EventSenderBindings::Install(weak_factory_.GetWeakPtr(), frame);
1180}
1181
[email protected]79ecada2014-05-04 05:16:161182void EventSender::SetDelegate(WebTestDelegate* delegate) {
[email protected]3db130e2014-03-27 08:14:481183 delegate_ = delegate;
1184}
1185
1186void EventSender::SetWebView(WebView* view) {
1187 view_ = view;
1188}
1189
1190void EventSender::SetContextMenuData(const WebContextMenuData& data) {
1191 last_context_menu_data_.reset(new WebContextMenuData(data));
1192}
1193
1194void EventSender::DoDragDrop(const WebDragData& drag_data,
1195 WebDragOperationsMask mask) {
1196 WebMouseEvent event;
1197 InitMouseEvent(WebInputEvent::MouseDown,
1198 pressed_button_,
1199 last_mouse_pos_,
1200 GetCurrentEventTimeSec(),
1201 click_count_,
1202 0,
1203 &event);
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);
1210
1211 // Finish processing events.
1212 ReplaySavedEvents();
1213}
1214
1215void EventSender::MouseDown(int button_number, int modifiers) {
1216 if (force_layout_on_events_)
1217 view_->layout();
1218
1219 DCHECK_NE(-1, button_number);
1220
1221 WebMouseEvent::Button button_type =
1222 GetButtonTypeFromButtonNumber(button_number);
1223
1224 UpdateClickCountForButton(button_type);
1225
1226 pressed_button_ = button_type;
1227
1228 WebMouseEvent event;
1229 InitMouseEvent(WebInputEvent::MouseDown,
1230 button_type,
1231 last_mouse_pos_,
1232 GetCurrentEventTimeSec(),
1233 click_count_,
1234 modifiers,
1235 &event);
tkent588765612014-11-28 01:07:481236 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481237}
1238
1239void EventSender::MouseUp(int button_number, int modifiers) {
1240 if (force_layout_on_events_)
1241 view_->layout();
1242
1243 DCHECK_NE(-1, button_number);
1244
1245 WebMouseEvent::Button button_type =
1246 GetButtonTypeFromButtonNumber(button_number);
1247
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();
1255 } else {
1256 WebMouseEvent event;
1257 InitMouseEvent(WebInputEvent::MouseUp,
1258 button_type,
1259 last_mouse_pos_,
1260 GetCurrentEventTimeSec(),
1261 click_count_,
1262 modifiers,
1263 &event);
1264 DoMouseUp(event);
1265 }
1266}
1267
1268void EventSender::KeyDown(const std::string& code_str,
1269 int modifiers,
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?
1274
1275 bool generate_char = false;
1276
1277 // Convert \n -> VK_RETURN. Some layout tests use \n to mean "Enter", when
1278 // Windows uses \r for "Enter".
1279 int code = 0;
1280 int text = 0;
1281 bool needs_shift_key_modifier = false;
habib.virji565c80c2015-02-06 12:26:431282 std::string domString;
[email protected]3db130e2014-03-27 08:14:481283
1284 if ("\n" == code_str) {
1285 generate_char = true;
[email protected]a731f1a92014-04-17 19:31:061286 text = code = ui::VKEY_RETURN;
habib.virji565c80c2015-02-06 12:26:431287 domString.assign("Enter");
[email protected]3db130e2014-03-27 08:14:481288 } else if ("rightArrow" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061289 code = ui::VKEY_RIGHT;
habib.virji565c80c2015-02-06 12:26:431290 domString.assign("ArrowRight");
[email protected]3db130e2014-03-27 08:14:481291 } else if ("downArrow" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061292 code = ui::VKEY_DOWN;
habib.virji565c80c2015-02-06 12:26:431293 domString.assign("ArrowDown");
[email protected]3db130e2014-03-27 08:14:481294 } else if ("leftArrow" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061295 code = ui::VKEY_LEFT;
habib.virji565c80c2015-02-06 12:26:431296 domString.assign("ArrowLeft");
[email protected]3db130e2014-03-27 08:14:481297 } else if ("upArrow" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061298 code = ui::VKEY_UP;
habib.virji565c80c2015-02-06 12:26:431299 domString.assign("ArrowUp");
[email protected]3db130e2014-03-27 08:14:481300 } else if ("insert" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061301 code = ui::VKEY_INSERT;
habib.virji565c80c2015-02-06 12:26:431302 domString.assign("Insert");
[email protected]3db130e2014-03-27 08:14:481303 } else if ("delete" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061304 code = ui::VKEY_DELETE;
habib.virji565c80c2015-02-06 12:26:431305 domString.assign("Delete");
[email protected]3db130e2014-03-27 08:14:481306 } else if ("pageUp" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061307 code = ui::VKEY_PRIOR;
habib.virji565c80c2015-02-06 12:26:431308 domString.assign("PageUp");
[email protected]3db130e2014-03-27 08:14:481309 } else if ("pageDown" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061310 code = ui::VKEY_NEXT;
habib.virji565c80c2015-02-06 12:26:431311 domString.assign("PageDown");
[email protected]3db130e2014-03-27 08:14:481312 } else if ("home" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061313 code = ui::VKEY_HOME;
habib.virji565c80c2015-02-06 12:26:431314 domString.assign("Home");
[email protected]3db130e2014-03-27 08:14:481315 } else if ("end" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061316 code = ui::VKEY_END;
habib.virji565c80c2015-02-06 12:26:431317 domString.assign("End");
[email protected]3db130e2014-03-27 08:14:481318 } else if ("printScreen" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061319 code = ui::VKEY_SNAPSHOT;
habib.virji565c80c2015-02-06 12:26:431320 domString.assign("PrintScreen");
[email protected]3db130e2014-03-27 08:14:481321 } else if ("menu" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061322 code = ui::VKEY_APPS;
habib.virji565c80c2015-02-06 12:26:431323 domString.assign("ContextMenu");
[email protected]3db130e2014-03-27 08:14:481324 } else if ("leftControl" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061325 code = ui::VKEY_LCONTROL;
habib.virji565c80c2015-02-06 12:26:431326 domString.assign("ControlLeft");
[email protected]3db130e2014-03-27 08:14:481327 } else if ("rightControl" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061328 code = ui::VKEY_RCONTROL;
habib.virji565c80c2015-02-06 12:26:431329 domString.assign("ControlRight");
[email protected]3db130e2014-03-27 08:14:481330 } else if ("leftShift" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061331 code = ui::VKEY_LSHIFT;
habib.virji565c80c2015-02-06 12:26:431332 domString.assign("ShiftLeft");
[email protected]3db130e2014-03-27 08:14:481333 } else if ("rightShift" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061334 code = ui::VKEY_RSHIFT;
habib.virji565c80c2015-02-06 12:26:431335 domString.assign("ShiftRight");
[email protected]3db130e2014-03-27 08:14:481336 } else if ("leftAlt" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061337 code = ui::VKEY_LMENU;
habib.virji565c80c2015-02-06 12:26:431338 domString.assign("AltLeft");
[email protected]3db130e2014-03-27 08:14:481339 } else if ("rightAlt" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061340 code = ui::VKEY_RMENU;
habib.virji565c80c2015-02-06 12:26:431341 domString.assign("AltRight");
[email protected]3db130e2014-03-27 08:14:481342 } else if ("numLock" == code_str) {
[email protected]a731f1a92014-04-17 19:31:061343 code = ui::VKEY_NUMLOCK;
habib.virji565c80c2015-02-06 12:26:431344 domString.assign("NumLock");
[email protected]4c07a712014-08-21 17:05:541345 } else if ("backspace" == code_str) {
1346 code = ui::VKEY_BACK;
habib.virji565c80c2015-02-06 12:26:431347 domString.assign("Backspace");
[email protected]4c07a712014-08-21 17:05:541348 } else if ("escape" == code_str) {
1349 code = ui::VKEY_ESCAPE;
habib.virji565c80c2015-02-06 12:26:431350 domString.assign("Escape");
[email protected]3db130e2014-03-27 08:14:481351 } else {
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) {
[email protected]a731f1a92014-04-17 19:31:061358 code = ui::VKEY_F1 + (i - 1);
habib.virji565c80c2015-02-06 12:26:431359 domString = function_key_name;
[email protected]3db130e2014-03-27 08:14:481360 break;
1361 }
1362 }
1363 if (!code) {
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')
1370 code -= 'a' - 'A';
habib.virji565c80c2015-02-06 12:26:431371 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");
1381 }
[email protected]3db130e2014-03-27 08:14:481382 generate_char = true;
1383 }
1384
1385 if ("(" == code_str) {
1386 code = '9';
1387 needs_shift_key_modifier = true;
1388 }
1389 }
1390
1391 // For one generated keyboard event, we need to generate a keyDown/keyUp
1392 // pair;
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;
habib.virji565c80c2015-02-06 12:26:431400 event_down.domCode = static_cast<int>(
1401 ui::KeycodeConverter::CodeStringToDomCode(domString.c_str()));
[email protected]3db130e2014-03-27 08:14:481402
[email protected]3db130e2014-03-27 08:14:481403 if (generate_char) {
1404 event_down.text[0] = text;
1405 event_down.unmodifiedText[0] = text;
1406 }
1407
1408 event_down.setKeyIdentifierFromWindowsKeyCode();
1409
[email protected]3db130e2014-03-27 08:14:481410 if (event_down.modifiers != 0)
[email protected]a731f1a92014-04-17 19:31:061411 event_down.isSystemKey = IsSystemKeyEvent(event_down);
[email protected]3db130e2014-03-27 08:14:481412
1413 if (needs_shift_key_modifier)
1414 event_down.modifiers |= WebInputEvent::ShiftKey;
1415
1416 // See if KeyLocation argument is given.
1417 if (location == DOMKeyLocationNumpad)
1418 event_down.modifiers |= WebInputEvent::IsKeyPad;
1419
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_)
1426 view_->layout();
1427
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))
abhishek.a21ca9b5602014-09-19 07:33:331435 delegate_->SetEditCommand(edit_command, "");
[email protected]3db130e2014-03-27 08:14:481436
tkent588765612014-11-28 01:07:481437 HandleInputEventOnViewOrPopup(event_down);
[email protected]3db130e2014-03-27 08:14:481438
[email protected]a731f1a92014-04-17 19:31:061439 if (code == ui::VKEY_ESCAPE && !current_drag_data_.isNull()) {
[email protected]3db130e2014-03-27 08:14:481440 WebMouseEvent event;
1441 InitMouseEvent(WebInputEvent::MouseDown,
1442 pressed_button_,
1443 last_mouse_pos_,
1444 GetCurrentEventTimeSec(),
1445 click_count_,
1446 0,
1447 &event);
1448 FinishDragAndDrop(event, blink::WebDragOperationNone);
1449 }
1450
abhishek.a21ca9b5602014-09-19 07:33:331451 delegate_->ClearEditCommand();
[email protected]3db130e2014-03-27 08:14:481452
1453 if (generate_char) {
1454 WebKeyboardEvent event_char = event_up;
1455 event_char.type = WebInputEvent::Char;
rob994f9e82014-11-02 20:55:041456 // 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';
tkent588765612014-11-28 01:07:481461 HandleInputEventOnViewOrPopup(event_char);
[email protected]3db130e2014-03-27 08:14:481462 }
1463
tkent588765612014-11-28 01:07:481464 HandleInputEventOnViewOrPopup(event_up);
[email protected]3db130e2014-03-27 08:14:481465}
1466
1467void EventSender::EnableDOMUIEventLogging() {}
1468
1469void EventSender::FireKeyboardEventsToElement() {}
1470
1471void EventSender::ClearKillRing() {}
1472
1473std::vector<std::string> EventSender::ContextClick() {
1474 if (force_layout_on_events_) {
1475 view_->layout();
1476 }
1477
1478 UpdateClickCountForButton(WebMouseEvent::ButtonRight);
1479
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();
1483
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
1488 // pressed.
1489 if (pressed_button_ == WebMouseEvent::ButtonNone) {
1490 pressed_button_ = WebMouseEvent::ButtonRight;
1491 }
1492 InitMouseEvent(WebInputEvent::MouseDown,
1493 WebMouseEvent::ButtonRight,
1494 last_mouse_pos_,
1495 GetCurrentEventTimeSec(),
1496 click_count_,
1497 0,
1498 &event);
tkent588765612014-11-28 01:07:481499 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481500
1501#if defined(OS_WIN)
1502 InitMouseEvent(WebInputEvent::MouseUp,
1503 WebMouseEvent::ButtonRight,
1504 last_mouse_pos_,
1505 GetCurrentEventTimeSec(),
1506 click_count_,
1507 0,
1508 &event);
tkent588765612014-11-28 01:07:481509 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481510
1511 pressed_button_= WebMouseEvent::ButtonNone;
1512#endif
1513
[email protected]e7c71192014-04-23 11:53:481514 std::vector<std::string> menu_items = MakeMenuItemStringsFor(last_context_menu_data_.get(), delegate_);
1515 last_context_menu_data_.reset();
1516 return menu_items;
[email protected]3db130e2014-03-27 08:14:481517}
1518
1519void EventSender::TextZoomIn() {
1520 view_->setTextZoomFactor(view_->textZoomFactor() * 1.2f);
1521}
1522
1523void EventSender::TextZoomOut() {
1524 view_->setTextZoomFactor(view_->textZoomFactor() / 1.2f);
1525}
1526
1527void EventSender::ZoomPageIn() {
[email protected]8ed8bf432014-08-11 19:47:551528 const std::vector<WebTestProxyBase*>& window_list =
1529 interfaces_->GetWindowList();
[email protected]3db130e2014-03-27 08:14:481530
1531 for (size_t i = 0; i < window_list.size(); ++i) {
[email protected]a1640e42014-05-14 13:43:321532 window_list.at(i)->GetWebView()->setZoomLevel(
1533 window_list.at(i)->GetWebView()->zoomLevel() + 1);
[email protected]3db130e2014-03-27 08:14:481534 }
1535}
1536
1537void EventSender::ZoomPageOut() {
[email protected]8ed8bf432014-08-11 19:47:551538 const std::vector<WebTestProxyBase*>& window_list =
1539 interfaces_->GetWindowList();
[email protected]3db130e2014-03-27 08:14:481540
1541 for (size_t i = 0; i < window_list.size(); ++i) {
[email protected]a1640e42014-05-14 13:43:321542 window_list.at(i)->GetWebView()->setZoomLevel(
1543 window_list.at(i)->GetWebView()->zoomLevel() - 1);
[email protected]3db130e2014-03-27 08:14:481544 }
1545}
1546
[email protected]b32fe542014-04-30 08:42:061547void EventSender::SetPageZoomFactor(double zoom_factor) {
[email protected]8ed8bf432014-08-11 19:47:551548 const std::vector<WebTestProxyBase*>& window_list =
1549 interfaces_->GetWindowList();
[email protected]b32fe542014-04-30 08:42:061550
1551 for (size_t i = 0; i < window_list.size(); ++i) {
[email protected]a1640e42014-05-14 13:43:321552 window_list.at(i)->GetWebView()->setZoomLevel(
[email protected]79ecada2014-05-04 05:16:161553 ZoomFactorToZoomLevel(zoom_factor));
[email protected]b32fe542014-04-30 08:42:061554 }
1555}
1556
[email protected]3db130e2014-03-27 08:14:481557void EventSender::SetPageScaleFactor(float scale_factor, int x, int y) {
[email protected]3db130e2014-03-27 08:14:481558 view_->setPageScaleFactor(scale_factor, WebPoint(x, y));
1559}
1560
bokan798ccc52014-11-19 23:32:001561void EventSender::SetPageScaleFactorLimits(float min_scale, float max_scale) {
bokan28eb1a562015-01-16 02:09:201562 view_->setDefaultPageScaleLimits(min_scale, max_scale);
bokan798ccc52014-11-19 23:32:001563}
1564
[email protected]3db130e2014-03-27 08:14:481565void EventSender::ClearTouchPoints() {
1566 touch_points_.clear();
1567}
1568
[email protected]bfb6a602014-04-16 19:59:411569void EventSender::ThrowTouchPointError() {
1570 v8::Isolate* isolate = blink::mainThreadIsolate();
1571 isolate->ThrowException(v8::Exception::TypeError(
1572 gin::StringToV8(isolate, "Invalid touch point.")));
1573}
1574
[email protected]3db130e2014-03-27 08:14:481575void EventSender::ReleaseTouchPoint(unsigned index) {
[email protected]bfb6a602014-04-16 19:59:411576 if (index >= touch_points_.size()) {
1577 ThrowTouchPointError();
1578 return;
1579 }
[email protected]3db130e2014-03-27 08:14:481580
1581 WebTouchPoint* touch_point = &touch_points_[index];
1582 touch_point->state = WebTouchPoint::StateReleased;
1583}
1584
[email protected]f3d5009d2014-06-06 05:24:571585void EventSender::UpdateTouchPoint(unsigned index, float x, float y) {
[email protected]bfb6a602014-04-16 19:59:411586 if (index >= touch_points_.size()) {
1587 ThrowTouchPointError();
1588 return;
1589 }
[email protected]3db130e2014-03-27 08:14:481590
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;
1595}
1596
1597void EventSender::CancelTouchPoint(unsigned index) {
[email protected]bfb6a602014-04-16 19:59:411598 if (index >= touch_points_.size()) {
1599 ThrowTouchPointError();
1600 return;
1601 }
[email protected]3db130e2014-03-27 08:14:481602
1603 WebTouchPoint* touch_point = &touch_points_[index];
1604 touch_point->state = WebTouchPoint::StateCancelled;
1605}
1606
1607void EventSender::SetTouchModifier(const std::string& key_name,
1608 bool set_mask) {
1609 int mask = 0;
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;
1618
1619 if (set_mask)
1620 touch_modifiers_ |= mask;
1621 else
1622 touch_modifiers_ &= ~mask;
1623}
1624
[email protected]ace1cd502014-04-24 21:05:301625void EventSender::SetTouchCancelable(bool cancelable) {
1626 touch_cancelable_ = cancelable;
1627}
1628
[email protected]3db130e2014-03-27 08:14:481629void EventSender::DumpFilenameBeingDragged() {
dchengc3fe4642015-01-22 06:29:521630 if (current_drag_data_.isNull())
1631 return;
1632
[email protected]3db130e2014-03-27 08:14:481633 WebString filename;
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;
1638 break;
1639 }
1640 }
abhishek.a21ca9b5602014-09-19 07:33:331641 delegate_->PrintMessage(std::string("Filename being dragged: ") +
[email protected]3db130e2014-03-27 08:14:481642 filename.utf8().data() + "\n");
1643}
1644
1645void EventSender::GestureFlingCancel() {
1646 WebGestureEvent event;
1647 event.type = WebInputEvent::GestureFlingCancel;
1648 event.timeStampSeconds = GetCurrentEventTimeSec();
1649
1650 if (force_layout_on_events_)
1651 view_->layout();
1652
tkent588765612014-11-28 01:07:481653 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481654}
1655
1656void EventSender::GestureFlingStart(float x,
tdresser3a1c9722015-02-13 15:44:531657 float y,
1658 float velocity_x,
1659 float velocity_y,
1660 gin::Arguments* args) {
[email protected]3db130e2014-03-27 08:14:481661 WebGestureEvent event;
1662 event.type = WebInputEvent::GestureFlingStart;
1663
tdresser15af5872015-02-18 14:03:021664 std::string device_string;
1665 if (!args->PeekNext().IsEmpty() && args->PeekNext()->IsString())
1666 args->GetNext(&device_string);
tdresser3a1c9722015-02-13 15:44:531667
1668 if (device_string == kSourceDeviceStringTouchpad) {
1669 event.sourceDevice = blink::WebGestureDeviceTouchpad;
1670 } else if (device_string == kSourceDeviceStringTouchscreen) {
1671 event.sourceDevice = blink::WebGestureDeviceTouchscreen;
1672 } else {
1673 args->ThrowError();
1674 return;
1675 }
1676
[email protected]3db130e2014-03-27 08:14:481677 event.x = x;
1678 event.y = y;
1679 event.globalX = event.x;
1680 event.globalY = event.y;
1681
1682 event.data.flingStart.velocityX = velocity_x;
1683 event.data.flingStart.velocityY = velocity_y;
1684 event.timeStampSeconds = GetCurrentEventTimeSec();
1685
1686 if (force_layout_on_events_)
1687 view_->layout();
1688
tkent588765612014-11-28 01:07:481689 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481690}
1691
1692void EventSender::GestureScrollFirstPoint(int x, int y) {
1693 current_gesture_location_ = WebPoint(x, y);
1694}
1695
1696void EventSender::TouchStart() {
1697 SendCurrentTouchEvent(WebInputEvent::TouchStart);
1698}
1699
1700void EventSender::TouchMove() {
1701 SendCurrentTouchEvent(WebInputEvent::TouchMove);
1702}
1703
1704void EventSender::TouchCancel() {
1705 SendCurrentTouchEvent(WebInputEvent::TouchCancel);
1706}
1707
1708void EventSender::TouchEnd() {
1709 SendCurrentTouchEvent(WebInputEvent::TouchEnd);
1710}
1711
1712void 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);
1719 } else {
1720 DoLeapForward(milliseconds);
1721 }
1722}
1723
1724void 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;
abhishek.a21ca9b5602014-09-19 07:33:331730 item.filenameData = delegate_->GetAbsoluteWebStringFromUTF8Path(files[i]);
[email protected]3db130e2014-03-27 08:14:481731 current_drag_data_.addItem(item);
1732 absolute_filenames[i] = item.filenameData;
1733 }
1734 current_drag_data_.setFilesystemId(
abhishek.a21ca9b5602014-09-19 07:33:331735 delegate_->RegisterIsolatedFileSystem(absolute_filenames));
[email protected]3db130e2014-03-27 08:14:481736 current_drag_effects_allowed_ = blink::WebDragOperationCopy;
1737
1738 // Provide a drag source.
1739 view_->dragTargetDragEnter(current_drag_data_,
1740 last_mouse_pos_,
1741 last_mouse_pos_,
1742 current_drag_effects_allowed_,
1743 0);
1744 // |is_drag_mode_| saves events and then replays them later. We don't
1745 // need/want that.
1746 is_drag_mode_ = false;
1747
1748 // Make the rest of eventSender think a drag is in progress.
1749 pressed_button_ = WebMouseEvent::ButtonLeft;
1750}
1751
1752void EventSender::AddTouchPoint(gin::Arguments* args) {
[email protected]f53eba122014-04-16 11:30:011753 double x;
1754 double y;
mustaq0fff7fc32014-09-24 20:21:431755 if (!args->GetNext(&x) || !args->GetNext(&y)) {
1756 args->ThrowError();
1757 return;
1758 }
[email protected]3db130e2014-03-27 08:14:481759
1760 WebTouchPoint touch_point;
1761 touch_point.state = WebTouchPoint::StatePressed;
[email protected]f3d5009d2014-06-06 05:24:571762 touch_point.position = WebFloatPoint(static_cast<float>(x),
1763 static_cast<float>(y));
[email protected]3db130e2014-03-27 08:14:481764 touch_point.screenPosition = touch_point.position;
1765
1766 if (!args->PeekNext().IsEmpty()) {
[email protected]f53eba122014-04-16 11:30:011767 double radius_x;
[email protected]3db130e2014-03-27 08:14:481768 if (!args->GetNext(&radius_x)) {
1769 args->ThrowError();
1770 return;
1771 }
1772
[email protected]f53eba122014-04-16 11:30:011773 double radius_y = radius_x;
[email protected]3db130e2014-03-27 08:14:481774 if (!args->PeekNext().IsEmpty()) {
1775 if (!args->GetNext(&radius_y)) {
1776 args->ThrowError();
1777 return;
1778 }
1779 }
1780
[email protected]f3d5009d2014-06-06 05:24:571781 touch_point.radiusX = static_cast<float>(radius_x);
1782 touch_point.radiusY = static_cast<float>(radius_y);
[email protected]3db130e2014-03-27 08:14:481783 }
1784
1785 int lowest_id = 0;
1786 for (size_t i = 0; i < touch_points_.size(); i++) {
1787 if (touch_points_[i].id == lowest_id)
1788 lowest_id++;
1789 }
1790 touch_point.id = lowest_id;
1791 touch_points_.push_back(touch_point);
1792}
1793
1794void EventSender::MouseDragBegin() {
1795 WebMouseWheelEvent event;
1796 InitMouseEvent(WebInputEvent::MouseWheel,
1797 WebMouseEvent::ButtonNone,
1798 last_mouse_pos_,
1799 GetCurrentEventTimeSec(),
1800 click_count_,
1801 0,
1802 &event);
1803 event.phase = WebMouseWheelEvent::PhaseBegan;
1804 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481805 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481806}
1807
1808void EventSender::MouseDragEnd() {
1809 WebMouseWheelEvent event;
1810 InitMouseEvent(WebInputEvent::MouseWheel,
1811 WebMouseEvent::ButtonNone,
1812 last_mouse_pos_,
1813 GetCurrentEventTimeSec(),
1814 click_count_,
1815 0,
1816 &event);
1817 event.phase = WebMouseWheelEvent::PhaseEnded;
1818 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481819 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481820}
1821
[email protected]3db130e2014-03-27 08:14:481822void EventSender::GestureScrollBegin(gin::Arguments* args) {
1823 GestureEvent(WebInputEvent::GestureScrollBegin, args);
1824}
1825
1826void EventSender::GestureScrollEnd(gin::Arguments* args) {
1827 GestureEvent(WebInputEvent::GestureScrollEnd, args);
1828}
1829
1830void EventSender::GestureScrollUpdate(gin::Arguments* args) {
1831 GestureEvent(WebInputEvent::GestureScrollUpdate, args);
1832}
1833
ccameronb81b8072015-01-30 00:54:491834void EventSender::GesturePinchBegin(gin::Arguments* args) {
1835 GestureEvent(WebInputEvent::GesturePinchBegin, args);
1836}
1837
1838void EventSender::GesturePinchEnd(gin::Arguments* args) {
1839 GestureEvent(WebInputEvent::GesturePinchEnd, args);
1840}
1841
1842void EventSender::GesturePinchUpdate(gin::Arguments* args) {
1843 GestureEvent(WebInputEvent::GesturePinchUpdate, args);
1844}
1845
[email protected]3db130e2014-03-27 08:14:481846void EventSender::GestureTap(gin::Arguments* args) {
1847 GestureEvent(WebInputEvent::GestureTap, args);
1848}
1849
1850void EventSender::GestureTapDown(gin::Arguments* args) {
1851 GestureEvent(WebInputEvent::GestureTapDown, args);
1852}
1853
1854void EventSender::GestureShowPress(gin::Arguments* args) {
1855 GestureEvent(WebInputEvent::GestureShowPress, args);
1856}
1857
1858void EventSender::GestureTapCancel(gin::Arguments* args) {
1859 GestureEvent(WebInputEvent::GestureTapCancel, args);
1860}
1861
1862void EventSender::GestureLongPress(gin::Arguments* args) {
1863 GestureEvent(WebInputEvent::GestureLongPress, args);
1864}
1865
1866void EventSender::GestureLongTap(gin::Arguments* args) {
1867 GestureEvent(WebInputEvent::GestureLongTap, args);
1868}
1869
1870void EventSender::GestureTwoFingerTap(gin::Arguments* args) {
1871 GestureEvent(WebInputEvent::GestureTwoFingerTap, args);
1872}
1873
1874void EventSender::ContinuousMouseScrollBy(gin::Arguments* args) {
1875 WebMouseWheelEvent event;
1876 InitMouseWheelEvent(args, true, &event);
tkent588765612014-11-28 01:07:481877 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481878}
1879
[email protected]3db130e2014-03-27 08:14:481880void EventSender::MouseMoveTo(gin::Arguments* args) {
1881 if (force_layout_on_events_)
1882 view_->layout();
1883
[email protected]f53eba122014-04-16 11:30:011884 double x;
1885 double y;
mustaq0fff7fc32014-09-24 20:21:431886 if (!args->GetNext(&x) || !args->GetNext(&y)) {
1887 args->ThrowError();
1888 return;
1889 }
[email protected]f53eba122014-04-16 11:30:011890 WebPoint mouse_pos(static_cast<int>(x), static_cast<int>(y));
[email protected]3db130e2014-03-27 08:14:481891
1892 int modifiers = 0;
1893 if (!args->PeekNext().IsEmpty())
1894 modifiers = GetKeyModifiersFromV8(args->PeekNext());
1895
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);
1903 } else {
1904 WebMouseEvent event;
1905 InitMouseEvent(WebInputEvent::MouseMove,
1906 pressed_button_,
1907 mouse_pos,
1908 GetCurrentEventTimeSec(),
1909 click_count_,
1910 modifiers,
1911 &event);
1912 DoMouseMove(event);
1913 }
1914}
1915
[email protected]9d80c822014-05-19 19:07:121916void EventSender::TrackpadScrollBegin() {
1917 WebMouseWheelEvent event;
1918 InitMouseEvent(WebInputEvent::MouseWheel,
1919 WebMouseEvent::ButtonNone,
1920 last_mouse_pos_,
1921 GetCurrentEventTimeSec(),
1922 click_count_,
1923 0,
1924 &event);
1925 event.phase = blink::WebMouseWheelEvent::PhaseBegan;
1926 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481927 HandleInputEventOnViewOrPopup(event);
[email protected]9d80c822014-05-19 19:07:121928}
1929
1930void EventSender::TrackpadScroll(gin::Arguments* args) {
1931 WebMouseWheelEvent event;
1932 InitMouseWheelEvent(args, true, &event);
1933 event.phase = blink::WebMouseWheelEvent::PhaseChanged;
1934 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481935 HandleInputEventOnViewOrPopup(event);
[email protected]9d80c822014-05-19 19:07:121936}
1937
1938void EventSender::TrackpadScrollEnd() {
1939 WebMouseWheelEvent event;
1940 InitMouseEvent(WebInputEvent::MouseWheel,
1941 WebMouseEvent::ButtonNone,
1942 last_mouse_pos_,
1943 GetCurrentEventTimeSec(),
1944 click_count_,
1945 0,
1946 &event);
1947 event.phase = WebMouseWheelEvent::PhaseEnded;
1948 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481949 HandleInputEventOnViewOrPopup(event);
[email protected]9d80c822014-05-19 19:07:121950}
1951
[email protected]3db130e2014-03-27 08:14:481952void EventSender::MouseScrollBy(gin::Arguments* args) {
1953 WebMouseWheelEvent event;
1954 InitMouseWheelEvent(args, false, &event);
tkent588765612014-11-28 01:07:481955 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481956}
1957
[email protected]9d80c822014-05-19 19:07:121958void EventSender::MouseMomentumBegin() {
1959 WebMouseWheelEvent event;
1960 InitMouseEvent(WebInputEvent::MouseWheel,
1961 WebMouseEvent::ButtonNone,
1962 last_mouse_pos_,
1963 GetCurrentEventTimeSec(),
1964 click_count_,
1965 0,
1966 &event);
1967 event.momentumPhase = WebMouseWheelEvent::PhaseBegan;
1968 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481969 HandleInputEventOnViewOrPopup(event);
[email protected]9d80c822014-05-19 19:07:121970}
1971
1972void EventSender::MouseMomentumBegin2(gin::Arguments* args) {
1973 WebMouseWheelEvent event;
1974 InitMouseWheelEvent(args, true, &event);
1975 event.momentumPhase = WebMouseWheelEvent::PhaseBegan;
1976 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481977 HandleInputEventOnViewOrPopup(event);
[email protected]9d80c822014-05-19 19:07:121978}
1979
[email protected]3db130e2014-03-27 08:14:481980void EventSender::MouseMomentumScrollBy(gin::Arguments* args) {
1981 WebMouseWheelEvent event;
1982 InitMouseWheelEvent(args, true, &event);
1983 event.momentumPhase = WebMouseWheelEvent::PhaseChanged;
1984 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481985 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:481986}
1987
1988void EventSender::MouseMomentumEnd() {
1989 WebMouseWheelEvent event;
1990 InitMouseEvent(WebInputEvent::MouseWheel,
1991 WebMouseEvent::ButtonNone,
1992 last_mouse_pos_,
1993 GetCurrentEventTimeSec(),
1994 click_count_,
1995 0,
1996 &event);
1997 event.momentumPhase = WebMouseWheelEvent::PhaseEnded;
1998 event.hasPreciseScrollingDeltas = true;
tkent588765612014-11-28 01:07:481999 HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:482000}
2001
2002void EventSender::ScheduleAsynchronousClick(int button_number, int modifiers) {
abhishek.a21ca9b5602014-09-19 07:33:332003 delegate_->PostTask(new MouseDownTask(this, button_number, modifiers));
2004 delegate_->PostTask(new MouseUpTask(this, button_number, modifiers));
[email protected]3db130e2014-03-27 08:14:482005}
2006
2007void EventSender::ScheduleAsynchronousKeyDown(const std::string& code_str,
2008 int modifiers,
2009 KeyLocationCode location) {
abhishek.a21ca9b5602014-09-19 07:33:332010 delegate_->PostTask(new KeyDownTask(this, code_str, modifiers, location));
[email protected]3db130e2014-03-27 08:14:482011}
2012
2013double EventSender::GetCurrentEventTimeSec() {
abhishek.a21ca9b5602014-09-19 07:33:332014 return (delegate_->GetCurrentTimeInMillisecond() + time_offset_ms_) / 1000.0;
[email protected]3db130e2014-03-27 08:14:482015}
2016
2017void EventSender::DoLeapForward(int milliseconds) {
2018 time_offset_ms_ += milliseconds;
2019}
2020
2021void EventSender::SendCurrentTouchEvent(WebInputEvent::Type type) {
2022 DCHECK_GT(static_cast<unsigned>(WebTouchEvent::touchesLengthCap),
2023 touch_points_.size());
2024 if (force_layout_on_events_)
2025 view_->layout();
2026
2027 WebTouchEvent touch_event;
2028 touch_event.type = type;
2029 touch_event.modifiers = touch_modifiers_;
[email protected]ace1cd502014-04-24 21:05:302030 touch_event.cancelable = touch_cancelable_;
[email protected]3db130e2014-03-27 08:14:482031 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];
tkent588765612014-11-28 01:07:482035 HandleInputEventOnViewOrPopup(touch_event);
[email protected]3db130e2014-03-27 08:14:482036
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);
2041 --i;
2042 } else
2043 touch_point->state = WebTouchPoint::StateStationary;
2044 }
2045}
2046
2047void EventSender::GestureEvent(WebInputEvent::Type type,
majidvp41c4272a2014-12-08 15:51:142048 gin::Arguments* args) {
ccameronb81b8072015-01-30 00:54:492049 WebGestureEvent event;
2050 event.type = type;
2051
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
2054 // assuming this).
2055 event.sourceDevice = blink::WebGestureDeviceTouchscreen;
2056 if (args->PeekNext()->IsString()) {
2057 std::string device_string;
2058 if (!args->GetNext(&device_string)) {
2059 args->ThrowError();
2060 return;
2061 }
tdresser3a1c9722015-02-13 15:44:532062 if (device_string == kSourceDeviceStringTouchpad) {
ccameronb81b8072015-01-30 00:54:492063 event.sourceDevice = blink::WebGestureDeviceTouchpad;
tdresser3a1c9722015-02-13 15:44:532064 } else if (device_string == kSourceDeviceStringTouchscreen) {
ccameronb81b8072015-01-30 00:54:492065 event.sourceDevice = blink::WebGestureDeviceTouchscreen;
2066 } else {
2067 args->ThrowError();
2068 return;
2069 }
2070 }
2071
[email protected]3db130e2014-03-27 08:14:482072 double x;
2073 double y;
mustaq0fff7fc32014-09-24 20:21:432074 if (!args->GetNext(&x) || !args->GetNext(&y)) {
2075 args->ThrowError();
2076 return;
2077 }
[email protected]3db130e2014-03-27 08:14:482078
[email protected]3db130e2014-03-27 08:14:482079 switch (type) {
2080 case WebInputEvent::GestureScrollUpdate:
majidvp50205db2014-11-27 17:28:522081 {
majidvp41c4272a2014-12-08 15:51:142082 bool preventPropagation = false;
2083 if (!args->PeekNext().IsEmpty()) {
majidvp50205db2014-11-27 17:28:522084 if (!args->GetNext(&preventPropagation)) {
2085 args->ThrowError();
2086 return;
2087 }
2088 }
2089
[email protected]3db130e2014-03-27 08:14:482090 event.data.scrollUpdate.deltaX = static_cast<float>(x);
2091 event.data.scrollUpdate.deltaY = static_cast<float>(y);
majidvp50205db2014-11-27 17:28:522092 event.data.scrollUpdate.preventPropagation = preventPropagation;
[email protected]3db130e2014-03-27 08:14:482093 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;
2099 break;
majidvp50205db2014-11-27 17:28:522100 }
[email protected]3db130e2014-03-27 08:14:482101 case WebInputEvent::GestureScrollBegin:
mustaq0fff7fc32014-09-24 20:21:432102 current_gesture_location_ = WebPoint(x, y);
[email protected]3db130e2014-03-27 08:14:482103 event.x = current_gesture_location_.x;
2104 event.y = current_gesture_location_.y;
2105 break;
2106 case WebInputEvent::GestureScrollEnd:
2107 case WebInputEvent::GestureFlingStart:
2108 event.x = current_gesture_location_.x;
2109 event.y = current_gesture_location_.y;
2110 break;
ccameronb81b8072015-01-30 00:54:492111 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;
2116 break;
2117 case WebInputEvent::GesturePinchUpdate:
2118 {
2119 float scale = 1;
2120 if (!args->PeekNext().IsEmpty()) {
2121 if (!args->GetNext(&scale)) {
2122 args->ThrowError();
2123 return;
2124 }
2125 }
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;
2130 break;
2131 }
[email protected]4c07a712014-08-21 17:05:542132 case WebInputEvent::GestureTap:
[email protected]c278d7532014-07-31 19:51:452133 {
2134 float tap_count = 1;
2135 float width = 30;
2136 float height = 30;
[email protected]3db130e2014-03-27 08:14:482137 if (!args->PeekNext().IsEmpty()) {
[email protected]3db130e2014-03-27 08:14:482138 if (!args->GetNext(&tap_count)) {
2139 args->ThrowError();
2140 return;
2141 }
[email protected]3db130e2014-03-27 08:14:482142 }
[email protected]cc42ccf2014-06-27 21:31:432143 if (!args->PeekNext().IsEmpty()) {
[email protected]cc42ccf2014-06-27 21:31:432144 if (!args->GetNext(&width)) {
2145 args->ThrowError();
2146 return;
2147 }
[email protected]cc42ccf2014-06-27 21:31:432148 }
2149 if (!args->PeekNext().IsEmpty()) {
[email protected]cc42ccf2014-06-27 21:31:432150 if (!args->GetNext(&height)) {
2151 args->ThrowError();
2152 return;
2153 }
[email protected]cc42ccf2014-06-27 21:31:432154 }
[email protected]c278d7532014-07-31 19:51:452155 event.data.tap.tapCount = tap_count;
2156 event.data.tap.width = width;
2157 event.data.tap.height = height;
mustaq0fff7fc32014-09-24 20:21:432158 event.x = x;
2159 event.y = y;
[email protected]3db130e2014-03-27 08:14:482160 break;
[email protected]c278d7532014-07-31 19:51:452161 }
[email protected]3db130e2014-03-27 08:14:482162 case WebInputEvent::GestureTapUnconfirmed:
2163 if (!args->PeekNext().IsEmpty()) {
2164 float tap_count;
2165 if (!args->GetNext(&tap_count)) {
2166 args->ThrowError();
2167 return;
2168 }
2169 event.data.tap.tapCount = tap_count;
2170 } else {
2171 event.data.tap.tapCount = 1;
2172 }
mustaq0fff7fc32014-09-24 20:21:432173 event.x = x;
2174 event.y = y;
[email protected]3db130e2014-03-27 08:14:482175 break;
2176 case WebInputEvent::GestureTapDown:
[email protected]c278d7532014-07-31 19:51:452177 {
2178 float width = 30;
2179 float height = 30;
[email protected]3db130e2014-03-27 08:14:482180 if (!args->PeekNext().IsEmpty()) {
[email protected]3db130e2014-03-27 08:14:482181 if (!args->GetNext(&width)) {
2182 args->ThrowError();
2183 return;
2184 }
[email protected]3db130e2014-03-27 08:14:482185 }
2186 if (!args->PeekNext().IsEmpty()) {
[email protected]3db130e2014-03-27 08:14:482187 if (!args->GetNext(&height)) {
2188 args->ThrowError();
2189 return;
2190 }
[email protected]3db130e2014-03-27 08:14:482191 }
mustaq0fff7fc32014-09-24 20:21:432192 event.x = x;
2193 event.y = y;
[email protected]c278d7532014-07-31 19:51:452194 event.data.tapDown.width = width;
2195 event.data.tapDown.height = height;
2196 break;
2197 }
2198 case WebInputEvent::GestureShowPress:
2199 {
2200 float width = 30;
2201 float height = 30;
[email protected]3db130e2014-03-27 08:14:482202 if (!args->PeekNext().IsEmpty()) {
[email protected]3db130e2014-03-27 08:14:482203 if (!args->GetNext(&width)) {
2204 args->ThrowError();
2205 return;
2206 }
[email protected]3db130e2014-03-27 08:14:482207 if (!args->PeekNext().IsEmpty()) {
[email protected]3db130e2014-03-27 08:14:482208 if (!args->GetNext(&height)) {
2209 args->ThrowError();
2210 return;
2211 }
[email protected]3db130e2014-03-27 08:14:482212 }
2213 }
mustaq0fff7fc32014-09-24 20:21:432214 event.x = x;
2215 event.y = y;
[email protected]c278d7532014-07-31 19:51:452216 event.data.showPress.width = width;
2217 event.data.showPress.height = height;
[email protected]3db130e2014-03-27 08:14:482218 break;
[email protected]c278d7532014-07-31 19:51:452219 }
[email protected]3db130e2014-03-27 08:14:482220 case WebInputEvent::GestureTapCancel:
mustaq0fff7fc32014-09-24 20:21:432221 event.x = x;
2222 event.y = y;
[email protected]3db130e2014-03-27 08:14:482223 break;
2224 case WebInputEvent::GestureLongPress:
mustaq0fff7fc32014-09-24 20:21:432225 event.x = x;
2226 event.y = y;
[email protected]3db130e2014-03-27 08:14:482227 if (!args->PeekNext().IsEmpty()) {
2228 float width;
2229 if (!args->GetNext(&width)) {
2230 args->ThrowError();
2231 return;
2232 }
2233 event.data.longPress.width = width;
2234 if (!args->PeekNext().IsEmpty()) {
2235 float height;
2236 if (!args->GetNext(&height)) {
2237 args->ThrowError();
2238 return;
2239 }
2240 event.data.longPress.height = height;
2241 }
2242 }
2243 break;
2244 case WebInputEvent::GestureLongTap:
mustaq0fff7fc32014-09-24 20:21:432245 event.x = x;
2246 event.y = y;
[email protected]3db130e2014-03-27 08:14:482247 if (!args->PeekNext().IsEmpty()) {
2248 float width;
2249 if (!args->GetNext(&width)) {
2250 args->ThrowError();
2251 return;
2252 }
2253 event.data.longPress.width = width;
2254 if (!args->PeekNext().IsEmpty()) {
2255 float height;
2256 if (!args->GetNext(&height)) {
2257 args->ThrowError();
2258 return;
2259 }
2260 event.data.longPress.height = height;
2261 }
2262 }
2263 break;
2264 case WebInputEvent::GestureTwoFingerTap:
mustaq0fff7fc32014-09-24 20:21:432265 event.x = x;
2266 event.y = y;
[email protected]3db130e2014-03-27 08:14:482267 if (!args->PeekNext().IsEmpty()) {
2268 float first_finger_width;
2269 if (!args->GetNext(&first_finger_width)) {
2270 args->ThrowError();
2271 return;
2272 }
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)) {
2277 args->ThrowError();
2278 return;
2279 }
2280 event.data.twoFingerTap.firstFingerHeight = first_finger_height;
2281 }
2282 }
2283 break;
2284 default:
2285 NOTREACHED();
2286 }
2287
2288 event.globalX = event.x;
2289 event.globalY = event.y;
2290 event.timeStampSeconds = GetCurrentEventTimeSec();
2291
2292 if (force_layout_on_events_)
2293 view_->layout();
2294
tkent588765612014-11-28 01:07:482295 bool result = HandleInputEventOnViewOrPopup(event);
[email protected]3db130e2014-03-27 08:14:482296
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,
2301 pressed_button_,
mustaq0fff7fc32014-09-24 20:21:432302 WebPoint(x, y),
[email protected]3db130e2014-03-27 08:14:482303 GetCurrentEventTimeSec(),
2304 click_count_,
2305 0,
2306 &mouse_event);
2307
2308 FinishDragAndDrop(mouse_event, blink::WebDragOperationNone);
2309 }
[email protected]4d86d942014-06-02 22:36:322310 args->Return(result);
[email protected]3db130e2014-03-27 08:14:482311}
2312
2313void 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_)) {
2319 ++click_count_;
2320 } else {
2321 click_count_ = 1;
2322 last_button_type_ = button_type;
2323 }
2324}
2325
2326void EventSender::InitMouseWheelEvent(gin::Arguments* args,
2327 bool continuous,
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_)
2333 view_->layout();
2334
2335 double horizontal;
2336 if (!args->GetNext(&horizontal)) {
2337 args->ThrowError();
2338 return;
2339 }
2340 double vertical;
2341 if (!args->GetNext(&vertical)) {
2342 args->ThrowError();
2343 return;
2344 }
2345
2346 bool paged = false;
2347 bool has_precise_scrolling_deltas = false;
2348 int modifiers = 0;
lanweia93644f2015-01-21 22:00:332349 bool can_scroll = true;
yutakf3990fd2014-12-23 03:52:382350 if (!args->PeekNext().IsEmpty()) {
2351 args->GetNext(&paged);
2352 if (!args->PeekNext().IsEmpty()) {
2353 args->GetNext(&has_precise_scrolling_deltas);
lanweia93644f2015-01-21 22:00:332354 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);
2360 }
yutakf3990fd2014-12-23 03:52:382361 }
2362 }
[email protected]3db130e2014-03-27 08:14:482363
2364 InitMouseEvent(WebInputEvent::MouseWheel,
2365 pressed_button_,
2366 last_mouse_pos_,
2367 GetCurrentEventTimeSec(),
2368 click_count_,
2369 modifiers,
2370 event);
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;
lanweia93644f2015-01-21 22:00:332377 event->canScroll = can_scroll;
[email protected]3db130e2014-03-27 08:14:482378 if (continuous) {
2379 event->wheelTicksX /= kScrollbarPixelsPerTick;
2380 event->wheelTicksY /= kScrollbarPixelsPerTick;
2381 } else {
2382 event->deltaX *= kScrollbarPixelsPerTick;
2383 event->deltaY *= kScrollbarPixelsPerTick;
2384 }
2385}
2386
2387void 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);
2396 } else {
2397 view_->dragTargetDragLeave();
2398 }
2399 view_->dragSourceEndedAt(client_point, screen_point, current_drag_effect_);
2400 view_->dragSourceSystemDragEnded();
2401
2402 current_drag_data_.reset();
2403}
2404
2405void EventSender::DoMouseUp(const WebMouseEvent& e) {
tkent588765612014-11-28 01:07:482406 HandleInputEventOnViewOrPopup(e);
[email protected]3db130e2014-03-27 08:14:482407
2408 pressed_button_ = WebMouseEvent::ButtonNone;
2409 last_click_time_sec_ = e.timeStampSeconds;
2410 last_click_pos_ = last_mouse_pos_;
2411
2412 // If we're in a drag operation, complete it.
2413 if (current_drag_data_.isNull())
2414 return;
2415
2416 WebPoint client_point(e.x, e.y);
2417 WebPoint screen_point(e.globalX, e.globalY);
2418 FinishDragAndDrop(
2419 e,
2420 view_->dragTargetDragOver(
2421 client_point, screen_point, current_drag_effects_allowed_, 0));
2422}
2423
2424void EventSender::DoMouseMove(const WebMouseEvent& e) {
2425 last_mouse_pos_ = WebPoint(e.x, e.y);
2426
tkent588765612014-11-28 01:07:482427 HandleInputEventOnViewOrPopup(e);
[email protected]3db130e2014-03-27 08:14:482428
2429 if (pressed_button_ == WebMouseEvent::ButtonNone ||
2430 current_drag_data_.isNull()) {
2431 return;
2432 }
2433
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);
2438}
2439
2440void 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();
2445
2446 switch (e.type) {
2447 case SavedEvent::TYPE_MOUSE_MOVE: {
2448 WebMouseEvent event;
2449 InitMouseEvent(WebInputEvent::MouseMove,
2450 pressed_button_,
2451 e.pos,
2452 GetCurrentEventTimeSec(),
2453 click_count_,
2454 e.modifiers,
2455 &event);
2456 DoMouseMove(event);
2457 break;
2458 }
2459 case SavedEvent::TYPE_LEAP_FORWARD:
2460 DoLeapForward(e.milliseconds);
2461 break;
2462 case SavedEvent::TYPE_MOUSE_UP: {
2463 WebMouseEvent event;
2464 InitMouseEvent(WebInputEvent::MouseUp,
2465 e.button_type,
2466 last_mouse_pos_,
2467 GetCurrentEventTimeSec(),
2468 click_count_,
2469 e.modifiers,
2470 &event);
2471 DoMouseUp(event);
2472 break;
2473 }
2474 default:
2475 NOTREACHED();
2476 }
2477 }
2478
2479 replaying_saved_events_ = false;
2480}
2481
tkent588765612014-11-28 01:07:482482bool EventSender::HandleInputEventOnViewOrPopup(const WebInputEvent& event) {
2483 if (WebPagePopup* popup = view_->pagePopup()) {
2484 if (!WebInputEvent::isKeyboardEventType(event.type))
2485 return popup->handleInputEvent(event);
2486 }
2487 return view_->handleInputEvent(event);
2488}
2489
[email protected]3db130e2014-03-27 08:14:482490} // namespace content