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