1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/shared/WidgetEventImpl.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,332 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/BasicEvents.h" 1.10 +#include "mozilla/ContentEvents.h" 1.11 +#include "mozilla/InternalMutationEvent.h" 1.12 +#include "mozilla/MiscEvents.h" 1.13 +#include "mozilla/MouseEvents.h" 1.14 +#include "mozilla/TextEvents.h" 1.15 +#include "mozilla/TouchEvents.h" 1.16 + 1.17 +namespace mozilla { 1.18 + 1.19 +/****************************************************************************** 1.20 + * As*Event() implementation 1.21 + ******************************************************************************/ 1.22 + 1.23 +#define NS_ROOT_EVENT_CLASS(aPrefix, aName) 1.24 +#define NS_EVENT_CLASS(aPrefix, aName) \ 1.25 +aPrefix##aName* \ 1.26 +WidgetEvent::As##aName() \ 1.27 +{ \ 1.28 + return nullptr; \ 1.29 +} \ 1.30 +\ 1.31 +const aPrefix##aName* \ 1.32 +WidgetEvent::As##aName() const \ 1.33 +{ \ 1.34 + return const_cast<WidgetEvent*>(this)->As##aName(); \ 1.35 +} 1.36 + 1.37 +#include "mozilla/EventClassList.h" 1.38 + 1.39 +#undef NS_EVENT_CLASS 1.40 +#undef NS_ROOT_EVENT_CLASS 1.41 + 1.42 +/****************************************************************************** 1.43 + * mozilla::WidgetEvent 1.44 + * 1.45 + * Event struct type checking methods. 1.46 + ******************************************************************************/ 1.47 + 1.48 +bool 1.49 +WidgetEvent::IsQueryContentEvent() const 1.50 +{ 1.51 + return eventStructType == NS_QUERY_CONTENT_EVENT; 1.52 +} 1.53 + 1.54 +bool 1.55 +WidgetEvent::IsSelectionEvent() const 1.56 +{ 1.57 + return eventStructType == NS_SELECTION_EVENT; 1.58 +} 1.59 + 1.60 +bool 1.61 +WidgetEvent::IsContentCommandEvent() const 1.62 +{ 1.63 + return eventStructType == NS_CONTENT_COMMAND_EVENT; 1.64 +} 1.65 + 1.66 +bool 1.67 +WidgetEvent::IsNativeEventDelivererForPlugin() const 1.68 +{ 1.69 + return eventStructType == NS_PLUGIN_EVENT; 1.70 +} 1.71 + 1.72 + 1.73 +/****************************************************************************** 1.74 + * mozilla::WidgetEvent 1.75 + * 1.76 + * Event message checking methods. 1.77 + ******************************************************************************/ 1.78 + 1.79 +bool 1.80 +WidgetEvent::HasMouseEventMessage() const 1.81 +{ 1.82 + switch (message) { 1.83 + case NS_MOUSE_BUTTON_DOWN: 1.84 + case NS_MOUSE_BUTTON_UP: 1.85 + case NS_MOUSE_CLICK: 1.86 + case NS_MOUSE_DOUBLECLICK: 1.87 + case NS_MOUSE_ENTER: 1.88 + case NS_MOUSE_EXIT: 1.89 + case NS_MOUSE_ACTIVATE: 1.90 + case NS_MOUSE_ENTER_SYNTH: 1.91 + case NS_MOUSE_EXIT_SYNTH: 1.92 + case NS_MOUSE_MOZHITTEST: 1.93 + case NS_MOUSE_MOVE: 1.94 + return true; 1.95 + default: 1.96 + return false; 1.97 + } 1.98 +} 1.99 + 1.100 +bool 1.101 +WidgetEvent::HasDragEventMessage() const 1.102 +{ 1.103 + switch (message) { 1.104 + case NS_DRAGDROP_ENTER: 1.105 + case NS_DRAGDROP_OVER: 1.106 + case NS_DRAGDROP_EXIT: 1.107 + case NS_DRAGDROP_DRAGDROP: 1.108 + case NS_DRAGDROP_GESTURE: 1.109 + case NS_DRAGDROP_DRAG: 1.110 + case NS_DRAGDROP_END: 1.111 + case NS_DRAGDROP_START: 1.112 + case NS_DRAGDROP_DROP: 1.113 + case NS_DRAGDROP_LEAVE_SYNTH: 1.114 + return true; 1.115 + default: 1.116 + return false; 1.117 + } 1.118 +} 1.119 + 1.120 +bool 1.121 +WidgetEvent::HasKeyEventMessage() const 1.122 +{ 1.123 + switch (message) { 1.124 + case NS_KEY_DOWN: 1.125 + case NS_KEY_PRESS: 1.126 + case NS_KEY_UP: 1.127 + return true; 1.128 + default: 1.129 + return false; 1.130 + } 1.131 +} 1.132 + 1.133 +bool 1.134 +WidgetEvent::HasIMEEventMessage() const 1.135 +{ 1.136 + switch (message) { 1.137 + case NS_TEXT_TEXT: 1.138 + case NS_COMPOSITION_START: 1.139 + case NS_COMPOSITION_END: 1.140 + case NS_COMPOSITION_UPDATE: 1.141 + return true; 1.142 + default: 1.143 + return false; 1.144 + } 1.145 +} 1.146 + 1.147 +bool 1.148 +WidgetEvent::HasPluginActivationEventMessage() const 1.149 +{ 1.150 + return message == NS_PLUGIN_ACTIVATE || 1.151 + message == NS_PLUGIN_FOCUS; 1.152 +} 1.153 + 1.154 +/****************************************************************************** 1.155 + * mozilla::WidgetEvent 1.156 + * 1.157 + * Specific event checking methods. 1.158 + ******************************************************************************/ 1.159 + 1.160 +bool 1.161 +WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const 1.162 +{ 1.163 + const WidgetPluginEvent* pluginEvent = AsPluginEvent(); 1.164 + return pluginEvent && pluginEvent->retargetToFocusedDocument; 1.165 +} 1.166 + 1.167 +bool 1.168 +WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const 1.169 +{ 1.170 + const WidgetPluginEvent* pluginEvent = AsPluginEvent(); 1.171 + return pluginEvent && !pluginEvent->retargetToFocusedDocument; 1.172 +} 1.173 + 1.174 +bool 1.175 +WidgetEvent::IsIMERelatedEvent() const 1.176 +{ 1.177 + return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent(); 1.178 +} 1.179 + 1.180 +bool 1.181 +WidgetEvent::IsUsingCoordinates() const 1.182 +{ 1.183 + const WidgetMouseEvent* mouseEvent = AsMouseEvent(); 1.184 + if (mouseEvent) { 1.185 + return !mouseEvent->IsContextMenuKeyEvent(); 1.186 + } 1.187 + return !HasKeyEventMessage() && !IsIMERelatedEvent() && 1.188 + !HasPluginActivationEventMessage() && 1.189 + !IsNativeEventDelivererForPlugin() && 1.190 + !IsContentCommandEvent() && 1.191 + message != NS_PLUGIN_RESOLUTION_CHANGED; 1.192 +} 1.193 + 1.194 +bool 1.195 +WidgetEvent::IsTargetedAtFocusedWindow() const 1.196 +{ 1.197 + const WidgetMouseEvent* mouseEvent = AsMouseEvent(); 1.198 + if (mouseEvent) { 1.199 + return mouseEvent->IsContextMenuKeyEvent(); 1.200 + } 1.201 + return HasKeyEventMessage() || IsIMERelatedEvent() || 1.202 + IsContentCommandEvent() || 1.203 + IsRetargetedNativeEventDelivererForPlugin(); 1.204 +} 1.205 + 1.206 +bool 1.207 +WidgetEvent::IsTargetedAtFocusedContent() const 1.208 +{ 1.209 + const WidgetMouseEvent* mouseEvent = AsMouseEvent(); 1.210 + if (mouseEvent) { 1.211 + return mouseEvent->IsContextMenuKeyEvent(); 1.212 + } 1.213 + return HasKeyEventMessage() || IsIMERelatedEvent() || 1.214 + IsRetargetedNativeEventDelivererForPlugin(); 1.215 +} 1.216 + 1.217 +bool 1.218 +WidgetEvent::IsAllowedToDispatchDOMEvent() const 1.219 +{ 1.220 + switch (eventStructType) { 1.221 + case NS_MOUSE_EVENT: 1.222 + case NS_POINTER_EVENT: 1.223 + // We want synthesized mouse moves to cause mouseover and mouseout 1.224 + // DOM events (EventStateManager::PreHandleEvent), but not mousemove 1.225 + // DOM events. 1.226 + // Synthesized button up events also do not cause DOM events because they 1.227 + // do not have a reliable refPoint. 1.228 + return AsMouseEvent()->reason == WidgetMouseEvent::eReal; 1.229 + 1.230 + case NS_WHEEL_EVENT: { 1.231 + // wheel event whose all delta values are zero by user pref applied, it 1.232 + // shouldn't cause a DOM event. 1.233 + const WidgetWheelEvent* wheelEvent = AsWheelEvent(); 1.234 + return wheelEvent->deltaX != 0.0 || wheelEvent->deltaY != 0.0 || 1.235 + wheelEvent->deltaZ != 0.0; 1.236 + } 1.237 + 1.238 + // Following events are handled in EventStateManager, so, we don't need to 1.239 + // dispatch DOM event for them into the DOM tree. 1.240 + case NS_QUERY_CONTENT_EVENT: 1.241 + case NS_SELECTION_EVENT: 1.242 + case NS_CONTENT_COMMAND_EVENT: 1.243 + return false; 1.244 + 1.245 + default: 1.246 + return true; 1.247 + } 1.248 +} 1.249 + 1.250 +/****************************************************************************** 1.251 + * mozilla::WidgetKeyboardEvent (TextEvents.h) 1.252 + ******************************************************************************/ 1.253 + 1.254 +/*static*/ void 1.255 +WidgetKeyboardEvent::GetDOMKeyName(KeyNameIndex aKeyNameIndex, 1.256 + nsAString& aKeyName) 1.257 +{ 1.258 + // The expected way to implement this function would be to use a 1.259 + // switch statement. By using a table-based implementation, below, we 1.260 + // ensure that this function executes in constant time in cases where 1.261 + // compilers wouldn't be able to convert the switch statement to a 1.262 + // jump table. This table-based implementation also minimizes the 1.263 + // space required by the code and data. 1.264 +#define KEY_STR_NUM_INTERNAL(line) key##line 1.265 +#define KEY_STR_NUM(line) KEY_STR_NUM_INTERNAL(line) 1.266 + 1.267 + // Catch non-ASCII DOM key names in our key name list. 1.268 +#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \ 1.269 + static_assert(sizeof(aDOMKeyName) == MOZ_ARRAY_LENGTH(aDOMKeyName), \ 1.270 + "Invalid DOM key name"); 1.271 +#include "mozilla/KeyNameList.h" 1.272 +#undef NS_DEFINE_KEYNAME 1.273 + 1.274 + struct KeyNameTable 1.275 + { 1.276 +#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \ 1.277 + char16_t KEY_STR_NUM(__LINE__)[sizeof(aDOMKeyName)]; 1.278 +#include "mozilla/KeyNameList.h" 1.279 +#undef NS_DEFINE_KEYNAME 1.280 + }; 1.281 + 1.282 + static const KeyNameTable kKeyNameTable = { 1.283 +#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) MOZ_UTF16(aDOMKeyName), 1.284 +#include "mozilla/KeyNameList.h" 1.285 +#undef NS_DEFINE_KEYNAME 1.286 + }; 1.287 + 1.288 + static const uint16_t kKeyNameOffsets[] = { 1.289 +#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \ 1.290 + offsetof(struct KeyNameTable, KEY_STR_NUM(__LINE__)) / sizeof(char16_t), 1.291 +#include "mozilla/KeyNameList.h" 1.292 +#undef NS_DEFINE_KEYNAME 1.293 + // Include this entry so we can compute lengths easily. 1.294 + sizeof(kKeyNameTable) 1.295 + }; 1.296 + 1.297 + // Use the sizeof trick rather than MOZ_ARRAY_LENGTH to avoid problems 1.298 + // with constexpr functions called inside static_assert with some 1.299 + // compilers. 1.300 + static_assert(KEY_NAME_INDEX_USE_STRING == 1.301 + (sizeof(kKeyNameOffsets)/sizeof(kKeyNameOffsets[0])) - 1, 1.302 + "Invalid enumeration values!"); 1.303 + 1.304 + if (aKeyNameIndex >= KEY_NAME_INDEX_USE_STRING) { 1.305 + aKeyName.Truncate(); 1.306 + return; 1.307 + } 1.308 + 1.309 + uint16_t offset = kKeyNameOffsets[aKeyNameIndex]; 1.310 + uint16_t nextOffset = kKeyNameOffsets[aKeyNameIndex + 1]; 1.311 + const char16_t* table = reinterpret_cast<const char16_t*>(&kKeyNameTable); 1.312 + 1.313 + // Subtract off 1 for the null terminator. 1.314 + aKeyName.Assign(table + offset, nextOffset - offset - 1); 1.315 + 1.316 +#undef KEY_STR_NUM 1.317 +#undef KEY_STR_NUM_INTERNAL 1.318 +} 1.319 + 1.320 +/* static */ const char* 1.321 +WidgetKeyboardEvent::GetCommandStr(Command aCommand) 1.322 +{ 1.323 +#define NS_DEFINE_COMMAND(aName, aCommandStr) , #aCommandStr 1.324 + static const char* kCommands[] = { 1.325 + "" // CommandDoNothing 1.326 +#include "mozilla/CommandList.h" 1.327 + }; 1.328 +#undef NS_DEFINE_COMMAND 1.329 + 1.330 + MOZ_RELEASE_ASSERT(static_cast<size_t>(aCommand) < ArrayLength(kCommands), 1.331 + "Illegal command enumeration value"); 1.332 + return kCommands[aCommand]; 1.333 +} 1.334 + 1.335 +} // namespace mozilla