Bug 514732. Issue a DOM event for document resizing. r=smaug sr=roc

This commit is contained in:
Roy Frostig 2009-09-11 16:13:56 -07:00
parent ce915e403f
commit a3198800a2
20 changed files with 720 additions and 2 deletions

View File

@ -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 } },

View File

@ -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")

View File

@ -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__

View File

@ -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.

View File

@ -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;
}

View File

@ -171,7 +171,8 @@ public:
eDOMEvents_MozRotateGestureUpdate,
eDOMEvents_MozRotateGesture,
eDOMEvents_MozTapGesture,
eDOMEvents_MozPressTapGesture
eDOMEvents_MozPressTapGesture,
eDOMEvents_MozScrolledAreaChanged
};
nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);

View 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);
}

View 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__

View File

@ -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;
}

View File

@ -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);

View File

@ -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
};

View File

@ -81,6 +81,7 @@ XPIDLSRCS = \
nsIDOMSimpleGestureEvent.idl \
nsIDOMNSMouseEvent.idl \
nsIDOMOrientationEvent.idl \
nsIDOMScrollAreaEvent.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View 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);
};

View File

@ -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

View File

@ -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;
};
/**

View File

@ -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 \

View 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>

View 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>

View 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>

View File

@ -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: