mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 378028. Add an 'axis' field to DOMMouseScroll events so that we can distinguish horizontal from vertical scrolling, and use it in trees and listboxes. r=smaug,sr=sicking
This commit is contained in:
parent
9d6e86ec20
commit
52086cd743
@ -39,9 +39,6 @@
|
||||
#endif
|
||||
*/
|
||||
|
||||
// From nsMouseScrollEvent::kIsHorizontal
|
||||
const MOUSE_SCROLL_IS_HORIZONTAL = 1 << 2;
|
||||
|
||||
// One of the possible values for the mousewheel.* preferences.
|
||||
// From nsEventStateManager.cpp.
|
||||
const MOUSE_SCROLL_ZOOM = 3;
|
||||
@ -148,7 +145,7 @@ var FullZoom = {
|
||||
// Construct the "mousewheel action" pref key corresponding to this event.
|
||||
// Based on nsEventStateManager::GetBasePrefKeyForMouseWheel.
|
||||
var pref = "mousewheel";
|
||||
if (event.scrollFlags & MOUSE_SCROLL_IS_HORIZONTAL)
|
||||
if (event.axis == event.HORIZONTAL_AXIS)
|
||||
pref += ".horizscroll";
|
||||
|
||||
if (event.shiftKey)
|
||||
|
@ -81,6 +81,8 @@ NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext,
|
||||
nsresult
|
||||
NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
|
||||
|
@ -75,6 +75,7 @@ CPPSRCS = \
|
||||
nsDOMKeyboardEvent.cpp \
|
||||
nsDOMTextEvent.cpp \
|
||||
nsDOMMouseEvent.cpp \
|
||||
nsDOMMouseScrollEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMPopupBlockedEvent.cpp \
|
||||
nsDOMBeforeUnloadEvent.cpp \
|
||||
|
@ -67,9 +67,6 @@ nsDOMMouseEvent::nsDOMMouseEvent(nsPresContext* aPresContext,
|
||||
case NS_MOUSE_EVENT:
|
||||
mDetail = static_cast<nsMouseEvent*>(mEvent)->clickCount;
|
||||
break;
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
mDetail = static_cast<nsMouseScrollEvent*>(mEvent)->delta;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -77,15 +74,12 @@ nsDOMMouseEvent::nsDOMMouseEvent(nsPresContext* aPresContext,
|
||||
|
||||
nsDOMMouseEvent::~nsDOMMouseEvent()
|
||||
{
|
||||
if (mEventIsInternal) {
|
||||
if (mEventIsInternal && mEvent) {
|
||||
switch (mEvent->eventStructType)
|
||||
{
|
||||
case NS_MOUSE_EVENT:
|
||||
delete static_cast<nsMouseEvent*>(mEvent);
|
||||
break;
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
delete static_cast<nsMouseScrollEvent*>(mEvent);
|
||||
break;
|
||||
default:
|
||||
delete mEvent;
|
||||
break;
|
||||
@ -129,10 +123,7 @@ nsDOMMouseEvent::InitMouseEvent(const nsAString & aType, PRBool aCanBubble, PRBo
|
||||
inputEvent->refPoint.x = aScreenX;
|
||||
inputEvent->refPoint.y = aScreenY;
|
||||
|
||||
if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
nsMouseScrollEvent* scrollEvent = static_cast<nsMouseScrollEvent*>(mEvent);
|
||||
scrollEvent->delta = aDetail;
|
||||
} else {
|
||||
if (mEvent->eventStructType == NS_MOUSE_EVENT) {
|
||||
nsMouseEvent* mouseEvent = static_cast<nsMouseEvent*>(mEvent);
|
||||
mouseEvent->clickCount = aDetail;
|
||||
}
|
||||
|
@ -65,4 +65,8 @@ public:
|
||||
NS_IMETHOD GetWhich(PRUint32 *aWhich);
|
||||
};
|
||||
|
||||
#define NS_FORWARD_TO_NSDOMMOUSEEVENT \
|
||||
NS_FORWARD_NSIDOMMOUSEEVENT(nsDOMMouseEvent::) \
|
||||
NS_FORWARD_TO_NSDOMUIEVENT
|
||||
|
||||
#endif // nsDOMMouseEvent_h__
|
||||
|
127
content/events/src/nsDOMMouseScrollEvent.cpp
Normal file
127
content/events/src/nsDOMMouseScrollEvent.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Markus Stange <mstange@themasta.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMMouseScrollEvent.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
nsDOMMouseScrollEvent::nsDOMMouseScrollEvent(nsPresContext* aPresContext,
|
||||
nsInputEvent* aEvent)
|
||||
: nsDOMMouseEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsMouseScrollEvent(PR_FALSE, 0, nsnull))
|
||||
{
|
||||
if(mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
nsMouseScrollEvent* mouseEvent = static_cast<nsMouseScrollEvent*>(mEvent);
|
||||
mDetail = mouseEvent->delta;
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMMouseScrollEvent::~nsDOMMouseScrollEvent()
|
||||
{
|
||||
if (mEventIsInternal && mEvent) {
|
||||
switch (mEvent->eventStructType)
|
||||
{
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
delete static_cast<nsMouseScrollEvent*>(mEvent);
|
||||
break;
|
||||
default:
|
||||
delete mEvent;
|
||||
break;
|
||||
}
|
||||
mEvent = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMMouseScrollEvent, nsDOMMouseEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMMouseScrollEvent, nsDOMMouseEvent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMMouseScrollEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseScrollEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(MouseScrollEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMMouseEvent)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMouseScrollEvent::InitMouseScrollEvent(const nsAString & aType, PRBool aCanBubble, PRBool aCancelable,
|
||||
nsIDOMAbstractView *aView, PRInt32 aDetail, PRInt32 aScreenX,
|
||||
PRInt32 aScreenY, PRInt32 aClientX, PRInt32 aClientY,
|
||||
PRBool aCtrlKey, PRBool aAltKey, PRBool aShiftKey,
|
||||
PRBool aMetaKey, PRUint16 aButton, nsIDOMEventTarget *aRelatedTarget,
|
||||
PRInt32 aAxis)
|
||||
{
|
||||
nsresult rv = nsDOMMouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
|
||||
aScreenX, aScreenY, aClientX, aClientY, aCtrlKey,
|
||||
aAltKey, aShiftKey, aMetaKey, aButton, aRelatedTarget);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
static_cast<nsMouseScrollEvent*>(mEvent)->scrollFlags =
|
||||
(aAxis == HORIZONTAL_AXIS) ? nsMouseScrollEvent::kIsHorizontal
|
||||
: nsMouseScrollEvent::kIsVertical;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMouseScrollEvent::GetAxis(PRInt32* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
PRUint32 flags = static_cast<nsMouseScrollEvent*>(mEvent)->scrollFlags;
|
||||
*aResult = (flags & nsMouseScrollEvent::kIsHorizontal)
|
||||
? PRInt32(HORIZONTAL_AXIS) : PRInt32(VERTICAL_AXIS);
|
||||
} else {
|
||||
*aResult = 0;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsInputEvent *aEvent)
|
||||
{
|
||||
nsDOMMouseScrollEvent* it = new nsDOMMouseScrollEvent(aPresContext, aEvent);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(it, aInstancePtrResult);
|
||||
}
|
60
content/events/src/nsDOMMouseScrollEvent.h
Normal file
60
content/events/src/nsDOMMouseScrollEvent.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Markus Stange <mstange@themasta.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMMouseScrollEvent_h__
|
||||
#define nsDOMMouseScrollEvent_h__
|
||||
|
||||
#include "nsIDOMMouseScrollEvent.h"
|
||||
#include "nsDOMMouseEvent.h"
|
||||
|
||||
class nsDOMMouseScrollEvent : public nsIDOMMouseScrollEvent,
|
||||
public nsDOMMouseEvent
|
||||
{
|
||||
public:
|
||||
nsDOMMouseScrollEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
|
||||
virtual ~nsDOMMouseScrollEvent();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMMouseScrollEvent Interface
|
||||
NS_DECL_NSIDOMMOUSESCROLLEVENT
|
||||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMMOUSEEVENT
|
||||
};
|
||||
|
||||
#endif // nsDOMMouseScrollEvent_h__
|
@ -566,10 +566,12 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsKeyEvent*>(aEvent));
|
||||
case NS_MOUSE_EVENT:
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
case NS_POPUP_EVENT:
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsInputEvent*>(aEvent));
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsInputEvent*>(aEvent));
|
||||
case NS_POPUPBLOCKED_EVENT:
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsPopupBlockedEvent*>
|
||||
@ -612,9 +614,10 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
|
||||
if (aEventType.LowerCaseEqualsLiteral("mouseevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mouseevents") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mousescrollevents") ||
|
||||
aEventType.LowerCaseEqualsLiteral("popupevents"))
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("mousescrollevents"))
|
||||
return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("keyevents"))
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
interface nsIDOMElement;
|
||||
|
||||
[scriptable, uuid(ef136142-9925-45f4-a3e4-6f0d275c6aa8)]
|
||||
[scriptable, uuid(ee6500aa-fd51-4b89-801f-d4fbf2663beb)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -127,6 +127,33 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
in long aClickCount,
|
||||
in long aModifiers);
|
||||
|
||||
/** Synthesize a mouse scroll event for a window. The event types supported
|
||||
* are:
|
||||
* DOMMouseScroll
|
||||
*
|
||||
* Events are sent in coordinates offset by aX and aY from the window.
|
||||
*
|
||||
* Cannot be accessed from unprivileged context (not content-accessible)
|
||||
* Will throw a DOM security error if called without UniversalXPConnect
|
||||
* privileges.
|
||||
*
|
||||
* @param aType event type
|
||||
* @param aX x offset
|
||||
* @param aY y offset
|
||||
* @param aButton button to synthesize
|
||||
* @param aScrollFlags flag bits --- see nsMouseScrollFlags in nsGUIEvent.h
|
||||
* @param aDelta the direction and amount to scroll (in lines or pixels,
|
||||
* depending on whether kIsPixels is set in aScrollFlags)
|
||||
* @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
|
||||
*/
|
||||
void sendMouseScrollEvent(in AString aType,
|
||||
in long aX,
|
||||
in long aY,
|
||||
in long aButton,
|
||||
in long aScrollFlags,
|
||||
in long aDelta,
|
||||
in long aModifiers);
|
||||
|
||||
/**
|
||||
* Synthesize a key event to the window. The event types supported are:
|
||||
* keydown, keyup, keypress
|
||||
|
@ -56,6 +56,7 @@ SDK_XPIDLSRCS = \
|
||||
nsIDOMEventGroup.idl \
|
||||
nsIDOMCustomEvent.idl \
|
||||
nsIDOMMouseEvent.idl \
|
||||
nsIDOMMouseScrollEvent.idl \
|
||||
nsIDOMUIEvent.idl \
|
||||
$(NULL)
|
||||
|
||||
|
65
dom/public/idl/events/nsIDOMMouseScrollEvent.idl
Normal file
65
dom/public/idl/events/nsIDOMMouseScrollEvent.idl
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert O'Callahan <robert@ocallahan.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(f172af88-48c3-4989-b814-60449823fc7d)]
|
||||
interface nsIDOMMouseScrollEvent : nsISupports
|
||||
{
|
||||
const long HORIZONTAL_AXIS = 1;
|
||||
const long VERTICAL_AXIS = 2;
|
||||
|
||||
readonly attribute long axis;
|
||||
|
||||
void initMouseScrollEvent(in DOMString typeArg,
|
||||
in boolean canBubbleArg,
|
||||
in boolean cancelableArg,
|
||||
in nsIDOMAbstractView viewArg,
|
||||
in long detailArg,
|
||||
in long screenXArg,
|
||||
in long screenYArg,
|
||||
in long clientXArg,
|
||||
in long clientYArg,
|
||||
in boolean ctrlKeyArg,
|
||||
in boolean altKeyArg,
|
||||
in boolean shiftKeyArg,
|
||||
in boolean metaKeyArg,
|
||||
in unsigned short buttonArg,
|
||||
in nsIDOMEventTarget relatedTargetArg,
|
||||
in long axis);
|
||||
};
|
@ -83,6 +83,7 @@ enum nsDOMClassInfoID {
|
||||
eDOMClassInfo_MutationEvent_id,
|
||||
eDOMClassInfo_UIEvent_id,
|
||||
eDOMClassInfo_MouseEvent_id,
|
||||
eDOMClassInfo_MouseScrollEvent_id,
|
||||
eDOMClassInfo_KeyboardEvent_id,
|
||||
eDOMClassInfo_PopupBlockedEvent_id,
|
||||
|
||||
|
@ -234,6 +234,7 @@
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMMouseScrollEvent.h"
|
||||
#include "nsIDOMCommandEvent.h"
|
||||
#include "nsIDOMPopupBlockedEvent.h"
|
||||
#include "nsIDOMBeforeUnloadEvent.h"
|
||||
@ -650,6 +651,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MouseEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MouseScrollEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(PopupBlockedEvent, nsDOMGenericSH,
|
||||
@ -2105,6 +2108,11 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MouseScrollEvent, nsIDOMMouseScrollEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMouseScrollEvent)
|
||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(HTMLDocument, nsIDOMHTMLDocument)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDocument)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLDocument)
|
||||
|
@ -246,6 +246,49 @@ nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
|
||||
return widget->DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
|
||||
PRInt32 aX,
|
||||
PRInt32 aY,
|
||||
PRInt32 aButton,
|
||||
PRInt32 aScrollFlags,
|
||||
PRInt32 aDelta,
|
||||
PRInt32 aModifiers)
|
||||
{
|
||||
PRBool hasCap = PR_FALSE;
|
||||
if (NS_FAILED(nsContentUtils::GetSecurityManager()->IsCapabilityEnabled("UniversalXPConnect", &hasCap))
|
||||
|| !hasCap)
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
// get the widget to send the event to
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 msg;
|
||||
if (aType.EqualsLiteral("DOMMouseScroll"))
|
||||
msg = NS_MOUSE_SCROLL;
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsMouseScrollEvent event(PR_TRUE, msg, widget);
|
||||
event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
|
||||
event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
|
||||
event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
|
||||
event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
|
||||
event.button = aButton;
|
||||
event.widget = widget;
|
||||
event.delta = aDelta;
|
||||
event.scrollFlags = aScrollFlags;
|
||||
|
||||
event.time = PR_IntervalNow();
|
||||
event.refPoint.x = aX;
|
||||
event.refPoint.y = aY;
|
||||
|
||||
nsEventStatus status;
|
||||
return widget->DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
|
||||
PRInt32 aKeyCode,
|
||||
|
@ -187,7 +187,7 @@ function _parseModifiers(aEvent)
|
||||
* aOffsetY. This allows mouse clicks to be simulated by calling this method.
|
||||
*
|
||||
* aEvent is an object which may contain the properties:
|
||||
* shiftKey, ctrlKey, altKey, metaKey, accessKey, type
|
||||
* shiftKey, ctrlKey, altKey, metaKey, accessKey, clickCount, button, type
|
||||
*
|
||||
* If the type is specified, an mouse event of that type is fired. Otherwise,
|
||||
* a mousedown followed by a mouse up is performed.
|
||||
@ -221,6 +221,59 @@ function synthesizeMouse(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize a mouse scroll event on a target. The actual client point is determined
|
||||
* by taking the aTarget's client box and offseting it by aOffsetX and
|
||||
* aOffsetY.
|
||||
*
|
||||
* aEvent is an object which may contain the properties:
|
||||
* shiftKey, ctrlKey, altKey, metaKey, accessKey, button, type, axis, units, delta
|
||||
*
|
||||
* If the type is specified, an mouse scroll event of that type is fired. Otherwise,
|
||||
* "DOMMouseScroll" is used.
|
||||
*
|
||||
* If the axis is specified, it must be one of "horizontal" or "vertical". If not specified,
|
||||
* "vertical" is used.
|
||||
*
|
||||
* 'delta' is the amount to scroll by (can be positive or negative). It must
|
||||
* be specified. 'units' is the units of 'delta', either "pixels" or "lines"; "lines"
|
||||
* is the default if 'units' is ommitted.
|
||||
*
|
||||
* aWindow is optional, and defaults to the current window object.
|
||||
*/
|
||||
function synthesizeMouseScroll(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
|
||||
if (!aWindow)
|
||||
aWindow = window;
|
||||
|
||||
var utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
if (utils) {
|
||||
// See nsMouseScrollFlags in nsGUIEvent.h
|
||||
const kIsVertical = 0x02;
|
||||
const kIsHorizontal = 0x04;
|
||||
const kIsPixels = 0x08;
|
||||
|
||||
var button = aEvent.button || 0;
|
||||
var modifiers = _parseModifiers(aEvent);
|
||||
|
||||
var left = aTarget.boxObject.x;
|
||||
var top = aTarget.boxObject.y;
|
||||
|
||||
var type = aEvent.type || "DOMMouseScroll";
|
||||
var axis = aEvent.axis || "vertical";
|
||||
var units = aEvent.units || "lines";
|
||||
var scrollFlags = (axis == "horizontal") ? kIsHorizontal : kIsVertical;
|
||||
if (units == "pixels") {
|
||||
scrollFlags |= kIsPixels;
|
||||
}
|
||||
utils.sendMouseScrollEvent(type, left + aOffsetX, top + aOffsetY, button,
|
||||
scrollFlags, aEvent.delta, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize a key event. It is targeted at whatever would be targeted by an
|
||||
* actual keypress by the user, typically the focused element.
|
||||
|
@ -101,6 +101,7 @@ _TEST_FILES = test_bug360220.xul \
|
||||
test_menu_hide.xul \
|
||||
test_focus.xul \
|
||||
test_tabindex.xul \
|
||||
test_mousescroll.xul \
|
||||
test_scrollbar.xul \
|
||||
test_sorttemplate.xul \
|
||||
$(NULL)
|
||||
|
186
toolkit/content/tests/widgets/test_mousescroll.xul
Normal file
186
toolkit/content/tests/widgets/test_mousescroll.xul
Normal file
@ -0,0 +1,186 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=378028
|
||||
-->
|
||||
<window title="Mozilla Bug 378028"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="/MochiKit/packed.js" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=378028"
|
||||
target="_blank">Mozilla Bug 378028</a>
|
||||
</body>
|
||||
|
||||
<!-- richlistbox currently has no way of giving us a defined number of
|
||||
rows, so we just choose an arbitrary height limit that should give
|
||||
us plenty of vertical scrollability -->
|
||||
<richlistbox id="richlistbox" style="height:50px;">
|
||||
<richlistitem id="richlistbox_item1"><label value="Item 1"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item2"><label value="Item 2"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item3"><label value="Item 3"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item4"><label value="Item 4"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item5"><label value="Item 5"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item6"><label value="Item 6"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item7"><label value="Item 7"/></richlistitem>
|
||||
<richlistitem id="richlistbox_item8"><label value="Item 8"/></richlistitem>
|
||||
</richlistbox>
|
||||
|
||||
<listbox id="listbox" rows="2">
|
||||
<listitem id="listbox_item1" label="Item 1"/>
|
||||
<listitem id="listbox_item2" label="Item 2"/>
|
||||
<listitem id="listbox_item3" label="Item 3"/>
|
||||
<listitem id="listbox_item4" label="Item 4"/>
|
||||
<listitem id="listbox_item5" label="Item 5"/>
|
||||
<listitem id="listbox_item6" label="Item 6"/>
|
||||
<listitem id="listbox_item7" label="Item 7"/>
|
||||
<listitem id="listbox_item8" label="Item 8"/>
|
||||
</listbox>
|
||||
|
||||
<box orient="horizontal">
|
||||
<arrowscrollbox id="hscrollbox" clicktoscroll="true" orient="horizontal"
|
||||
smoothscroll="false" style="max-width:80px;" flex="1">
|
||||
<hbox style="width:40px; height:20px; background:white;"/>
|
||||
<hbox style="width:40px; height:20px; background:black;"/>
|
||||
<hbox style="width:40px; height:20px; background:white;"/>
|
||||
<hbox style="width:40px; height:20px; background:black;"/>
|
||||
<hbox style="width:40px; height:20px; background:white;"/>
|
||||
<hbox style="width:40px; height:20px; background:black;"/>
|
||||
<hbox style="width:40px; height:20px; background:white;"/>
|
||||
<hbox style="width:40px; height:20px; background:black;"/>
|
||||
</arrowscrollbox>
|
||||
</box>
|
||||
|
||||
<arrowscrollbox id="vscrollbox" clicktoscroll="true" orient="vertical"
|
||||
smoothscroll="false" style="max-height:80px;" flex="1">
|
||||
<vbox style="width:100px; height:40px; background:white;"/>
|
||||
<vbox style="width:100px; height:40px; background:black;"/>
|
||||
<vbox style="width:100px; height:40px; background:white;"/>
|
||||
<vbox style="width:100px; height:40px; background:black;"/>
|
||||
<vbox style="width:100px; height:40px; background:white;"/>
|
||||
<vbox style="width:100px; height:40px; background:black;"/>
|
||||
<vbox style="width:100px; height:40px; background:white;"/>
|
||||
<vbox style="width:100px; height:40px; background:black;"/>
|
||||
<vbox style="width:100px; height:40px; background:white;"/>
|
||||
<vbox style="width:100px; height:40px; background:black;"/>
|
||||
</arrowscrollbox>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 378028 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function testListbox(id)
|
||||
{
|
||||
var listbox = document.getElementById(id);
|
||||
|
||||
function helper(aStart, aDelta)
|
||||
{
|
||||
listbox.scrollToIndex(aStart);
|
||||
synthesizeMouseScroll(listbox, 10, 10,
|
||||
{axis:"vertical", delta:aDelta});
|
||||
is(listbox.getIndexOfFirstVisibleRow(), aStart + aDelta,
|
||||
"mouse-scroll of '" + id + "' vertical starting " + aStart + " delta " + aDelta);
|
||||
|
||||
// Check that horizontal scrolling has no effect
|
||||
listbox.scrollToIndex(aStart);
|
||||
synthesizeMouseScroll(listbox, 10, 10,
|
||||
{axis:"horizontal", delta:aDelta});
|
||||
is(listbox.getIndexOfFirstVisibleRow(), aStart,
|
||||
"mouse-scroll of '" + id + "' horizontal starting " + aStart + " delta " + aDelta);
|
||||
}
|
||||
|
||||
helper(2, -1);
|
||||
helper(2, 1);
|
||||
helper(2, -2);
|
||||
helper(2, 2);
|
||||
}
|
||||
|
||||
function testRichListbox(id)
|
||||
{
|
||||
var listbox = document.getElementById(id);
|
||||
|
||||
function helper(aStart, aDelta, aExpected)
|
||||
{
|
||||
listbox.scrollToIndex(aStart);
|
||||
synthesizeMouseScroll(listbox, 10, 10,
|
||||
{axis:"vertical", delta:aDelta});
|
||||
is(listbox.getIndexOfFirstVisibleRow(), aExpected,
|
||||
"mouse-scroll of '" + id + "' vertical starting " + aStart + " delta " + aDelta);
|
||||
|
||||
// Check that horizontal scrolling has no effect
|
||||
listbox.scrollToIndex(aStart);
|
||||
synthesizeMouseScroll(listbox, 10, 10,
|
||||
{axis:"horizontal", delta:aDelta});
|
||||
is(listbox.getIndexOfFirstVisibleRow(), aStart,
|
||||
"mouse-scroll of '" + id + "' horizontal starting " + aStart + " delta " + aDelta);
|
||||
}
|
||||
|
||||
// richlistbox currently uses native XUL scrolling, so the "line"
|
||||
// amounts don't necessarily correspond 1-to-1 with listbox items. So
|
||||
// we just check that scrolling up/down a lot hits the first/last items
|
||||
helper(2, -100, 0);
|
||||
helper(2, 100, listbox.getRowCount() - listbox.getNumberOfVisibleRows());
|
||||
}
|
||||
|
||||
function testArrowScrollbox(id)
|
||||
{
|
||||
var scrollbox = document.getElementById(id);
|
||||
var scrollBoxObject = scrollbox.scrollBoxObject;
|
||||
var orient = scrollbox.getAttribute("orient");
|
||||
|
||||
function helper(aStart, aDelta, aExpected)
|
||||
{
|
||||
var xpos = {};
|
||||
var ypos = {};
|
||||
var pos = orient == "horizontal" ? xpos : ypos;
|
||||
|
||||
scrollBoxObject.scrollTo(aStart, aStart);
|
||||
synthesizeMouseScroll(scrollbox, 5, 5,
|
||||
{axis:"vertical", delta:aDelta});
|
||||
scrollBoxObject.getPosition(xpos, ypos);
|
||||
// Note, vertical mouse scrolling is allowed to scroll horizontal
|
||||
// arrowscrollboxes, because many users have no horizontal mouse scroll
|
||||
// capability
|
||||
is(pos.value, aExpected,
|
||||
"mouse-scroll of '" + id + "' vertical starting " + aStart + " delta " + aDelta);
|
||||
|
||||
scrollBoxObject.scrollTo(aStart, aStart);
|
||||
synthesizeMouseScroll(scrollbox, 5, 5,
|
||||
{axis:"horizontal", delta:aDelta});
|
||||
// horizontal mouse scrolling is never allowed to scroll vertical
|
||||
// arrowscrollboxes
|
||||
scrollBoxObject.getPosition(xpos, ypos);
|
||||
var expected = orient == "horizontal" ? aExpected : aStart;
|
||||
is(pos.value, expected,
|
||||
"mouse-scroll of '" + id + "' horizontal starting " + aStart + " delta " + aDelta);
|
||||
}
|
||||
|
||||
var scrolledWidth = {};
|
||||
var scrolledHeight = {};
|
||||
scrollBoxObject.getScrolledSize(scrolledWidth, scrolledHeight);
|
||||
var scrollMaxX = scrolledWidth.value - scrollBoxObject.width;
|
||||
var scrollMaxY = scrolledHeight.value - scrollBoxObject.height;
|
||||
var scrollMax = orient == "horizontal" ? scrollMaxX : scrollMaxY;
|
||||
|
||||
helper(50, -100, 0);
|
||||
helper(50, 100, scrollMax);
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
testRichListbox("richlistbox");
|
||||
testListbox("listbox");
|
||||
testArrowScrollbox("hscrollbox");
|
||||
testArrowScrollbox("vscrollbox");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.onload = function() { setTimeout(runTests, 0); };
|
||||
]]></script>
|
||||
</window>
|
@ -23,6 +23,13 @@ function testtag_tree(treeid, treerowinfoid, seltype, columnstype, testid)
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
// Stop keystrokes that aren't handled by the tree from leaking out and
|
||||
// scrolling the main Mochitests window!
|
||||
function preventDefault(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
document.addEventListener("keypress", preventDefault, false);
|
||||
|
||||
var multiple = (seltype == "multiple");
|
||||
var editable = false;
|
||||
|
||||
@ -93,6 +100,10 @@ function testtag_tree(treeid, treerowinfoid, seltype, columnstype, testid)
|
||||
// do the sorting tests last as it will cause the rows to rearrange
|
||||
testtag_tree_TreeView_rows_sort(tree, testid, rowInfo);
|
||||
|
||||
testtag_tree_mousescroll(tree);
|
||||
|
||||
document.removeEventListener("keypress", preventDefault, false);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -1050,8 +1061,30 @@ function testtag_tree_column_reorder()
|
||||
checkColumns(tree, reference, "drag to itself");
|
||||
is(document.treecolDragging, null, "drag to itself completed");
|
||||
|
||||
// XXX roc should this be here???
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function testtag_tree_mousescroll(aTree)
|
||||
{
|
||||
function helper(aStart, aDelta)
|
||||
{
|
||||
aTree.treeBoxObject.scrollToRow(aStart);
|
||||
synthesizeMouseScroll(aTree.body, 1, 1,
|
||||
{type:"mousescroll", axis:"vertical", delta:aDelta});
|
||||
is(aTree.treeBoxObject.getFirstVisibleRow(), aStart + aDelta, "mouse-scroll vertical starting " + aStart + " delta " + aDelta);
|
||||
|
||||
aTree.treeBoxObject.scrollToRow(aStart);
|
||||
// Check that horizontal scrolling has no effect
|
||||
synthesizeMouseScroll(aTree.body, 1, 1,
|
||||
{type:"mousescroll", axis:"horizontal", delta:aDelta});
|
||||
is(aTree.treeBoxObject.getFirstVisibleRow(), aStart, "mouse-scroll horizontal starting " + aStart + " delta " + aDelta);
|
||||
}
|
||||
|
||||
helper(2, -1);
|
||||
helper(2, 1);
|
||||
helper(2, -2);
|
||||
helper(2, 2);
|
||||
}
|
||||
|
||||
function synthesizeColumnDrag(aTree, aMouseDownColumnNumber, aMouseUpColumnNumber, aAfter)
|
||||
|
@ -865,6 +865,9 @@
|
||||
<handlers>
|
||||
<handler event="DOMMouseScroll" phase="capturing">
|
||||
<![CDATA[
|
||||
if (event.axis == event.HORIZONTAL_AXIS)
|
||||
return;
|
||||
|
||||
var listBox = this.parentNode.listBoxObject;
|
||||
var rows = event.detail;
|
||||
if (rows == NSUIEvent.SCROLL_PAGE_UP)
|
||||
|
@ -360,7 +360,18 @@
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="DOMMouseScroll" action="this.scrollByIndex(event.detail); event.stopPropagation();"/>
|
||||
<handler event="DOMMouseScroll"><![CDATA[
|
||||
// prevent horizontal scrolling from scrolling a vertical scrollbox
|
||||
if (event.axis == event.HORIZONTAL_AXIS &&
|
||||
this.getAttribute("orient") != "horizontal")
|
||||
return;
|
||||
// We allow vertical scrolling to scroll a horizontal scrollbox
|
||||
// because many users have a vertical scroll wheel but no
|
||||
// horizontal support.
|
||||
|
||||
this.scrollByIndex(event.detail);
|
||||
event.stopPropagation();
|
||||
]]></handler>
|
||||
|
||||
<handler event="underflow"><![CDATA[
|
||||
// filter underflow events which were dispatched on nested scrollboxes
|
||||
|
@ -633,6 +633,8 @@
|
||||
<![CDATA[
|
||||
if (this._editingColumn)
|
||||
return;
|
||||
if (event.axis == event.HORIZONTAL_AXIS)
|
||||
return;
|
||||
|
||||
var rows = event.detail;
|
||||
if (rows == NSUIEvent.SCROLL_PAGE_UP)
|
||||
|
Loading…
Reference in New Issue
Block a user