widget/shared/WidgetEventImpl.cpp

changeset 0
6474c204b198
     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

mercurial