mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 514732. Issue a DOM event for document resizing. r=smaug sr=roc
This commit is contained in:
parent
ce915e403f
commit
a3198800a2
@ -493,6 +493,7 @@ nsContentUtils::InitializeEventTable() {
|
||||
{ &nsGkAtoms::onvolumechange, { NS_VOLUMECHANGE, EventNameType_HTML }},
|
||||
#endif //MOZ_MEDIA
|
||||
{ &nsGkAtoms::onMozAfterPaint, { NS_AFTERPAINT, EventNameType_None }},
|
||||
{ &nsGkAtoms::onMozScrolledAreaChanged, { NS_SCROLLEDAREACHANGED, EventNameType_None }},
|
||||
|
||||
// Simple gesture events
|
||||
{ &nsGkAtoms::onMozSwipeGesture, { NS_SIMPLE_GESTURE_SWIPE, EventNameType_None } },
|
||||
|
@ -654,6 +654,7 @@ GK_ATOM(onmouseover, "onmouseover")
|
||||
GK_ATOM(onmouseup, "onmouseup")
|
||||
GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
|
||||
GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
|
||||
GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
|
||||
GK_ATOM(ononline, "ononline")
|
||||
GK_ATOM(onoffline, "onoffline")
|
||||
GK_ATOM(onoverflow, "onoverflow")
|
||||
|
@ -113,4 +113,6 @@ NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext,
|
||||
nsInvalidateRequestList* aInvalidateRequests = nsnull);
|
||||
nsresult
|
||||
NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsSimpleGestureEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMScrollAreaEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsScrollAreaEvent* aEvent);
|
||||
#endif // nsIPrivateDOMEvent_h__
|
||||
|
@ -79,6 +79,7 @@ CPPSRCS = \
|
||||
nsDOMNotifyPaintEvent.cpp \
|
||||
nsDOMSimpleGestureEvent.cpp \
|
||||
nsDOMEventTargetHelper.cpp \
|
||||
nsDOMScrollAreaEvent.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
@ -91,7 +91,8 @@ static const char* const sEventNames[] = {
|
||||
"MozRotateGestureUpdate",
|
||||
"MozRotateGesture",
|
||||
"MozTapGesture",
|
||||
"MozPressTapGesture"
|
||||
"MozPressTapGesture",
|
||||
"MozScrolledAreaChanged"
|
||||
};
|
||||
|
||||
static char *sPopupAllowedEvents;
|
||||
@ -582,6 +583,9 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
||||
mEvent->message = NS_UI_FOCUSOUT;
|
||||
else if (atom == nsGkAtoms::oninput)
|
||||
mEvent->message = NS_FORM_INPUT;
|
||||
} else if (mEvent->eventStructType == NS_SCROLLAREA_EVENT) {
|
||||
if (atom == nsGkAtoms::onMozScrolledAreaChanged)
|
||||
mEvent->message = NS_SCROLLEDAREACHANGED;
|
||||
} else if (mEvent->eventStructType == NS_INPUT_EVENT) {
|
||||
if (atom == nsGkAtoms::oncommand)
|
||||
mEvent->message = NS_XUL_COMMAND;
|
||||
@ -890,6 +894,16 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
static_cast<nsScrollPortEvent*>(mEvent)->orient;
|
||||
break;
|
||||
}
|
||||
case NS_SCROLLAREA_EVENT:
|
||||
{
|
||||
nsScrollAreaEvent *newScrollAreaEvent =
|
||||
new nsScrollAreaEvent(PR_FALSE, msg, nsnull);
|
||||
NS_ENSURE_TRUE(newScrollAreaEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
newScrollAreaEvent->mArea =
|
||||
static_cast<nsScrollAreaEvent *>(mEvent)->mArea;
|
||||
newEvent = newScrollAreaEvent;
|
||||
break;
|
||||
}
|
||||
case NS_MUTATION_EVENT:
|
||||
{
|
||||
nsMutationEvent* mutationEvent = new nsMutationEvent(PR_FALSE, msg);
|
||||
@ -1452,6 +1466,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
||||
return sEventNames[eDOMEvents_MozTapGesture];
|
||||
case NS_SIMPLE_GESTURE_PRESSTAP:
|
||||
return sEventNames[eDOMEvents_MozPressTapGesture];
|
||||
case NS_SCROLLEDAREACHANGED:
|
||||
return sEventNames[eDOMEvents_MozScrolledAreaChanged];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -171,7 +171,8 @@ public:
|
||||
eDOMEvents_MozRotateGestureUpdate,
|
||||
eDOMEvents_MozRotateGesture,
|
||||
eDOMEvents_MozTapGesture,
|
||||
eDOMEvents_MozPressTapGesture
|
||||
eDOMEvents_MozPressTapGesture,
|
||||
eDOMEvents_MozScrolledAreaChanged
|
||||
};
|
||||
|
||||
nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
|
121
content/events/src/nsDOMScrollAreaEvent.cpp
Normal file
121
content/events/src/nsDOMScrollAreaEvent.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/* -*- 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 code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roy Frostig <froystig@cs.stanford.edu>
|
||||
*
|
||||
* 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 "nsDOMScrollAreaEvent.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsClientRect.h"
|
||||
|
||||
nsDOMScrollAreaEvent::nsDOMScrollAreaEvent(nsPresContext *aPresContext,
|
||||
nsScrollAreaEvent *aEvent)
|
||||
: nsDOMUIEvent(aPresContext, aEvent)
|
||||
{
|
||||
mClientArea.SetLayoutRect(aEvent ? aEvent->mArea : nsRect());
|
||||
}
|
||||
|
||||
nsDOMScrollAreaEvent::~nsDOMScrollAreaEvent()
|
||||
{
|
||||
if (mEventIsInternal && mEvent) {
|
||||
if (mEvent->eventStructType == NS_SCROLLAREA_EVENT) {
|
||||
delete static_cast<nsScrollAreaEvent *>(mEvent);
|
||||
mEvent = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMScrollAreaEvent, nsDOMUIEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMScrollAreaEvent, nsDOMUIEvent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMScrollAreaEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMScrollAreaEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ScrollAreaEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMUIEvent)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMScrollAreaEvent::GetX(float *aX)
|
||||
{
|
||||
return mClientArea.GetLeft(aX);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMScrollAreaEvent::GetY(float *aY)
|
||||
{
|
||||
return mClientArea.GetTop(aY);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMScrollAreaEvent::GetWidth(float *aWidth)
|
||||
{
|
||||
return mClientArea.GetWidth(aWidth);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMScrollAreaEvent::GetHeight(float *aHeight)
|
||||
{
|
||||
return mClientArea.GetHeight(aHeight);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMScrollAreaEvent::InitScrollAreaEvent(const nsAString &aEventType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
nsIDOMAbstractView *aView,
|
||||
PRInt32 aDetail,
|
||||
float aX, float aY,
|
||||
float aWidth, float aHeight)
|
||||
{
|
||||
nsresult rv = nsDOMUIEvent::InitUIEvent(aEventType, aCanBubble, aCancelable, aView, aDetail);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mClientArea.SetRect(aX, aY, aWidth, aHeight);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewDOMScrollAreaEvent(nsIDOMEvent **aInstancePtrResult,
|
||||
nsPresContext *aPresContext,
|
||||
nsScrollAreaEvent *aEvent)
|
||||
{
|
||||
nsDOMScrollAreaEvent *ev = new nsDOMScrollAreaEvent(aPresContext, aEvent);
|
||||
|
||||
if (!ev) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(ev, aInstancePtrResult);
|
||||
}
|
65
content/events/src/nsDOMScrollAreaEvent.h
Normal file
65
content/events/src/nsDOMScrollAreaEvent.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- 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 code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roy Frostig <froystig@cs.stanford.edu>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef nsDOMScrollAreaEvent_h__
|
||||
#define nsDOMScrollAreaEvent_h__
|
||||
|
||||
#include "nsIDOMScrollAreaEvent.h"
|
||||
#include "nsDOMUIEvent.h"
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsClientRect.h"
|
||||
|
||||
class nsDOMScrollAreaEvent : public nsDOMUIEvent,
|
||||
public nsIDOMScrollAreaEvent
|
||||
{
|
||||
public:
|
||||
nsDOMScrollAreaEvent(nsPresContext *aPresContext,
|
||||
nsScrollAreaEvent *aEvent);
|
||||
virtual ~nsDOMScrollAreaEvent();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIDOMSCROLLAREAEVENT
|
||||
|
||||
NS_FORWARD_TO_NSDOMUIEVENT
|
||||
|
||||
protected:
|
||||
nsClientRect mClientArea;
|
||||
};
|
||||
|
||||
#endif // nsDOMScrollAreaEvent_h__
|
@ -625,6 +625,9 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsGUIEvent*>(aEvent));
|
||||
case NS_SCROLLAREA_EVENT:
|
||||
return NS_NewDOMScrollAreaEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsScrollAreaEvent *>(aEvent));
|
||||
case NS_KEY_EVENT:
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsKeyEvent*>(aEvent));
|
||||
@ -722,6 +725,8 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
return NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("pagetransition"))
|
||||
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("scrollareaevent"))
|
||||
return NS_NewDOMScrollAreaEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
@ -234,6 +234,7 @@
|
||||
#include "nsIDOMMessageEvent.h"
|
||||
#include "nsPaintRequest.h"
|
||||
#include "nsIDOMNotifyPaintEvent.h"
|
||||
#include "nsIDOMScrollAreaEvent.h"
|
||||
#include "nsIDOMNSDocumentStyle.h"
|
||||
#include "nsIDOMDocumentRange.h"
|
||||
#include "nsIDOMDocumentTraversal.h"
|
||||
@ -1346,6 +1347,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(PaintRequestList, nsPaintRequestListSH,
|
||||
ARRAY_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
};
|
||||
|
||||
// Objects that shuld be constructable through |new Name();|
|
||||
@ -3701,6 +3705,11 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequestList)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(ScrollAreaEvent, nsIDOMScrollAreaEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMScrollAreaEvent)
|
||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||
|
@ -482,6 +482,8 @@ enum nsDOMClassInfoID {
|
||||
eDOMClassInfo_PaintRequest_id,
|
||||
eDOMClassInfo_PaintRequestList_id,
|
||||
|
||||
eDOMClassInfo_ScrollAreaEvent_id,
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
@ -81,6 +81,7 @@ XPIDLSRCS = \
|
||||
nsIDOMSimpleGestureEvent.idl \
|
||||
nsIDOMNSMouseEvent.idl \
|
||||
nsIDOMOrientationEvent.idl \
|
||||
nsIDOMScrollAreaEvent.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
58
dom/interfaces/events/nsIDOMScrollAreaEvent.idl
Normal file
58
dom/interfaces/events/nsIDOMScrollAreaEvent.idl
Normal file
@ -0,0 +1,58 @@
|
||||
/* -*- 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 code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roy Frostig <froystig@cs.stanford.edu>
|
||||
*
|
||||
* 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 "nsIDOMUIEvent.idl"
|
||||
|
||||
[scriptable, uuid(b2f49035-4a2f-4e62-8fb0-deb68b0de4d9)]
|
||||
interface nsIDOMScrollAreaEvent : nsIDOMUIEvent
|
||||
{
|
||||
// Scroll area client rect
|
||||
readonly attribute float x;
|
||||
readonly attribute float y;
|
||||
readonly attribute float width;
|
||||
readonly attribute float height;
|
||||
|
||||
void initScrollAreaEvent(in DOMString aEventType,
|
||||
in boolean aCanBubble,
|
||||
in boolean aCancelable,
|
||||
in nsIDOMAbstractView aView,
|
||||
in long aDetail,
|
||||
in float x,
|
||||
in float y,
|
||||
in float width,
|
||||
in float height);
|
||||
};
|
@ -156,6 +156,7 @@ void
|
||||
nsHTMLScrollFrame::Destroy()
|
||||
{
|
||||
mInner.Destroy();
|
||||
mScrolledAreaEventDispatcher.Revoke();
|
||||
nsHTMLContainerFrame::Destroy();
|
||||
}
|
||||
|
||||
@ -892,12 +893,70 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (mInner.mIsRoot && oldScrolledAreaBounds != newScrolledAreaBounds) {
|
||||
PostScrolledAreaEvent(newScrolledAreaBounds);
|
||||
}
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||
mInner.PostOverflowEvent();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ScrolledArea change event dispatch
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLScrollFrame::ScrolledAreaEventDispatcher::Run()
|
||||
{
|
||||
if (mScrollFrame)
|
||||
mScrollFrame->FireScrolledAreaEvent(mScrolledArea);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLScrollFrame::FireScrolledAreaEvent(nsRect &aScrolledArea)
|
||||
{
|
||||
mScrolledAreaEventDispatcher.Forget();
|
||||
|
||||
nsScrollAreaEvent event(PR_TRUE, NS_SCROLLEDAREACHANGED, nsnull);
|
||||
nsPresContext *prescontext = PresContext();
|
||||
nsIContent* content = GetContent();
|
||||
|
||||
event.mArea = aScrolledArea;
|
||||
|
||||
nsIDocument *doc = content->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsEventDispatcher::Dispatch(doc, prescontext, &event, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLScrollFrame::PostScrolledAreaEvent(nsRect &aScrolledArea)
|
||||
{
|
||||
if (mScrolledAreaEventDispatcher.IsPending()) {
|
||||
mScrolledAreaEventDispatcher.get()->mScrolledArea = aScrolledArea;
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ScrolledAreaEventDispatcher> dp = new ScrolledAreaEventDispatcher(this);
|
||||
if (!dp) {
|
||||
NS_WARNING("OOM while posting NS_SCROLLEDAREACHANGED");
|
||||
return;
|
||||
}
|
||||
|
||||
dp->mScrolledArea = aScrolledArea;
|
||||
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(dp))) {
|
||||
NS_WARNING("Failed to dispatch ScrolledAreaEventDispatcher");
|
||||
} else {
|
||||
mScrolledAreaEventDispatcher = dp;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsHTMLScrollFrame::GetFrameName(nsAString& aResult) const
|
||||
|
@ -384,6 +384,30 @@ public:
|
||||
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper functions and class to dispatch events related to changes in the
|
||||
* scroll frame's scrolled content area.
|
||||
*/
|
||||
|
||||
void PostScrolledAreaEvent(nsRect &aScrolledArea);
|
||||
void FireScrolledAreaEvent(nsRect &aScrolledArea);
|
||||
|
||||
class ScrolledAreaEventDispatcher : public nsRunnable {
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
ScrolledAreaEventDispatcher(nsHTMLScrollFrame *aScrollFrame)
|
||||
: mScrollFrame(aScrollFrame),
|
||||
mScrolledArea(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
void Revoke() { mScrollFrame = nsnull; }
|
||||
|
||||
nsHTMLScrollFrame *mScrollFrame;
|
||||
nsRect mScrolledArea;
|
||||
};
|
||||
|
||||
protected:
|
||||
nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, PRBool aIsRoot);
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
@ -416,6 +440,8 @@ protected:
|
||||
private:
|
||||
friend class nsGfxScrollFrameInner;
|
||||
nsGfxScrollFrameInner mInner;
|
||||
|
||||
nsRevocableEventPtr<ScrolledAreaEventDispatcher> mScrolledAreaEventDispatcher;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,6 +88,7 @@ _TEST_FILES = \
|
||||
test_bug470212.html \
|
||||
test_bug503813.html \
|
||||
test_bug507902.html \
|
||||
test_bug514732.html \
|
||||
test_movement_by_characters.html \
|
||||
test_movement_by_words.html \
|
||||
test_plugin_clipping.xhtml \
|
||||
@ -101,6 +102,8 @@ _TEST_FILES = \
|
||||
file_Dolske.png \
|
||||
file_IconTestServer.sjs \
|
||||
file_LoadingImageReference.png \
|
||||
file_bug514732_1.html \
|
||||
file_bug514732_helper.html \
|
||||
$(NULL)
|
||||
# disabled temporarily
|
||||
# test_bug488417.html \
|
||||
|
9
layout/generic/test/file_bug514732_1.html
Normal file
9
layout/generic/test/file_bug514732_1.html
Normal file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<h1>hi</h1>
|
||||
<div id="imgs" style="whitespace: nowrap; overflow: visible; height: 10px;">feh</div>
|
||||
|
||||
</body>
|
||||
</html>
|
294
layout/generic/test/file_bug514732_helper.html
Normal file
294
layout/generic/test/file_bug514732_helper.html
Normal file
@ -0,0 +1,294 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=514732
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 514732</title>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug?id=514732">Mozilla Bug 514732</a>
|
||||
|
||||
<div id="imgs" style="whitespace: nowrap; overflow: visible; height: 10px;"></div>
|
||||
|
||||
<iframe id="testframe" src="./file_bug514732_1.html"></iframe>
|
||||
|
||||
<br/><br/>
|
||||
<div id="log">log:<br/></div>
|
||||
<br/><br/>
|
||||
|
||||
<script class="testbody" style="width: 300; height: 150;" type="text/javascript;version=1.8">
|
||||
// Import test API
|
||||
var is = window.opener.is;
|
||||
var ok = window.opener.ok;
|
||||
var todo = window.opener.todo;
|
||||
var finish = window.opener.SimpleTest.finish;
|
||||
|
||||
function log(msg) {
|
||||
document.getElementById("log").innerHTML += msg;
|
||||
}
|
||||
|
||||
function logln(msg) {
|
||||
if (arguments.length == 0) msg = "";
|
||||
document.getElementById("log").innerHTML += msg + "<br/>";
|
||||
}
|
||||
|
||||
function logev(ev) {
|
||||
logln([ev.x, ev.y, ev.width, ev.height].join(' '));
|
||||
}
|
||||
|
||||
/* Absolutely position a 500x500 div at x, y on doc */
|
||||
function phoom(doc, x, y) {
|
||||
var d = doc.createElement('div');
|
||||
d.id = "phoomer";
|
||||
d.style.position = "absolute";
|
||||
d.style.left = x + 'px';
|
||||
d.style.top = y + 'px';
|
||||
d.style.backgroundColor = "#00FFF0";
|
||||
d.style.width = 500 + 'px';
|
||||
d.style.height = 500 + 'px';
|
||||
doc.getElementById('imgs').appendChild(d);
|
||||
}
|
||||
|
||||
function unphoom(doc) {
|
||||
var phoomer = doc.getElementById('phoomer');
|
||||
if (phoomer)
|
||||
doc.getElementById('imgs').removeChild(phoomer);
|
||||
}
|
||||
|
||||
function getDocBodyDimensions(doc) {
|
||||
return [doc.documentElement.scrollWidth, doc.documentElement.scrollHeight];
|
||||
}
|
||||
|
||||
function makeResult() {
|
||||
return {
|
||||
success: false,
|
||||
event: null
|
||||
};
|
||||
}
|
||||
|
||||
function waitInterrupt(result, gen, timewait) {
|
||||
result.event = null;
|
||||
result.success = false;
|
||||
setTimeout(function() { if (!result.success) gen.next(); }, (timewait || 2000));
|
||||
}
|
||||
|
||||
function testPhoom(isCapturing, x, y, expectEvent) {
|
||||
var result;
|
||||
|
||||
var eventGen = (function() {
|
||||
var innerdoc = document.getElementById('testframe').contentDocument;
|
||||
|
||||
for each (var doc in [document, innerdoc]) {
|
||||
var inner = (doc == innerdoc);
|
||||
var w, h;
|
||||
var listener = function(ev) {
|
||||
result.success = true;
|
||||
result.event = ev;
|
||||
setTimeout(function() { eventGen.next(); }, 0);
|
||||
};
|
||||
|
||||
/* --- EXPANSION --- */
|
||||
|
||||
doc.addEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
result = makeResult();
|
||||
waitInterrupt(result, eventGen, 1200);
|
||||
phoom(doc, x, y);
|
||||
yield;
|
||||
|
||||
doc.removeEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
/* If we're expecting an event, better check that we got one. If we are not expecting one,
|
||||
one can still arrive, but we don't complain if it did not. In either case, any event
|
||||
that arrives will have its data checked below. */
|
||||
if (expectEvent) {
|
||||
ok(result.success, "Received expected expansion event");
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
is(result.event.x, 0, "Expansion event x is 0");
|
||||
is(result.event.y, 0, "Expansion event y is 0");
|
||||
if (inner) {
|
||||
/* In iframe-land, the values of |myiframe.contentDocument.documentElement.scrollWidth| and
|
||||
|.scrollHeight| appear to be not as expected (they stay very small). This is fine, since
|
||||
we know exactly where we're positioning our fixed-dimensions div, and we know our iframe's
|
||||
dimensions, so we can do our own math. NB: The inner iframe is styled at 300x500. */
|
||||
is(Math.round(result.event.width),
|
||||
Math.max(x + 500, 300),
|
||||
"Inner expansion event width matches body width");
|
||||
is(Math.round(result.event.height),
|
||||
Math.max(y + 500, 150),
|
||||
"Inner expansion event height matches body height");
|
||||
} else {
|
||||
[w, h] = getDocBodyDimensions(doc);
|
||||
is(Math.round(result.event.width), w, "Expansion event width matches body width");
|
||||
is(Math.round(result.event.height), h, "Expansion event height matches body height");
|
||||
}
|
||||
}
|
||||
|
||||
/* --- CONTRACTION --- */
|
||||
|
||||
doc.addEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
result = makeResult();
|
||||
waitInterrupt(result, eventGen, 1200);
|
||||
unphoom(doc);
|
||||
yield;
|
||||
|
||||
doc.removeEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
if (expectEvent) {
|
||||
ok(result.success, "Received expected contraction event");
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
is(result.event.x, 0, "Contraction event x is 0");
|
||||
is(result.event.y, 0, "Contraction event y is 0");
|
||||
if (inner) {
|
||||
is(Math.round(result.event.width), 300, "Inner contraction event width matches body width");
|
||||
is(Math.round(result.event.height), 150, "Inner contraction event height matches body height");
|
||||
} else {
|
||||
[w, h] = getDocBodyDimensions(doc);
|
||||
is(Math.round(result.event.width), w, "Contraction event width matches body width");
|
||||
is(Math.round(result.event.height), h, "Contraction event height matches body height");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(nextTest, 0);
|
||||
|
||||
yield;
|
||||
})();
|
||||
|
||||
setTimeout(function() { eventGen.next(); }, 0);
|
||||
}
|
||||
|
||||
function testPreliminaries() {
|
||||
/* Do any setup here */
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function testEventCapturingHorz() {
|
||||
testPhoom(true, 10000, 0, true); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventCapturingVert() {
|
||||
testPhoom(true, 0, 10000, true); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventCapturingBoth() {
|
||||
testPhoom(true, 10000, 10000, true); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventCapturingNegv() {
|
||||
testPhoom(true, -10000, -10000, false); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventBubblingHorz() {
|
||||
testPhoom(false, 10000, 0, true); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventBubblingVert() {
|
||||
testPhoom(false, 0, 10000, true); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventBubblingBoth() {
|
||||
testPhoom(false, 10000, 10000, true); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testEventBubblingNegv() {
|
||||
testPhoom(false, -10000, -10000, false); // calls nextTest() when finished
|
||||
}
|
||||
|
||||
function testCustomCreationHelper(creatingDoc, listeningDoc, x, y, w, h, expectEvent) {
|
||||
var result = makeResult();
|
||||
|
||||
var listener = function(evt) {
|
||||
result.success = true;
|
||||
result.event = evt;
|
||||
};
|
||||
|
||||
var ev = creatingDoc.createEvent("ScrollAreaEvent");
|
||||
ev.initScrollAreaEvent("MozScrolledAreaChanged",
|
||||
true, true, window, 0,
|
||||
x, y, w, h);
|
||||
|
||||
listeningDoc.addEventListener("MozScrolledAreaChanged", listener, true);
|
||||
|
||||
result.success = false;
|
||||
creatingDoc.dispatchEvent(ev);
|
||||
|
||||
listeningDoc.removeEventListener("MozScrolledAreaChanged", listener, true);
|
||||
|
||||
is(result.success, expectEvent, "Received custom event iff expected");
|
||||
if (result.success) {
|
||||
is(result.event.x, x, "Custom event data matches for x");
|
||||
is(result.event.y, y, "Custom event data matches for y");
|
||||
is(result.event.width, w, "Custom event data matches for width");
|
||||
is(result.event.height, h, "Custom event data matches for height");
|
||||
}
|
||||
}
|
||||
|
||||
function testCustomCreation() {
|
||||
var innerdoc = document.getElementById('testframe').contentDocument;
|
||||
testCustomCreationHelper(document, document, 2, 7, 1, 8, true); // e = 2.718 ...
|
||||
testCustomCreationHelper(innerdoc, innerdoc, 2, 8, 1, 8, true); // ... 2818 ...
|
||||
testCustomCreationHelper(innerdoc, document, 2, 8, 4, 5, false); // ... 2845 ...
|
||||
nextTest();
|
||||
}
|
||||
|
||||
var TESTS = [testPreliminaries,
|
||||
testEventCapturingHorz,
|
||||
testEventCapturingVert,
|
||||
testEventCapturingBoth,
|
||||
testEventCapturingNegv,
|
||||
testEventBubblingHorz,
|
||||
testEventBubblingVert,
|
||||
testEventBubblingBoth,
|
||||
testEventBubblingNegv,
|
||||
testCustomCreation,
|
||||
__end];
|
||||
|
||||
var PC = 0;
|
||||
|
||||
function nextTest() {
|
||||
TESTS[PC++]();
|
||||
}
|
||||
|
||||
function __end() {
|
||||
log("done!");
|
||||
finish();
|
||||
window.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* We need both the parent document and all iframe documents to load
|
||||
* before starting anything
|
||||
*/
|
||||
var loaded = 0;
|
||||
|
||||
window
|
||||
.addEventListener('load', function(ev) {
|
||||
logln(++loaded);
|
||||
if (loaded >= 2) {
|
||||
logln("go...");
|
||||
nextTest();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.getElementById("testframe").contentWindow
|
||||
.addEventListener('load', function(ev) {
|
||||
logln(++loaded);
|
||||
if (loaded >= 2) {
|
||||
logln("go...");
|
||||
nextTest();
|
||||
}
|
||||
}, false);
|
||||
|
||||
// window.opener says: SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
28
layout/generic/test/test_bug514732.html
Normal file
28
layout/generic/test/test_bug514732.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=514732
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 514732</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug?id=514732">Mozilla Bug 514732</a>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" style="width: 300; height: 150;" type="text/javascript;version=1.8">
|
||||
window.open("./file_bug514732_helper.html", "", "width=600,height=600");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -88,6 +88,7 @@ class nsHashKey;
|
||||
#define NS_FORM_EVENT 21
|
||||
#define NS_POPUP_EVENT 23
|
||||
#define NS_COMMAND_EVENT 24
|
||||
#define NS_SCROLLAREA_EVENT 25
|
||||
|
||||
|
||||
#define NS_UI_EVENT 27
|
||||
@ -435,6 +436,10 @@ class nsHashKey;
|
||||
|
||||
#define NS_ORIENTATION_EVENT 4000
|
||||
|
||||
#define NS_SCROLLAREA_EVENT_START 4100
|
||||
#define NS_SCROLLEDAREACHANGED (NS_SCROLLAREA_EVENT_START)
|
||||
|
||||
|
||||
/**
|
||||
* Return status for event processors, nsEventStatus, is defined in
|
||||
* nsEvent.h.
|
||||
@ -665,6 +670,17 @@ public:
|
||||
orientType orient;
|
||||
};
|
||||
|
||||
class nsScrollAreaEvent : public nsGUIEvent
|
||||
{
|
||||
public:
|
||||
nsScrollAreaEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w)
|
||||
: nsGUIEvent(isTrusted, msg, w, NS_SCROLLAREA_EVENT)
|
||||
{
|
||||
}
|
||||
|
||||
nsRect mArea;
|
||||
};
|
||||
|
||||
class nsInputEvent : public nsGUIEvent
|
||||
{
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user