From 1788d13287cd0726622096fafc70f588827cf523 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 30 Aug 2013 11:10:32 +0900 Subject: [PATCH] Bug 910156 Add AssignKeyEventData() and AssignMouseEventData() for sharing the code in nsDOMEvent::DuplicatePrivateData() and nsDelayed*Event r=smaug --- content/events/src/nsDOMEvent.cpp | 176 ++++++++++-------- layout/base/nsPresShell.h | 17 +- widget/nsGUIEvent.h | 68 +++++++ widget/tests/Makefile.in | 1 + widget/tests/test_assign_event_data.html | 219 +++++++++++++++++++++++ 5 files changed, 389 insertions(+), 92 deletions(-) create mode 100644 widget/tests/test_assign_event_data.html diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index c8615f0bf99..e2e1cf59937 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -500,43 +500,47 @@ nsDOMEvent::DuplicatePrivateData() nsEvent* newEvent = nullptr; uint32_t msg = mEvent->message; - bool isInputEvent = false; switch (mEvent->eventStructType) { case NS_EVENT: { newEvent = new nsEvent(false, msg); + newEvent->AssignEventData(*mEvent, true); break; } case NS_GUI_EVENT: { + nsGUIEvent* oldGUIEvent = static_cast(mEvent); // Not copying widget, it is a weak reference. - newEvent = new nsGUIEvent(false, msg, nullptr); + nsGUIEvent* guiEvent = new nsGUIEvent(false, msg, nullptr); + guiEvent->AssignGUIEventData(*oldGUIEvent, true); + newEvent = guiEvent; break; } case NS_SCROLLBAR_EVENT: { - newEvent = new nsScrollbarEvent(false, msg, nullptr); - static_cast(newEvent)->position = - static_cast(mEvent)->position; + nsScrollbarEvent* oldScrollbarEvent = + static_cast(mEvent); + nsScrollbarEvent* scrollbarEvent = + new nsScrollbarEvent(false, msg, nullptr); + scrollbarEvent->AssignGUIEventData(*scrollbarEvent, true); + scrollbarEvent->position = oldScrollbarEvent->position; + newEvent = scrollbarEvent; break; } case NS_INPUT_EVENT: { - newEvent = new nsInputEvent(false, msg, nullptr); - isInputEvent = true; + nsInputEvent* oldInputEvent = static_cast(mEvent); + nsInputEvent* inputEvent = new nsInputEvent(false, msg, nullptr); + inputEvent->AssignInputEventData(*oldInputEvent, true); + newEvent = inputEvent; break; } case NS_KEY_EVENT: { - nsKeyEvent* keyEvent = new nsKeyEvent(false, msg, nullptr); nsKeyEvent* oldKeyEvent = static_cast(mEvent); - isInputEvent = true; - keyEvent->keyCode = oldKeyEvent->keyCode; - keyEvent->charCode = oldKeyEvent->charCode; - keyEvent->location = oldKeyEvent->location; - keyEvent->isChar = oldKeyEvent->isChar; - keyEvent->mKeyNameIndex = oldKeyEvent->mKeyNameIndex; + nsKeyEvent* keyEvent = new nsKeyEvent(false, msg, nullptr); + keyEvent->AssignKeyEventData(*oldKeyEvent, true); newEvent = keyEvent; break; } @@ -545,15 +549,7 @@ nsDOMEvent::DuplicatePrivateData() nsMouseEvent* oldMouseEvent = static_cast(mEvent); nsMouseEvent* mouseEvent = new nsMouseEvent(false, msg, nullptr, oldMouseEvent->reason); - isInputEvent = true; - mouseEvent->clickCount = oldMouseEvent->clickCount; - mouseEvent->acceptActivation = oldMouseEvent->acceptActivation; - mouseEvent->context = oldMouseEvent->context; - mouseEvent->relatedTarget = oldMouseEvent->relatedTarget; - mouseEvent->button = oldMouseEvent->button; - mouseEvent->buttons = oldMouseEvent->buttons; - mouseEvent->pressure = oldMouseEvent->pressure; - mouseEvent->inputSource = oldMouseEvent->inputSource; + mouseEvent->AssignMouseEventData(*oldMouseEvent, true); newEvent = mouseEvent; break; } @@ -562,7 +558,7 @@ nsDOMEvent::DuplicatePrivateData() nsDragEvent* oldDragEvent = static_cast(mEvent); nsDragEvent* dragEvent = new nsDragEvent(false, msg, nullptr); - isInputEvent = true; + dragEvent->AssignInputEventData(*oldDragEvent, true); dragEvent->dataTransfer = oldDragEvent->dataTransfer; dragEvent->clickCount = oldDragEvent->clickCount; dragEvent->acceptActivation = oldDragEvent->acceptActivation; @@ -578,21 +574,27 @@ nsDOMEvent::DuplicatePrivateData() { nsClipboardEvent* oldClipboardEvent = static_cast(mEvent); nsClipboardEvent* clipboardEvent = new nsClipboardEvent(false, msg); + clipboardEvent->AssignEventData(*oldClipboardEvent, true); clipboardEvent->clipboardData = oldClipboardEvent->clipboardData; newEvent = clipboardEvent; break; } case NS_SCRIPT_ERROR_EVENT: { - newEvent = new nsScriptErrorEvent(false, msg); - static_cast(newEvent)->lineNr = - static_cast(mEvent)->lineNr; + nsScriptErrorEvent* oldScriptErrorEvent = + static_cast(mEvent); + nsScriptErrorEvent* scriptErrorEvent = new nsScriptErrorEvent(false, msg); + scriptErrorEvent->AssignEventData(*oldScriptErrorEvent, true); + scriptErrorEvent->lineNr = oldScriptErrorEvent->lineNr; + newEvent = scriptErrorEvent; break; } case NS_TEXT_EVENT: { - newEvent = new nsTextEvent(false, msg, nullptr); - isInputEvent = true; + nsTextEvent* oldTextEvent = static_cast(mEvent); + nsTextEvent* textEvent = new nsTextEvent(false, msg, nullptr); + textEvent->AssignGUIEventData(*oldTextEvent, true); + newEvent = textEvent; break; } case NS_COMPOSITION_EVENT: @@ -601,17 +603,18 @@ nsDOMEvent::DuplicatePrivateData() new nsCompositionEvent(false, msg, nullptr); nsCompositionEvent* oldCompositionEvent = static_cast(mEvent); + compositionEvent->AssignGUIEventData(*oldCompositionEvent, true); compositionEvent->data = oldCompositionEvent->data; newEvent = compositionEvent; break; } case NS_MOUSE_SCROLL_EVENT: { - nsMouseScrollEvent* mouseScrollEvent = - new nsMouseScrollEvent(false, msg, nullptr); - isInputEvent = true; nsMouseScrollEvent* oldMouseScrollEvent = static_cast(mEvent); + nsMouseScrollEvent* mouseScrollEvent = + new nsMouseScrollEvent(false, msg, nullptr); + mouseScrollEvent->AssignInputEventData(*oldMouseScrollEvent, true); mouseScrollEvent->isHorizontal = oldMouseScrollEvent->isHorizontal; mouseScrollEvent->delta = oldMouseScrollEvent->delta; mouseScrollEvent->relatedTarget = oldMouseScrollEvent->relatedTarget; @@ -624,11 +627,11 @@ nsDOMEvent::DuplicatePrivateData() } case NS_WHEEL_EVENT: { - widget::WheelEvent* wheelEvent = - new widget::WheelEvent(false, msg, nullptr); - isInputEvent = true; widget::WheelEvent* oldWheelEvent = static_cast(mEvent); + widget::WheelEvent* wheelEvent = + new widget::WheelEvent(false, msg, nullptr); + wheelEvent->AssignInputEventData(*oldWheelEvent, true); wheelEvent->deltaX = oldWheelEvent->deltaX; wheelEvent->deltaY = oldWheelEvent->deltaY; wheelEvent->deltaZ = oldWheelEvent->deltaZ; @@ -651,18 +654,24 @@ nsDOMEvent::DuplicatePrivateData() } case NS_SCROLLPORT_EVENT: { - newEvent = new nsScrollPortEvent(false, msg, nullptr); - static_cast(newEvent)->orient = - static_cast(mEvent)->orient; + nsScrollPortEvent* oldScrollPortEvent = + static_cast(mEvent); + nsScrollPortEvent* scrollPortEvent = + new nsScrollPortEvent(false, msg, nullptr); + scrollPortEvent->AssignGUIEventData(*oldScrollPortEvent, true); + scrollPortEvent->orient = oldScrollPortEvent->orient; + newEvent = scrollPortEvent; break; } case NS_SCROLLAREA_EVENT: { - nsScrollAreaEvent *newScrollAreaEvent = + nsScrollAreaEvent* oldScrollAreaEvent = + static_cast(mEvent); + nsScrollAreaEvent* scrollAreaEvent = new nsScrollAreaEvent(false, msg, nullptr); - newScrollAreaEvent->mArea = - static_cast(mEvent)->mArea; - newEvent = newScrollAreaEvent; + scrollAreaEvent->AssignGUIEventData(*oldScrollAreaEvent, true); + scrollAreaEvent->mArea = oldScrollAreaEvent->mArea; + newEvent = scrollAreaEvent; break; } case NS_MUTATION_EVENT: @@ -670,6 +679,7 @@ nsDOMEvent::DuplicatePrivateData() nsMutationEvent* mutationEvent = new nsMutationEvent(false, msg); nsMutationEvent* oldMutationEvent = static_cast(mEvent); + mutationEvent->AssignEventData(*oldMutationEvent, true); mutationEvent->mRelatedNode = oldMutationEvent->mRelatedNode; mutationEvent->mAttrName = oldMutationEvent->mAttrName; mutationEvent->mPrevAttrValue = oldMutationEvent->mPrevAttrValue; @@ -680,13 +690,17 @@ nsDOMEvent::DuplicatePrivateData() } case NS_FORM_EVENT: { - newEvent = new nsFormEvent(false, msg); + nsFormEvent* oldFormEvent = static_cast(mEvent); + nsFormEvent* formEvent = new nsFormEvent(false, msg); + formEvent->AssignEventData(*oldFormEvent, true); + newEvent = formEvent; break; } case NS_FOCUS_EVENT: { nsFocusEvent* newFocusEvent = new nsFocusEvent(false, msg); nsFocusEvent* oldFocusEvent = static_cast(mEvent); + newFocusEvent->AssignGUIEventData(*oldFocusEvent, true); newFocusEvent->fromRaise = oldFocusEvent->fromRaise; newFocusEvent->isRefocus = oldFocusEvent->isRefocus; newEvent = newFocusEvent; @@ -694,34 +708,47 @@ nsDOMEvent::DuplicatePrivateData() } case NS_COMMAND_EVENT: { - newEvent = new nsCommandEvent(false, mEvent->userType, - static_cast(mEvent)->command, nullptr); + nsCommandEvent* oldCommandEvent = static_cast(mEvent); + nsCommandEvent* commandEvent = + new nsCommandEvent(false, mEvent->userType, + oldCommandEvent->command, nullptr); + commandEvent->AssignGUIEventData(*oldCommandEvent, true); + newEvent = commandEvent; break; } case NS_UI_EVENT: { - newEvent = new nsUIEvent(false, msg, - static_cast(mEvent)->detail); + nsUIEvent* oldUIEvent = static_cast(mEvent); + nsUIEvent* uiEvent = new nsUIEvent(false, msg, oldUIEvent->detail); + uiEvent->AssignEventData(*oldUIEvent, true); + newEvent = uiEvent; break; } case NS_SVGZOOM_EVENT: { - newEvent = new nsGUIEvent(false, msg, nullptr); - newEvent->eventStructType = NS_SVGZOOM_EVENT; + nsGUIEvent* oldGUIEvent = static_cast(mEvent); + nsGUIEvent* guiEvent = new nsGUIEvent(false, msg, nullptr); + guiEvent->eventStructType = NS_SVGZOOM_EVENT; + guiEvent->AssignGUIEventData(*oldGUIEvent, true); + newEvent = guiEvent; break; } case NS_SMIL_TIME_EVENT: { - newEvent = new nsUIEvent(false, msg, 0); - newEvent->eventStructType = NS_SMIL_TIME_EVENT; + nsUIEvent* oldUIEvent = static_cast(mEvent); + nsUIEvent* uiEvent = new nsUIEvent(false, msg, 0); + uiEvent->eventStructType = NS_SMIL_TIME_EVENT; + uiEvent->AssignGUIEventData(*oldUIEvent, true); + newEvent = uiEvent; break; } case NS_SIMPLE_GESTURE_EVENT: { - nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast(mEvent); + nsSimpleGestureEvent* oldSimpleGestureEvent = + static_cast(mEvent); nsSimpleGestureEvent* simpleGestureEvent = new nsSimpleGestureEvent(false, msg, nullptr, 0, 0.0); - isInputEvent = true; + simpleGestureEvent->AssignInputEventData(*oldSimpleGestureEvent, true); simpleGestureEvent->direction = oldSimpleGestureEvent->direction; simpleGestureEvent->delta = oldSimpleGestureEvent->delta; simpleGestureEvent->clickCount = oldSimpleGestureEvent->clickCount; @@ -732,27 +759,34 @@ nsDOMEvent::DuplicatePrivateData() { nsTransitionEvent* oldTransitionEvent = static_cast(mEvent); - newEvent = new nsTransitionEvent(false, msg, - oldTransitionEvent->propertyName, - oldTransitionEvent->elapsedTime, - oldTransitionEvent->pseudoElement); + nsTransitionEvent* transitionEvent = + new nsTransitionEvent(false, msg, + oldTransitionEvent->propertyName, + oldTransitionEvent->elapsedTime, + oldTransitionEvent->pseudoElement); + transitionEvent->AssignEventData(*oldTransitionEvent, true); + newEvent = transitionEvent; break; } case NS_ANIMATION_EVENT: { nsAnimationEvent* oldAnimationEvent = static_cast(mEvent); - newEvent = new nsAnimationEvent(false, msg, - oldAnimationEvent->animationName, - oldAnimationEvent->elapsedTime, - oldAnimationEvent->pseudoElement); + nsAnimationEvent* animationEvent = + new nsAnimationEvent(false, msg, + oldAnimationEvent->animationName, + oldAnimationEvent->elapsedTime, + oldAnimationEvent->pseudoElement); + animationEvent->AssignEventData(*oldAnimationEvent, true); + newEvent = animationEvent; break; } case NS_TOUCH_EVENT: { - nsTouchEvent *oldTouchEvent = static_cast(mEvent); - newEvent = new nsTouchEvent(false, oldTouchEvent); - isInputEvent = true; + nsTouchEvent* oldTouchEvent = static_cast(mEvent); + nsTouchEvent* touchEvent = new nsTouchEvent(false, oldTouchEvent); + touchEvent->AssignInputEventData(*oldTouchEvent, true); + newEvent = touchEvent; break; } default: @@ -762,19 +796,7 @@ nsDOMEvent::DuplicatePrivateData() } } - if (isInputEvent) { - nsInputEvent* oldInputEvent = static_cast(mEvent); - nsInputEvent* newInputEvent = static_cast(newEvent); - newInputEvent->modifiers = oldInputEvent->modifiers; - } - - newEvent->target = mEvent->target; - newEvent->currentTarget = mEvent->currentTarget; - newEvent->originalTarget = mEvent->originalTarget; - newEvent->mFlags = mEvent->mFlags; - newEvent->time = mEvent->time; - newEvent->refPoint = mEvent->refPoint; - newEvent->userType = mEvent->userType; + newEvent->mFlags = mEvent->mFlags; mEvent = newEvent; mPresContext = nullptr; diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 8d9ce0bbea9..82acdd83ebf 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -556,13 +556,6 @@ protected: } protected: - void Init(nsInputEvent* aEvent) - { - mEvent->time = aEvent->time; - mEvent->refPoint = aEvent->refPoint; - mEvent->modifiers = aEvent->modifiers; - } - nsDelayedInputEvent() : nsDelayedEvent(), mEvent(nullptr) {} @@ -579,8 +572,7 @@ protected: aEvent->widget, aEvent->reason, aEvent->context); - Init(aEvent); - static_cast(mEvent)->clickCount = aEvent->clickCount; + static_cast(mEvent)->AssignMouseEventData(*aEvent, false); } virtual ~nsDelayedMouseEvent() @@ -597,12 +589,7 @@ protected: mEvent = new nsKeyEvent(aEvent->mFlags.mIsTrusted, aEvent->message, aEvent->widget); - Init(aEvent); - static_cast(mEvent)->keyCode = aEvent->keyCode; - static_cast(mEvent)->charCode = aEvent->charCode; - static_cast(mEvent)->alternativeCharCodes = - aEvent->alternativeCharCodes; - static_cast(mEvent)->isChar = aEvent->isChar; + static_cast(mEvent)->AssignKeyEventData(*aEvent, false); } virtual ~nsDelayedKeyEvent() diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h index 4c2005eb5e3..90b9356fb4f 100644 --- a/widget/nsGUIEvent.h +++ b/widget/nsGUIEvent.h @@ -692,6 +692,20 @@ public: nsCOMPtr target; nsCOMPtr currentTarget; nsCOMPtr originalTarget; + + void AssignEventData(const nsEvent& aEvent, bool aCopyTargets) + { + // eventStructType, message should be initialized with the constructor. + refPoint = aEvent.refPoint; + // lastRefPoint doesn't need to be copied. + time = aEvent.time; + // mFlags should be copied manually if it's necessary. + userType = aEvent.userType; + // typeString should be copied manually if it's necessary. + target = aCopyTargets ? aEvent.target : nullptr; + currentTarget = aCopyTargets ? aEvent.currentTarget : nullptr; + originalTarget = aCopyTargets ? aEvent.originalTarget : nullptr; + } }; /** @@ -725,6 +739,17 @@ public: /// Event for NPAPI plugin void* pluginEvent; + + void AssignGUIEventData(const nsGUIEvent& aEvent, bool aCopyTargets) + { + AssignEventData(aEvent, aCopyTargets); + + // widget should be initialized with the constructor. + + // pluginEvent shouldn't be copied because it may be referred after its + // instance is destroyed. + pluginEvent = nullptr; + } }; /** @@ -894,6 +919,13 @@ public: } mozilla::widget::Modifiers modifiers; + + void AssignInputEventData(const nsInputEvent& aEvent, bool aCopyTargets) + { + AssignGUIEventData(aEvent, aCopyTargets); + + modifiers = aEvent.modifiers; + } }; /** @@ -929,6 +961,18 @@ public: // Possible values at nsIDOMMouseEvent uint16_t inputSource; + + void AssignMouseEventBaseData(const nsMouseEvent_base& aEvent, + bool aCopyTargets) + { + AssignInputEventData(aEvent, aCopyTargets); + + relatedTarget = aCopyTargets ? aEvent.relatedTarget : nullptr; + button = aEvent.button; + buttons = aEvent.buttons; + pressure = aEvent.pressure; + inputSource = aEvent.inputSource; + } }; class nsMouseEvent : public nsMouseEvent_base @@ -1024,6 +1068,15 @@ public: /// The number of mouse clicks uint32_t clickCount; + + void AssignMouseEventData(const nsMouseEvent& aEvent, bool aCopyTargets) + { + AssignMouseEventBaseData(aEvent, aCopyTargets); + + acceptActivation = aEvent.acceptActivation; + ignoreRootScrollFrame = aEvent.ignoreRootScrollFrame; + clickCount = aEvent.clickCount; + } }; /** @@ -1116,6 +1169,21 @@ public: } #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; + } }; /** diff --git a/widget/tests/Makefile.in b/widget/tests/Makefile.in index d90c64376d4..815643f032d 100644 --- a/widget/tests/Makefile.in +++ b/widget/tests/Makefile.in @@ -50,6 +50,7 @@ MOCHITEST_CHROME_FILES = test_bug343416.xul \ empty_window.xul \ test_sizemode_events.xul \ test_bug760802.xul \ + test_assign_event_data.html \ $(NULL) # test_bug413277.html mac-only based on 604789, 605178 diff --git a/widget/tests/test_assign_event_data.html b/widget/tests/test_assign_event_data.html new file mode 100644 index 00000000000..42e168f05e9 --- /dev/null +++ b/widget/tests/test_assign_event_data.html @@ -0,0 +1,219 @@ + + + + Testing ns*Event::Assign*EventData() + + + + + + + +
+ + +
+ +
+
+ + +