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