From 6839535c4249d838fdd12352e3789cc12aca6a87 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 24 Sep 2013 19:04:15 +0900 Subject: [PATCH] Bug 912956 part.4 Create mozilla/TextEvents.h r=roc --- content/base/public/nsISelectionPrivate.idl | 2 +- content/events/public/nsIPrivateTextRange.h | 2 +- content/events/src/nsPrivateTextRange.h | 1 + toolkit/xre/nsAppRunner.cpp | 7 +- widget/BasicEvents.h | 16 +- widget/EventForwards.h | 37 +- widget/TextEvents.h | 547 ++++++++++++++++++++ widget/moz.build | 1 + widget/nsGUIEvent.h | 436 +--------------- 9 files changed, 586 insertions(+), 463 deletions(-) create mode 100644 widget/TextEvents.h diff --git a/content/base/public/nsISelectionPrivate.idl b/content/base/public/nsISelectionPrivate.idl index acbeabd9ecc5..f7af60543819 100644 --- a/content/base/public/nsISelectionPrivate.idl +++ b/content/base/public/nsISelectionPrivate.idl @@ -13,12 +13,12 @@ interface nsINode; %{C++ class nsIFrame; -struct nsTextRangeStyle; struct nsPoint; struct ScrollAxis; template class nsTArray; #include "nsDirection.h" #include "nsIPresShell.h" // TODO: Remove this include +#include "mozilla/EventForwards.h" %} [ptr] native nsIFrame(nsIFrame); diff --git a/content/events/public/nsIPrivateTextRange.h b/content/events/public/nsIPrivateTextRange.h index 901ad297d2b1..5ceb024c4c0f 100644 --- a/content/events/public/nsIPrivateTextRange.h +++ b/content/events/public/nsIPrivateTextRange.h @@ -9,7 +9,7 @@ #include "nsISupports.h" #include "nsString.h" #include "nsCOMPtr.h" -#include "nsGUIEvent.h" +#include "mozilla/EventForwards.h" #define NS_IPRIVATETEXTRANGE_IID \ { 0xf795a44d, 0x413a, 0x4c63, \ diff --git a/content/events/src/nsPrivateTextRange.h b/content/events/src/nsPrivateTextRange.h index 653f447fad84..7d79db1ade19 100644 --- a/content/events/src/nsPrivateTextRange.h +++ b/content/events/src/nsPrivateTextRange.h @@ -10,6 +10,7 @@ #include "nsTArray.h" #include "nsAutoPtr.h" #include "mozilla/Attributes.h" +#include "mozilla/TextEvents.h" class nsPrivateTextRange MOZ_FINAL : public nsIPrivateTextRange { diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 42fbd15921d2..a8268bd1d77b 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -95,10 +95,6 @@ #include "mozilla/unused.h" -using namespace mozilla; -using mozilla::unused; -using mozilla::scache::StartupCache; - #ifdef XP_WIN #include "nsIWinAppHelper.h" #include @@ -248,6 +244,9 @@ namespace mozilla { int (*RunGTest)() = 0; } +using namespace mozilla; +using mozilla::unused; +using mozilla::scache::StartupCache; using mozilla::dom::ContentParent; using mozilla::dom::ContentChild; diff --git a/widget/BasicEvents.h b/widget/BasicEvents.h index 8ad699021b78..168d750f7766 100644 --- a/widget/BasicEvents.h +++ b/widget/BasicEvents.h @@ -29,6 +29,13 @@ enum nsEventStructType NS_INPUT_EVENT, // WidgetInputEvent NS_UI_EVENT, // InternalUIEvent + // TextEvents.h + NS_KEY_EVENT, // WidgetKeyboardEvent + NS_COMPOSITION_EVENT, // WidgetCompositionEvent + NS_TEXT_EVENT, // WidgetTextEvent + NS_QUERY_CONTENT_EVENT, // WidgetQueryContentEvent + NS_SELECTION_EVENT, // WidgetSelectionEvent + // Mouse related events NS_MOUSE_EVENT, // nsMouseEvent NS_MOUSE_SCROLL_EVENT, // nsMouseScrollEvent @@ -40,15 +47,6 @@ enum nsEventStructType NS_SIMPLE_GESTURE_EVENT, // nsSimpleGestureEvent NS_TOUCH_EVENT, // nsTouchEvent - // Key or IME events - NS_KEY_EVENT, // nsKeyEvent - NS_COMPOSITION_EVENT, // nsCompositionEvent - NS_TEXT_EVENT, // nsTextEvent - - // IME related events - NS_QUERY_CONTENT_EVENT, // nsQueryContentEvent - NS_SELECTION_EVENT, // nsSelectionEvent - // Scroll related events NS_SCROLLPORT_EVENT, // nsScrollPortEvent NS_SCROLLAREA_EVENT, // nsScrollAreaEvent diff --git a/widget/EventForwards.h b/widget/EventForwards.h index de153b04efa6..fbc09717acbf 100644 --- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -57,18 +57,20 @@ class WidgetEvent; class WidgetGUIEvent; class WidgetInputEvent; class InternalUIEvent; -} // namespace mozilla // TextEvents.h -struct nsAlternativeCharCode; -struct nsTextRangeStyle; -struct nsTextRange; +struct AlternativeCharCode; +struct TextRangeStyle; +struct TextRange; -class nsKeyEvent; -class nsTextEvent; -class nsCompositionEvent; -class nsQueryContentEvent; -class nsSelectionEvent; +typedef TextRange* TextRangeArray; + +class WidgetKeyboardEvent; +class WidgetTextEvent; +class WidgetCompositionEvent; +class WidgetQueryContentEvent; +class WidgetSelectionEvent; +} // namespace mozilla // MouseEvents.h class nsMouseEvent_base; @@ -104,9 +106,18 @@ class nsPluginEvent; class nsMutationEvent; // TODO: Remove following typedefs -typedef mozilla::WidgetEvent nsEvent; -typedef mozilla::WidgetGUIEvent nsGUIEvent; -typedef mozilla::WidgetInputEvent nsInputEvent; -typedef mozilla::InternalUIEvent nsUIEvent; +typedef mozilla::WidgetEvent nsEvent; +typedef mozilla::WidgetGUIEvent nsGUIEvent; +typedef mozilla::WidgetInputEvent nsInputEvent; +typedef mozilla::InternalUIEvent nsUIEvent; +typedef mozilla::AlternativeCharCode nsAlternativeCharCode; +typedef mozilla::WidgetKeyboardEvent nsKeyEvent; +typedef mozilla::TextRangeStyle nsTextRangeStyle; +typedef mozilla::TextRange nsTextRange; +typedef mozilla::TextRangeArray nsTextRangeArray; +typedef mozilla::WidgetTextEvent nsTextEvent; +typedef mozilla::WidgetCompositionEvent nsCompositionEvent; +typedef mozilla::WidgetQueryContentEvent nsQueryContentEvent; +typedef mozilla::WidgetSelectionEvent nsSelectionEvent; #endif // mozilla_EventForwards_h__ diff --git a/widget/TextEvents.h b/widget/TextEvents.h new file mode 100644 index 000000000000..5f7964134284 --- /dev/null +++ b/widget/TextEvents.h @@ -0,0 +1,547 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_TextEvents_h__ +#define mozilla_TextEvents_h__ + +#include + +#include "mozilla/Assertions.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/EventForwards.h" // for KeyNameIndex, temporarily +#include "nsColor.h" +#include "nsCOMPtr.h" +#include "nsIDOMKeyEvent.h" +#include "nsITransferable.h" +#include "nsRect.h" +#include "nsStringGlue.h" +#include "nsStyleConsts.h" +#include "nsTArray.h" + +/****************************************************************************** + * virtual keycode values + ******************************************************************************/ + +#define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode + +enum +{ +#include "nsVKList.h" +}; + +#undef NS_DEFINE_VK + +namespace mozilla { + +namespace dom { + class PBrowserParent; + class PBrowserChild; +} // namespace dom +namespace plugins { + class PPluginInstanceChild; +} // namespace plugins + +/****************************************************************************** + * mozilla::AlternativeCharCode + * + * This stores alternative charCode values of a key event with some modifiers. + * The stored values proper for testing shortcut key or access key. + ******************************************************************************/ + +struct AlternativeCharCode +{ + AlternativeCharCode(uint32_t aUnshiftedCharCode, uint32_t aShiftedCharCode) : + mUnshiftedCharCode(aUnshiftedCharCode), mShiftedCharCode(aShiftedCharCode) + { + } + uint32_t mUnshiftedCharCode; + uint32_t mShiftedCharCode; +}; + +/****************************************************************************** + * mozilla::WidgetKeyboardEvent + ******************************************************************************/ + +class WidgetKeyboardEvent : public WidgetInputEvent +{ +private: + friend class dom::PBrowserParent; + friend class dom::PBrowserChild; + +public: + WidgetKeyboardEvent() + { + } + + WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) : + WidgetInputEvent(aIsTrusted, aMessage, aWidget, NS_KEY_EVENT), + keyCode(0), charCode(0), + location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD), isChar(0), + mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified), + mNativeKeyEvent(nullptr), + mUniqueId(0) + { + } + + // A DOM keyCode value or 0. If a keypress event whose charCode is 0, this + // should be 0. + uint32_t keyCode; + // If the instance is a keypress event of a printable key, this is a UTF-16 + // value of the key. Otherwise, 0. This value must not be a control + // character when some modifiers are active. Then, this value should be an + // unmodified value except Shift and AltGr. + uint32_t charCode; + // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_* + uint32_t location; + // OS translated Unicode chars which are used for accesskey and accelkey + // handling. The handlers will try from first character to last character. + nsTArray alternativeCharCodes; + // Indicates whether the event signifies a printable character + bool isChar; + // DOM KeyboardEvent.key + KeyNameIndex mKeyNameIndex; + // OS-specific native event can optionally be preserved + void* mNativeKeyEvent; + // Unique id associated with a keydown / keypress event. Used in identifing + // keypress events for removal from async event dispatch queue in metrofx + // after preventDefault is called on keydown events. It's ok if this wraps + // over long periods. + uint32_t mUniqueId; + + void GetDOMKeyName(nsAString& aKeyName) + { + GetDOMKeyName(mKeyNameIndex, aKeyName); + } + + static void GetDOMKeyName(mozilla::KeyNameIndex aKeyNameIndex, + nsAString& aKeyName) + { +#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \ + case KEY_NAME_INDEX_##aCPPName: \ + aKeyName.Assign(NS_LITERAL_STRING(aDOMKeyName)); return; + switch (aKeyNameIndex) { +#include "nsDOMKeyNameList.h" + default: + aKeyName.Truncate(); + return; + } +#undef NS_DEFINE_KEYNAME + } + + void AssignKeyEventData(const WidgetKeyboardEvent& aEvent, bool aCopyTargets) + { + AssignInputEventData(aEvent, aCopyTargets); + + keyCode = aEvent.keyCode; + charCode = aEvent.charCode; + location = aEvent.location; + alternativeCharCodes = aEvent.alternativeCharCodes; + isChar = aEvent.isChar; + mKeyNameIndex = aEvent.mKeyNameIndex; + // Don't copy mNativeKeyEvent because it may be referred after its instance + // is destroyed. + mNativeKeyEvent = nullptr; + mUniqueId = aEvent.mUniqueId; + } +}; + +/****************************************************************************** + * mozilla::TextRangeStyle + ******************************************************************************/ + +struct TextRangeStyle +{ + enum { + LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, + LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, + LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, + LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, + LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, + LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY + }; + + enum { + DEFINED_NONE = 0x00, + DEFINED_LINESTYLE = 0x01, + DEFINED_FOREGROUND_COLOR = 0x02, + DEFINED_BACKGROUND_COLOR = 0x04, + DEFINED_UNDERLINE_COLOR = 0x08 + }; + + // Initialize all members, because TextRange instances may be compared by + // memcomp. + TextRangeStyle() + { + Clear(); + } + + void Clear() + { + mDefinedStyles = DEFINED_NONE; + mLineStyle = LINESTYLE_NONE; + mIsBoldLine = false; + mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); + } + + bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } + + bool IsLineStyleDefined() const + { + return (mDefinedStyles & DEFINED_LINESTYLE) != 0; + } + + bool IsForegroundColorDefined() const + { + return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; + } + + bool IsBackgroundColorDefined() const + { + return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; + } + + bool IsUnderlineColorDefined() const + { + return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; + } + + bool IsNoChangeStyle() const + { + return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && + IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; + } + + bool Equals(const nsTextRangeStyle& aOther) + { + if (mDefinedStyles != aOther.mDefinedStyles) + return false; + if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || + !mIsBoldLine != !aOther.mIsBoldLine)) + return false; + if (IsForegroundColorDefined() && + (mForegroundColor != aOther.mForegroundColor)) + return false; + if (IsBackgroundColorDefined() && + (mBackgroundColor != aOther.mBackgroundColor)) + return false; + if (IsUnderlineColorDefined() && + (mUnderlineColor != aOther.mUnderlineColor)) + return false; + return true; + } + + bool operator !=(const TextRangeStyle &aOther) + { + return !Equals(aOther); + } + + bool operator ==(const TextRangeStyle &aOther) + { + return Equals(aOther); + } + + uint8_t mDefinedStyles; + uint8_t mLineStyle; // DEFINED_LINESTYLE + + bool mIsBoldLine; // DEFINED_LINESTYLE + + nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR + nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR + nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR +}; + +/****************************************************************************** + * mozilla::TextRange + ******************************************************************************/ + +// Sync with nsIPrivateTextRange.h when you change these constants. +#define NS_TEXTRANGE_CARETPOSITION 0x01 +#define NS_TEXTRANGE_RAWINPUT 0x02 +#define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 +#define NS_TEXTRANGE_CONVERTEDTEXT 0x04 +#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 + +struct TextRange +{ + TextRange() : + mStartOffset(0), mEndOffset(0), mRangeType(0) + { + } + + uint32_t mStartOffset; + // XXX Storing end offset makes the initializing code very complicated. + // We should replace it with mLength. + uint32_t mEndOffset; + uint32_t mRangeType; + + TextRangeStyle mRangeStyle; + + uint32_t Length() const { return mEndOffset - mStartOffset; } +}; + +/****************************************************************************** + * mozilla::TextRangeArray + * + * XXX This should be replaced with nsTArray. + ******************************************************************************/ + +typedef TextRange* TextRangeArray; + +/****************************************************************************** + * mozilla::WidgetTextEvent + * + * XXX WidgetTextEvent is fired with compositionupdate event almost every time. + * This wastes performance and the cost of mantaining each platform's + * implementation. Therefore, we should merge WidgetTextEvent and + * WidgetCompositionEvent. Then, DOM compositionupdate should be fired + * from TextComposition automatically. + ******************************************************************************/ + +class WidgetTextEvent : public WidgetGUIEvent +{ +private: + friend class dom::PBrowserParent; + friend class dom::PBrowserChild; + friend class plugins::PPluginInstanceChild; + + WidgetTextEvent() + { + } + +public: + uint32_t seqno; + +public: + WidgetTextEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) : + WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_TEXT_EVENT), + rangeCount(0), rangeArray(nullptr), isChar(false) + { + } + + // The composition string or the commit string. + nsString theText; + // Count of rangeArray. + uint32_t rangeCount; + // Pointer to the first item of the ranges (clauses). + // Note that the range array may not specify a caret position; in that + // case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the + // array. + nsTextRangeArray rangeArray; + // Indicates whether the event signifies printable text. + // XXX This is not a standard, and most platforms don't set this properly. + // So, perhaps, we can get rid of this. + bool isChar; + + void AssignTextEventData(const WidgetTextEvent& aEvent, bool aCopyTargets) + { + AssignGUIEventData(aEvent, aCopyTargets); + + isChar = aEvent.isChar; + + // Currently, we don't need to copy the other members because they are + // for internal use only (not available from JS). + } +}; + +/****************************************************************************** + * mozilla::WidgetCompositionEvent + ******************************************************************************/ + +class WidgetCompositionEvent : public WidgetGUIEvent +{ +private: + friend class mozilla::dom::PBrowserParent; + friend class mozilla::dom::PBrowserChild; + + WidgetCompositionEvent() + { + } + +public: + uint32_t seqno; + +public: + WidgetCompositionEvent(bool aIsTrusted, uint32_t aMessage, + nsIWidget* aWidget) : + WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_COMPOSITION_EVENT) + { + // XXX compositionstart is cancelable in draft of DOM3 Events. + // However, it doesn't make sense for us, we cannot cancel composition + // when we send compositionstart event. + mFlags.mCancelable = false; + } + + // The composition string or the commit string. If the instance is a + // compositionstart event, this is initialized with selected text by + // TextComposition automatically. + nsString data; + + void AssignCompositionEventData(const WidgetCompositionEvent& aEvent, + bool aCopyTargets) + { + AssignGUIEventData(aEvent, aCopyTargets); + + data = aEvent.data; + } +}; + +/****************************************************************************** + * mozilla::WidgetQueryContentEvent + ******************************************************************************/ + +class WidgetQueryContentEvent : public WidgetGUIEvent +{ +private: + friend class dom::PBrowserParent; + friend class dom::PBrowserChild; + + WidgetQueryContentEvent() + { + MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments"); + } + +public: + WidgetQueryContentEvent(bool aIsTrusted, uint32_t aMessage, + nsIWidget* aWidget) : + WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_QUERY_CONTENT_EVENT), + mSucceeded(false), mWasAsync(false) + { + } + + void InitForQueryTextContent(uint32_t aOffset, uint32_t aLength) + { + NS_ASSERTION(message == NS_QUERY_TEXT_CONTENT, + "wrong initializer is called"); + mInput.mOffset = aOffset; + mInput.mLength = aLength; + } + + void InitForQueryCaretRect(uint32_t aOffset) + { + NS_ASSERTION(message == NS_QUERY_CARET_RECT, + "wrong initializer is called"); + mInput.mOffset = aOffset; + } + + void InitForQueryTextRect(uint32_t aOffset, uint32_t aLength) + { + NS_ASSERTION(message == NS_QUERY_TEXT_RECT, + "wrong initializer is called"); + mInput.mOffset = aOffset; + mInput.mLength = aLength; + } + + void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint& aPoint) + { + NS_ASSERTION(message == NS_QUERY_DOM_WIDGET_HITTEST, + "wrong initializer is called"); + refPoint = aPoint; + } + + uint32_t GetSelectionStart(void) const + { + NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT, + "not querying selection"); + return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0); + } + + uint32_t GetSelectionEnd(void) const + { + NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT, + "not querying selection"); + return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length()); + } + + bool mSucceeded; + bool mWasAsync; + struct + { + uint32_t mOffset; + uint32_t mLength; + } mInput; + struct + { + void* mContentsRoot; + uint32_t mOffset; + nsString mString; + // Finally, the coordinates is system coordinates. + nsIntRect mRect; + // The return widget has the caret. This is set at all query events. + nsIWidget* mFocusedWidget; + // true if selection is reversed (end < start) + bool mReversed; + // true if the selection exists + bool mHasSelection; + // true if DOM element under mouse belongs to widget + bool mWidgetIsHit; + // used by NS_QUERY_SELECTION_AS_TRANSFERABLE + nsCOMPtr mTransferable; + } mReply; + + enum + { + NOT_FOUND = UINT32_MAX + }; + + // values of mComputedScrollAction + enum + { + SCROLL_ACTION_NONE, + SCROLL_ACTION_LINE, + SCROLL_ACTION_PAGE + }; +}; + +/****************************************************************************** + * mozilla::WidgetSelectionEvent + ******************************************************************************/ + +class WidgetSelectionEvent : public WidgetGUIEvent +{ +private: + friend class mozilla::dom::PBrowserParent; + friend class mozilla::dom::PBrowserChild; + + WidgetSelectionEvent() + { + MOZ_CRASH("WidgetSelectionEvent is created without proper arguments"); + } + +public: + uint32_t seqno; + +public: + WidgetSelectionEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) : + WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_SELECTION_EVENT), + mExpandToClusterBoundary(true), mSucceeded(false) + { + } + + // Start offset of selection + uint32_t mOffset; + // Length of selection + uint32_t mLength; + // Selection "anchor" should be in front + bool mReversed; + // Cluster-based or character-based + bool mExpandToClusterBoundary; + // true if setting selection succeeded. + bool mSucceeded; +}; + +} // namespace mozilla + +// TODO: Remove following typedefs +typedef mozilla::AlternativeCharCode nsAlternativeCharCode; +typedef mozilla::WidgetKeyboardEvent nsKeyEvent; +typedef mozilla::TextRangeStyle nsTextRangeStyle; +typedef mozilla::TextRange nsTextRange; +typedef mozilla::TextRangeArray nsTextRangeArray; +typedef mozilla::WidgetTextEvent nsTextEvent; +typedef mozilla::WidgetCompositionEvent nsCompositionEvent; +typedef mozilla::WidgetQueryContentEvent nsQueryContentEvent; +typedef mozilla::WidgetSelectionEvent nsSelectionEvent; + +#endif // mozilla_TextEvents_h__ diff --git a/widget/moz.build b/widget/moz.build index 7a2104f2e550..862f7b4b1db8 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -114,6 +114,7 @@ EXPORTS.mozilla += [ 'BasicEvents.h', 'EventForwards.h', 'LookAndFeel.h', + 'TextEvents.h', 'WidgetUtils.h', ] diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h index f16d833c8e03..eb19b5a7a976 100644 --- a/widget/nsGUIEvent.h +++ b/widget/nsGUIEvent.h @@ -8,17 +8,15 @@ #include "mozilla/BasicEvents.h" #include "mozilla/MathAlgorithms.h" +#include "mozilla/TextEvents.h" #include "nsPoint.h" #include "nsRect.h" -#include "nsIDOMKeyEvent.h" #include "nsIDOMMouseEvent.h" #include "nsIDOMWheelEvent.h" #include "nsIDOMDataTransfer.h" #include "nsWeakPtr.h" -#include "nsTArray.h" #include "nsITransferable.h" -#include "nsStyleConsts.h" #include "nsAutoPtr.h" #include "mozilla/dom/Touch.h" @@ -300,296 +298,6 @@ public: } }; -/** - * Keyboard event - */ - -struct nsAlternativeCharCode { - nsAlternativeCharCode(uint32_t aUnshiftedCharCode, - uint32_t aShiftedCharCode) : - mUnshiftedCharCode(aUnshiftedCharCode), mShiftedCharCode(aShiftedCharCode) - { - } - uint32_t mUnshiftedCharCode; - uint32_t mShiftedCharCode; -}; - -class nsKeyEvent : public nsInputEvent -{ -private: - friend class mozilla::dom::PBrowserParent; - friend class mozilla::dom::PBrowserChild; - -public: - nsKeyEvent() - { - } - - nsKeyEvent(bool isTrusted, uint32_t msg, nsIWidget *w) - : nsInputEvent(isTrusted, msg, w, NS_KEY_EVENT), - keyCode(0), charCode(0), - location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD), isChar(0), - mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified), - mNativeKeyEvent(nullptr), - mUniqueId(0) - { - } - - /// see NS_VK codes - uint32_t keyCode; - /// OS translated Unicode char - uint32_t charCode; - // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_* - uint32_t location; - // OS translated Unicode chars which are used for accesskey and accelkey - // handling. The handlers will try from first character to last character. - nsTArray alternativeCharCodes; - // indicates whether the event signifies a printable character - bool isChar; - // DOM KeyboardEvent.key - mozilla::KeyNameIndex mKeyNameIndex; - // OS-specific native event can optionally be preserved - void* mNativeKeyEvent; - // Unique id associated with a keydown / keypress event. Used in identifing - // keypress events for removal from async event dispatch queue in metrofx - // after preventDefault is called on keydown events. It's ok if this wraps - // over long periods. - uint32_t mUniqueId; - - void GetDOMKeyName(nsAString& aKeyName) - { - GetDOMKeyName(mKeyNameIndex, aKeyName); - } - - static void GetDOMKeyName(mozilla::KeyNameIndex aKeyNameIndex, - nsAString& aKeyName) - { -#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \ - case mozilla::KEY_NAME_INDEX_##aCPPName: \ - aKeyName.Assign(NS_LITERAL_STRING(aDOMKeyName)); return; - switch (aKeyNameIndex) { -#include "nsDOMKeyNameList.h" - default: - aKeyName.Truncate(); - return; - } -#undef NS_DEFINE_KEYNAME - } - - void AssignKeyEventData(const nsKeyEvent& aEvent, bool aCopyTargets) - { - AssignInputEventData(aEvent, aCopyTargets); - - keyCode = aEvent.keyCode; - charCode = aEvent.charCode; - location = aEvent.location; - alternativeCharCodes = aEvent.alternativeCharCodes; - isChar = aEvent.isChar; - mKeyNameIndex = aEvent.mKeyNameIndex; - // Don't copy mNativeKeyEvent because it may be referred after its instance - // is destroyed. - mNativeKeyEvent = nullptr; - mUniqueId = aEvent.mUniqueId; - } -}; - -/** - * IME Related Events - */ - -struct nsTextRangeStyle -{ - enum { - LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, - LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, - LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, - LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, - LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, - LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY - }; - - enum { - DEFINED_NONE = 0x00, - DEFINED_LINESTYLE = 0x01, - DEFINED_FOREGROUND_COLOR = 0x02, - DEFINED_BACKGROUND_COLOR = 0x04, - DEFINED_UNDERLINE_COLOR = 0x08 - }; - - // Initialize all members, because nsTextRange instances may be compared by - // memcomp. - nsTextRangeStyle() - { - Clear(); - } - - void Clear() - { - mDefinedStyles = DEFINED_NONE; - mLineStyle = LINESTYLE_NONE; - mIsBoldLine = false; - mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); - } - - bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } - - bool IsLineStyleDefined() const - { - return (mDefinedStyles & DEFINED_LINESTYLE) != 0; - } - - bool IsForegroundColorDefined() const - { - return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; - } - - bool IsBackgroundColorDefined() const - { - return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; - } - - bool IsUnderlineColorDefined() const - { - return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; - } - - bool IsNoChangeStyle() const - { - return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && - IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; - } - - bool Equals(const nsTextRangeStyle& aOther) - { - if (mDefinedStyles != aOther.mDefinedStyles) - return false; - if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || - !mIsBoldLine != !aOther.mIsBoldLine)) - return false; - if (IsForegroundColorDefined() && - (mForegroundColor != aOther.mForegroundColor)) - return false; - if (IsBackgroundColorDefined() && - (mBackgroundColor != aOther.mBackgroundColor)) - return false; - if (IsUnderlineColorDefined() && - (mUnderlineColor != aOther.mUnderlineColor)) - return false; - return true; - } - - bool operator !=(const nsTextRangeStyle &aOther) - { - return !Equals(aOther); - } - - bool operator ==(const nsTextRangeStyle &aOther) - { - return Equals(aOther); - } - - uint8_t mDefinedStyles; - uint8_t mLineStyle; // DEFINED_LINESTYLE - - bool mIsBoldLine; // DEFINED_LINESTYLE - - nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR - nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR - nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR -}; - -struct nsTextRange -{ - nsTextRange() - : mStartOffset(0), mEndOffset(0), mRangeType(0) - { - } - - uint32_t mStartOffset; - uint32_t mEndOffset; - uint32_t mRangeType; - - nsTextRangeStyle mRangeStyle; - - uint32_t Length() const { return mEndOffset - mStartOffset; } -}; - -typedef nsTextRange* nsTextRangeArray; - -class nsTextEvent : public nsGUIEvent -{ -private: - friend class mozilla::dom::PBrowserParent; - friend class mozilla::dom::PBrowserChild; - friend class mozilla::plugins::PPluginInstanceChild; - - nsTextEvent() - { - } - -public: - uint32_t seqno; - -public: - nsTextEvent(bool isTrusted, uint32_t msg, nsIWidget *w) - : nsGUIEvent(isTrusted, msg, w, NS_TEXT_EVENT), - rangeCount(0), rangeArray(nullptr), isChar(false) - { - } - - nsString theText; - uint32_t rangeCount; - // Note that the range array may not specify a caret position; in that - // case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the - // array. - nsTextRangeArray rangeArray; - bool isChar; - - void AssignTextEventData(const nsTextEvent& aEvent, bool aCopyTargets) - { - AssignGUIEventData(aEvent, aCopyTargets); - - isChar = aEvent.isChar; - - // Currently, we don't need to copy the other members because they are - // for internal use only (not available from JS). - } -}; - -class nsCompositionEvent : public nsGUIEvent -{ -private: - friend class mozilla::dom::PBrowserParent; - friend class mozilla::dom::PBrowserChild; - - nsCompositionEvent() - { - } - -public: - uint32_t seqno; - -public: - nsCompositionEvent(bool isTrusted, uint32_t msg, nsIWidget *w) - : nsGUIEvent(isTrusted, msg, w, NS_COMPOSITION_EVENT) - { - // XXX compositionstart is cancelable in draft of DOM3 Events. - // However, it doesn't make sense for us, we cannot cancel composition - // when we send compositionstart event. - mFlags.mCancelable = false; - } - - nsString data; - - void AssignCompositionEventData(const nsCompositionEvent& aEvent, - bool aCopyTargets) - { - AssignGUIEventData(aEvent, aCopyTargets); - - data = aEvent.data; - } -}; - /** * nsMouseScrollEvent is used for legacy DOM mouse scroll events, i.e., * DOMMouseScroll and MozMousePixelScroll event. These events are NOT hanbled @@ -779,128 +487,6 @@ public: } }; -class nsQueryContentEvent : public nsGUIEvent -{ -private: - friend class mozilla::dom::PBrowserParent; - friend class mozilla::dom::PBrowserChild; - - nsQueryContentEvent() - { - mReply.mContentsRoot = nullptr; - mReply.mFocusedWidget = nullptr; - } - -public: - nsQueryContentEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget) : - nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_QUERY_CONTENT_EVENT), - mSucceeded(false), mWasAsync(false) - { - } - - void InitForQueryTextContent(uint32_t aOffset, uint32_t aLength) - { - NS_ASSERTION(message == NS_QUERY_TEXT_CONTENT, - "wrong initializer is called"); - mInput.mOffset = aOffset; - mInput.mLength = aLength; - } - - void InitForQueryCaretRect(uint32_t aOffset) - { - NS_ASSERTION(message == NS_QUERY_CARET_RECT, - "wrong initializer is called"); - mInput.mOffset = aOffset; - } - - void InitForQueryTextRect(uint32_t aOffset, uint32_t aLength) - { - NS_ASSERTION(message == NS_QUERY_TEXT_RECT, - "wrong initializer is called"); - mInput.mOffset = aOffset; - mInput.mLength = aLength; - } - - void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint& aPoint) - { - NS_ASSERTION(message == NS_QUERY_DOM_WIDGET_HITTEST, - "wrong initializer is called"); - refPoint = aPoint; - } - - uint32_t GetSelectionStart(void) const - { - NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT, - "not querying selection"); - return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0); - } - - uint32_t GetSelectionEnd(void) const - { - NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT, - "not querying selection"); - return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length()); - } - - bool mSucceeded; - bool mWasAsync; - struct { - uint32_t mOffset; - uint32_t mLength; - } mInput; - struct { - void* mContentsRoot; - uint32_t mOffset; - nsString mString; - nsIntRect mRect; // Finally, the coordinates is system coordinates. - // The return widget has the caret. This is set at all query events. - nsIWidget* mFocusedWidget; - bool mReversed; // true if selection is reversed (end < start) - bool mHasSelection; // true if the selection exists - bool mWidgetIsHit; // true if DOM element under mouse belongs to widget - // used by NS_QUERY_SELECTION_AS_TRANSFERABLE - nsCOMPtr mTransferable; - } mReply; - - enum { - NOT_FOUND = UINT32_MAX - }; - - // values of mComputedScrollAction - enum { - SCROLL_ACTION_NONE, - SCROLL_ACTION_LINE, - SCROLL_ACTION_PAGE - }; -}; - -class nsSelectionEvent : public nsGUIEvent -{ -private: - friend class mozilla::dom::PBrowserParent; - friend class mozilla::dom::PBrowserChild; - - nsSelectionEvent() - { - } - -public: - uint32_t seqno; - -public: - nsSelectionEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget) : - nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_SELECTION_EVENT), - mExpandToClusterBoundary(true), mSucceeded(false) - { - } - - uint32_t mOffset; // start offset of selection - uint32_t mLength; // length of selection - bool mReversed; // selection "anchor" should be in front - bool mExpandToClusterBoundary; // cluster-based or character-based - bool mSucceeded; -}; - class nsContentCommandEvent : public nsGUIEvent { public: @@ -1295,26 +881,6 @@ enum nsDragDropEventStatus { NS_IS_QUERY_CONTENT_EVENT(evnt) || \ NS_IS_SELECTION_EVENT(evnt)) -/* - * Virtual key bindings for keyboard events. - * These come from nsIDOMKeyEvent.h, which is generated from MouseKeyEvent.idl. - * Really, it would be better if we phased out the NS_VK symbols altogether - * in favor of the DOM ones, but at least this way they'll be in sync. - */ - -enum { -#define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode -#include "nsVKList.h" -#undef NS_DEFINE_VK -}; - -// IME Constants -- keep in synch with nsIPrivateTextRange.h -#define NS_TEXTRANGE_CARETPOSITION 0x01 -#define NS_TEXTRANGE_RAWINPUT 0x02 -#define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 -#define NS_TEXTRANGE_CONVERTEDTEXT 0x04 -#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 - /** * Whether the event should be handled by the frame of the mouse cursor * position or not. When it should be handled there (e.g., the mouse events),