widget/shared/WidgetEventImpl.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "mozilla/BasicEvents.h"
michael@0 7 #include "mozilla/ContentEvents.h"
michael@0 8 #include "mozilla/InternalMutationEvent.h"
michael@0 9 #include "mozilla/MiscEvents.h"
michael@0 10 #include "mozilla/MouseEvents.h"
michael@0 11 #include "mozilla/TextEvents.h"
michael@0 12 #include "mozilla/TouchEvents.h"
michael@0 13
michael@0 14 namespace mozilla {
michael@0 15
michael@0 16 /******************************************************************************
michael@0 17 * As*Event() implementation
michael@0 18 ******************************************************************************/
michael@0 19
michael@0 20 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
michael@0 21 #define NS_EVENT_CLASS(aPrefix, aName) \
michael@0 22 aPrefix##aName* \
michael@0 23 WidgetEvent::As##aName() \
michael@0 24 { \
michael@0 25 return nullptr; \
michael@0 26 } \
michael@0 27 \
michael@0 28 const aPrefix##aName* \
michael@0 29 WidgetEvent::As##aName() const \
michael@0 30 { \
michael@0 31 return const_cast<WidgetEvent*>(this)->As##aName(); \
michael@0 32 }
michael@0 33
michael@0 34 #include "mozilla/EventClassList.h"
michael@0 35
michael@0 36 #undef NS_EVENT_CLASS
michael@0 37 #undef NS_ROOT_EVENT_CLASS
michael@0 38
michael@0 39 /******************************************************************************
michael@0 40 * mozilla::WidgetEvent
michael@0 41 *
michael@0 42 * Event struct type checking methods.
michael@0 43 ******************************************************************************/
michael@0 44
michael@0 45 bool
michael@0 46 WidgetEvent::IsQueryContentEvent() const
michael@0 47 {
michael@0 48 return eventStructType == NS_QUERY_CONTENT_EVENT;
michael@0 49 }
michael@0 50
michael@0 51 bool
michael@0 52 WidgetEvent::IsSelectionEvent() const
michael@0 53 {
michael@0 54 return eventStructType == NS_SELECTION_EVENT;
michael@0 55 }
michael@0 56
michael@0 57 bool
michael@0 58 WidgetEvent::IsContentCommandEvent() const
michael@0 59 {
michael@0 60 return eventStructType == NS_CONTENT_COMMAND_EVENT;
michael@0 61 }
michael@0 62
michael@0 63 bool
michael@0 64 WidgetEvent::IsNativeEventDelivererForPlugin() const
michael@0 65 {
michael@0 66 return eventStructType == NS_PLUGIN_EVENT;
michael@0 67 }
michael@0 68
michael@0 69
michael@0 70 /******************************************************************************
michael@0 71 * mozilla::WidgetEvent
michael@0 72 *
michael@0 73 * Event message checking methods.
michael@0 74 ******************************************************************************/
michael@0 75
michael@0 76 bool
michael@0 77 WidgetEvent::HasMouseEventMessage() const
michael@0 78 {
michael@0 79 switch (message) {
michael@0 80 case NS_MOUSE_BUTTON_DOWN:
michael@0 81 case NS_MOUSE_BUTTON_UP:
michael@0 82 case NS_MOUSE_CLICK:
michael@0 83 case NS_MOUSE_DOUBLECLICK:
michael@0 84 case NS_MOUSE_ENTER:
michael@0 85 case NS_MOUSE_EXIT:
michael@0 86 case NS_MOUSE_ACTIVATE:
michael@0 87 case NS_MOUSE_ENTER_SYNTH:
michael@0 88 case NS_MOUSE_EXIT_SYNTH:
michael@0 89 case NS_MOUSE_MOZHITTEST:
michael@0 90 case NS_MOUSE_MOVE:
michael@0 91 return true;
michael@0 92 default:
michael@0 93 return false;
michael@0 94 }
michael@0 95 }
michael@0 96
michael@0 97 bool
michael@0 98 WidgetEvent::HasDragEventMessage() const
michael@0 99 {
michael@0 100 switch (message) {
michael@0 101 case NS_DRAGDROP_ENTER:
michael@0 102 case NS_DRAGDROP_OVER:
michael@0 103 case NS_DRAGDROP_EXIT:
michael@0 104 case NS_DRAGDROP_DRAGDROP:
michael@0 105 case NS_DRAGDROP_GESTURE:
michael@0 106 case NS_DRAGDROP_DRAG:
michael@0 107 case NS_DRAGDROP_END:
michael@0 108 case NS_DRAGDROP_START:
michael@0 109 case NS_DRAGDROP_DROP:
michael@0 110 case NS_DRAGDROP_LEAVE_SYNTH:
michael@0 111 return true;
michael@0 112 default:
michael@0 113 return false;
michael@0 114 }
michael@0 115 }
michael@0 116
michael@0 117 bool
michael@0 118 WidgetEvent::HasKeyEventMessage() const
michael@0 119 {
michael@0 120 switch (message) {
michael@0 121 case NS_KEY_DOWN:
michael@0 122 case NS_KEY_PRESS:
michael@0 123 case NS_KEY_UP:
michael@0 124 return true;
michael@0 125 default:
michael@0 126 return false;
michael@0 127 }
michael@0 128 }
michael@0 129
michael@0 130 bool
michael@0 131 WidgetEvent::HasIMEEventMessage() const
michael@0 132 {
michael@0 133 switch (message) {
michael@0 134 case NS_TEXT_TEXT:
michael@0 135 case NS_COMPOSITION_START:
michael@0 136 case NS_COMPOSITION_END:
michael@0 137 case NS_COMPOSITION_UPDATE:
michael@0 138 return true;
michael@0 139 default:
michael@0 140 return false;
michael@0 141 }
michael@0 142 }
michael@0 143
michael@0 144 bool
michael@0 145 WidgetEvent::HasPluginActivationEventMessage() const
michael@0 146 {
michael@0 147 return message == NS_PLUGIN_ACTIVATE ||
michael@0 148 message == NS_PLUGIN_FOCUS;
michael@0 149 }
michael@0 150
michael@0 151 /******************************************************************************
michael@0 152 * mozilla::WidgetEvent
michael@0 153 *
michael@0 154 * Specific event checking methods.
michael@0 155 ******************************************************************************/
michael@0 156
michael@0 157 bool
michael@0 158 WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
michael@0 159 {
michael@0 160 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
michael@0 161 return pluginEvent && pluginEvent->retargetToFocusedDocument;
michael@0 162 }
michael@0 163
michael@0 164 bool
michael@0 165 WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
michael@0 166 {
michael@0 167 const WidgetPluginEvent* pluginEvent = AsPluginEvent();
michael@0 168 return pluginEvent && !pluginEvent->retargetToFocusedDocument;
michael@0 169 }
michael@0 170
michael@0 171 bool
michael@0 172 WidgetEvent::IsIMERelatedEvent() const
michael@0 173 {
michael@0 174 return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
michael@0 175 }
michael@0 176
michael@0 177 bool
michael@0 178 WidgetEvent::IsUsingCoordinates() const
michael@0 179 {
michael@0 180 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
michael@0 181 if (mouseEvent) {
michael@0 182 return !mouseEvent->IsContextMenuKeyEvent();
michael@0 183 }
michael@0 184 return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
michael@0 185 !HasPluginActivationEventMessage() &&
michael@0 186 !IsNativeEventDelivererForPlugin() &&
michael@0 187 !IsContentCommandEvent() &&
michael@0 188 message != NS_PLUGIN_RESOLUTION_CHANGED;
michael@0 189 }
michael@0 190
michael@0 191 bool
michael@0 192 WidgetEvent::IsTargetedAtFocusedWindow() const
michael@0 193 {
michael@0 194 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
michael@0 195 if (mouseEvent) {
michael@0 196 return mouseEvent->IsContextMenuKeyEvent();
michael@0 197 }
michael@0 198 return HasKeyEventMessage() || IsIMERelatedEvent() ||
michael@0 199 IsContentCommandEvent() ||
michael@0 200 IsRetargetedNativeEventDelivererForPlugin();
michael@0 201 }
michael@0 202
michael@0 203 bool
michael@0 204 WidgetEvent::IsTargetedAtFocusedContent() const
michael@0 205 {
michael@0 206 const WidgetMouseEvent* mouseEvent = AsMouseEvent();
michael@0 207 if (mouseEvent) {
michael@0 208 return mouseEvent->IsContextMenuKeyEvent();
michael@0 209 }
michael@0 210 return HasKeyEventMessage() || IsIMERelatedEvent() ||
michael@0 211 IsRetargetedNativeEventDelivererForPlugin();
michael@0 212 }
michael@0 213
michael@0 214 bool
michael@0 215 WidgetEvent::IsAllowedToDispatchDOMEvent() const
michael@0 216 {
michael@0 217 switch (eventStructType) {
michael@0 218 case NS_MOUSE_EVENT:
michael@0 219 case NS_POINTER_EVENT:
michael@0 220 // We want synthesized mouse moves to cause mouseover and mouseout
michael@0 221 // DOM events (EventStateManager::PreHandleEvent), but not mousemove
michael@0 222 // DOM events.
michael@0 223 // Synthesized button up events also do not cause DOM events because they
michael@0 224 // do not have a reliable refPoint.
michael@0 225 return AsMouseEvent()->reason == WidgetMouseEvent::eReal;
michael@0 226
michael@0 227 case NS_WHEEL_EVENT: {
michael@0 228 // wheel event whose all delta values are zero by user pref applied, it
michael@0 229 // shouldn't cause a DOM event.
michael@0 230 const WidgetWheelEvent* wheelEvent = AsWheelEvent();
michael@0 231 return wheelEvent->deltaX != 0.0 || wheelEvent->deltaY != 0.0 ||
michael@0 232 wheelEvent->deltaZ != 0.0;
michael@0 233 }
michael@0 234
michael@0 235 // Following events are handled in EventStateManager, so, we don't need to
michael@0 236 // dispatch DOM event for them into the DOM tree.
michael@0 237 case NS_QUERY_CONTENT_EVENT:
michael@0 238 case NS_SELECTION_EVENT:
michael@0 239 case NS_CONTENT_COMMAND_EVENT:
michael@0 240 return false;
michael@0 241
michael@0 242 default:
michael@0 243 return true;
michael@0 244 }
michael@0 245 }
michael@0 246
michael@0 247 /******************************************************************************
michael@0 248 * mozilla::WidgetKeyboardEvent (TextEvents.h)
michael@0 249 ******************************************************************************/
michael@0 250
michael@0 251 /*static*/ void
michael@0 252 WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex,
michael@0 253 nsAString& aKeyName)
michael@0 254 {
michael@0 255 // The expected way to implement this function would be to use a
michael@0 256 // switch statement. By using a table-based implementation, below, we
michael@0 257 // ensure that this function executes in constant time in cases where
michael@0 258 // compilers wouldn't be able to convert the switch statement to a
michael@0 259 // jump table. This table-based implementation also minimizes the
michael@0 260 // space required by the code and data.
michael@0 261 #define KEY_STR_NUM_INTERNAL(line) key##line
michael@0 262 #define KEY_STR_NUM(line) KEY_STR_NUM_INTERNAL(line)
michael@0 263
michael@0 264 // Catch non-ASCII DOM key names in our key name list.
michael@0 265 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
michael@0 266 static_assert(sizeof(aDOMKeyName) == MOZ_ARRAY_LENGTH(aDOMKeyName), \
michael@0 267 "Invalid DOM key name");
michael@0 268 #include "mozilla/KeyNameList.h"
michael@0 269 #undef NS_DEFINE_KEYNAME
michael@0 270
michael@0 271 struct KeyNameTable
michael@0 272 {
michael@0 273 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
michael@0 274 char16_t KEY_STR_NUM(__LINE__)[sizeof(aDOMKeyName)];
michael@0 275 #include "mozilla/KeyNameList.h"
michael@0 276 #undef NS_DEFINE_KEYNAME
michael@0 277 };
michael@0 278
michael@0 279 static const KeyNameTable kKeyNameTable = {
michael@0 280 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) MOZ_UTF16(aDOMKeyName),
michael@0 281 #include "mozilla/KeyNameList.h"
michael@0 282 #undef NS_DEFINE_KEYNAME
michael@0 283 };
michael@0 284
michael@0 285 static const uint16_t kKeyNameOffsets[] = {
michael@0 286 #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
michael@0 287 offsetof(struct KeyNameTable, KEY_STR_NUM(__LINE__)) / sizeof(char16_t),
michael@0 288 #include "mozilla/KeyNameList.h"
michael@0 289 #undef NS_DEFINE_KEYNAME
michael@0 290 // Include this entry so we can compute lengths easily.
michael@0 291 sizeof(kKeyNameTable)
michael@0 292 };
michael@0 293
michael@0 294 // Use the sizeof trick rather than MOZ_ARRAY_LENGTH to avoid problems
michael@0 295 // with constexpr functions called inside static_assert with some
michael@0 296 // compilers.
michael@0 297 static_assert(KEY_NAME_INDEX_USE_STRING ==
michael@0 298 (sizeof(kKeyNameOffsets)/sizeof(kKeyNameOffsets[0])) - 1,
michael@0 299 "Invalid enumeration values!");
michael@0 300
michael@0 301 if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) {
michael@0 302 aKeyName.Truncate();
michael@0 303 return;
michael@0 304 }
michael@0 305
michael@0 306 uint16_t offset = kKeyNameOffsets[aKeyNameIndex];
michael@0 307 uint16_t nextOffset = kKeyNameOffsets[aKeyNameIndex + 1];
michael@0 308 const char16_t* table = reinterpret_cast<const char16_t*>(&kKeyNameTable);
michael@0 309
michael@0 310 // Subtract off 1 for the null terminator.
michael@0 311 aKeyName.Assign(table + offset, nextOffset - offset - 1);
michael@0 312
michael@0 313 #undef KEY_STR_NUM
michael@0 314 #undef KEY_STR_NUM_INTERNAL
michael@0 315 }
michael@0 316
michael@0 317 /* static */ const char*
michael@0 318 WidgetKeyboardEvent::GetCommandStr(Command aCommand)
michael@0 319 {
michael@0 320 #define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr
michael@0 321 static const char* kCommands[] = {
michael@0 322 "" // CommandDoNothing
michael@0 323 #include "mozilla/CommandList.h"
michael@0 324 };
michael@0 325 #undef NS_DEFINE_COMMAND
michael@0 326
michael@0 327 MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands),
michael@0 328 "Illegal command enumeration value");
michael@0 329 return kCommands[aCommand];
michael@0 330 }
michael@0 331
michael@0 332 } // namespace mozilla

mercurial