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

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

mercurial