| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/shell/renderer/test_runner/event_sender.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/strings/stringprintf.h" | |
| 11 #include "content/shell/renderer/test_runner/mock_spell_check.h" | |
| 12 #include "content/shell/renderer/test_runner/test_interfaces.h" | |
| 13 #include "content/shell/renderer/test_runner/web_test_delegate.h" | |
| 14 #include "content/shell/renderer/test_runner/web_test_proxy.h" | |
| 15 #include "gin/handle.h" | |
| 16 #include "gin/object_template_builder.h" | |
| 17 #include "gin/wrappable.h" | |
| 18 #include "third_party/WebKit/public/platform/WebString.h" | |
| 19 #include "third_party/WebKit/public/platform/WebVector.h" | |
| 20 #include "third_party/WebKit/public/web/WebContextMenuData.h" | |
| 21 #include "third_party/WebKit/public/web/WebFrame.h" | |
| 22 #include "third_party/WebKit/public/web/WebKit.h" | |
| 23 #include "third_party/WebKit/public/web/WebPagePopup.h" | |
| 24 #include "third_party/WebKit/public/web/WebView.h" | |
| 25 #include "ui/events/keycodes/dom/keycode_converter.h" | |
| 26 #include "ui/events/keycodes/keyboard_codes.h" | |
| 27 #include "v8/include/v8.h" | |
| 28 | |
| 29 using blink::WebContextMenuData; | |
| 30 using blink::WebDragData; | |
| 31 using blink::WebDragOperationsMask; | |
| 32 using blink::WebFloatPoint; | |
| 33 using blink::WebFrame; | |
| 34 using blink::WebGestureEvent; | |
| 35 using blink::WebInputEvent; | |
| 36 using blink::WebKeyboardEvent; | |
| 37 using blink::WebMenuItemInfo; | |
| 38 using blink::WebMouseEvent; | |
| 39 using blink::WebMouseWheelEvent; | |
| 40 using blink::WebPagePopup; | |
| 41 using blink::WebPoint; | |
| 42 using blink::WebString; | |
| 43 using blink::WebTouchEvent; | |
| 44 using blink::WebTouchPoint; | |
| 45 using blink::WebVector; | |
| 46 using blink::WebView; | |
| 47 | |
| 48 namespace content { | |
| 49 | |
| 50 namespace { | |
| 51 | |
| 52 void InitMouseEvent(WebInputEvent::Type t, | |
| 53 WebMouseEvent::Button b, | |
| 54 const WebPoint& pos, | |
| 55 double time_stamp, | |
| 56 int click_count, | |
| 57 int modifiers, | |
| 58 WebMouseEvent* e) { | |
| 59 e->type = t; | |
| 60 e->button = b; | |
| 61 e->modifiers = modifiers; | |
| 62 e->x = pos.x; | |
| 63 e->y = pos.y; | |
| 64 e->globalX = pos.x; | |
| 65 e->globalY = pos.y; | |
| 66 e->timeStampSeconds = time_stamp; | |
| 67 e->clickCount = click_count; | |
| 68 } | |
| 69 | |
| 70 int GetKeyModifier(const std::string& modifier_name) { | |
| 71 const char* characters = modifier_name.c_str(); | |
| 72 if (!strcmp(characters, "ctrlKey") | |
| 73 #ifndef __APPLE__ | |
| 74 || !strcmp(characters, "addSelectionKey") | |
| 75 #endif | |
| 76 ) { | |
| 77 return WebInputEvent::ControlKey; | |
| 78 } else if (!strcmp(characters, "shiftKey") || | |
| 79 !strcmp(characters, "rangeSelectionKey")) { | |
| 80 return WebInputEvent::ShiftKey; | |
| 81 } else if (!strcmp(characters, "altKey")) { | |
| 82 return WebInputEvent::AltKey; | |
| 83 #ifdef __APPLE__ | |
| 84 } else if (!strcmp(characters, "metaKey") || | |
| 85 !strcmp(characters, "addSelectionKey")) { | |
| 86 return WebInputEvent::MetaKey; | |
| 87 #else | |
| 88 } else if (!strcmp(characters, "metaKey")) { | |
| 89 return WebInputEvent::MetaKey; | |
| 90 #endif | |
| 91 } else if (!strcmp(characters, "autoRepeat")) { | |
| 92 return WebInputEvent::IsAutoRepeat; | |
| 93 } else if (!strcmp(characters, "copyKey")) { | |
| 94 #ifdef __APPLE__ | |
| 95 return WebInputEvent::AltKey; | |
| 96 #else | |
| 97 return WebInputEvent::ControlKey; | |
| 98 #endif | |
| 99 } else if (!strcmp(characters, "leftButton")) { | |
| 100 return WebInputEvent::LeftButtonDown; | |
| 101 } else if (!strcmp(characters, "middleButton")) { | |
| 102 return WebInputEvent::MiddleButtonDown; | |
| 103 } else if (!strcmp(characters, "rightButton")) { | |
| 104 return WebInputEvent::RightButtonDown; | |
| 105 } | |
| 106 | |
| 107 return 0; | |
| 108 } | |
| 109 | |
| 110 int GetKeyModifiers(const std::vector<std::string>& modifier_names) { | |
| 111 int modifiers = 0; | |
| 112 for (std::vector<std::string>::const_iterator it = modifier_names.begin(); | |
| 113 it != modifier_names.end(); ++it) { | |
| 114 modifiers |= GetKeyModifier(*it); | |
| 115 } | |
| 116 return modifiers; | |
| 117 } | |
| 118 | |
| 119 int GetKeyModifiersFromV8(v8::Isolate* isolate, v8::Local<v8::Value> value) { | |
| 120 std::vector<std::string> modifier_names; | |
| 121 if (value->IsString()) { | |
| 122 modifier_names.push_back(gin::V8ToString(value)); | |
| 123 } else if (value->IsArray()) { | |
| 124 gin::Converter<std::vector<std::string> >::FromV8( | |
| 125 isolate, value, &modifier_names); | |
| 126 } | |
| 127 return GetKeyModifiers(modifier_names); | |
| 128 } | |
| 129 | |
| 130 // Maximum distance (in space and time) for a mouse click to register as a | |
| 131 // double or triple click. | |
| 132 const double kMultipleClickTimeSec = 1; | |
| 133 const int kMultipleClickRadiusPixels = 5; | |
| 134 const char kSubMenuDepthIdentifier[] = "_"; | |
| 135 const char kSubMenuIdentifier[] = " >"; | |
| 136 const char kSeparatorIdentifier[] = "---------"; | |
| 137 const char kDisabledIdentifier[] = "#"; | |
| 138 const char kCheckedIdentifier[] = "*"; | |
| 139 | |
| 140 bool OutsideMultiClickRadius(const WebPoint& a, const WebPoint& b) { | |
| 141 return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) > | |
| 142 kMultipleClickRadiusPixels * kMultipleClickRadiusPixels; | |
| 143 } | |
| 144 | |
| 145 void PopulateCustomItems(const WebVector<WebMenuItemInfo>& customItems, | |
| 146 const std::string& prefix, std::vector<std::string>* strings) { | |
| 147 for (size_t i = 0; i < customItems.size(); ++i) { | |
| 148 std::string prefixCopy = prefix; | |
| 149 if (!customItems[i].enabled) | |
| 150 prefixCopy = kDisabledIdentifier + prefix; | |
| 151 if (customItems[i].checked) | |
| 152 prefixCopy = kCheckedIdentifier + prefix; | |
| 153 if (customItems[i].type == blink::WebMenuItemInfo::Separator) { | |
| 154 strings->push_back(prefixCopy + kSeparatorIdentifier); | |
| 155 } else if (customItems[i].type == blink::WebMenuItemInfo::SubMenu) { | |
| 156 strings->push_back(prefixCopy + customItems[i].label.utf8() + | |
| 157 customItems[i].icon.utf8() + kSubMenuIdentifier); | |
| 158 PopulateCustomItems(customItems[i].subMenuItems, prefixCopy + | |
| 159 kSubMenuDepthIdentifier, strings); | |
| 160 } else { | |
| 161 strings->push_back(prefixCopy + customItems[i].label.utf8() + | |
| 162 customItems[i].icon.utf8()); | |
| 163 } | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 // Because actual context menu is implemented by the browser side, | |
| 168 // this function does only what LayoutTests are expecting: | |
| 169 // - Many test checks the count of items. So returning non-zero value makes | |
| 170 // sense. | |
| 171 // - Some test compares the count before and after some action. So changing the | |
| 172 // count based on flags also makes sense. This function is doing such for some | |
| 173 // flags. | |
| 174 // - Some test even checks actual string content. So providing it would be also | |
| 175 // helpful. | |
| 176 std::vector<std::string> MakeMenuItemStringsFor( | |
| 177 WebContextMenuData* context_menu, | |
| 178 WebTestDelegate* delegate) { | |
| 179 // These constants are based on Safari's context menu because tests are made | |
| 180 // for it. | |
| 181 static const char* kNonEditableMenuStrings[] = { | |
| 182 "Back", | |
| 183 "Reload Page", | |
| 184 "Open in Dashbaord", | |
| 185 "<separator>", | |
| 186 "View Source", | |
| 187 "Save Page As", | |
| 188 "Print Page", | |
| 189 "Inspect Element", | |
| 190 0 | |
| 191 }; | |
| 192 static const char* kEditableMenuStrings[] = { | |
| 193 "Cut", | |
| 194 "Copy", | |
| 195 "<separator>", | |
| 196 "Paste", | |
| 197 "Spelling and Grammar", | |
| 198 "Substitutions, Transformations", | |
| 199 "Font", | |
| 200 "Speech", | |
| 201 "Paragraph Direction", | |
| 202 "<separator>", | |
| 203 0 | |
| 204 }; | |
| 205 | |
| 206 // This is possible because mouse events are cancelleable. | |
| 207 if (!context_menu) | |
| 208 return std::vector<std::string>(); | |
| 209 | |
| 210 std::vector<std::string> strings; | |
| 211 | |
| 212 // Populate custom menu items if provided by blink. | |
| 213 PopulateCustomItems(context_menu->customItems, "", &strings); | |
| 214 | |
| 215 if (context_menu->isEditable) { | |
| 216 for (const char** item = kEditableMenuStrings; *item; ++item) { | |
| 217 strings.push_back(*item); | |
| 218 } | |
| 219 WebVector<WebString> suggestions; | |
| 220 MockSpellCheck::FillSuggestionList(context_menu->misspelledWord, | |
| 221 &suggestions); | |
| 222 for (size_t i = 0; i < suggestions.size(); ++i) { | |
| 223 strings.push_back(suggestions[i].utf8()); | |
| 224 } | |
| 225 } else { | |
| 226 for (const char** item = kNonEditableMenuStrings; *item; ++item) { | |
| 227 strings.push_back(*item); | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 return strings; | |
| 232 } | |
| 233 | |
| 234 // How much we should scroll per event - the value here is chosen to match the | |
| 235 // WebKit impl and layout test results. | |
| 236 const float kScrollbarPixelsPerTick = 40.0f; | |
| 237 | |
| 238 WebMouseEvent::Button GetButtonTypeFromButtonNumber(int button_code) { | |
| 239 if (!button_code) | |
| 240 return WebMouseEvent::ButtonLeft; | |
| 241 if (button_code == 2) | |
| 242 return WebMouseEvent::ButtonRight; | |
| 243 return WebMouseEvent::ButtonMiddle; | |
| 244 } | |
| 245 | |
| 246 class MouseDownTask : public WebMethodTask<EventSender> { | |
| 247 public: | |
| 248 MouseDownTask(EventSender* obj, int button_number, int modifiers) | |
| 249 : WebMethodTask<EventSender>(obj), | |
| 250 button_number_(button_number), | |
| 251 modifiers_(modifiers) {} | |
| 252 | |
| 253 void RunIfValid() override { object_->MouseDown(button_number_, modifiers_); } | |
| 254 | |
| 255 private: | |
| 256 int button_number_; | |
| 257 int modifiers_; | |
| 258 }; | |
| 259 | |
| 260 class MouseUpTask : public WebMethodTask<EventSender> { | |
| 261 public: | |
| 262 MouseUpTask(EventSender* obj, int button_number, int modifiers) | |
| 263 : WebMethodTask<EventSender>(obj), | |
| 264 button_number_(button_number), | |
| 265 modifiers_(modifiers) {} | |
| 266 | |
| 267 void RunIfValid() override { object_->MouseUp(button_number_, modifiers_); } | |
| 268 | |
| 269 private: | |
| 270 int button_number_; | |
| 271 int modifiers_; | |
| 272 }; | |
| 273 | |
| 274 class KeyDownTask : public WebMethodTask<EventSender> { | |
| 275 public: | |
| 276 KeyDownTask(EventSender* obj, | |
| 277 const std::string code_str, | |
| 278 int modifiers, | |
| 279 KeyLocationCode location) | |
| 280 : WebMethodTask<EventSender>(obj), | |
| 281 code_str_(code_str), | |
| 282 modifiers_(modifiers), | |
| 283 location_(location) {} | |
| 284 | |
| 285 void RunIfValid() override { | |
| 286 object_->KeyDown(code_str_, modifiers_, location_); | |
| 287 } | |
| 288 | |
| 289 private: | |
| 290 std::string code_str_; | |
| 291 int modifiers_; | |
| 292 KeyLocationCode location_; | |
| 293 }; | |
| 294 | |
| 295 bool NeedsShiftModifier(int keyCode) { | |
| 296 // If code is an uppercase letter, assign a SHIFT key to eventDown.modifier. | |
| 297 return (keyCode & 0xFF) >= 'A' && (keyCode & 0xFF) <= 'Z'; | |
| 298 } | |
| 299 | |
| 300 // Get the edit command corresponding to a keyboard event. | |
| 301 // Returns true if the specified event corresponds to an edit command, the name | |
| 302 // of the edit command will be stored in |*name|. | |
| 303 bool GetEditCommand(const WebKeyboardEvent& event, std::string* name) { | |
| 304 #if defined(OS_MACOSX) | |
| 305 // We only cares about Left,Right,Up,Down keys with Command or Command+Shift | |
| 306 // modifiers. These key events correspond to some special movement and | |
| 307 // selection editor commands. These keys will be marked as system key, which | |
| 308 // prevents them from being handled. Thus they must be handled specially. | |
| 309 if ((event.modifiers & ~WebKeyboardEvent::ShiftKey) != | |
| 310 WebKeyboardEvent::MetaKey) | |
| 311 return false; | |
| 312 | |
| 313 switch (event.windowsKeyCode) { | |
| 314 case ui::VKEY_LEFT: | |
| 315 *name = "MoveToBeginningOfLine"; | |
| 316 break; | |
| 317 case ui::VKEY_RIGHT: | |
| 318 *name = "MoveToEndOfLine"; | |
| 319 break; | |
| 320 case ui::VKEY_UP: | |
| 321 *name = "MoveToBeginningOfDocument"; | |
| 322 break; | |
| 323 case ui::VKEY_DOWN: | |
| 324 *name = "MoveToEndOfDocument"; | |
| 325 break; | |
| 326 default: | |
| 327 return false; | |
| 328 } | |
| 329 | |
| 330 if (event.modifiers & WebKeyboardEvent::ShiftKey) | |
| 331 name->append("AndModifySelection"); | |
| 332 | |
| 333 return true; | |
| 334 #else | |
| 335 return false; | |
| 336 #endif | |
| 337 } | |
| 338 | |
| 339 bool IsSystemKeyEvent(const WebKeyboardEvent& event) { | |
| 340 #if defined(OS_MACOSX) | |
| 341 return event.modifiers & WebInputEvent::MetaKey && | |
| 342 event.windowsKeyCode != ui::VKEY_B && | |
| 343 event.windowsKeyCode != ui::VKEY_I; | |
| 344 #else | |
| 345 return !!(event.modifiers & WebInputEvent::AltKey); | |
| 346 #endif | |
| 347 } | |
| 348 | |
| 349 const char* kSourceDeviceStringTouchpad = "touchpad"; | |
| 350 const char* kSourceDeviceStringTouchscreen = "touchscreen"; | |
| 351 | |
| 352 } // namespace | |
| 353 | |
| 354 class EventSenderBindings : public gin::Wrappable<EventSenderBindings> { | |
| 355 public: | |
| 356 static gin::WrapperInfo kWrapperInfo; | |
| 357 | |
| 358 static void Install(base::WeakPtr<EventSender> sender, | |
| 359 blink::WebFrame* frame); | |
| 360 | |
| 361 private: | |
| 362 explicit EventSenderBindings(base::WeakPtr<EventSender> sender); | |
| 363 ~EventSenderBindings() override; | |
| 364 | |
| 365 // gin::Wrappable: | |
| 366 gin::ObjectTemplateBuilder GetObjectTemplateBuilder( | |
| 367 v8::Isolate* isolate) override; | |
| 368 | |
| 369 // Bound methods: | |
| 370 void EnableDOMUIEventLogging(); | |
| 371 void FireKeyboardEventsToElement(); | |
| 372 void ClearKillRing(); | |
| 373 std::vector<std::string> ContextClick(); | |
| 374 void TextZoomIn(); | |
| 375 void TextZoomOut(); | |
| 376 void ZoomPageIn(); | |
| 377 void ZoomPageOut(); | |
| 378 void SetPageZoomFactor(double factor); | |
| 379 void ClearTouchPoints(); | |
| 380 void ReleaseTouchPoint(unsigned index); | |
| 381 void UpdateTouchPoint(unsigned index, double x, double y); | |
| 382 void CancelTouchPoint(unsigned index); | |
| 383 void SetTouchModifier(const std::string& key_name, bool set_mask); | |
| 384 void SetTouchCancelable(bool cancelable); | |
| 385 void DumpFilenameBeingDragged(); | |
| 386 void GestureFlingCancel(); | |
| 387 void GestureFlingStart(float x, | |
| 388 float y, | |
| 389 float velocity_x, | |
| 390 float velocity_y, | |
| 391 gin::Arguments* args); | |
| 392 void GestureScrollFirstPoint(int x, int y); | |
| 393 void TouchStart(); | |
| 394 void TouchMove(); | |
| 395 void TouchCancel(); | |
| 396 void TouchEnd(); | |
| 397 void LeapForward(int milliseconds); | |
| 398 void BeginDragWithFiles(const std::vector<std::string>& files); | |
| 399 void AddTouchPoint(gin::Arguments* args); | |
| 400 void MouseDragBegin(); | |
| 401 void MouseDragEnd(); | |
| 402 void GestureScrollBegin(gin::Arguments* args); | |
| 403 void GestureScrollEnd(gin::Arguments* args); | |
| 404 void GestureScrollUpdate(gin::Arguments* args); | |
| 405 void GesturePinchBegin(gin::Arguments* args); | |
| 406 void GesturePinchEnd(gin::Arguments* args); | |
| 407 void GesturePinchUpdate(gin::Arguments* args); | |
| 408 void GestureTap(gin::Arguments* args); | |
| 409 void GestureTapDown(gin::Arguments* args); | |
| 410 void GestureShowPress(gin::Arguments* args); | |
| 411 void GestureTapCancel(gin::Arguments* args); | |
| 412 void GestureLongPress(gin::Arguments* args); | |
| 413 void GestureLongTap(gin::Arguments* args); | |
| 414 void GestureTwoFingerTap(gin::Arguments* args); | |
| 415 void ContinuousMouseScrollBy(gin::Arguments* args); | |
| 416 void MouseMoveTo(gin::Arguments* args); | |
| 417 void MouseLeave(); | |
| 418 void TrackpadScrollBegin(); | |
| 419 void TrackpadScroll(gin::Arguments* args); | |
| 420 void TrackpadScrollEnd(); | |
| 421 void MouseScrollBy(gin::Arguments* args); | |
| 422 // TODO(erikchen): Remove MouseMomentumBegin once CL 282743002 has landed. | |
| 423 void MouseMomentumBegin(); | |
| 424 void MouseMomentumBegin2(gin::Arguments* args); | |
| 425 void MouseMomentumScrollBy(gin::Arguments* args); | |
| 426 void MouseMomentumEnd(); | |
| 427 void ScheduleAsynchronousClick(gin::Arguments* args); | |
| 428 void ScheduleAsynchronousKeyDown(gin::Arguments* args); | |
| 429 void MouseDown(gin::Arguments* args); | |
| 430 void MouseUp(gin::Arguments* args); | |
| 431 void KeyDown(gin::Arguments* args); | |
| 432 | |
| 433 // Binding properties: | |
| 434 bool ForceLayoutOnEvents() const; | |
| 435 void SetForceLayoutOnEvents(bool force); | |
| 436 bool IsDragMode() const; | |
| 437 void SetIsDragMode(bool drag_mode); | |
| 438 | |
| 439 #if defined(OS_WIN) | |
| 440 int WmKeyDown() const; | |
| 441 void SetWmKeyDown(int key_down); | |
| 442 | |
| 443 int WmKeyUp() const; | |
| 444 void SetWmKeyUp(int key_up); | |
| 445 | |
| 446 int WmChar() const; | |
| 447 void SetWmChar(int wm_char); | |
| 448 | |
| 449 int WmDeadChar() const; | |
| 450 void SetWmDeadChar(int dead_char); | |
| 451 | |
| 452 int WmSysKeyDown() const; | |
| 453 void SetWmSysKeyDown(int key_down); | |
| 454 | |
| 455 int WmSysKeyUp() const; | |
| 456 void SetWmSysKeyUp(int key_up); | |
| 457 | |
| 458 int WmSysChar() const; | |
| 459 void SetWmSysChar(int sys_char); | |
| 460 | |
| 461 int WmSysDeadChar() const; | |
| 462 void SetWmSysDeadChar(int sys_dead_char); | |
| 463 #endif | |
| 464 | |
| 465 base::WeakPtr<EventSender> sender_; | |
| 466 | |
| 467 DISALLOW_COPY_AND_ASSIGN(EventSenderBindings); | |
| 468 }; | |
| 469 | |
| 470 gin::WrapperInfo EventSenderBindings::kWrapperInfo = {gin::kEmbedderNativeGin}; | |
| 471 | |
| 472 EventSenderBindings::EventSenderBindings(base::WeakPtr<EventSender> sender) | |
| 473 : sender_(sender) { | |
| 474 } | |
| 475 | |
| 476 EventSenderBindings::~EventSenderBindings() {} | |
| 477 | |
| 478 // static | |
| 479 void EventSenderBindings::Install(base::WeakPtr<EventSender> sender, | |
| 480 WebFrame* frame) { | |
| 481 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
| 482 v8::HandleScope handle_scope(isolate); | |
| 483 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | |
| 484 if (context.IsEmpty()) | |
| 485 return; | |
| 486 | |
| 487 v8::Context::Scope context_scope(context); | |
| 488 | |
| 489 gin::Handle<EventSenderBindings> bindings = | |
| 490 gin::CreateHandle(isolate, new EventSenderBindings(sender)); | |
| 491 if (bindings.IsEmpty()) | |
| 492 return; | |
| 493 v8::Local<v8::Object> global = context->Global(); | |
| 494 global->Set(gin::StringToV8(isolate, "eventSender"), bindings.ToV8()); | |
| 495 } | |
| 496 | |
| 497 gin::ObjectTemplateBuilder | |
| 498 EventSenderBindings::GetObjectTemplateBuilder(v8::Isolate* isolate) { | |
| 499 return gin::Wrappable<EventSenderBindings>::GetObjectTemplateBuilder(isolate) | |
| 500 .SetMethod("enableDOMUIEventLogging", | |
| 501 &EventSenderBindings::EnableDOMUIEventLogging) | |
| 502 .SetMethod("fireKeyboardEventsToElement", | |
| 503 &EventSenderBindings::FireKeyboardEventsToElement) | |
| 504 .SetMethod("clearKillRing", &EventSenderBindings::ClearKillRing) | |
| 505 .SetMethod("contextClick", &EventSenderBindings::ContextClick) | |
| 506 .SetMethod("textZoomIn", &EventSenderBindings::TextZoomIn) | |
| 507 .SetMethod("textZoomOut", &EventSenderBindings::TextZoomOut) | |
| 508 .SetMethod("zoomPageIn", &EventSenderBindings::ZoomPageIn) | |
| 509 .SetMethod("zoomPageOut", &EventSenderBindings::ZoomPageOut) | |
| 510 .SetMethod("setPageZoomFactor", &EventSenderBindings::SetPageZoomFactor) | |
| 511 .SetMethod("clearTouchPoints", &EventSenderBindings::ClearTouchPoints) | |
| 512 .SetMethod("releaseTouchPoint", &EventSenderBindings::ReleaseTouchPoint) | |
| 513 .SetMethod("updateTouchPoint", &EventSenderBindings::UpdateTouchPoint) | |
| 514 .SetMethod("cancelTouchPoint", &EventSenderBindings::CancelTouchPoint) | |
| 515 .SetMethod("setTouchModifier", &EventSenderBindings::SetTouchModifier) | |
| 516 .SetMethod("setTouchCancelable", &EventSenderBindings::SetTouchCancelable) | |
| 517 .SetMethod("dumpFilenameBeingDragged", | |
| 518 &EventSenderBindings::DumpFilenameBeingDragged) | |
| 519 .SetMethod("gestureFlingCancel", &EventSenderBindings::GestureFlingCancel) | |
| 520 .SetMethod("gestureFlingStart", &EventSenderBindings::GestureFlingStart) | |
| 521 .SetMethod("gestureScrollFirstPoint", | |
| 522 &EventSenderBindings::GestureScrollFirstPoint) | |
| 523 .SetMethod("touchStart", &EventSenderBindings::TouchStart) | |
| 524 .SetMethod("touchMove", &EventSenderBindings::TouchMove) | |
| 525 .SetMethod("touchCancel", &EventSenderBindings::TouchCancel) | |
| 526 .SetMethod("touchEnd", &EventSenderBindings::TouchEnd) | |
| 527 .SetMethod("leapForward", &EventSenderBindings::LeapForward) | |
| 528 .SetMethod("beginDragWithFiles", &EventSenderBindings::BeginDragWithFiles) | |
| 529 .SetMethod("addTouchPoint", &EventSenderBindings::AddTouchPoint) | |
| 530 .SetMethod("mouseDragBegin", &EventSenderBindings::MouseDragBegin) | |
| 531 .SetMethod("mouseDragEnd", &EventSenderBindings::MouseDragEnd) | |
| 532 .SetMethod("gestureScrollBegin", &EventSenderBindings::GestureScrollBegin) | |
| 533 .SetMethod("gestureScrollEnd", &EventSenderBindings::GestureScrollEnd) | |
| 534 .SetMethod("gestureScrollUpdate", | |
| 535 &EventSenderBindings::GestureScrollUpdate) | |
| 536 .SetMethod("gesturePinchBegin", &EventSenderBindings::GesturePinchBegin) | |
| 537 .SetMethod("gesturePinchEnd", &EventSenderBindings::GesturePinchEnd) | |
| 538 .SetMethod("gesturePinchUpdate", &EventSenderBindings::GesturePinchUpdate) | |
| 539 .SetMethod("gestureTap", &EventSenderBindings::GestureTap) | |
| 540 .SetMethod("gestureTapDown", &EventSenderBindings::GestureTapDown) | |
| 541 .SetMethod("gestureShowPress", &EventSenderBindings::GestureShowPress) | |
| 542 .SetMethod("gestureTapCancel", &EventSenderBindings::GestureTapCancel) | |
| 543 .SetMethod("gestureLongPress", &EventSenderBindings::GestureLongPress) | |
| 544 .SetMethod("gestureLongTap", &EventSenderBindings::GestureLongTap) | |
| 545 .SetMethod("gestureTwoFingerTap", | |
| 546 &EventSenderBindings::GestureTwoFingerTap) | |
| 547 .SetMethod("continuousMouseScrollBy", | |
| 548 &EventSenderBindings::ContinuousMouseScrollBy) | |
| 549 .SetMethod("keyDown", &EventSenderBindings::KeyDown) | |
| 550 .SetMethod("mouseDown", &EventSenderBindings::MouseDown) | |
| 551 .SetMethod("mouseMoveTo", &EventSenderBindings::MouseMoveTo) | |
| 552 .SetMethod("mouseLeave", &EventSenderBindings::MouseLeave) | |
| 553 .SetMethod("trackpadScrollBegin", | |
| 554 &EventSenderBindings::TrackpadScrollBegin) | |
| 555 .SetMethod("trackpadScroll", &EventSenderBindings::TrackpadScroll) | |
| 556 .SetMethod("trackpadScrollEnd", &EventSenderBindings::TrackpadScrollEnd) | |
| 557 .SetMethod("mouseScrollBy", &EventSenderBindings::MouseScrollBy) | |
| 558 .SetMethod("mouseUp", &EventSenderBindings::MouseUp) | |
| 559 .SetMethod("mouseMomentumBegin", &EventSenderBindings::MouseMomentumBegin) | |
| 560 .SetMethod("mouseMomentumBegin2", | |
| 561 &EventSenderBindings::MouseMomentumBegin2) | |
| 562 .SetMethod("mouseMomentumScrollBy", | |
| 563 &EventSenderBindings::MouseMomentumScrollBy) | |
| 564 .SetMethod("mouseMomentumEnd", &EventSenderBindings::MouseMomentumEnd) | |
| 565 .SetMethod("scheduleAsynchronousClick", | |
| 566 &EventSenderBindings::ScheduleAsynchronousClick) | |
| 567 .SetMethod("scheduleAsynchronousKeyDown", | |
| 568 &EventSenderBindings::ScheduleAsynchronousKeyDown) | |
| 569 .SetProperty("forceLayoutOnEvents", | |
| 570 &EventSenderBindings::ForceLayoutOnEvents, | |
| 571 &EventSenderBindings::SetForceLayoutOnEvents) | |
| 572 .SetProperty("dragMode", | |
| 573 &EventSenderBindings::IsDragMode, | |
| 574 &EventSenderBindings::SetIsDragMode) | |
| 575 #if defined(OS_WIN) | |
| 576 .SetProperty("WM_KEYDOWN", | |
| 577 &EventSenderBindings::WmKeyDown, | |
| 578 &EventSenderBindings::SetWmKeyDown) | |
| 579 .SetProperty("WM_KEYUP", | |
| 580 &EventSenderBindings::WmKeyUp, | |
| 581 &EventSenderBindings::SetWmKeyUp) | |
| 582 .SetProperty("WM_CHAR", | |
| 583 &EventSenderBindings::WmChar, | |
| 584 &EventSenderBindings::SetWmChar) | |
| 585 .SetProperty("WM_DEADCHAR", | |
| 586 &EventSenderBindings::WmDeadChar, | |
| 587 &EventSenderBindings::SetWmDeadChar) | |
| 588 .SetProperty("WM_SYSKEYDOWN", | |
| 589 &EventSenderBindings::WmSysKeyDown, | |
| 590 &EventSenderBindings::SetWmSysKeyDown) | |
| 591 .SetProperty("WM_SYSKEYUP", | |
| 592 &EventSenderBindings::WmSysKeyUp, | |
| 593 &EventSenderBindings::SetWmSysKeyUp) | |
| 594 .SetProperty("WM_SYSCHAR", | |
| 595 &EventSenderBindings::WmSysChar, | |
| 596 &EventSenderBindings::SetWmSysChar) | |
| 597 .SetProperty("WM_SYSDEADCHAR", | |
| 598 &EventSenderBindings::WmSysDeadChar, | |
| 599 &EventSenderBindings::SetWmSysDeadChar); | |
| 600 #else | |
| 601 ; | |
| 602 #endif | |
| 603 } | |
| 604 | |
| 605 void EventSenderBindings::EnableDOMUIEventLogging() { | |
| 606 if (sender_) | |
| 607 sender_->EnableDOMUIEventLogging(); | |
| 608 } | |
| 609 | |
| 610 void EventSenderBindings::FireKeyboardEventsToElement() { | |
| 611 if (sender_) | |
| 612 sender_->FireKeyboardEventsToElement(); | |
| 613 } | |
| 614 | |
| 615 void EventSenderBindings::ClearKillRing() { | |
| 616 if (sender_) | |
| 617 sender_->ClearKillRing(); | |
| 618 } | |
| 619 | |
| 620 std::vector<std::string> EventSenderBindings::ContextClick() { | |
| 621 if (sender_) | |
| 622 return sender_->ContextClick(); | |
| 623 return std::vector<std::string>(); | |
| 624 } | |
| 625 | |
| 626 void EventSenderBindings::TextZoomIn() { | |
| 627 if (sender_) | |
| 628 sender_->TextZoomIn(); | |
| 629 } | |
| 630 | |
| 631 void EventSenderBindings::TextZoomOut() { | |
| 632 if (sender_) | |
| 633 sender_->TextZoomOut(); | |
| 634 } | |
| 635 | |
| 636 void EventSenderBindings::ZoomPageIn() { | |
| 637 if (sender_) | |
| 638 sender_->ZoomPageIn(); | |
| 639 } | |
| 640 | |
| 641 void EventSenderBindings::ZoomPageOut() { | |
| 642 if (sender_) | |
| 643 sender_->ZoomPageOut(); | |
| 644 } | |
| 645 | |
| 646 void EventSenderBindings::SetPageZoomFactor(double factor) { | |
| 647 if (sender_) | |
| 648 sender_->SetPageZoomFactor(factor); | |
| 649 } | |
| 650 | |
| 651 void EventSenderBindings::ClearTouchPoints() { | |
| 652 if (sender_) | |
| 653 sender_->ClearTouchPoints(); | |
| 654 } | |
| 655 | |
| 656 void EventSenderBindings::ReleaseTouchPoint(unsigned index) { | |
| 657 if (sender_) | |
| 658 sender_->ReleaseTouchPoint(index); | |
| 659 } | |
| 660 | |
| 661 void EventSenderBindings::UpdateTouchPoint(unsigned index, double x, double y) { | |
| 662 if (sender_) | |
| 663 sender_->UpdateTouchPoint(index, static_cast<float>(x), static_cast<float>(y
)); | |
| 664 } | |
| 665 | |
| 666 void EventSenderBindings::CancelTouchPoint(unsigned index) { | |
| 667 if (sender_) | |
| 668 sender_->CancelTouchPoint(index); | |
| 669 } | |
| 670 | |
| 671 void EventSenderBindings::SetTouchModifier(const std::string& key_name, | |
| 672 bool set_mask) { | |
| 673 if (sender_) | |
| 674 sender_->SetTouchModifier(key_name, set_mask); | |
| 675 } | |
| 676 | |
| 677 void EventSenderBindings::SetTouchCancelable(bool cancelable) { | |
| 678 if (sender_) | |
| 679 sender_->SetTouchCancelable(cancelable); | |
| 680 } | |
| 681 | |
| 682 void EventSenderBindings::DumpFilenameBeingDragged() { | |
| 683 if (sender_) | |
| 684 sender_->DumpFilenameBeingDragged(); | |
| 685 } | |
| 686 | |
| 687 void EventSenderBindings::GestureFlingCancel() { | |
| 688 if (sender_) | |
| 689 sender_->GestureFlingCancel(); | |
| 690 } | |
| 691 | |
| 692 void EventSenderBindings::GestureFlingStart(float x, | |
| 693 float y, | |
| 694 float velocity_x, | |
| 695 float velocity_y, | |
| 696 gin::Arguments* args) { | |
| 697 if (sender_) | |
| 698 sender_->GestureFlingStart(x, y, velocity_x, velocity_y, args); | |
| 699 } | |
| 700 | |
| 701 void EventSenderBindings::GestureScrollFirstPoint(int x, int y) { | |
| 702 if (sender_) | |
| 703 sender_->GestureScrollFirstPoint(x, y); | |
| 704 } | |
| 705 | |
| 706 void EventSenderBindings::TouchStart() { | |
| 707 if (sender_) | |
| 708 sender_->TouchStart(); | |
| 709 } | |
| 710 | |
| 711 void EventSenderBindings::TouchMove() { | |
| 712 if (sender_) | |
| 713 sender_->TouchMove(); | |
| 714 } | |
| 715 | |
| 716 void EventSenderBindings::TouchCancel() { | |
| 717 if (sender_) | |
| 718 sender_->TouchCancel(); | |
| 719 } | |
| 720 | |
| 721 void EventSenderBindings::TouchEnd() { | |
| 722 if (sender_) | |
| 723 sender_->TouchEnd(); | |
| 724 } | |
| 725 | |
| 726 void EventSenderBindings::LeapForward(int milliseconds) { | |
| 727 if (sender_) | |
| 728 sender_->LeapForward(milliseconds); | |
| 729 } | |
| 730 | |
| 731 void EventSenderBindings::BeginDragWithFiles( | |
| 732 const std::vector<std::string>& files) { | |
| 733 if (sender_) | |
| 734 sender_->BeginDragWithFiles(files); | |
| 735 } | |
| 736 | |
| 737 void EventSenderBindings::AddTouchPoint(gin::Arguments* args) { | |
| 738 if (sender_) | |
| 739 sender_->AddTouchPoint(args); | |
| 740 } | |
| 741 | |
| 742 void EventSenderBindings::MouseDragBegin() { | |
| 743 if (sender_) | |
| 744 sender_->MouseDragBegin(); | |
| 745 } | |
| 746 | |
| 747 void EventSenderBindings::MouseDragEnd() { | |
| 748 if (sender_) | |
| 749 sender_->MouseDragEnd(); | |
| 750 } | |
| 751 | |
| 752 void EventSenderBindings::GestureScrollBegin(gin::Arguments* args) { | |
| 753 if (sender_) | |
| 754 sender_->GestureScrollBegin(args); | |
| 755 } | |
| 756 | |
| 757 void EventSenderBindings::GestureScrollEnd(gin::Arguments* args) { | |
| 758 if (sender_) | |
| 759 sender_->GestureScrollEnd(args); | |
| 760 } | |
| 761 | |
| 762 void EventSenderBindings::GestureScrollUpdate(gin::Arguments* args) { | |
| 763 if (sender_) | |
| 764 sender_->GestureScrollUpdate(args); | |
| 765 } | |
| 766 | |
| 767 void EventSenderBindings::GesturePinchBegin(gin::Arguments* args) { | |
| 768 if (sender_) | |
| 769 sender_->GesturePinchBegin(args); | |
| 770 } | |
| 771 | |
| 772 void EventSenderBindings::GesturePinchEnd(gin::Arguments* args) { | |
| 773 if (sender_) | |
| 774 sender_->GesturePinchEnd(args); | |
| 775 } | |
| 776 | |
| 777 void EventSenderBindings::GesturePinchUpdate(gin::Arguments* args) { | |
| 778 if (sender_) | |
| 779 sender_->GesturePinchUpdate(args); | |
| 780 } | |
| 781 | |
| 782 void EventSenderBindings::GestureTap(gin::Arguments* args) { | |
| 783 if (sender_) | |
| 784 sender_->GestureTap(args); | |
| 785 } | |
| 786 | |
| 787 void EventSenderBindings::GestureTapDown(gin::Arguments* args) { | |
| 788 if (sender_) | |
| 789 sender_->GestureTapDown(args); | |
| 790 } | |
| 791 | |
| 792 void EventSenderBindings::GestureShowPress(gin::Arguments* args) { | |
| 793 if (sender_) | |
| 794 sender_->GestureShowPress(args); | |
| 795 } | |
| 796 | |
| 797 void EventSenderBindings::GestureTapCancel(gin::Arguments* args) { | |
| 798 if (sender_) | |
| 799 sender_->GestureTapCancel(args); | |
| 800 } | |
| 801 | |
| 802 void EventSenderBindings::GestureLongPress(gin::Arguments* args) { | |
| 803 if (sender_) | |
| 804 sender_->GestureLongPress(args); | |
| 805 } | |
| 806 | |
| 807 void EventSenderBindings::GestureLongTap(gin::Arguments* args) { | |
| 808 if (sender_) | |
| 809 sender_->GestureLongTap(args); | |
| 810 } | |
| 811 | |
| 812 void EventSenderBindings::GestureTwoFingerTap(gin::Arguments* args) { | |
| 813 if (sender_) | |
| 814 sender_->GestureTwoFingerTap(args); | |
| 815 } | |
| 816 | |
| 817 void EventSenderBindings::ContinuousMouseScrollBy(gin::Arguments* args) { | |
| 818 if (sender_) | |
| 819 sender_->ContinuousMouseScrollBy(args); | |
| 820 } | |
| 821 | |
| 822 void EventSenderBindings::MouseMoveTo(gin::Arguments* args) { | |
| 823 if (sender_) | |
| 824 sender_->MouseMoveTo(args); | |
| 825 } | |
| 826 | |
| 827 void EventSenderBindings::MouseLeave() { | |
| 828 if (sender_) | |
| 829 sender_->MouseLeave(); | |
| 830 } | |
| 831 | |
| 832 void EventSenderBindings::TrackpadScrollBegin() { | |
| 833 if (sender_) | |
| 834 sender_->TrackpadScrollBegin(); | |
| 835 } | |
| 836 | |
| 837 void EventSenderBindings::TrackpadScroll(gin::Arguments* args) { | |
| 838 if (sender_) | |
| 839 sender_->TrackpadScroll(args); | |
| 840 } | |
| 841 | |
| 842 void EventSenderBindings::TrackpadScrollEnd() { | |
| 843 if (sender_) | |
| 844 sender_->TrackpadScrollEnd(); | |
| 845 } | |
| 846 | |
| 847 void EventSenderBindings::MouseScrollBy(gin::Arguments* args) { | |
| 848 if (sender_) | |
| 849 sender_->MouseScrollBy(args); | |
| 850 } | |
| 851 | |
| 852 void EventSenderBindings::MouseMomentumBegin() { | |
| 853 if (sender_) | |
| 854 sender_->MouseMomentumBegin(); | |
| 855 } | |
| 856 | |
| 857 void EventSenderBindings::MouseMomentumBegin2(gin::Arguments* args) { | |
| 858 if (sender_) | |
| 859 sender_->MouseMomentumBegin2(args); | |
| 860 } | |
| 861 | |
| 862 void EventSenderBindings::MouseMomentumScrollBy(gin::Arguments* args) { | |
| 863 if (sender_) | |
| 864 sender_->MouseMomentumScrollBy(args); | |
| 865 } | |
| 866 | |
| 867 void EventSenderBindings::MouseMomentumEnd() { | |
| 868 if (sender_) | |
| 869 sender_->MouseMomentumEnd(); | |
| 870 } | |
| 871 | |
| 872 void EventSenderBindings::ScheduleAsynchronousClick(gin::Arguments* args) { | |
| 873 if (!sender_) | |
| 874 return; | |
| 875 | |
| 876 int button_number = 0; | |
| 877 int modifiers = 0; | |
| 878 if (!args->PeekNext().IsEmpty()) { | |
| 879 args->GetNext(&button_number); | |
| 880 if (!args->PeekNext().IsEmpty()) | |
| 881 modifiers = GetKeyModifiersFromV8(args->isolate(), args->PeekNext()); | |
| 882 } | |
| 883 sender_->ScheduleAsynchronousClick(button_number, modifiers); | |
| 884 } | |
| 885 | |
| 886 void EventSenderBindings::ScheduleAsynchronousKeyDown(gin::Arguments* args) { | |
| 887 if (!sender_) | |
| 888 return; | |
| 889 | |
| 890 std::string code_str; | |
| 891 int modifiers = 0; | |
| 892 int location = DOMKeyLocationStandard; | |
| 893 args->GetNext(&code_str); | |
| 894 if (!args->PeekNext().IsEmpty()) { | |
| 895 v8::Local<v8::Value> value; | |
| 896 args->GetNext(&value); | |
| 897 modifiers = GetKeyModifiersFromV8(args->isolate(), value); | |
| 898 if (!args->PeekNext().IsEmpty()) | |
| 899 args->GetNext(&location); | |
| 900 } | |
| 901 sender_->ScheduleAsynchronousKeyDown(code_str, modifiers, | |
| 902 static_cast<KeyLocationCode>(location)); | |
| 903 } | |
| 904 | |
| 905 void EventSenderBindings::MouseDown(gin::Arguments* args) { | |
| 906 if (!sender_) | |
| 907 return; | |
| 908 | |
| 909 int button_number = 0; | |
| 910 int modifiers = 0; | |
| 911 if (!args->PeekNext().IsEmpty()) { | |
| 912 args->GetNext(&button_number); | |
| 913 if (!args->PeekNext().IsEmpty()) | |
| 914 modifiers = GetKeyModifiersFromV8(args->isolate(), args->PeekNext()); | |
| 915 } | |
| 916 sender_->MouseDown(button_number, modifiers); | |
| 917 } | |
| 918 | |
| 919 void EventSenderBindings::MouseUp(gin::Arguments* args) { | |
| 920 if (!sender_) | |
| 921 return; | |
| 922 | |
| 923 int button_number = 0; | |
| 924 int modifiers = 0; | |
| 925 if (!args->PeekNext().IsEmpty()) { | |
| 926 args->GetNext(&button_number); | |
| 927 if (!args->PeekNext().IsEmpty()) | |
| 928 modifiers = GetKeyModifiersFromV8(args->isolate(), args->PeekNext()); | |
| 929 } | |
| 930 sender_->MouseUp(button_number, modifiers); | |
| 931 } | |
| 932 | |
| 933 void EventSenderBindings::KeyDown(gin::Arguments* args) { | |
| 934 if (!sender_) | |
| 935 return; | |
| 936 | |
| 937 std::string code_str; | |
| 938 int modifiers = 0; | |
| 939 int location = DOMKeyLocationStandard; | |
| 940 args->GetNext(&code_str); | |
| 941 if (!args->PeekNext().IsEmpty()) { | |
| 942 v8::Local<v8::Value> value; | |
| 943 args->GetNext(&value); | |
| 944 modifiers = GetKeyModifiersFromV8(args->isolate(), value); | |
| 945 if (!args->PeekNext().IsEmpty()) | |
| 946 args->GetNext(&location); | |
| 947 } | |
| 948 sender_->KeyDown(code_str, modifiers, static_cast<KeyLocationCode>(location)); | |
| 949 } | |
| 950 | |
| 951 bool EventSenderBindings::ForceLayoutOnEvents() const { | |
| 952 if (sender_) | |
| 953 return sender_->force_layout_on_events(); | |
| 954 return false; | |
| 955 } | |
| 956 | |
| 957 void EventSenderBindings::SetForceLayoutOnEvents(bool force) { | |
| 958 if (sender_) | |
| 959 sender_->set_force_layout_on_events(force); | |
| 960 } | |
| 961 | |
| 962 bool EventSenderBindings::IsDragMode() const { | |
| 963 if (sender_) | |
| 964 return sender_->is_drag_mode(); | |
| 965 return true; | |
| 966 } | |
| 967 | |
| 968 void EventSenderBindings::SetIsDragMode(bool drag_mode) { | |
| 969 if (sender_) | |
| 970 sender_->set_is_drag_mode(drag_mode); | |
| 971 } | |
| 972 | |
| 973 #if defined(OS_WIN) | |
| 974 int EventSenderBindings::WmKeyDown() const { | |
| 975 if (sender_) | |
| 976 return sender_->wm_key_down(); | |
| 977 return 0; | |
| 978 } | |
| 979 | |
| 980 void EventSenderBindings::SetWmKeyDown(int key_down) { | |
| 981 if (sender_) | |
| 982 sender_->set_wm_key_down(key_down); | |
| 983 } | |
| 984 | |
| 985 int EventSenderBindings::WmKeyUp() const { | |
| 986 if (sender_) | |
| 987 return sender_->wm_key_up(); | |
| 988 return 0; | |
| 989 } | |
| 990 | |
| 991 void EventSenderBindings::SetWmKeyUp(int key_up) { | |
| 992 if (sender_) | |
| 993 sender_->set_wm_key_up(key_up); | |
| 994 } | |
| 995 | |
| 996 int EventSenderBindings::WmChar() const { | |
| 997 if (sender_) | |
| 998 return sender_->wm_char(); | |
| 999 return 0; | |
| 1000 } | |
| 1001 | |
| 1002 void EventSenderBindings::SetWmChar(int wm_char) { | |
| 1003 if (sender_) | |
| 1004 sender_->set_wm_char(wm_char); | |
| 1005 } | |
| 1006 | |
| 1007 int EventSenderBindings::WmDeadChar() const { | |
| 1008 if (sender_) | |
| 1009 return sender_->wm_dead_char(); | |
| 1010 return 0; | |
| 1011 } | |
| 1012 | |
| 1013 void EventSenderBindings::SetWmDeadChar(int dead_char) { | |
| 1014 if (sender_) | |
| 1015 sender_->set_wm_dead_char(dead_char); | |
| 1016 } | |
| 1017 | |
| 1018 int EventSenderBindings::WmSysKeyDown() const { | |
| 1019 if (sender_) | |
| 1020 return sender_->wm_sys_key_down(); | |
| 1021 return 0; | |
| 1022 } | |
| 1023 | |
| 1024 void EventSenderBindings::SetWmSysKeyDown(int key_down) { | |
| 1025 if (sender_) | |
| 1026 sender_->set_wm_sys_key_down(key_down); | |
| 1027 } | |
| 1028 | |
| 1029 int EventSenderBindings::WmSysKeyUp() const { | |
| 1030 if (sender_) | |
| 1031 return sender_->wm_sys_key_up(); | |
| 1032 return 0; | |
| 1033 } | |
| 1034 | |
| 1035 void EventSenderBindings::SetWmSysKeyUp(int key_up) { | |
| 1036 if (sender_) | |
| 1037 sender_->set_wm_sys_key_up(key_up); | |
| 1038 } | |
| 1039 | |
| 1040 int EventSenderBindings::WmSysChar() const { | |
| 1041 if (sender_) | |
| 1042 return sender_->wm_sys_char(); | |
| 1043 return 0; | |
| 1044 } | |
| 1045 | |
| 1046 void EventSenderBindings::SetWmSysChar(int sys_char) { | |
| 1047 if (sender_) | |
| 1048 sender_->set_wm_sys_char(sys_char); | |
| 1049 } | |
| 1050 | |
| 1051 int EventSenderBindings::WmSysDeadChar() const { | |
| 1052 if (sender_) | |
| 1053 return sender_->wm_sys_dead_char(); | |
| 1054 return 0; | |
| 1055 } | |
| 1056 | |
| 1057 void EventSenderBindings::SetWmSysDeadChar(int sys_dead_char) { | |
| 1058 if (sender_) | |
| 1059 sender_->set_wm_sys_dead_char(sys_dead_char); | |
| 1060 } | |
| 1061 #endif | |
| 1062 | |
| 1063 // EventSender ----------------------------------------------------------------- | |
| 1064 | |
| 1065 WebMouseEvent::Button EventSender::pressed_button_ = WebMouseEvent::ButtonNone; | |
| 1066 int EventSender::modifiers_ = 0; | |
| 1067 | |
| 1068 WebPoint EventSender::last_mouse_pos_; | |
| 1069 | |
| 1070 WebMouseEvent::Button EventSender::last_button_type_ = | |
| 1071 WebMouseEvent::ButtonNone; | |
| 1072 | |
| 1073 EventSender::SavedEvent::SavedEvent() | |
| 1074 : type(TYPE_UNSPECIFIED), | |
| 1075 button_type(WebMouseEvent::ButtonNone), | |
| 1076 milliseconds(0), | |
| 1077 modifiers(0) {} | |
| 1078 | |
| 1079 EventSender::EventSender(TestInterfaces* interfaces) | |
| 1080 : interfaces_(interfaces), | |
| 1081 delegate_(NULL), | |
| 1082 view_(NULL), | |
| 1083 force_layout_on_events_(false), | |
| 1084 is_drag_mode_(true), | |
| 1085 touch_modifiers_(0), | |
| 1086 touch_cancelable_(true), | |
| 1087 replaying_saved_events_(false), | |
| 1088 current_drag_effects_allowed_(blink::WebDragOperationNone), | |
| 1089 last_click_time_sec_(0), | |
| 1090 current_drag_effect_(blink::WebDragOperationNone), | |
| 1091 time_offset_ms_(0), | |
| 1092 click_count_(0), | |
| 1093 #if defined(OS_WIN) | |
| 1094 wm_key_down_(0), | |
| 1095 wm_key_up_(0), | |
| 1096 wm_char_(0), | |
| 1097 wm_dead_char_(0), | |
| 1098 wm_sys_key_down_(0), | |
| 1099 wm_sys_key_up_(0), | |
| 1100 wm_sys_char_(0), | |
| 1101 wm_sys_dead_char_(0), | |
| 1102 #endif | |
| 1103 weak_factory_(this) {} | |
| 1104 | |
| 1105 EventSender::~EventSender() {} | |
| 1106 | |
| 1107 void EventSender::Reset() { | |
| 1108 DCHECK(current_drag_data_.isNull()); | |
| 1109 current_drag_data_.reset(); | |
| 1110 current_drag_effect_ = blink::WebDragOperationNone; | |
| 1111 current_drag_effects_allowed_ = blink::WebDragOperationNone; | |
| 1112 if (view_ && pressed_button_ != WebMouseEvent::ButtonNone) | |
| 1113 view_->mouseCaptureLost(); | |
| 1114 pressed_button_ = WebMouseEvent::ButtonNone; | |
| 1115 is_drag_mode_ = true; | |
| 1116 force_layout_on_events_ = true; | |
| 1117 | |
| 1118 #if defined(OS_WIN) | |
| 1119 wm_key_down_ = WM_KEYDOWN; | |
| 1120 wm_key_up_ = WM_KEYUP; | |
| 1121 wm_char_ = WM_CHAR; | |
| 1122 wm_dead_char_ = WM_DEADCHAR; | |
| 1123 wm_sys_key_down_ = WM_SYSKEYDOWN; | |
| 1124 wm_sys_key_up_ = WM_SYSKEYUP; | |
| 1125 wm_sys_char_ = WM_SYSCHAR; | |
| 1126 wm_sys_dead_char_ = WM_SYSDEADCHAR; | |
| 1127 #endif | |
| 1128 | |
| 1129 last_mouse_pos_ = WebPoint(0, 0); | |
| 1130 last_click_time_sec_ = 0; | |
| 1131 last_click_pos_ = WebPoint(0, 0); | |
| 1132 last_button_type_ = WebMouseEvent::ButtonNone; | |
| 1133 touch_points_.clear(); | |
| 1134 last_context_menu_data_.reset(); | |
| 1135 task_list_.RevokeAll(); | |
| 1136 current_gesture_location_ = WebPoint(0, 0); | |
| 1137 mouse_event_queue_.clear(); | |
| 1138 | |
| 1139 time_offset_ms_ = 0; | |
| 1140 click_count_ = 0; | |
| 1141 | |
| 1142 touch_modifiers_ = 0; | |
| 1143 touch_cancelable_ = true; | |
| 1144 touch_points_.clear(); | |
| 1145 } | |
| 1146 | |
| 1147 void EventSender::Install(WebFrame* frame) { | |
| 1148 EventSenderBindings::Install(weak_factory_.GetWeakPtr(), frame); | |
| 1149 } | |
| 1150 | |
| 1151 void EventSender::SetDelegate(WebTestDelegate* delegate) { | |
| 1152 delegate_ = delegate; | |
| 1153 } | |
| 1154 | |
| 1155 void EventSender::SetWebView(WebView* view) { | |
| 1156 view_ = view; | |
| 1157 } | |
| 1158 | |
| 1159 void EventSender::SetContextMenuData(const WebContextMenuData& data) { | |
| 1160 last_context_menu_data_.reset(new WebContextMenuData(data)); | |
| 1161 } | |
| 1162 | |
| 1163 void EventSender::DoDragDrop(const WebDragData& drag_data, | |
| 1164 WebDragOperationsMask mask) { | |
| 1165 WebMouseEvent event; | |
| 1166 InitMouseEvent(WebInputEvent::MouseDown, | |
| 1167 pressed_button_, | |
| 1168 last_mouse_pos_, | |
| 1169 GetCurrentEventTimeSec(), | |
| 1170 click_count_, | |
| 1171 modifiers_, | |
| 1172 &event); | |
| 1173 WebPoint client_point(event.x, event.y); | |
| 1174 WebPoint screen_point(event.globalX, event.globalY); | |
| 1175 current_drag_data_ = drag_data; | |
| 1176 current_drag_effects_allowed_ = mask; | |
| 1177 current_drag_effect_ = view_->dragTargetDragEnter( | |
| 1178 drag_data, | |
| 1179 client_point, | |
| 1180 screen_point, | |
| 1181 current_drag_effects_allowed_, | |
| 1182 modifiers_); | |
| 1183 | |
| 1184 // Finish processing events. | |
| 1185 ReplaySavedEvents(); | |
| 1186 } | |
| 1187 | |
| 1188 void EventSender::MouseDown(int button_number, int modifiers) { | |
| 1189 if (force_layout_on_events_) | |
| 1190 view_->layout(); | |
| 1191 | |
| 1192 DCHECK_NE(-1, button_number); | |
| 1193 | |
| 1194 WebMouseEvent::Button button_type = | |
| 1195 GetButtonTypeFromButtonNumber(button_number); | |
| 1196 | |
| 1197 UpdateClickCountForButton(button_type); | |
| 1198 | |
| 1199 pressed_button_ = button_type; | |
| 1200 modifiers_ = modifiers; | |
| 1201 | |
| 1202 WebMouseEvent event; | |
| 1203 InitMouseEvent(WebInputEvent::MouseDown, | |
| 1204 button_type, | |
| 1205 last_mouse_pos_, | |
| 1206 GetCurrentEventTimeSec(), | |
| 1207 click_count_, | |
| 1208 modifiers, | |
| 1209 &event); | |
| 1210 HandleInputEventOnViewOrPopup(event); | |
| 1211 } | |
| 1212 | |
| 1213 void EventSender::MouseUp(int button_number, int modifiers) { | |
| 1214 if (force_layout_on_events_) | |
| 1215 view_->layout(); | |
| 1216 | |
| 1217 DCHECK_NE(-1, button_number); | |
| 1218 | |
| 1219 WebMouseEvent::Button button_type = | |
| 1220 GetButtonTypeFromButtonNumber(button_number); | |
| 1221 | |
| 1222 if (is_drag_mode_ && !replaying_saved_events_) { | |
| 1223 SavedEvent saved_event; | |
| 1224 saved_event.type = SavedEvent::TYPE_MOUSE_UP; | |
| 1225 saved_event.button_type = button_type; | |
| 1226 saved_event.modifiers = modifiers; | |
| 1227 mouse_event_queue_.push_back(saved_event); | |
| 1228 ReplaySavedEvents(); | |
| 1229 } else { | |
| 1230 WebMouseEvent event; | |
| 1231 InitMouseEvent(WebInputEvent::MouseUp, | |
| 1232 button_type, | |
| 1233 last_mouse_pos_, | |
| 1234 GetCurrentEventTimeSec(), | |
| 1235 click_count_, | |
| 1236 modifiers, | |
| 1237 &event); | |
| 1238 DoMouseUp(event); | |
| 1239 } | |
| 1240 } | |
| 1241 | |
| 1242 void EventSender::KeyDown(const std::string& code_str, | |
| 1243 int modifiers, | |
| 1244 KeyLocationCode location) { | |
| 1245 // FIXME: I'm not exactly sure how we should convert the string to a key | |
| 1246 // event. This seems to work in the cases I tested. | |
| 1247 // FIXME: Should we also generate a KEY_UP? | |
| 1248 | |
| 1249 bool generate_char = false; | |
| 1250 | |
| 1251 // Convert \n -> VK_RETURN. Some layout tests use \n to mean "Enter", when | |
| 1252 // Windows uses \r for "Enter". | |
| 1253 int code = 0; | |
| 1254 int text = 0; | |
| 1255 bool needs_shift_key_modifier = false; | |
| 1256 std::string domString; | |
| 1257 | |
| 1258 if ("\n" == code_str) { | |
| 1259 generate_char = true; | |
| 1260 text = code = ui::VKEY_RETURN; | |
| 1261 domString.assign("Enter"); | |
| 1262 } else if ("rightArrow" == code_str) { | |
| 1263 code = ui::VKEY_RIGHT; | |
| 1264 domString.assign("ArrowRight"); | |
| 1265 } else if ("downArrow" == code_str) { | |
| 1266 code = ui::VKEY_DOWN; | |
| 1267 domString.assign("ArrowDown"); | |
| 1268 } else if ("leftArrow" == code_str) { | |
| 1269 code = ui::VKEY_LEFT; | |
| 1270 domString.assign("ArrowLeft"); | |
| 1271 } else if ("upArrow" == code_str) { | |
| 1272 code = ui::VKEY_UP; | |
| 1273 domString.assign("ArrowUp"); | |
| 1274 } else if ("insert" == code_str) { | |
| 1275 code = ui::VKEY_INSERT; | |
| 1276 domString.assign("Insert"); | |
| 1277 } else if ("delete" == code_str) { | |
| 1278 code = ui::VKEY_DELETE; | |
| 1279 domString.assign("Delete"); | |
| 1280 } else if ("pageUp" == code_str) { | |
| 1281 code = ui::VKEY_PRIOR; | |
| 1282 domString.assign("PageUp"); | |
| 1283 } else if ("pageDown" == code_str) { | |
| 1284 code = ui::VKEY_NEXT; | |
| 1285 domString.assign("PageDown"); | |
| 1286 } else if ("home" == code_str) { | |
| 1287 code = ui::VKEY_HOME; | |
| 1288 domString.assign("Home"); | |
| 1289 } else if ("end" == code_str) { | |
| 1290 code = ui::VKEY_END; | |
| 1291 domString.assign("End"); | |
| 1292 } else if ("printScreen" == code_str) { | |
| 1293 code = ui::VKEY_SNAPSHOT; | |
| 1294 domString.assign("PrintScreen"); | |
| 1295 } else if ("menu" == code_str) { | |
| 1296 code = ui::VKEY_APPS; | |
| 1297 domString.assign("ContextMenu"); | |
| 1298 } else if ("leftControl" == code_str) { | |
| 1299 code = ui::VKEY_LCONTROL; | |
| 1300 domString.assign("ControlLeft"); | |
| 1301 } else if ("rightControl" == code_str) { | |
| 1302 code = ui::VKEY_RCONTROL; | |
| 1303 domString.assign("ControlRight"); | |
| 1304 } else if ("leftShift" == code_str) { | |
| 1305 code = ui::VKEY_LSHIFT; | |
| 1306 domString.assign("ShiftLeft"); | |
| 1307 } else if ("rightShift" == code_str) { | |
| 1308 code = ui::VKEY_RSHIFT; | |
| 1309 domString.assign("ShiftRight"); | |
| 1310 } else if ("leftAlt" == code_str) { | |
| 1311 code = ui::VKEY_LMENU; | |
| 1312 domString.assign("AltLeft"); | |
| 1313 } else if ("rightAlt" == code_str) { | |
| 1314 code = ui::VKEY_RMENU; | |
| 1315 domString.assign("AltRight"); | |
| 1316 } else if ("numLock" == code_str) { | |
| 1317 code = ui::VKEY_NUMLOCK; | |
| 1318 domString.assign("NumLock"); | |
| 1319 } else if ("backspace" == code_str) { | |
| 1320 code = ui::VKEY_BACK; | |
| 1321 domString.assign("Backspace"); | |
| 1322 } else if ("escape" == code_str) { | |
| 1323 code = ui::VKEY_ESCAPE; | |
| 1324 domString.assign("Escape"); | |
| 1325 } else { | |
| 1326 // Compare the input string with the function-key names defined by the | |
| 1327 // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key | |
| 1328 // name, set its key code. | |
| 1329 for (int i = 1; i <= 24; ++i) { | |
| 1330 std::string function_key_name = base::StringPrintf("F%d", i); | |
| 1331 if (function_key_name == code_str) { | |
| 1332 code = ui::VKEY_F1 + (i - 1); | |
| 1333 domString = function_key_name; | |
| 1334 break; | |
| 1335 } | |
| 1336 } | |
| 1337 if (!code) { | |
| 1338 WebString web_code_str = | |
| 1339 WebString::fromUTF8(code_str.data(), code_str.size()); | |
| 1340 if (web_code_str.length() != 1u) { | |
| 1341 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
| 1342 isolate->ThrowException(v8::Exception::TypeError( | |
| 1343 gin::StringToV8(isolate, "Invalid web code."))); | |
| 1344 return; | |
| 1345 } | |
| 1346 text = code = web_code_str.at(0); | |
| 1347 needs_shift_key_modifier = NeedsShiftModifier(code); | |
| 1348 if ((code & 0xFF) >= 'a' && (code & 0xFF) <= 'z') | |
| 1349 code -= 'a' - 'A'; | |
| 1350 if ((code >= 'A' && code <= 'Z') || (code >= 'a' && code <= 'z')) { | |
| 1351 domString.assign("Key"); | |
| 1352 domString.push_back(base::ToUpperASCII(code)); | |
| 1353 } else if (code >= '0' && code <= '9') { | |
| 1354 domString.assign("Digit"); | |
| 1355 domString.push_back(code); | |
| 1356 } else if (code == ' ') { | |
| 1357 domString.assign("Space"); | |
| 1358 } else if (code == 9) { | |
| 1359 domString.assign("Tab"); | |
| 1360 } | |
| 1361 generate_char = true; | |
| 1362 } | |
| 1363 | |
| 1364 if ("(" == code_str) { | |
| 1365 code = '9'; | |
| 1366 needs_shift_key_modifier = true; | |
| 1367 } | |
| 1368 } | |
| 1369 | |
| 1370 // For one generated keyboard event, we need to generate a keyDown/keyUp | |
| 1371 // pair; | |
| 1372 // On Windows, we might also need to generate a char event to mimic the | |
| 1373 // Windows event flow; on other platforms we create a merged event and test | |
| 1374 // the event flow that that platform provides. | |
| 1375 WebKeyboardEvent event_down; | |
| 1376 event_down.type = WebInputEvent::RawKeyDown; | |
| 1377 event_down.modifiers = modifiers; | |
| 1378 event_down.windowsKeyCode = code; | |
| 1379 event_down.domCode = static_cast<int>( | |
| 1380 ui::KeycodeConverter::CodeStringToDomCode(domString.c_str())); | |
| 1381 | |
| 1382 if (generate_char) { | |
| 1383 event_down.text[0] = text; | |
| 1384 event_down.unmodifiedText[0] = text; | |
| 1385 } | |
| 1386 | |
| 1387 event_down.setKeyIdentifierFromWindowsKeyCode(); | |
| 1388 | |
| 1389 if (event_down.modifiers != 0) | |
| 1390 event_down.isSystemKey = IsSystemKeyEvent(event_down); | |
| 1391 | |
| 1392 if (needs_shift_key_modifier) | |
| 1393 event_down.modifiers |= WebInputEvent::ShiftKey; | |
| 1394 | |
| 1395 // See if KeyLocation argument is given. | |
| 1396 if (location == DOMKeyLocationNumpad) | |
| 1397 event_down.modifiers |= WebInputEvent::IsKeyPad; | |
| 1398 | |
| 1399 WebKeyboardEvent event_up; | |
| 1400 event_up = event_down; | |
| 1401 event_up.type = WebInputEvent::KeyUp; | |
| 1402 // EventSender.m forces a layout here, with at least one | |
| 1403 // test (fast/forms/focus-control-to-page.html) relying on this. | |
| 1404 if (force_layout_on_events_) | |
| 1405 view_->layout(); | |
| 1406 | |
| 1407 // In the browser, if a keyboard event corresponds to an editor command, | |
| 1408 // the command will be dispatched to the renderer just before dispatching | |
| 1409 // the keyboard event, and then it will be executed in the | |
| 1410 // RenderView::handleCurrentKeyboardEvent() method. | |
| 1411 // We just simulate the same behavior here. | |
| 1412 std::string edit_command; | |
| 1413 if (GetEditCommand(event_down, &edit_command)) | |
| 1414 delegate_->SetEditCommand(edit_command, ""); | |
| 1415 | |
| 1416 HandleInputEventOnViewOrPopup(event_down); | |
| 1417 | |
| 1418 if (code == ui::VKEY_ESCAPE && !current_drag_data_.isNull()) { | |
| 1419 WebMouseEvent event; | |
| 1420 InitMouseEvent(WebInputEvent::MouseDown, | |
| 1421 pressed_button_, | |
| 1422 last_mouse_pos_, | |
| 1423 GetCurrentEventTimeSec(), | |
| 1424 click_count_, | |
| 1425 0, | |
| 1426 &event); | |
| 1427 FinishDragAndDrop(event, blink::WebDragOperationNone); | |
| 1428 } | |
| 1429 | |
| 1430 delegate_->ClearEditCommand(); | |
| 1431 | |
| 1432 if (generate_char) { | |
| 1433 WebKeyboardEvent event_char = event_up; | |
| 1434 event_char.type = WebInputEvent::Char; | |
| 1435 // keyIdentifier is an empty string, unless the Enter key was pressed. | |
| 1436 // This behavior is not standard (keyIdentifier itself is not even a | |
| 1437 // standard any more), but it matches the actual behavior in Blink. | |
| 1438 if (code != ui::VKEY_RETURN) | |
| 1439 event_char.keyIdentifier[0] = '\0'; | |
| 1440 HandleInputEventOnViewOrPopup(event_char); | |
| 1441 } | |
| 1442 | |
| 1443 HandleInputEventOnViewOrPopup(event_up); | |
| 1444 } | |
| 1445 | |
| 1446 void EventSender::EnableDOMUIEventLogging() {} | |
| 1447 | |
| 1448 void EventSender::FireKeyboardEventsToElement() {} | |
| 1449 | |
| 1450 void EventSender::ClearKillRing() {} | |
| 1451 | |
| 1452 std::vector<std::string> EventSender::ContextClick() { | |
| 1453 if (force_layout_on_events_) { | |
| 1454 view_->layout(); | |
| 1455 } | |
| 1456 | |
| 1457 UpdateClickCountForButton(WebMouseEvent::ButtonRight); | |
| 1458 | |
| 1459 // Clears last context menu data because we need to know if the context menu | |
| 1460 // be requested after following mouse events. | |
| 1461 last_context_menu_data_.reset(); | |
| 1462 | |
| 1463 // Generate right mouse down and up. | |
| 1464 WebMouseEvent event; | |
| 1465 // This is a hack to work around only allowing a single pressed button since | |
| 1466 // we want to test the case where both the left and right mouse buttons are | |
| 1467 // pressed. | |
| 1468 if (pressed_button_ == WebMouseEvent::ButtonNone) { | |
| 1469 pressed_button_ = WebMouseEvent::ButtonRight; | |
| 1470 } | |
| 1471 InitMouseEvent(WebInputEvent::MouseDown, | |
| 1472 WebMouseEvent::ButtonRight, | |
| 1473 last_mouse_pos_, | |
| 1474 GetCurrentEventTimeSec(), | |
| 1475 click_count_, | |
| 1476 0, | |
| 1477 &event); | |
| 1478 HandleInputEventOnViewOrPopup(event); | |
| 1479 | |
| 1480 #if defined(OS_WIN) | |
| 1481 InitMouseEvent(WebInputEvent::MouseUp, | |
| 1482 WebMouseEvent::ButtonRight, | |
| 1483 last_mouse_pos_, | |
| 1484 GetCurrentEventTimeSec(), | |
| 1485 click_count_, | |
| 1486 0, | |
| 1487 &event); | |
| 1488 HandleInputEventOnViewOrPopup(event); | |
| 1489 | |
| 1490 pressed_button_= WebMouseEvent::ButtonNone; | |
| 1491 #endif | |
| 1492 | |
| 1493 std::vector<std::string> menu_items = MakeMenuItemStringsFor(last_context_menu
_data_.get(), delegate_); | |
| 1494 last_context_menu_data_.reset(); | |
| 1495 return menu_items; | |
| 1496 } | |
| 1497 | |
| 1498 void EventSender::TextZoomIn() { | |
| 1499 view_->setTextZoomFactor(view_->textZoomFactor() * 1.2f); | |
| 1500 } | |
| 1501 | |
| 1502 void EventSender::TextZoomOut() { | |
| 1503 view_->setTextZoomFactor(view_->textZoomFactor() / 1.2f); | |
| 1504 } | |
| 1505 | |
| 1506 void EventSender::ZoomPageIn() { | |
| 1507 const std::vector<WebTestProxyBase*>& window_list = | |
| 1508 interfaces_->GetWindowList(); | |
| 1509 | |
| 1510 for (size_t i = 0; i < window_list.size(); ++i) { | |
| 1511 window_list.at(i)->GetWebView()->setZoomLevel( | |
| 1512 window_list.at(i)->GetWebView()->zoomLevel() + 1); | |
| 1513 } | |
| 1514 } | |
| 1515 | |
| 1516 void EventSender::ZoomPageOut() { | |
| 1517 const std::vector<WebTestProxyBase*>& window_list = | |
| 1518 interfaces_->GetWindowList(); | |
| 1519 | |
| 1520 for (size_t i = 0; i < window_list.size(); ++i) { | |
| 1521 window_list.at(i)->GetWebView()->setZoomLevel( | |
| 1522 window_list.at(i)->GetWebView()->zoomLevel() - 1); | |
| 1523 } | |
| 1524 } | |
| 1525 | |
| 1526 void EventSender::SetPageZoomFactor(double zoom_factor) { | |
| 1527 const std::vector<WebTestProxyBase*>& window_list = | |
| 1528 interfaces_->GetWindowList(); | |
| 1529 | |
| 1530 for (size_t i = 0; i < window_list.size(); ++i) { | |
| 1531 window_list.at(i)->GetWebView()->setZoomLevel( | |
| 1532 std::log(zoom_factor) / std::log(1.2)); | |
| 1533 } | |
| 1534 } | |
| 1535 | |
| 1536 void EventSender::ClearTouchPoints() { | |
| 1537 touch_points_.clear(); | |
| 1538 } | |
| 1539 | |
| 1540 void EventSender::ThrowTouchPointError() { | |
| 1541 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
| 1542 isolate->ThrowException(v8::Exception::TypeError( | |
| 1543 gin::StringToV8(isolate, "Invalid touch point."))); | |
| 1544 } | |
| 1545 | |
| 1546 void EventSender::ReleaseTouchPoint(unsigned index) { | |
| 1547 if (index >= touch_points_.size()) { | |
| 1548 ThrowTouchPointError(); | |
| 1549 return; | |
| 1550 } | |
| 1551 | |
| 1552 WebTouchPoint* touch_point = &touch_points_[index]; | |
| 1553 touch_point->state = WebTouchPoint::StateReleased; | |
| 1554 } | |
| 1555 | |
| 1556 void EventSender::UpdateTouchPoint(unsigned index, float x, float y) { | |
| 1557 if (index >= touch_points_.size()) { | |
| 1558 ThrowTouchPointError(); | |
| 1559 return; | |
| 1560 } | |
| 1561 | |
| 1562 WebTouchPoint* touch_point = &touch_points_[index]; | |
| 1563 touch_point->state = WebTouchPoint::StateMoved; | |
| 1564 touch_point->position = WebFloatPoint(x, y); | |
| 1565 touch_point->screenPosition = touch_point->position; | |
| 1566 } | |
| 1567 | |
| 1568 void EventSender::CancelTouchPoint(unsigned index) { | |
| 1569 if (index >= touch_points_.size()) { | |
| 1570 ThrowTouchPointError(); | |
| 1571 return; | |
| 1572 } | |
| 1573 | |
| 1574 WebTouchPoint* touch_point = &touch_points_[index]; | |
| 1575 touch_point->state = WebTouchPoint::StateCancelled; | |
| 1576 } | |
| 1577 | |
| 1578 void EventSender::SetTouchModifier(const std::string& key_name, | |
| 1579 bool set_mask) { | |
| 1580 int mask = 0; | |
| 1581 if (key_name == "shift") | |
| 1582 mask = WebInputEvent::ShiftKey; | |
| 1583 else if (key_name == "alt") | |
| 1584 mask = WebInputEvent::AltKey; | |
| 1585 else if (key_name == "ctrl") | |
| 1586 mask = WebInputEvent::ControlKey; | |
| 1587 else if (key_name == "meta") | |
| 1588 mask = WebInputEvent::MetaKey; | |
| 1589 | |
| 1590 if (set_mask) | |
| 1591 touch_modifiers_ |= mask; | |
| 1592 else | |
| 1593 touch_modifiers_ &= ~mask; | |
| 1594 } | |
| 1595 | |
| 1596 void EventSender::SetTouchCancelable(bool cancelable) { | |
| 1597 touch_cancelable_ = cancelable; | |
| 1598 } | |
| 1599 | |
| 1600 void EventSender::DumpFilenameBeingDragged() { | |
| 1601 if (current_drag_data_.isNull()) | |
| 1602 return; | |
| 1603 | |
| 1604 WebString filename; | |
| 1605 WebVector<WebDragData::Item> items = current_drag_data_.items(); | |
| 1606 for (size_t i = 0; i < items.size(); ++i) { | |
| 1607 if (items[i].storageType == WebDragData::Item::StorageTypeBinaryData) { | |
| 1608 filename = items[i].title; | |
| 1609 break; | |
| 1610 } | |
| 1611 } | |
| 1612 delegate_->PrintMessage(std::string("Filename being dragged: ") + | |
| 1613 filename.utf8().data() + "\n"); | |
| 1614 } | |
| 1615 | |
| 1616 void EventSender::GestureFlingCancel() { | |
| 1617 WebGestureEvent event; | |
| 1618 event.type = WebInputEvent::GestureFlingCancel; | |
| 1619 event.timeStampSeconds = GetCurrentEventTimeSec(); | |
| 1620 | |
| 1621 if (force_layout_on_events_) | |
| 1622 view_->layout(); | |
| 1623 | |
| 1624 HandleInputEventOnViewOrPopup(event); | |
| 1625 } | |
| 1626 | |
| 1627 void EventSender::GestureFlingStart(float x, | |
| 1628 float y, | |
| 1629 float velocity_x, | |
| 1630 float velocity_y, | |
| 1631 gin::Arguments* args) { | |
| 1632 WebGestureEvent event; | |
| 1633 event.type = WebInputEvent::GestureFlingStart; | |
| 1634 | |
| 1635 std::string device_string; | |
| 1636 if (!args->PeekNext().IsEmpty() && args->PeekNext()->IsString()) | |
| 1637 args->GetNext(&device_string); | |
| 1638 | |
| 1639 if (device_string == kSourceDeviceStringTouchpad) { | |
| 1640 event.sourceDevice = blink::WebGestureDeviceTouchpad; | |
| 1641 } else if (device_string == kSourceDeviceStringTouchscreen) { | |
| 1642 event.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
| 1643 } else { | |
| 1644 args->ThrowError(); | |
| 1645 return; | |
| 1646 } | |
| 1647 | |
| 1648 event.x = x; | |
| 1649 event.y = y; | |
| 1650 event.globalX = event.x; | |
| 1651 event.globalY = event.y; | |
| 1652 | |
| 1653 event.data.flingStart.velocityX = velocity_x; | |
| 1654 event.data.flingStart.velocityY = velocity_y; | |
| 1655 event.timeStampSeconds = GetCurrentEventTimeSec(); | |
| 1656 | |
| 1657 if (force_layout_on_events_) | |
| 1658 view_->layout(); | |
| 1659 | |
| 1660 HandleInputEventOnViewOrPopup(event); | |
| 1661 } | |
| 1662 | |
| 1663 void EventSender::GestureScrollFirstPoint(int x, int y) { | |
| 1664 current_gesture_location_ = WebPoint(x, y); | |
| 1665 } | |
| 1666 | |
| 1667 void EventSender::TouchStart() { | |
| 1668 SendCurrentTouchEvent(WebInputEvent::TouchStart); | |
| 1669 } | |
| 1670 | |
| 1671 void EventSender::TouchMove() { | |
| 1672 SendCurrentTouchEvent(WebInputEvent::TouchMove); | |
| 1673 } | |
| 1674 | |
| 1675 void EventSender::TouchCancel() { | |
| 1676 SendCurrentTouchEvent(WebInputEvent::TouchCancel); | |
| 1677 } | |
| 1678 | |
| 1679 void EventSender::TouchEnd() { | |
| 1680 SendCurrentTouchEvent(WebInputEvent::TouchEnd); | |
| 1681 } | |
| 1682 | |
| 1683 void EventSender::LeapForward(int milliseconds) { | |
| 1684 if (is_drag_mode_ && pressed_button_ == WebMouseEvent::ButtonLeft && | |
| 1685 !replaying_saved_events_) { | |
| 1686 SavedEvent saved_event; | |
| 1687 saved_event.type = SavedEvent::TYPE_LEAP_FORWARD; | |
| 1688 saved_event.milliseconds = milliseconds; | |
| 1689 mouse_event_queue_.push_back(saved_event); | |
| 1690 } else { | |
| 1691 DoLeapForward(milliseconds); | |
| 1692 } | |
| 1693 } | |
| 1694 | |
| 1695 void EventSender::BeginDragWithFiles(const std::vector<std::string>& files) { | |
| 1696 current_drag_data_.initialize(); | |
| 1697 WebVector<WebString> absolute_filenames(files.size()); | |
| 1698 for (size_t i = 0; i < files.size(); ++i) { | |
| 1699 WebDragData::Item item; | |
| 1700 item.storageType = WebDragData::Item::StorageTypeFilename; | |
| 1701 item.filenameData = delegate_->GetAbsoluteWebStringFromUTF8Path(files[i]); | |
| 1702 current_drag_data_.addItem(item); | |
| 1703 absolute_filenames[i] = item.filenameData; | |
| 1704 } | |
| 1705 current_drag_data_.setFilesystemId( | |
| 1706 delegate_->RegisterIsolatedFileSystem(absolute_filenames)); | |
| 1707 current_drag_effects_allowed_ = blink::WebDragOperationCopy; | |
| 1708 | |
| 1709 // Provide a drag source. | |
| 1710 view_->dragTargetDragEnter(current_drag_data_, | |
| 1711 last_mouse_pos_, | |
| 1712 last_mouse_pos_, | |
| 1713 current_drag_effects_allowed_, | |
| 1714 0); | |
| 1715 // |is_drag_mode_| saves events and then replays them later. We don't | |
| 1716 // need/want that. | |
| 1717 is_drag_mode_ = false; | |
| 1718 | |
| 1719 // Make the rest of eventSender think a drag is in progress. | |
| 1720 pressed_button_ = WebMouseEvent::ButtonLeft; | |
| 1721 } | |
| 1722 | |
| 1723 void EventSender::AddTouchPoint(gin::Arguments* args) { | |
| 1724 double x; | |
| 1725 double y; | |
| 1726 if (!args->GetNext(&x) || !args->GetNext(&y)) { | |
| 1727 args->ThrowError(); | |
| 1728 return; | |
| 1729 } | |
| 1730 | |
| 1731 WebTouchPoint touch_point; | |
| 1732 touch_point.state = WebTouchPoint::StatePressed; | |
| 1733 touch_point.position = WebFloatPoint(static_cast<float>(x), | |
| 1734 static_cast<float>(y)); | |
| 1735 touch_point.screenPosition = touch_point.position; | |
| 1736 | |
| 1737 if (!args->PeekNext().IsEmpty()) { | |
| 1738 double radius_x; | |
| 1739 if (!args->GetNext(&radius_x)) { | |
| 1740 args->ThrowError(); | |
| 1741 return; | |
| 1742 } | |
| 1743 | |
| 1744 double radius_y = radius_x; | |
| 1745 if (!args->PeekNext().IsEmpty()) { | |
| 1746 if (!args->GetNext(&radius_y)) { | |
| 1747 args->ThrowError(); | |
| 1748 return; | |
| 1749 } | |
| 1750 } | |
| 1751 | |
| 1752 touch_point.radiusX = static_cast<float>(radius_x); | |
| 1753 touch_point.radiusY = static_cast<float>(radius_y); | |
| 1754 } | |
| 1755 | |
| 1756 int lowest_id = 0; | |
| 1757 for (size_t i = 0; i < touch_points_.size(); i++) { | |
| 1758 if (touch_points_[i].id == lowest_id) | |
| 1759 lowest_id++; | |
| 1760 } | |
| 1761 touch_point.id = lowest_id; | |
| 1762 touch_points_.push_back(touch_point); | |
| 1763 } | |
| 1764 | |
| 1765 void EventSender::MouseDragBegin() { | |
| 1766 WebMouseWheelEvent event; | |
| 1767 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 1768 WebMouseEvent::ButtonNone, | |
| 1769 last_mouse_pos_, | |
| 1770 GetCurrentEventTimeSec(), | |
| 1771 click_count_, | |
| 1772 0, | |
| 1773 &event); | |
| 1774 event.phase = WebMouseWheelEvent::PhaseBegan; | |
| 1775 event.hasPreciseScrollingDeltas = true; | |
| 1776 HandleInputEventOnViewOrPopup(event); | |
| 1777 } | |
| 1778 | |
| 1779 void EventSender::MouseDragEnd() { | |
| 1780 WebMouseWheelEvent event; | |
| 1781 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 1782 WebMouseEvent::ButtonNone, | |
| 1783 last_mouse_pos_, | |
| 1784 GetCurrentEventTimeSec(), | |
| 1785 click_count_, | |
| 1786 0, | |
| 1787 &event); | |
| 1788 event.phase = WebMouseWheelEvent::PhaseEnded; | |
| 1789 event.hasPreciseScrollingDeltas = true; | |
| 1790 HandleInputEventOnViewOrPopup(event); | |
| 1791 } | |
| 1792 | |
| 1793 void EventSender::GestureScrollBegin(gin::Arguments* args) { | |
| 1794 GestureEvent(WebInputEvent::GestureScrollBegin, args); | |
| 1795 } | |
| 1796 | |
| 1797 void EventSender::GestureScrollEnd(gin::Arguments* args) { | |
| 1798 GestureEvent(WebInputEvent::GestureScrollEnd, args); | |
| 1799 } | |
| 1800 | |
| 1801 void EventSender::GestureScrollUpdate(gin::Arguments* args) { | |
| 1802 GestureEvent(WebInputEvent::GestureScrollUpdate, args); | |
| 1803 } | |
| 1804 | |
| 1805 void EventSender::GesturePinchBegin(gin::Arguments* args) { | |
| 1806 GestureEvent(WebInputEvent::GesturePinchBegin, args); | |
| 1807 } | |
| 1808 | |
| 1809 void EventSender::GesturePinchEnd(gin::Arguments* args) { | |
| 1810 GestureEvent(WebInputEvent::GesturePinchEnd, args); | |
| 1811 } | |
| 1812 | |
| 1813 void EventSender::GesturePinchUpdate(gin::Arguments* args) { | |
| 1814 GestureEvent(WebInputEvent::GesturePinchUpdate, args); | |
| 1815 } | |
| 1816 | |
| 1817 void EventSender::GestureTap(gin::Arguments* args) { | |
| 1818 GestureEvent(WebInputEvent::GestureTap, args); | |
| 1819 } | |
| 1820 | |
| 1821 void EventSender::GestureTapDown(gin::Arguments* args) { | |
| 1822 GestureEvent(WebInputEvent::GestureTapDown, args); | |
| 1823 } | |
| 1824 | |
| 1825 void EventSender::GestureShowPress(gin::Arguments* args) { | |
| 1826 GestureEvent(WebInputEvent::GestureShowPress, args); | |
| 1827 } | |
| 1828 | |
| 1829 void EventSender::GestureTapCancel(gin::Arguments* args) { | |
| 1830 GestureEvent(WebInputEvent::GestureTapCancel, args); | |
| 1831 } | |
| 1832 | |
| 1833 void EventSender::GestureLongPress(gin::Arguments* args) { | |
| 1834 GestureEvent(WebInputEvent::GestureLongPress, args); | |
| 1835 } | |
| 1836 | |
| 1837 void EventSender::GestureLongTap(gin::Arguments* args) { | |
| 1838 GestureEvent(WebInputEvent::GestureLongTap, args); | |
| 1839 } | |
| 1840 | |
| 1841 void EventSender::GestureTwoFingerTap(gin::Arguments* args) { | |
| 1842 GestureEvent(WebInputEvent::GestureTwoFingerTap, args); | |
| 1843 } | |
| 1844 | |
| 1845 void EventSender::ContinuousMouseScrollBy(gin::Arguments* args) { | |
| 1846 WebMouseWheelEvent event; | |
| 1847 InitMouseWheelEvent(args, true, &event); | |
| 1848 HandleInputEventOnViewOrPopup(event); | |
| 1849 } | |
| 1850 | |
| 1851 void EventSender::MouseMoveTo(gin::Arguments* args) { | |
| 1852 if (force_layout_on_events_) | |
| 1853 view_->layout(); | |
| 1854 | |
| 1855 double x; | |
| 1856 double y; | |
| 1857 if (!args->GetNext(&x) || !args->GetNext(&y)) { | |
| 1858 args->ThrowError(); | |
| 1859 return; | |
| 1860 } | |
| 1861 WebPoint mouse_pos(static_cast<int>(x), static_cast<int>(y)); | |
| 1862 | |
| 1863 int modifiers = 0; | |
| 1864 if (!args->PeekNext().IsEmpty()) | |
| 1865 modifiers = GetKeyModifiersFromV8(args->isolate(), args->PeekNext()); | |
| 1866 | |
| 1867 if (is_drag_mode_ && pressed_button_ == WebMouseEvent::ButtonLeft && | |
| 1868 !replaying_saved_events_) { | |
| 1869 SavedEvent saved_event; | |
| 1870 saved_event.type = SavedEvent::TYPE_MOUSE_MOVE; | |
| 1871 saved_event.pos = mouse_pos; | |
| 1872 saved_event.modifiers = modifiers; | |
| 1873 mouse_event_queue_.push_back(saved_event); | |
| 1874 } else { | |
| 1875 WebMouseEvent event; | |
| 1876 InitMouseEvent(WebInputEvent::MouseMove, | |
| 1877 pressed_button_, | |
| 1878 mouse_pos, | |
| 1879 GetCurrentEventTimeSec(), | |
| 1880 click_count_, | |
| 1881 modifiers, | |
| 1882 &event); | |
| 1883 DoMouseMove(event); | |
| 1884 } | |
| 1885 } | |
| 1886 | |
| 1887 void EventSender::MouseLeave() { | |
| 1888 if (force_layout_on_events_) | |
| 1889 view_->layout(); | |
| 1890 | |
| 1891 WebMouseEvent event; | |
| 1892 InitMouseEvent(WebInputEvent::MouseLeave, | |
| 1893 WebMouseEvent::ButtonNone, | |
| 1894 last_mouse_pos_, | |
| 1895 GetCurrentEventTimeSec(), | |
| 1896 click_count_, | |
| 1897 0, | |
| 1898 &event); | |
| 1899 view_->handleInputEvent(event); | |
| 1900 } | |
| 1901 | |
| 1902 | |
| 1903 void EventSender::TrackpadScrollBegin() { | |
| 1904 WebMouseWheelEvent event; | |
| 1905 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 1906 WebMouseEvent::ButtonNone, | |
| 1907 last_mouse_pos_, | |
| 1908 GetCurrentEventTimeSec(), | |
| 1909 click_count_, | |
| 1910 0, | |
| 1911 &event); | |
| 1912 event.phase = blink::WebMouseWheelEvent::PhaseBegan; | |
| 1913 event.hasPreciseScrollingDeltas = true; | |
| 1914 HandleInputEventOnViewOrPopup(event); | |
| 1915 } | |
| 1916 | |
| 1917 void EventSender::TrackpadScroll(gin::Arguments* args) { | |
| 1918 WebMouseWheelEvent event; | |
| 1919 InitMouseWheelEvent(args, true, &event); | |
| 1920 event.phase = blink::WebMouseWheelEvent::PhaseChanged; | |
| 1921 event.hasPreciseScrollingDeltas = true; | |
| 1922 HandleInputEventOnViewOrPopup(event); | |
| 1923 } | |
| 1924 | |
| 1925 void EventSender::TrackpadScrollEnd() { | |
| 1926 WebMouseWheelEvent event; | |
| 1927 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 1928 WebMouseEvent::ButtonNone, | |
| 1929 last_mouse_pos_, | |
| 1930 GetCurrentEventTimeSec(), | |
| 1931 click_count_, | |
| 1932 0, | |
| 1933 &event); | |
| 1934 event.phase = WebMouseWheelEvent::PhaseEnded; | |
| 1935 event.hasPreciseScrollingDeltas = true; | |
| 1936 HandleInputEventOnViewOrPopup(event); | |
| 1937 } | |
| 1938 | |
| 1939 void EventSender::MouseScrollBy(gin::Arguments* args) { | |
| 1940 WebMouseWheelEvent event; | |
| 1941 InitMouseWheelEvent(args, false, &event); | |
| 1942 HandleInputEventOnViewOrPopup(event); | |
| 1943 } | |
| 1944 | |
| 1945 void EventSender::MouseMomentumBegin() { | |
| 1946 WebMouseWheelEvent event; | |
| 1947 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 1948 WebMouseEvent::ButtonNone, | |
| 1949 last_mouse_pos_, | |
| 1950 GetCurrentEventTimeSec(), | |
| 1951 click_count_, | |
| 1952 0, | |
| 1953 &event); | |
| 1954 event.momentumPhase = WebMouseWheelEvent::PhaseBegan; | |
| 1955 event.hasPreciseScrollingDeltas = true; | |
| 1956 HandleInputEventOnViewOrPopup(event); | |
| 1957 } | |
| 1958 | |
| 1959 void EventSender::MouseMomentumBegin2(gin::Arguments* args) { | |
| 1960 WebMouseWheelEvent event; | |
| 1961 InitMouseWheelEvent(args, true, &event); | |
| 1962 event.momentumPhase = WebMouseWheelEvent::PhaseBegan; | |
| 1963 event.hasPreciseScrollingDeltas = true; | |
| 1964 HandleInputEventOnViewOrPopup(event); | |
| 1965 } | |
| 1966 | |
| 1967 void EventSender::MouseMomentumScrollBy(gin::Arguments* args) { | |
| 1968 WebMouseWheelEvent event; | |
| 1969 InitMouseWheelEvent(args, true, &event); | |
| 1970 event.momentumPhase = WebMouseWheelEvent::PhaseChanged; | |
| 1971 event.hasPreciseScrollingDeltas = true; | |
| 1972 HandleInputEventOnViewOrPopup(event); | |
| 1973 } | |
| 1974 | |
| 1975 void EventSender::MouseMomentumEnd() { | |
| 1976 WebMouseWheelEvent event; | |
| 1977 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 1978 WebMouseEvent::ButtonNone, | |
| 1979 last_mouse_pos_, | |
| 1980 GetCurrentEventTimeSec(), | |
| 1981 click_count_, | |
| 1982 0, | |
| 1983 &event); | |
| 1984 event.momentumPhase = WebMouseWheelEvent::PhaseEnded; | |
| 1985 event.hasPreciseScrollingDeltas = true; | |
| 1986 HandleInputEventOnViewOrPopup(event); | |
| 1987 } | |
| 1988 | |
| 1989 void EventSender::ScheduleAsynchronousClick(int button_number, int modifiers) { | |
| 1990 delegate_->PostTask(new MouseDownTask(this, button_number, modifiers)); | |
| 1991 delegate_->PostTask(new MouseUpTask(this, button_number, modifiers)); | |
| 1992 } | |
| 1993 | |
| 1994 void EventSender::ScheduleAsynchronousKeyDown(const std::string& code_str, | |
| 1995 int modifiers, | |
| 1996 KeyLocationCode location) { | |
| 1997 delegate_->PostTask(new KeyDownTask(this, code_str, modifiers, location)); | |
| 1998 } | |
| 1999 | |
| 2000 double EventSender::GetCurrentEventTimeSec() { | |
| 2001 return (delegate_->GetCurrentTimeInMillisecond() + time_offset_ms_) / 1000.0; | |
| 2002 } | |
| 2003 | |
| 2004 void EventSender::DoLeapForward(int milliseconds) { | |
| 2005 time_offset_ms_ += milliseconds; | |
| 2006 } | |
| 2007 | |
| 2008 void EventSender::SendCurrentTouchEvent(WebInputEvent::Type type) { | |
| 2009 DCHECK_GT(static_cast<unsigned>(WebTouchEvent::touchesLengthCap), | |
| 2010 touch_points_.size()); | |
| 2011 if (force_layout_on_events_) | |
| 2012 view_->layout(); | |
| 2013 | |
| 2014 WebTouchEvent touch_event; | |
| 2015 touch_event.type = type; | |
| 2016 touch_event.modifiers = touch_modifiers_; | |
| 2017 touch_event.cancelable = touch_cancelable_; | |
| 2018 touch_event.timeStampSeconds = GetCurrentEventTimeSec(); | |
| 2019 touch_event.touchesLength = touch_points_.size(); | |
| 2020 for (size_t i = 0; i < touch_points_.size(); ++i) | |
| 2021 touch_event.touches[i] = touch_points_[i]; | |
| 2022 HandleInputEventOnViewOrPopup(touch_event); | |
| 2023 | |
| 2024 for (size_t i = 0; i < touch_points_.size(); ++i) { | |
| 2025 WebTouchPoint* touch_point = &touch_points_[i]; | |
| 2026 if (touch_point->state == WebTouchPoint::StateReleased) { | |
| 2027 touch_points_.erase(touch_points_.begin() + i); | |
| 2028 --i; | |
| 2029 } else | |
| 2030 touch_point->state = WebTouchPoint::StateStationary; | |
| 2031 } | |
| 2032 } | |
| 2033 | |
| 2034 void EventSender::GestureEvent(WebInputEvent::Type type, | |
| 2035 gin::Arguments* args) { | |
| 2036 WebGestureEvent event; | |
| 2037 event.type = type; | |
| 2038 | |
| 2039 // If the first argument is a string, it is to specify the device, otherwise | |
| 2040 // the device is assumed to be a touchscreen (since most tests were written | |
| 2041 // assuming this). | |
| 2042 event.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
| 2043 if (args->PeekNext()->IsString()) { | |
| 2044 std::string device_string; | |
| 2045 if (!args->GetNext(&device_string)) { | |
| 2046 args->ThrowError(); | |
| 2047 return; | |
| 2048 } | |
| 2049 if (device_string == kSourceDeviceStringTouchpad) { | |
| 2050 event.sourceDevice = blink::WebGestureDeviceTouchpad; | |
| 2051 } else if (device_string == kSourceDeviceStringTouchscreen) { | |
| 2052 event.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
| 2053 } else { | |
| 2054 args->ThrowError(); | |
| 2055 return; | |
| 2056 } | |
| 2057 } | |
| 2058 | |
| 2059 double x; | |
| 2060 double y; | |
| 2061 if (!args->GetNext(&x) || !args->GetNext(&y)) { | |
| 2062 args->ThrowError(); | |
| 2063 return; | |
| 2064 } | |
| 2065 | |
| 2066 switch (type) { | |
| 2067 case WebInputEvent::GestureScrollUpdate: | |
| 2068 { | |
| 2069 bool preventPropagation = false; | |
| 2070 if (!args->PeekNext().IsEmpty()) { | |
| 2071 if (!args->GetNext(&preventPropagation)) { | |
| 2072 args->ThrowError(); | |
| 2073 return; | |
| 2074 } | |
| 2075 } | |
| 2076 | |
| 2077 event.data.scrollUpdate.deltaX = static_cast<float>(x); | |
| 2078 event.data.scrollUpdate.deltaY = static_cast<float>(y); | |
| 2079 event.data.scrollUpdate.preventPropagation = preventPropagation; | |
| 2080 event.x = current_gesture_location_.x; | |
| 2081 event.y = current_gesture_location_.y; | |
| 2082 current_gesture_location_.x = | |
| 2083 current_gesture_location_.x + event.data.scrollUpdate.deltaX; | |
| 2084 current_gesture_location_.y = | |
| 2085 current_gesture_location_.y + event.data.scrollUpdate.deltaY; | |
| 2086 break; | |
| 2087 } | |
| 2088 case WebInputEvent::GestureScrollBegin: | |
| 2089 current_gesture_location_ = WebPoint(x, y); | |
| 2090 event.x = current_gesture_location_.x; | |
| 2091 event.y = current_gesture_location_.y; | |
| 2092 break; | |
| 2093 case WebInputEvent::GestureScrollEnd: | |
| 2094 case WebInputEvent::GestureFlingStart: | |
| 2095 event.x = current_gesture_location_.x; | |
| 2096 event.y = current_gesture_location_.y; | |
| 2097 break; | |
| 2098 case WebInputEvent::GesturePinchBegin: | |
| 2099 case WebInputEvent::GesturePinchEnd: | |
| 2100 current_gesture_location_ = WebPoint(x, y); | |
| 2101 event.x = current_gesture_location_.x; | |
| 2102 event.y = current_gesture_location_.y; | |
| 2103 break; | |
| 2104 case WebInputEvent::GesturePinchUpdate: | |
| 2105 { | |
| 2106 float scale = 1; | |
| 2107 if (!args->PeekNext().IsEmpty()) { | |
| 2108 if (!args->GetNext(&scale)) { | |
| 2109 args->ThrowError(); | |
| 2110 return; | |
| 2111 } | |
| 2112 } | |
| 2113 event.data.pinchUpdate.scale = scale; | |
| 2114 current_gesture_location_ = WebPoint(x, y); | |
| 2115 event.x = current_gesture_location_.x; | |
| 2116 event.y = current_gesture_location_.y; | |
| 2117 break; | |
| 2118 } | |
| 2119 case WebInputEvent::GestureTap: | |
| 2120 { | |
| 2121 float tap_count = 1; | |
| 2122 float width = 30; | |
| 2123 float height = 30; | |
| 2124 if (!args->PeekNext().IsEmpty()) { | |
| 2125 if (!args->GetNext(&tap_count)) { | |
| 2126 args->ThrowError(); | |
| 2127 return; | |
| 2128 } | |
| 2129 } | |
| 2130 if (!args->PeekNext().IsEmpty()) { | |
| 2131 if (!args->GetNext(&width)) { | |
| 2132 args->ThrowError(); | |
| 2133 return; | |
| 2134 } | |
| 2135 } | |
| 2136 if (!args->PeekNext().IsEmpty()) { | |
| 2137 if (!args->GetNext(&height)) { | |
| 2138 args->ThrowError(); | |
| 2139 return; | |
| 2140 } | |
| 2141 } | |
| 2142 event.data.tap.tapCount = tap_count; | |
| 2143 event.data.tap.width = width; | |
| 2144 event.data.tap.height = height; | |
| 2145 event.x = x; | |
| 2146 event.y = y; | |
| 2147 break; | |
| 2148 } | |
| 2149 case WebInputEvent::GestureTapUnconfirmed: | |
| 2150 if (!args->PeekNext().IsEmpty()) { | |
| 2151 float tap_count; | |
| 2152 if (!args->GetNext(&tap_count)) { | |
| 2153 args->ThrowError(); | |
| 2154 return; | |
| 2155 } | |
| 2156 event.data.tap.tapCount = tap_count; | |
| 2157 } else { | |
| 2158 event.data.tap.tapCount = 1; | |
| 2159 } | |
| 2160 event.x = x; | |
| 2161 event.y = y; | |
| 2162 break; | |
| 2163 case WebInputEvent::GestureTapDown: | |
| 2164 { | |
| 2165 float width = 30; | |
| 2166 float height = 30; | |
| 2167 if (!args->PeekNext().IsEmpty()) { | |
| 2168 if (!args->GetNext(&width)) { | |
| 2169 args->ThrowError(); | |
| 2170 return; | |
| 2171 } | |
| 2172 } | |
| 2173 if (!args->PeekNext().IsEmpty()) { | |
| 2174 if (!args->GetNext(&height)) { | |
| 2175 args->ThrowError(); | |
| 2176 return; | |
| 2177 } | |
| 2178 } | |
| 2179 event.x = x; | |
| 2180 event.y = y; | |
| 2181 event.data.tapDown.width = width; | |
| 2182 event.data.tapDown.height = height; | |
| 2183 break; | |
| 2184 } | |
| 2185 case WebInputEvent::GestureShowPress: | |
| 2186 { | |
| 2187 float width = 30; | |
| 2188 float height = 30; | |
| 2189 if (!args->PeekNext().IsEmpty()) { | |
| 2190 if (!args->GetNext(&width)) { | |
| 2191 args->ThrowError(); | |
| 2192 return; | |
| 2193 } | |
| 2194 if (!args->PeekNext().IsEmpty()) { | |
| 2195 if (!args->GetNext(&height)) { | |
| 2196 args->ThrowError(); | |
| 2197 return; | |
| 2198 } | |
| 2199 } | |
| 2200 } | |
| 2201 event.x = x; | |
| 2202 event.y = y; | |
| 2203 event.data.showPress.width = width; | |
| 2204 event.data.showPress.height = height; | |
| 2205 break; | |
| 2206 } | |
| 2207 case WebInputEvent::GestureTapCancel: | |
| 2208 event.x = x; | |
| 2209 event.y = y; | |
| 2210 break; | |
| 2211 case WebInputEvent::GestureLongPress: | |
| 2212 event.x = x; | |
| 2213 event.y = y; | |
| 2214 if (!args->PeekNext().IsEmpty()) { | |
| 2215 float width; | |
| 2216 if (!args->GetNext(&width)) { | |
| 2217 args->ThrowError(); | |
| 2218 return; | |
| 2219 } | |
| 2220 event.data.longPress.width = width; | |
| 2221 if (!args->PeekNext().IsEmpty()) { | |
| 2222 float height; | |
| 2223 if (!args->GetNext(&height)) { | |
| 2224 args->ThrowError(); | |
| 2225 return; | |
| 2226 } | |
| 2227 event.data.longPress.height = height; | |
| 2228 } | |
| 2229 } | |
| 2230 break; | |
| 2231 case WebInputEvent::GestureLongTap: | |
| 2232 event.x = x; | |
| 2233 event.y = y; | |
| 2234 if (!args->PeekNext().IsEmpty()) { | |
| 2235 float width; | |
| 2236 if (!args->GetNext(&width)) { | |
| 2237 args->ThrowError(); | |
| 2238 return; | |
| 2239 } | |
| 2240 event.data.longPress.width = width; | |
| 2241 if (!args->PeekNext().IsEmpty()) { | |
| 2242 float height; | |
| 2243 if (!args->GetNext(&height)) { | |
| 2244 args->ThrowError(); | |
| 2245 return; | |
| 2246 } | |
| 2247 event.data.longPress.height = height; | |
| 2248 } | |
| 2249 } | |
| 2250 break; | |
| 2251 case WebInputEvent::GestureTwoFingerTap: | |
| 2252 event.x = x; | |
| 2253 event.y = y; | |
| 2254 if (!args->PeekNext().IsEmpty()) { | |
| 2255 float first_finger_width; | |
| 2256 if (!args->GetNext(&first_finger_width)) { | |
| 2257 args->ThrowError(); | |
| 2258 return; | |
| 2259 } | |
| 2260 event.data.twoFingerTap.firstFingerWidth = first_finger_width; | |
| 2261 if (!args->PeekNext().IsEmpty()) { | |
| 2262 float first_finger_height; | |
| 2263 if (!args->GetNext(&first_finger_height)) { | |
| 2264 args->ThrowError(); | |
| 2265 return; | |
| 2266 } | |
| 2267 event.data.twoFingerTap.firstFingerHeight = first_finger_height; | |
| 2268 } | |
| 2269 } | |
| 2270 break; | |
| 2271 default: | |
| 2272 NOTREACHED(); | |
| 2273 } | |
| 2274 | |
| 2275 event.globalX = event.x; | |
| 2276 event.globalY = event.y; | |
| 2277 event.timeStampSeconds = GetCurrentEventTimeSec(); | |
| 2278 | |
| 2279 if (force_layout_on_events_) | |
| 2280 view_->layout(); | |
| 2281 | |
| 2282 bool result = HandleInputEventOnViewOrPopup(event); | |
| 2283 | |
| 2284 // Long press might start a drag drop session. Complete it if so. | |
| 2285 if (type == WebInputEvent::GestureLongPress && !current_drag_data_.isNull()) { | |
| 2286 WebMouseEvent mouse_event; | |
| 2287 InitMouseEvent(WebInputEvent::MouseDown, | |
| 2288 pressed_button_, | |
| 2289 WebPoint(x, y), | |
| 2290 GetCurrentEventTimeSec(), | |
| 2291 click_count_, | |
| 2292 0, | |
| 2293 &mouse_event); | |
| 2294 | |
| 2295 FinishDragAndDrop(mouse_event, blink::WebDragOperationNone); | |
| 2296 } | |
| 2297 args->Return(result); | |
| 2298 } | |
| 2299 | |
| 2300 void EventSender::UpdateClickCountForButton( | |
| 2301 WebMouseEvent::Button button_type) { | |
| 2302 if ((GetCurrentEventTimeSec() - last_click_time_sec_ < | |
| 2303 kMultipleClickTimeSec) && | |
| 2304 (!OutsideMultiClickRadius(last_mouse_pos_, last_click_pos_)) && | |
| 2305 (button_type == last_button_type_)) { | |
| 2306 ++click_count_; | |
| 2307 } else { | |
| 2308 click_count_ = 1; | |
| 2309 last_button_type_ = button_type; | |
| 2310 } | |
| 2311 } | |
| 2312 | |
| 2313 void EventSender::InitMouseWheelEvent(gin::Arguments* args, | |
| 2314 bool continuous, | |
| 2315 WebMouseWheelEvent* event) { | |
| 2316 // Force a layout here just to make sure every position has been | |
| 2317 // determined before we send events (as well as all the other methods | |
| 2318 // that send an event do). | |
| 2319 if (force_layout_on_events_) | |
| 2320 view_->layout(); | |
| 2321 | |
| 2322 double horizontal; | |
| 2323 if (!args->GetNext(&horizontal)) { | |
| 2324 args->ThrowError(); | |
| 2325 return; | |
| 2326 } | |
| 2327 double vertical; | |
| 2328 if (!args->GetNext(&vertical)) { | |
| 2329 args->ThrowError(); | |
| 2330 return; | |
| 2331 } | |
| 2332 | |
| 2333 bool paged = false; | |
| 2334 bool has_precise_scrolling_deltas = false; | |
| 2335 int modifiers = 0; | |
| 2336 bool can_scroll = true; | |
| 2337 if (!args->PeekNext().IsEmpty()) { | |
| 2338 args->GetNext(&paged); | |
| 2339 if (!args->PeekNext().IsEmpty()) { | |
| 2340 args->GetNext(&has_precise_scrolling_deltas); | |
| 2341 if (!args->PeekNext().IsEmpty()) { | |
| 2342 v8::Local<v8::Value> value; | |
| 2343 args->GetNext(&value); | |
| 2344 modifiers = GetKeyModifiersFromV8(args->isolate(), value); | |
| 2345 if (!args->PeekNext().IsEmpty()) | |
| 2346 args->GetNext(&can_scroll); | |
| 2347 } | |
| 2348 } | |
| 2349 } | |
| 2350 | |
| 2351 InitMouseEvent(WebInputEvent::MouseWheel, | |
| 2352 pressed_button_, | |
| 2353 last_mouse_pos_, | |
| 2354 GetCurrentEventTimeSec(), | |
| 2355 click_count_, | |
| 2356 modifiers, | |
| 2357 event); | |
| 2358 event->wheelTicksX = static_cast<float>(horizontal); | |
| 2359 event->wheelTicksY = static_cast<float>(vertical); | |
| 2360 event->deltaX = event->wheelTicksX; | |
| 2361 event->deltaY = event->wheelTicksY; | |
| 2362 event->scrollByPage = paged; | |
| 2363 event->hasPreciseScrollingDeltas = has_precise_scrolling_deltas; | |
| 2364 event->canScroll = can_scroll; | |
| 2365 if (continuous) { | |
| 2366 event->wheelTicksX /= kScrollbarPixelsPerTick; | |
| 2367 event->wheelTicksY /= kScrollbarPixelsPerTick; | |
| 2368 } else { | |
| 2369 event->deltaX *= kScrollbarPixelsPerTick; | |
| 2370 event->deltaY *= kScrollbarPixelsPerTick; | |
| 2371 } | |
| 2372 } | |
| 2373 | |
| 2374 void EventSender::FinishDragAndDrop(const WebMouseEvent& e, | |
| 2375 blink::WebDragOperation drag_effect) { | |
| 2376 WebPoint client_point(e.x, e.y); | |
| 2377 WebPoint screen_point(e.globalX, e.globalY); | |
| 2378 current_drag_effect_ = drag_effect; | |
| 2379 if (current_drag_effect_) { | |
| 2380 // Specifically pass any keyboard modifiers to the drop method. This allows | |
| 2381 // tests to control the drop type (i.e. copy or move). | |
| 2382 view_->dragTargetDrop(client_point, screen_point, e.modifiers); | |
| 2383 } else { | |
| 2384 view_->dragTargetDragLeave(); | |
| 2385 } | |
| 2386 view_->dragSourceEndedAt(client_point, screen_point, current_drag_effect_); | |
| 2387 view_->dragSourceSystemDragEnded(); | |
| 2388 | |
| 2389 current_drag_data_.reset(); | |
| 2390 } | |
| 2391 | |
| 2392 void EventSender::DoMouseUp(const WebMouseEvent& e) { | |
| 2393 HandleInputEventOnViewOrPopup(e); | |
| 2394 | |
| 2395 pressed_button_ = WebMouseEvent::ButtonNone; | |
| 2396 last_click_time_sec_ = e.timeStampSeconds; | |
| 2397 last_click_pos_ = last_mouse_pos_; | |
| 2398 | |
| 2399 // If we're in a drag operation, complete it. | |
| 2400 if (current_drag_data_.isNull()) | |
| 2401 return; | |
| 2402 | |
| 2403 WebPoint client_point(e.x, e.y); | |
| 2404 WebPoint screen_point(e.globalX, e.globalY); | |
| 2405 FinishDragAndDrop( | |
| 2406 e, | |
| 2407 view_->dragTargetDragOver( | |
| 2408 client_point, | |
| 2409 screen_point, | |
| 2410 current_drag_effects_allowed_, | |
| 2411 e.modifiers)); | |
| 2412 } | |
| 2413 | |
| 2414 void EventSender::DoMouseMove(const WebMouseEvent& e) { | |
| 2415 last_mouse_pos_ = WebPoint(e.x, e.y); | |
| 2416 | |
| 2417 HandleInputEventOnViewOrPopup(e); | |
| 2418 | |
| 2419 if (pressed_button_ == WebMouseEvent::ButtonNone || | |
| 2420 current_drag_data_.isNull()) { | |
| 2421 return; | |
| 2422 } | |
| 2423 | |
| 2424 WebPoint client_point(e.x, e.y); | |
| 2425 WebPoint screen_point(e.globalX, e.globalY); | |
| 2426 current_drag_effect_ = view_->dragTargetDragOver( | |
| 2427 client_point, screen_point, current_drag_effects_allowed_, e.modifiers); | |
| 2428 } | |
| 2429 | |
| 2430 void EventSender::ReplaySavedEvents() { | |
| 2431 replaying_saved_events_ = true; | |
| 2432 while (!mouse_event_queue_.empty()) { | |
| 2433 SavedEvent e = mouse_event_queue_.front(); | |
| 2434 mouse_event_queue_.pop_front(); | |
| 2435 | |
| 2436 switch (e.type) { | |
| 2437 case SavedEvent::TYPE_MOUSE_MOVE: { | |
| 2438 WebMouseEvent event; | |
| 2439 InitMouseEvent(WebInputEvent::MouseMove, | |
| 2440 pressed_button_, | |
| 2441 e.pos, | |
| 2442 GetCurrentEventTimeSec(), | |
| 2443 click_count_, | |
| 2444 e.modifiers, | |
| 2445 &event); | |
| 2446 DoMouseMove(event); | |
| 2447 break; | |
| 2448 } | |
| 2449 case SavedEvent::TYPE_LEAP_FORWARD: | |
| 2450 DoLeapForward(e.milliseconds); | |
| 2451 break; | |
| 2452 case SavedEvent::TYPE_MOUSE_UP: { | |
| 2453 WebMouseEvent event; | |
| 2454 InitMouseEvent(WebInputEvent::MouseUp, | |
| 2455 e.button_type, | |
| 2456 last_mouse_pos_, | |
| 2457 GetCurrentEventTimeSec(), | |
| 2458 click_count_, | |
| 2459 e.modifiers, | |
| 2460 &event); | |
| 2461 DoMouseUp(event); | |
| 2462 break; | |
| 2463 } | |
| 2464 default: | |
| 2465 NOTREACHED(); | |
| 2466 } | |
| 2467 } | |
| 2468 | |
| 2469 replaying_saved_events_ = false; | |
| 2470 } | |
| 2471 | |
| 2472 bool EventSender::HandleInputEventOnViewOrPopup(const WebInputEvent& event) { | |
| 2473 if (WebPagePopup* popup = view_->pagePopup()) { | |
| 2474 if (!WebInputEvent::isKeyboardEventType(event.type)) | |
| 2475 return popup->handleInputEvent(event); | |
| 2476 } | |
| 2477 return view_->handleInputEvent(event); | |
| 2478 } | |
| 2479 | |
| 2480 } // namespace content | |
| OLD | NEW |