Bug 450930. Fire a DOM event when painting so that content and chrome can track what's being repainted. r=smaug,sr=dbaron
This commit is contained in:
@@ -444,19 +444,19 @@ nsContentUtils::InitializeEventTable() {
|
||||
{ &nsGkAtoms::ondragleave, { NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondrop, { NS_DRAGDROP_DROP, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::onoverflow, { NS_SCROLLPORT_OVERFLOW, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::onunderflow, { NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL }}
|
||||
{ &nsGkAtoms::onunderflow, { NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL }},
|
||||
#ifdef MOZ_SVG
|
||||
,{ &nsGkAtoms::onSVGLoad, { NS_SVG_LOAD, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGLoad, { NS_SVG_LOAD, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGUnload, { NS_SVG_UNLOAD, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGAbort, { NS_SVG_ABORT, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGError, { NS_SVG_ERROR, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGResize, { NS_SVG_RESIZE, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGScroll, { NS_SVG_SCROLL, EventNameType_None }},
|
||||
{ &nsGkAtoms::onSVGZoom, { NS_SVG_ZOOM, EventNameType_None }},
|
||||
{ &nsGkAtoms::onzoom, { NS_SVG_ZOOM, EventNameType_SVGSVG }}
|
||||
{ &nsGkAtoms::onzoom, { NS_SVG_ZOOM, EventNameType_SVGSVG }},
|
||||
#endif // MOZ_SVG
|
||||
#ifdef MOZ_MEDIA
|
||||
,{ &nsGkAtoms::onloadstart, { NS_LOADSTART, EventNameType_HTML }},
|
||||
{ &nsGkAtoms::onloadstart, { NS_LOADSTART, EventNameType_HTML }},
|
||||
{ &nsGkAtoms::onprogress, { NS_PROGRESS, EventNameType_HTML }},
|
||||
{ &nsGkAtoms::onloadedmetadata, { NS_LOADEDMETADATA, EventNameType_HTML }},
|
||||
{ &nsGkAtoms::onloadedfirstframe, { NS_LOADEDFIRSTFRAME, EventNameType_HTML }},
|
||||
@@ -477,6 +477,7 @@ nsContentUtils::InitializeEventTable() {
|
||||
{ &nsGkAtoms::ondurationchange, { NS_DURATIONCHANGE, EventNameType_HTML }},
|
||||
{ &nsGkAtoms::onvolumechange, { NS_VOLUMECHANGE, EventNameType_HTML }},
|
||||
#endif //MOZ_MEDIA
|
||||
{ &nsGkAtoms::onMozAfterPaint, { NS_AFTERPAINT, EventNameType_None }}
|
||||
};
|
||||
|
||||
sEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>;
|
||||
|
||||
@@ -1289,28 +1289,6 @@ GetContainingBlockForClientRect(nsIFrame* aFrame)
|
||||
return aFrame;
|
||||
}
|
||||
|
||||
static double
|
||||
RoundFloat(double aValue)
|
||||
{
|
||||
return floor(aValue + 0.5);
|
||||
}
|
||||
|
||||
static void
|
||||
SetClientRect(const nsRect& aLayoutRect, nsPresContext* aPresContext,
|
||||
nsClientRect* aRect)
|
||||
{
|
||||
double scale = 65536.0;
|
||||
// Round to the nearest 1/scale units. We choose scale so it can be represented
|
||||
// exactly by machine floating point.
|
||||
double scaleInv = 1/scale;
|
||||
double t2pScaled = scale/aPresContext->AppUnitsPerCSSPixel();
|
||||
double x = RoundFloat(aLayoutRect.x*t2pScaled)*scaleInv;
|
||||
double y = RoundFloat(aLayoutRect.y*t2pScaled)*scaleInv;
|
||||
aRect->SetRect(x, y,
|
||||
RoundFloat(aLayoutRect.XMost()*t2pScaled)*scaleInv - x,
|
||||
RoundFloat(aLayoutRect.YMost()*t2pScaled)*scaleInv - y);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSElementTearoff::GetBoundingClientRect(nsIDOMClientRect** aResult)
|
||||
{
|
||||
@@ -1330,7 +1308,7 @@ nsNSElementTearoff::GetBoundingClientRect(nsIDOMClientRect** aResult)
|
||||
nsPresContext* presContext = frame->PresContext();
|
||||
nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
|
||||
GetContainingBlockForClientRect(frame));
|
||||
SetClientRect(r, presContext, rect);
|
||||
rect->SetLayoutRect(r, presContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1350,7 +1328,7 @@ struct RectListBuilder : public nsLayoutUtils::RectCallback {
|
||||
return;
|
||||
}
|
||||
|
||||
SetClientRect(aRect, mPresContext, rect);
|
||||
rect->SetLayoutRect(aRect, mPresContext);
|
||||
mRectList->Append(rect);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -641,6 +641,7 @@ GK_ATOM(onmousemove, "onmousemove")
|
||||
GK_ATOM(onmouseout, "onmouseout")
|
||||
GK_ATOM(onmouseover, "onmouseover")
|
||||
GK_ATOM(onmouseup, "onmouseup")
|
||||
GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
|
||||
GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
|
||||
GK_ATOM(ononline, "ononline")
|
||||
GK_ATOM(onoffline, "onoffline")
|
||||
|
||||
@@ -110,4 +110,6 @@ nsresult
|
||||
NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsNotifyPaintEvent* aEvent);
|
||||
#endif // nsIPrivateDOMEvent_h__
|
||||
|
||||
@@ -94,6 +94,7 @@ CPPSRCS = \
|
||||
nsQueryContentEventHandler.cpp \
|
||||
nsDOMProgressEvent.cpp \
|
||||
nsDOMDataTransfer.cpp \
|
||||
nsDOMNotifyPaintEvent.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
||||
@@ -71,20 +71,19 @@ static const char* const sEventNames[] = {
|
||||
"DOMAttrModified", "DOMCharacterDataModified",
|
||||
"DOMActivate", "DOMFocusIn", "DOMFocusOut",
|
||||
"pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll",
|
||||
"offline", "online", "copy", "cut", "paste"
|
||||
"offline", "online", "copy", "cut", "paste",
|
||||
#ifdef MOZ_SVG
|
||||
,
|
||||
"SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
|
||||
"SVGZoom"
|
||||
"SVGZoom",
|
||||
#endif // MOZ_SVG
|
||||
#ifdef MOZ_MEDIA
|
||||
,
|
||||
"loadstart", "progress", "loadedmetadata", "loadedfirstframe",
|
||||
"emptied", "stalled", "play", "pause",
|
||||
"waiting", "seeking", "seeked", "timeupdate", "ended", "dataunavailable",
|
||||
"canshowcurrentframe", "canplay", "canplaythrough", "ratechange",
|
||||
"durationchange", "volumechange"
|
||||
"durationchange", "volumechange",
|
||||
#endif // MOZ_MEDIA
|
||||
"MozAfterPaint"
|
||||
};
|
||||
|
||||
static char *sPopupAllowedEvents;
|
||||
@@ -648,6 +647,11 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
||||
mEvent->message = NS_MEDIA_ERROR;
|
||||
}
|
||||
#endif // MOZ_MEDIA
|
||||
else if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
|
||||
if (atom == nsGkAtoms::onMozAfterPaint)
|
||||
mEvent->message = NS_AFTERPAINT;
|
||||
}
|
||||
|
||||
if (mEvent->message == NS_USER_DEFINED_EVENT)
|
||||
mEvent->userType = atom;
|
||||
|
||||
@@ -961,6 +965,14 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
static_cast<nsXULCommandEvent*>(mEvent)->sourceEvent;
|
||||
break;
|
||||
}
|
||||
case NS_NOTIFYPAINT_EVENT:
|
||||
{
|
||||
nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
|
||||
newEvent =
|
||||
new nsNotifyPaintEvent(PR_FALSE, msg,
|
||||
event->sameDocRegion, event->crossDocRegion);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_WARNING("Unknown event type!!!");
|
||||
@@ -1465,6 +1477,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
||||
case NS_VOLUMECHANGE:
|
||||
return sEventNames[eDOMEvents_volumechange];
|
||||
#endif
|
||||
case NS_AFTERPAINT:
|
||||
return sEventNames[eDOMEvents_afterpaint];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -129,19 +129,17 @@ public:
|
||||
eDOMEvents_online,
|
||||
eDOMEvents_copy,
|
||||
eDOMEvents_cut,
|
||||
eDOMEvents_paste
|
||||
eDOMEvents_paste,
|
||||
#ifdef MOZ_SVG
|
||||
,
|
||||
eDOMEvents_SVGLoad,
|
||||
eDOMEvents_SVGUnload,
|
||||
eDOMEvents_SVGAbort,
|
||||
eDOMEvents_SVGError,
|
||||
eDOMEvents_SVGResize,
|
||||
eDOMEvents_SVGScroll,
|
||||
eDOMEvents_SVGZoom
|
||||
eDOMEvents_SVGZoom,
|
||||
#endif // MOZ_SVG
|
||||
#ifdef MOZ_MEDIA
|
||||
,
|
||||
eDOMEvents_loadstart,
|
||||
eDOMEvents_progress,
|
||||
eDOMEvents_loadedmetadata,
|
||||
@@ -161,8 +159,9 @@ public:
|
||||
eDOMEvents_canplaythrough,
|
||||
eDOMEvents_ratechange,
|
||||
eDOMEvents_durationchange,
|
||||
eDOMEvents_volumechange
|
||||
eDOMEvents_volumechange,
|
||||
#endif
|
||||
eDOMEvents_afterpaint
|
||||
};
|
||||
|
||||
nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
|
||||
139
content/events/src/nsDOMNotifyPaintEvent.cpp
Normal file
139
content/events/src/nsDOMNotifyPaintEvent.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* -*- 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
|
||||
* Mozilla Corporation
|
||||
* 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 "nsDOMNotifyPaintEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsClientRect.h"
|
||||
|
||||
nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
|
||||
nsNotifyPaintEvent* aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsNotifyPaintEvent(PR_FALSE, 0, nsRegion(), nsRegion()))
|
||||
{
|
||||
if (aEvent) {
|
||||
mEventIsInternal = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEventIsInternal = PR_TRUE;
|
||||
mEvent->time = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMNotifyPaintEvent::~nsDOMNotifyPaintEvent()
|
||||
{
|
||||
if (mEventIsInternal) {
|
||||
if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
|
||||
delete static_cast<nsNotifyPaintEvent*>(mEvent);
|
||||
mEvent = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMNotifyPaintEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNotifyPaintEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(NotifyPaintEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMNotifyPaintEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMNotifyPaintEvent, nsDOMEvent)
|
||||
|
||||
nsRegion
|
||||
nsDOMNotifyPaintEvent::GetRegion()
|
||||
{
|
||||
nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
|
||||
|
||||
nsRegion r;
|
||||
if (nsContentUtils::IsCallerTrustedForRead()) {
|
||||
r.Or(event->sameDocRegion, event->crossDocRegion);
|
||||
} else {
|
||||
r = event->sameDocRegion;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMNotifyPaintEvent::GetBoundingClientRect(nsIDOMClientRect** aResult)
|
||||
{
|
||||
// Weak ref, since we addref it below
|
||||
nsClientRect* rect = new nsClientRect();
|
||||
if (!rect)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult = rect);
|
||||
if (!mPresContext)
|
||||
return NS_OK;
|
||||
|
||||
rect->SetLayoutRect(GetRegion().GetBounds(), mPresContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMNotifyPaintEvent::GetClientRects(nsIDOMClientRectList** aResult)
|
||||
{
|
||||
nsRefPtr<nsClientRectList> rectList = new nsClientRectList();
|
||||
if (!rectList)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsRegion r = GetRegion();
|
||||
nsRegionRectIterator iter(r);
|
||||
for (const nsRect* rgnRect = iter.Next(); rgnRect; rgnRect = iter.Next()) {
|
||||
nsRefPtr<nsClientRect> rect = new nsClientRect();
|
||||
if (!rect)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rect->SetLayoutRect(*rgnRect, mPresContext);
|
||||
rectList->Append(rect);
|
||||
}
|
||||
|
||||
*aResult = rectList.forget().get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsNotifyPaintEvent *aEvent)
|
||||
{
|
||||
nsDOMNotifyPaintEvent* it =
|
||||
new nsDOMNotifyPaintEvent(aPresContext, aEvent);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(it, aInstancePtrResult);
|
||||
}
|
||||
64
content/events/src/nsDOMNotifyPaintEvent.h
Normal file
64
content/events/src/nsDOMNotifyPaintEvent.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* -*- 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
|
||||
* Mozilla Corporation
|
||||
* 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 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 nsDOMNotifyPaintEvent_h_
|
||||
#define nsDOMNotifyPaintEvent_h_
|
||||
|
||||
#include "nsIDOMNotifyPaintEvent.h"
|
||||
#include "nsDOMEvent.h"
|
||||
|
||||
class nsDOMNotifyPaintEvent : public nsIDOMNotifyPaintEvent,
|
||||
public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
|
||||
nsNotifyPaintEvent* aEvent);
|
||||
virtual ~nsDOMNotifyPaintEvent();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIDOMNOTIFYPAINTEVENT
|
||||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
private:
|
||||
nsRegion GetRegion();
|
||||
};
|
||||
|
||||
#endif // nsDOMNotifyPaintEvent_h_
|
||||
@@ -611,6 +611,10 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
case NS_COMMAND_EVENT:
|
||||
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsCommandEvent*>(aEvent));
|
||||
case NS_NOTIFYPAINT_EVENT:
|
||||
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsNotifyPaintEvent*>
|
||||
(aEvent));
|
||||
}
|
||||
|
||||
// For all other types of events, create a vanilla event object.
|
||||
@@ -667,6 +671,8 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
return NS_NewDOMMessageEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("progressevent"))
|
||||
return NS_NewDOMProgressEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("notifypaintevent"))
|
||||
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ REQUIRES = xpcom \
|
||||
|
||||
EXPORTS = \
|
||||
nsImageMapUtils.h \
|
||||
nsClientRect.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
|
||||
#include "nsPresContext.h"
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsClientRect)
|
||||
NS_INTERFACE_TABLE1(nsClientRect, nsIDOMClientRect)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
@@ -124,3 +126,23 @@ nsClientRectList::Item(PRUint32 aIndex, nsIDOMClientRect** aReturn)
|
||||
NS_IF_ADDREF(*aReturn = mArray.ObjectAt(aIndex));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static double
|
||||
RoundFloat(double aValue)
|
||||
{
|
||||
return floor(aValue + 0.5);
|
||||
}
|
||||
|
||||
void
|
||||
nsClientRect::SetLayoutRect(const nsRect& aLayoutRect, nsPresContext* aPresContext)
|
||||
{
|
||||
double scale = 65536.0;
|
||||
// Round to the nearest 1/scale units. We choose scale so it can be represented
|
||||
// exactly by machine floating point.
|
||||
double scaleInv = 1/scale;
|
||||
double t2pScaled = scale/aPresContext->AppUnitsPerCSSPixel();
|
||||
double x = RoundFloat(aLayoutRect.x*t2pScaled)*scaleInv;
|
||||
double y = RoundFloat(aLayoutRect.y*t2pScaled)*scaleInv;
|
||||
SetRect(x, y, RoundFloat(aLayoutRect.XMost()*t2pScaled)*scaleInv - x,
|
||||
RoundFloat(aLayoutRect.YMost()*t2pScaled)*scaleInv - y);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
#include "nsIDOMClientRect.h"
|
||||
#include "nsIDOMClientRectList.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsPresContext;
|
||||
|
||||
class nsClientRect : public nsIDOMClientRect
|
||||
{
|
||||
@@ -56,6 +59,8 @@ public:
|
||||
|
||||
NS_DECL_NSIDOMCLIENTRECT
|
||||
|
||||
void SetLayoutRect(const nsRect& aLayoutRect, nsPresContext* aPresContext);
|
||||
|
||||
protected:
|
||||
float mX, mY, mWidth, mHeight;
|
||||
};
|
||||
|
||||
@@ -552,7 +552,7 @@ nsHTMLCanvasElement::InvalidateFrame()
|
||||
if (frame) {
|
||||
nsRect r = frame->GetRect();
|
||||
r.x = r.y = 0;
|
||||
frame->Invalidate(r, PR_FALSE);
|
||||
frame->Invalidate(r);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -563,7 +563,7 @@ nsHTMLCanvasElement::InvalidateFrameSubrect(const nsRect& damageRect)
|
||||
{
|
||||
nsIFrame *frame = GetPrimaryFrame(Flush_Frames);
|
||||
if (frame) {
|
||||
frame->Invalidate(damageRect, PR_FALSE);
|
||||
frame->Invalidate(damageRect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -140,7 +140,7 @@ void nsVideoDecoder::Invalidate()
|
||||
}
|
||||
}
|
||||
nsRect r(nsPoint(0,0), frame->GetSize());
|
||||
frame->Invalidate(r, PR_FALSE);
|
||||
frame->Invalidate(r);
|
||||
}
|
||||
|
||||
static void ProgressCallback(nsITimer* aTimer, void* aClosure)
|
||||
|
||||
@@ -76,6 +76,7 @@ XPIDLSRCS = \
|
||||
nsIDOMPageTransitionEvent.idl \
|
||||
nsIDOMCommandEvent.idl \
|
||||
nsIDOMMessageEvent.idl \
|
||||
nsIDOMNotifyPaintEvent.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
67
dom/public/idl/events/nsIDOMNotifyPaintEvent.idl
Normal file
67
dom/public/idl/events/nsIDOMNotifyPaintEvent.idl
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- 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 Corporation
|
||||
* 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 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 "nsIDOMEvent.idl"
|
||||
|
||||
/**
|
||||
* The nsIDOMNotifyPaintEvent interface is used for the MozDOMAfterPaint
|
||||
* event, which fires at a window when painting has happened in
|
||||
* that window.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(dec5582e-5cea-412f-bf98-6b27480fb46a)]
|
||||
interface nsIDOMNotifyPaintEvent : nsIDOMEvent
|
||||
{
|
||||
/**
|
||||
* Get a list of rectangles which are affected. The rectangles are in CSS pixels
|
||||
* relative to the viewport origin.
|
||||
* If the caller is not trusted (e.g., regular Web content) then only painting
|
||||
* caused by the current document is reported; in particular, painting in subdocuments
|
||||
* is not reported.
|
||||
*/
|
||||
readonly attribute nsIDOMClientRectList clientRects;
|
||||
/**
|
||||
* Get the bounding box of the rectangles which are affected. The rectangle
|
||||
* is in CSS pixels relative to the viewport origin.
|
||||
* If the caller is not trusted (e.g., regular Web content) then only painting
|
||||
* caused by the current document is reported; in particular, painting in subdocuments
|
||||
* is not reported.
|
||||
*/
|
||||
readonly attribute nsIDOMClientRect boundingClientRect;
|
||||
};
|
||||
|
||||
@@ -451,6 +451,8 @@ enum nsDOMClassInfoID {
|
||||
|
||||
eDOMClassInfo_DataTransfer_id,
|
||||
|
||||
eDOMClassInfo_NotifyPaintEvent_id,
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
#include "nsIDOMXULCommandEvent.h"
|
||||
#include "nsIDOMPageTransitionEvent.h"
|
||||
#include "nsIDOMMessageEvent.h"
|
||||
#include "nsIDOMNotifyPaintEvent.h"
|
||||
#include "nsIDOMNSDocumentStyle.h"
|
||||
#include "nsIDOMDocumentRange.h"
|
||||
#include "nsIDOMDocumentTraversal.h"
|
||||
@@ -1290,6 +1291,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(DataTransfer, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(NotifyPaintEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
};
|
||||
|
||||
// Objects that shuld be constructable through |new Name();|
|
||||
@@ -3529,6 +3532,11 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSDataTransfer)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(NotifyPaintEvent, nsIDOMNotifyPaintEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNotifyPaintEvent)
|
||||
DOM_CLASSINFO_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||
|
||||
@@ -178,7 +178,7 @@ nsDOMWindowUtils::Redraw(PRUint32 aCount, PRUint32 *aDurationOut)
|
||||
PRIntervalTime iStart = PR_IntervalNow();
|
||||
|
||||
for (PRUint32 i = 0; i < aCount; i++)
|
||||
rootFrame->Invalidate(r, PR_TRUE);
|
||||
rootFrame->InvalidateWithFlags(r, nsIFrame::INVALIDATE_IMMEDIATE);
|
||||
|
||||
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
|
||||
XSync(GDK_DISPLAY(), False);
|
||||
|
||||
@@ -1278,7 +1278,7 @@ void nsCaret::InvalidateRects(const nsRect &aRect, const nsRect &aHook,
|
||||
NS_ASSERTION(aFrame, "Must have a frame to invalidate");
|
||||
nsRect rect;
|
||||
rect.UnionRect(aRect, aHook);
|
||||
aFrame->Invalidate(rect, PR_FALSE);
|
||||
aFrame->Invalidate(rect);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -257,5 +257,5 @@ nsImageLoader::RedrawDirtyFrame(const nsRect* aDamageRect)
|
||||
|
||||
#endif
|
||||
|
||||
mFrame->Invalidate(bounds, PR_FALSE);
|
||||
mFrame->Invalidate(bounds);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
#include "nsStyleChangeList.h"
|
||||
#include "nsRuleNode.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsBidiPresUtils.h"
|
||||
@@ -1569,3 +1570,54 @@ nsPresContext::HasAuthorSpecifiedRules(nsIFrame *aFrame, PRUint32 ruleTypeMask)
|
||||
return nsRuleNode::
|
||||
HasAuthorSpecifiedRules(aFrame->GetStyleContext(), ruleTypeMask);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::FireDOMPaintEvent()
|
||||
{
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
|
||||
if (!docShell)
|
||||
return;
|
||||
nsCOMPtr<nsPIDOMWindow> ourWindow = do_GetInterface(docShell);
|
||||
nsISupports* eventTarget = ourWindow;
|
||||
if (mSameDocDirtyRegion.IsEmpty() && !IsChrome()) {
|
||||
// Don't tell the window about this event, it should not know that
|
||||
// something happened in a subdocument. Tell only the chrome event handler.
|
||||
// (Events sent to the window get propagated to the chrome event handler
|
||||
// automatically.)
|
||||
eventTarget = ourWindow->GetChromeEventHandler();
|
||||
}
|
||||
// Events sent to the window get propagated to the chrome event handler
|
||||
// automatically.
|
||||
|
||||
nsNotifyPaintEvent event(PR_TRUE, NS_AFTERPAINT, mSameDocDirtyRegion,
|
||||
mCrossDocDirtyRegion);
|
||||
// Empty our regions now in case dispatching the event causes more damage
|
||||
// (hopefully it won't, or we're likely to get an infinite loop! At least
|
||||
// it won't be blocking app execution though).
|
||||
mSameDocDirtyRegion.SetEmpty();
|
||||
mCrossDocDirtyRegion.SetEmpty();
|
||||
// Even if we're not telling the window about the event (so eventTarget is
|
||||
// the chrome event handler, not the window), the window is still
|
||||
// logically the event target.
|
||||
event.target = do_QueryInterface(ourWindow);
|
||||
nsEventDispatcher::Dispatch(eventTarget, this, &event);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::NotifyInvalidation(const nsRect& aRect, PRBool aIsCrossDoc)
|
||||
{
|
||||
if (aRect.IsEmpty())
|
||||
return;
|
||||
|
||||
if (mSameDocDirtyRegion.IsEmpty() && mCrossDocDirtyRegion.IsEmpty()) {
|
||||
// No event is pending. Dispatch one now.
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsRunnableMethod<nsPresContext>(this,
|
||||
&nsPresContext::FireDOMPaintEvent);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
}
|
||||
|
||||
nsRegion* r = aIsCrossDoc ? &mCrossDocDirtyRegion : &mSameDocDirtyRegion;
|
||||
r->Or(*r, aRect);
|
||||
r->SimplifyOutward(10);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "nsChangeHint.h"
|
||||
// This also pulls in gfxTypes.h, which we cannot include directly.
|
||||
#include "gfxRect.h"
|
||||
#include "nsRegion.h"
|
||||
class nsImageLoader;
|
||||
#ifdef IBMBIDI
|
||||
class nsBidiPresUtils;
|
||||
@@ -778,6 +779,9 @@ public:
|
||||
|
||||
PRBool SupressingResizeReflow() const { return mSupressResizeReflow; }
|
||||
|
||||
void NotifyInvalidation(const nsRect& aRect, PRBool aIsCrossDoc);
|
||||
void FireDOMPaintEvent();
|
||||
|
||||
protected:
|
||||
friend class nsRunnableMethod<nsPresContext>;
|
||||
NS_HIDDEN_(void) ThemeChangedInternal();
|
||||
@@ -838,6 +842,9 @@ protected:
|
||||
|
||||
nsPropertyTable mPropertyTable;
|
||||
|
||||
nsRegion mSameDocDirtyRegion;
|
||||
nsRegion mCrossDocDirtyRegion;
|
||||
|
||||
nsLanguageSpecificTransformType mLanguageSpecificTransformType;
|
||||
PRInt32 mFontScaler;
|
||||
nscoord mMinimumFontSize;
|
||||
|
||||
@@ -4312,7 +4312,7 @@ PresShell::UnsuppressAndInvalidate()
|
||||
if (rootFrame) {
|
||||
// let's assume that outline on a root frame is not supported
|
||||
nsRect rect(nsPoint(0, 0), rootFrame->GetSize());
|
||||
rootFrame->Invalidate(rect, PR_FALSE);
|
||||
rootFrame->Invalidate(rect);
|
||||
}
|
||||
|
||||
// This makes sure to get the same thing that nsPresContext::EnsureVisible()
|
||||
|
||||
@@ -92,6 +92,7 @@ _TEST_FILES = \
|
||||
test_bug423523.html \
|
||||
test_bug445810.html \
|
||||
test_bug449781.html \
|
||||
test_bug450930.xhtml \
|
||||
$(NULL)
|
||||
# test_bug396024.html is currently disabled because it interacts badly with
|
||||
# the "You can't print-preview while the page is loading" dialog.
|
||||
|
||||
211
layout/base/tests/test_bug450930.xhtml
Normal file
211
layout/base/tests/test_bug450930.xhtml
Normal file
@@ -0,0 +1,211 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=450930
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 450930</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.cgi?id=450930">Mozilla Bug 450930</a>
|
||||
<div id="display">
|
||||
<div id="d" style="width:400px; height:200px;"></div>
|
||||
<iframe id="iframe" style="width:400px; height:200px;"
|
||||
src="data:text/html,<div id='d'>Hello</div><div style='margin-top:500px' id='d2'>Hello</div>"></iframe>
|
||||
<svg:svg style="width:410px; height:210px;" id="svg">
|
||||
<svg:foreignObject width="100%" height="100%">
|
||||
<iframe id="iframe2" style="width:400px; height:200px;"
|
||||
src="data:text/html,<div id='d'>Hello</div><div style='margin-top:500px' id='d2'>Hello</div>"></iframe>
|
||||
</svg:foreignObject>
|
||||
</svg:svg>
|
||||
</div>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 450930 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function flash(doc, name) {
|
||||
var d = doc.getElementById(name);
|
||||
d.style.backgroundColor = d.style.backgroundColor == "blue" ? "yellow" : "blue";
|
||||
}
|
||||
|
||||
function le(v1, v2, s) {
|
||||
ok(v1 <= v2, s + " (" + v1 + "," + v2 + ")");
|
||||
}
|
||||
|
||||
function checkContains(r1, r2, s) {
|
||||
le(r1.left, r2.left, "Left edges out" + s);
|
||||
le(r2.right, r1.right, "Right edges out" + s);
|
||||
le(r1.top, r2.top, "Top edges out" + s);
|
||||
le(r2.bottom, r1.bottom, "Bottom edges out" + s);
|
||||
}
|
||||
|
||||
function isRect(r1, r2) {
|
||||
return r1.left == r2.left && r1.right == r2.right &&
|
||||
r1.top == r2.top && r1.bottom == r2.bottom;
|
||||
}
|
||||
|
||||
function isRectInList(r, list) {
|
||||
for (var i = 0; i < list.length; ++i) {
|
||||
if (isRect(r, list[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function doesRectContain(r1, r2) {
|
||||
return r1.left <= r2.left && r2.right <= r1.right &&
|
||||
r1.top <= r2.top && r2.bottom <= r1.bottom;
|
||||
}
|
||||
|
||||
function rectToString(r) {
|
||||
return "(" + r.left + "," + r.top + "," + r.right + "," + r.bottom + ")";
|
||||
}
|
||||
|
||||
function doesRectContainListElement(r, list) {
|
||||
dump("Incoming rect: " + rectToString(r) + "\n");
|
||||
for (var i = 0; i < list.length; ++i) {
|
||||
dump("List rect " + i + ": " + rectToString(list[i]));
|
||||
if (doesRectContain(r, list[i])) {
|
||||
dump(" FOUND\n");
|
||||
return true;
|
||||
}
|
||||
dump("\n");
|
||||
}
|
||||
dump("NOT FOUND\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkGotSubdoc(list, container) {
|
||||
var r = container.getBoundingClientRect();
|
||||
return doesRectContainListElement(r, list);
|
||||
}
|
||||
|
||||
function runTest1() {
|
||||
// test basic functionality
|
||||
var iterations = 0;
|
||||
var foundExactRect = false;
|
||||
|
||||
function listener(event) {
|
||||
var r = event.boundingClientRect;
|
||||
var bounds = document.getElementById('d').getBoundingClientRect();
|
||||
checkContains(r, bounds, "");
|
||||
if (isRectInList(bounds, event.clientRects)) {
|
||||
foundExactRect = true;
|
||||
}
|
||||
window.removeEventListener("MozAfterPaint", listener, false);
|
||||
++iterations;
|
||||
if (iterations < 4) {
|
||||
setTimeout(triggerPaint, 100);
|
||||
} else {
|
||||
ok(foundExactRect, "Found exact rect");
|
||||
runNext();
|
||||
}
|
||||
}
|
||||
|
||||
function triggerPaint() {
|
||||
window.addEventListener("MozAfterPaint", listener, false);
|
||||
flash(document, 'd');
|
||||
}
|
||||
triggerPaint();
|
||||
}
|
||||
|
||||
function runTest2(frameID, containerID) {
|
||||
// test reporting of painting in subdocuments
|
||||
var fired = false;
|
||||
var gotSubdocPrivileged = false;
|
||||
var gotSubdocNonprivileged = false;
|
||||
var iframe = document.getElementById(frameID);
|
||||
var container = document.getElementById(containerID);
|
||||
|
||||
function listener(event) {
|
||||
fired = true;
|
||||
if (checkGotSubdoc(event.clientRects, container))
|
||||
gotSubdocNonprivileged = true;
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
if (checkGotSubdoc(event.clientRects, container))
|
||||
gotSubdocPrivileged = true;
|
||||
}
|
||||
|
||||
function check() {
|
||||
ok(fired, "Event fired (" + frameID + ")");
|
||||
ok(gotSubdocPrivileged, "Didn't get subdoc invalidation while we were privileged (" + frameID + ")");
|
||||
ok(!gotSubdocNonprivileged, "Got subdoc invalidation while we were not privileged (" + frameID + ")");
|
||||
window.removeEventListener("MozAfterPaint", listener, false);
|
||||
runNext();
|
||||
}
|
||||
|
||||
function triggerPaint() {
|
||||
window.addEventListener("MozAfterPaint", listener, false);
|
||||
setTimeout(check, 100);
|
||||
document.body.offsetTop;
|
||||
flash(iframe.contentDocument, 'd');
|
||||
// make sure an event fires; since we're not using a chrome event handler, even though we
|
||||
// can get privileges we wouldn't get the event
|
||||
flash(document, 'd');
|
||||
}
|
||||
triggerPaint();
|
||||
}
|
||||
|
||||
function runTest3() {
|
||||
// test reporting of painting of scrolled-out-of-view areas
|
||||
var gotScrolledOutInMainDoc = false;
|
||||
var gotScrolledOutInSubdoc = false;
|
||||
var iframe = document.getElementById("iframe");
|
||||
|
||||
function listener(event) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
if (checkGotSubdoc(event.clientRects, iframe))
|
||||
gotScrolledOutInMainDoc = true;
|
||||
}
|
||||
|
||||
function IFRAMEListener(event) {
|
||||
if (doesRectContainListElement(
|
||||
iframe.contentDocument.getElementById("d2").getBoundingClientRect(), event.clientRects))
|
||||
gotScrolledOutInSubdoc = true;
|
||||
}
|
||||
|
||||
function check() {
|
||||
ok(!gotScrolledOutInMainDoc, "scrolled-out invalidation should not propagate to main doc");
|
||||
ok(gotScrolledOutInSubdoc, "scrolled-out invalidation should notify in subdoc");
|
||||
window.removeEventListener("MozAfterPaint", listener, false);
|
||||
iframe.contentWindow.removeEventListener("MozAfterPaint", IFRAMEListener, false);
|
||||
runNext();
|
||||
}
|
||||
|
||||
function triggerPaint() {
|
||||
window.addEventListener("MozAfterPaint", listener, false);
|
||||
iframe.contentWindow.addEventListener("MozAfterPaint", IFRAMEListener, false);
|
||||
setTimeout(check, 100);
|
||||
flash(iframe.contentDocument, 'd2');
|
||||
}
|
||||
triggerPaint();
|
||||
}
|
||||
|
||||
var test = 0;
|
||||
var tests = [runTest1,
|
||||
function() { runTest2("iframe", "iframe") },
|
||||
function() { runTest2("iframe2", "svg") },
|
||||
runTest3];
|
||||
function runNext() {
|
||||
if (test < tests.length) {
|
||||
++test;
|
||||
tests[test - 1]();
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = runNext();
|
||||
]]></script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -360,7 +360,7 @@ nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
|
||||
// This is needed on a temporary basis. It causes the focus
|
||||
// rect to be drawn. This is much faster than ReResolvingStyle
|
||||
// Bug 32920
|
||||
Invalidate(nsRect(0,0,mRect.width,mRect.height), PR_FALSE);
|
||||
Invalidate(nsRect(0,0,mRect.width,mRect.height));
|
||||
|
||||
// Make sure the content area gets updated for where the dropdown was
|
||||
// This is only needed for embedding, the focus may go to
|
||||
|
||||
@@ -165,7 +165,7 @@ NS_IMETHODIMP
|
||||
nsGfxCheckboxControlFrame::OnChecked(nsPresContext* aPresContext,
|
||||
PRBool aChecked)
|
||||
{
|
||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ NS_IMETHODIMP
|
||||
nsGfxRadioControlFrame::OnChecked(nsPresContext* aPresContext,
|
||||
PRBool aChecked)
|
||||
{
|
||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1818,11 +1818,13 @@ nsListControlFrame::IsContainingBlock() const
|
||||
void
|
||||
nsListControlFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (!IsInDropDownMode())
|
||||
nsHTMLScrollFrame::InvalidateInternal(aDamageRect, aX, aY, this, aImmediate);
|
||||
InvalidateRoot(aDamageRect, aX, aY, aImmediate);
|
||||
if (!IsInDropDownMode()) {
|
||||
nsHTMLScrollFrame::InvalidateInternal(aDamageRect, aX, aY, this, aFlags);
|
||||
return;
|
||||
}
|
||||
InvalidateRoot(aDamageRect + nsPoint(aX, aY), aFlags);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug
|
||||
|
||||
@@ -484,7 +484,7 @@ nsBlockFrame::GetType() const
|
||||
void
|
||||
nsBlockFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
// Optimize by suppressing invalidation of areas that are clipped out
|
||||
// with CSS 'clip'.
|
||||
@@ -495,12 +495,12 @@ nsBlockFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
// abs-pos clipping clips everything in the frame
|
||||
nsRect r;
|
||||
if (r.IntersectRect(aDamageRect, absPosClipRect - nsPoint(aX, aY))) {
|
||||
nsBlockFrameSuper::InvalidateInternal(r, aX, aY, this, aImmediate);
|
||||
nsBlockFrameSuper::InvalidateInternal(r, aX, aY, this, aFlags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsBlockFrameSuper::InvalidateInternal(aDamageRect, aX, aY, this, aImmediate);
|
||||
nsBlockFrameSuper::InvalidateInternal(aDamageRect, aX, aY, this, aFlags);
|
||||
}
|
||||
|
||||
nscoord
|
||||
|
||||
@@ -187,7 +187,7 @@ public:
|
||||
const nsDisplayListSet& aLists);
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
virtual nsIAtom* GetType() const;
|
||||
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
||||
@@ -1467,7 +1467,7 @@ NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
// The image has changed.
|
||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||
// always correct, and I'll be a stunned mullet if it ever matters for performance
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height), PR_FALSE);
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1497,7 +1497,7 @@ NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIContainer *aContainer,
|
||||
{
|
||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||
// always correct.
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height), PR_FALSE);
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -3634,8 +3634,7 @@ nsIFrame::IsLeaf() const
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::Invalidate(const nsRect& aDamageRect,
|
||||
PRBool aImmediate)
|
||||
nsIFrame::InvalidateWithFlags(const nsRect& aDamageRect, PRUint32 aFlags)
|
||||
{
|
||||
if (aDamageRect.IsEmpty()) {
|
||||
return;
|
||||
@@ -3651,7 +3650,7 @@ nsIFrame::Invalidate(const nsRect& aDamageRect,
|
||||
return;
|
||||
}
|
||||
|
||||
InvalidateInternal(aDamageRect, 0, 0, nsnull, aImmediate);
|
||||
InvalidateInternal(aDamageRect, 0, 0, nsnull, aFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3667,7 +3666,7 @@ nsIFrame::Invalidate(const nsRect& aDamageRect,
|
||||
*/
|
||||
void
|
||||
nsIFrame::InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
|
||||
nscoord aY, PRBool aImmediate)
|
||||
nscoord aY, PRUint32 aFlags)
|
||||
{
|
||||
/* If we're a transformed frame, then we need to apply our transform to the
|
||||
* damage rectangle so that the redraw correctly redraws the transformed
|
||||
@@ -3692,16 +3691,16 @@ nsIFrame::InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
|
||||
(aDamageRect, this, nsPoint(-aX, -aY)), aDamageRect);
|
||||
GetParent()->
|
||||
InvalidateInternal(newDamageRect, aX + mRect.x, aY + mRect.y, this,
|
||||
aImmediate);
|
||||
aFlags);
|
||||
}
|
||||
else
|
||||
GetParent()->
|
||||
InvalidateInternal(aDamageRect, aX + mRect.x, aY + mRect.y, this, aImmediate);
|
||||
InvalidateInternal(aDamageRect, aX + mRect.x, aY + mRect.y, this, aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY,
|
||||
nsIFrame* aForChild, PRBool aImmediate)
|
||||
nsIFrame* aForChild, PRUint32 aFlags)
|
||||
{
|
||||
#ifdef MOZ_SVG
|
||||
if (nsSVGIntegrationUtils::UsingEffectsForFrame(this)) {
|
||||
@@ -3711,12 +3710,12 @@ nsIFrame::InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY,
|
||||
* zero. Thus we'll pretend that the entire time this was in our own
|
||||
* local coordinate space and do any remaining processing.
|
||||
*/
|
||||
InvalidateInternalAfterResize(r, 0, 0, aImmediate);
|
||||
InvalidateInternalAfterResize(r, 0, 0, aFlags);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
InvalidateInternalAfterResize(aDamageRect, aX, aY, aImmediate);
|
||||
InvalidateInternalAfterResize(aDamageRect, aX, aY, aFlags);
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
@@ -3800,13 +3799,16 @@ nsIFrame::InvalidateOverflowRect()
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateRoot(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, PRBool aImmediate)
|
||||
nsIFrame::InvalidateRoot(const nsRect& aDamageRect, PRUint32 aFlags)
|
||||
{
|
||||
PRUint32 flags = aImmediate ? NS_VMREFRESH_IMMEDIATE : NS_VMREFRESH_NO_SYNC;
|
||||
if (aFlags & INVALIDATE_NOTIFY_ONLY)
|
||||
return;
|
||||
|
||||
PRUint32 flags =
|
||||
(aFlags & INVALIDATE_IMMEDIATE) ? NS_VMREFRESH_IMMEDIATE : NS_VMREFRESH_NO_SYNC;
|
||||
nsIView* view = GetView();
|
||||
NS_ASSERTION(view, "This can only be called on frames with views");
|
||||
view->GetViewManager()->UpdateView(view, aDamageRect + nsPoint(aX, aY), flags);
|
||||
view->GetViewManager()->UpdateView(view, aDamageRect, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4443,7 +4445,7 @@ nsFrame::SetSelected(nsPresContext* aPresContext, nsIDOMRange *aRange, PRBool aS
|
||||
RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
|
||||
// Repaint this frame subtree's entire area
|
||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
|
||||
#ifdef IBMBIDI
|
||||
PRInt32 start, end;
|
||||
|
||||
@@ -567,7 +567,7 @@ nsSubDocumentFrame::Reflow(nsPresContext* aPresContext,
|
||||
// Invalidate the frame contents
|
||||
// XXX is this really needed?
|
||||
nsRect rect(nsPoint(0, 0), GetSize());
|
||||
Invalidate(rect, PR_FALSE);
|
||||
Invalidate(rect);
|
||||
|
||||
if (!aPresContext->IsPaginated() && !mPostedReflowCallback) {
|
||||
PresContext()->PresShell()->PostReflowCallback(this);
|
||||
|
||||
@@ -227,19 +227,30 @@ nsHTMLScrollFrame::GetType() const
|
||||
void
|
||||
nsHTMLScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (aForChild == mInner.mScrolledFrame) {
|
||||
if (aForChild == mInner.mScrolledFrame && !(aFlags & INVALIDATE_NOTIFY_ONLY)) {
|
||||
// restrict aDamageRect to the scrollable view's bounds
|
||||
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
||||
nsRect r;
|
||||
if (r.IntersectRect(aDamageRect + nsPoint(aX, aY),
|
||||
mInner.mScrollableView->View()->GetBounds())) {
|
||||
nsHTMLContainerFrame::InvalidateInternal(r, 0, 0, aForChild, aImmediate);
|
||||
if (r.IntersectRect(damage, mInner.mScrollableView->View()->GetBounds())) {
|
||||
nsHTMLContainerFrame::InvalidateInternal(r, 0, 0, aForChild, aFlags);
|
||||
}
|
||||
if (mInner.mIsRoot && r != damage) {
|
||||
// Make sure we notify our prescontext about invalidations outside
|
||||
// viewport clipping.
|
||||
// This is important for things that are snapshotting the viewport,
|
||||
// possibly outside the scrolled bounds.
|
||||
// We don't need to propagate this any further up, though. Anyone who
|
||||
// cares about scrolled-out-of-view invalidates had better be listening
|
||||
// to our window directly.
|
||||
PresContext()->NotifyInvalidation(damage,
|
||||
(aFlags & INVALIDATE_CROSS_DOC) != 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsHTMLContainerFrame::InvalidateInternal(aDamageRect, aX, aY, aForChild, aImmediate);
|
||||
nsHTMLContainerFrame::InvalidateInternal(aDamageRect, aX, aY, aForChild, aFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1097,19 +1108,19 @@ nsXULScrollFrame::GetType() const
|
||||
void
|
||||
nsXULScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (aForChild == mInner.mScrolledFrame) {
|
||||
// restrict aDamageRect to the scrollable view's bounds
|
||||
nsRect r;
|
||||
if (r.IntersectRect(aDamageRect + nsPoint(aX, aY),
|
||||
mInner.mScrollableView->View()->GetBounds())) {
|
||||
nsBoxFrame::InvalidateInternal(r, 0, 0, aForChild, aImmediate);
|
||||
nsBoxFrame::InvalidateInternal(r, 0, 0, aForChild, aFlags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsBoxFrame::InvalidateInternal(aDamageRect, aX, aY, aForChild, aImmediate);
|
||||
nsBoxFrame::InvalidateInternal(aDamageRect, aX, aY, aForChild, aFlags);
|
||||
}
|
||||
|
||||
nscoord
|
||||
@@ -1822,6 +1833,9 @@ nsGfxScrollFrameInner::ScrollPositionDidChange(nsIScrollableView* aScrollable, n
|
||||
|
||||
PostScrollEvent();
|
||||
|
||||
// Notify that the display has changed
|
||||
mOuter->InvalidateWithFlags(nsRect(nsPoint(0, 0), mOuter->GetSize()),
|
||||
nsIFrame::INVALIDATE_NOTIFY_ONLY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ public:
|
||||
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
|
||||
virtual PRBool NeedsView() { return PR_TRUE; }
|
||||
virtual PRBool DoesClipChildren() { return PR_TRUE; }
|
||||
@@ -478,7 +478,7 @@ public:
|
||||
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
|
||||
virtual PRBool NeedsView() { return PR_TRUE; }
|
||||
virtual PRBool DoesClipChildren() { return PR_TRUE; }
|
||||
|
||||
@@ -160,7 +160,7 @@ nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
FinishAndStoreOverflow(&aMetrics);
|
||||
|
||||
if (mRect.width != aMetrics.width || mRect.height != aMetrics.height) {
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height), PR_FALSE);
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
||||
}
|
||||
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||
|
||||
@@ -370,7 +370,7 @@ CanvasFrame::RemoveFrame(nsIAtom* aListName,
|
||||
// Damage the area occupied by the deleted frame
|
||||
// The child of the canvas probably can't have an outline, but why bother
|
||||
// thinking about that?
|
||||
Invalidate(aOldFrame->GetOverflowRect() + aOldFrame->GetPosition(), PR_FALSE);
|
||||
Invalidate(aOldFrame->GetOverflowRect() + aOldFrame->GetPosition());
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aOldFrame);
|
||||
|
||||
@@ -105,10 +105,10 @@ struct nsMargin;
|
||||
typedef class nsIFrame nsIBox;
|
||||
|
||||
// IID for the nsIFrame interface
|
||||
// bc99463c-5ff7-4ff3-b2c8-b4172646f793
|
||||
// 626a1563-1bae-4a6e-8d2c-2dc2c13048dd
|
||||
#define NS_IFRAME_IID \
|
||||
{ 0xbc99463c, 0x5ff7, 0x4ff3, \
|
||||
{ 0xb2, 0xc8, 0xb4, 0x17, 0x26, 0x46, 0xf7, 0x93 } }
|
||||
{ 0x626a1563, 0x1bae, 0x4a6e, \
|
||||
{ 0x8d, 0x2c, 0x2d, 0xc2, 0xc1, 0x30, 0x48, 0xdd } }
|
||||
|
||||
/**
|
||||
* Indication of how the frame can be split. This is used when doing runaround
|
||||
@@ -1652,6 +1652,11 @@ public:
|
||||
*/
|
||||
virtual nsIView* GetMouseCapturer() const { return nsnull; }
|
||||
|
||||
/**
|
||||
* @param aFlags see InvalidateInternal below
|
||||
*/
|
||||
void InvalidateWithFlags(const nsRect& aDamageRect, PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
* Invalidate part of the frame by asking the view manager to repaint.
|
||||
* aDamageRect is allowed to extend outside the frame's bounds. We'll do the right
|
||||
@@ -1661,11 +1666,9 @@ public:
|
||||
* need to be repainted.
|
||||
*
|
||||
* @param aDamageRect is in the frame's local coordinate space
|
||||
* @param aImmediate repaint now if true, repaint later if false.
|
||||
* In case it's true, pending notifications will be flushed which
|
||||
* could cause frames to be deleted (including |this|).
|
||||
*/
|
||||
void Invalidate(const nsRect& aDamageRect, PRBool aImmediate = PR_FALSE);
|
||||
void Invalidate(const nsRect& aDamageRect)
|
||||
{ return InvalidateWithFlags(aDamageRect, 0); }
|
||||
|
||||
/**
|
||||
* Helper function that can be overridden by frame classes. The rectangle
|
||||
@@ -1681,13 +1684,20 @@ public:
|
||||
*
|
||||
* @param aForChild if the invalidation is coming from a child frame, this
|
||||
* is the frame; otherwise, this is null.
|
||||
* @param aImmediate repaint now if true, repaint later if false.
|
||||
* @param aFlags INVALIDATE_IMMEDIATE: repaint now if true, repaint later if false.
|
||||
* In case it's true, pending notifications will be flushed which
|
||||
* could cause frames to be deleted (including |this|).
|
||||
* @param aFlags INVALIDATE_CROSS_DOC: true if the invalidation
|
||||
* originated in a subdocument
|
||||
*/
|
||||
enum {
|
||||
INVALIDATE_IMMEDIATE = 0x1,
|
||||
INVALIDATE_CROSS_DOC = 0x2,
|
||||
INVALIDATE_NOTIFY_ONLY = 0x4
|
||||
};
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aOffsetX, nscoord aOffsetY,
|
||||
nsIFrame* aForChild, PRBool aImmediate);
|
||||
nsIFrame* aForChild, PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
* Helper function that funnels an InvalidateInternal request up to the
|
||||
@@ -1701,7 +1711,7 @@ public:
|
||||
* @return None, though this funnels the request up to the parent frame.
|
||||
*/
|
||||
void InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
|
||||
nscoord aY, PRBool aImmediate);
|
||||
nscoord aY, PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
* Take two rectangles in the coordinate system of this frame which
|
||||
@@ -2221,9 +2231,7 @@ protected:
|
||||
* For frames that have top-level windows (top-level viewports,
|
||||
* comboboxes, menupoups) this function will invalidate the window.
|
||||
*/
|
||||
void InvalidateRoot(const nsRect& aDamageRect,
|
||||
nscoord aOffsetX, nscoord aOffsetY,
|
||||
PRBool aImmediate);
|
||||
void InvalidateRoot(const nsRect& aDamageRect, PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
* Gets the overflow area for any properties that are common to all types of frames
|
||||
|
||||
@@ -552,7 +552,7 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
// handle iconLoads first...
|
||||
if (HandleIconLoads(aRequest, PR_FALSE)) {
|
||||
// Image changed, invalidate
|
||||
Invalidate(r, PR_FALSE);
|
||||
Invalidate(r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -580,7 +580,7 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
r.x, r.y, r.width, r.height);
|
||||
#endif
|
||||
|
||||
Invalidate(r, PR_FALSE);
|
||||
Invalidate(r);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -633,7 +633,7 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
||||
nsSize s = GetSize();
|
||||
nsRect r(0, 0, s.width, s.height);
|
||||
// Update border+content to account for image change
|
||||
Invalidate(r, PR_FALSE);
|
||||
Invalidate(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,7 +658,7 @@ nsImageFrame::FrameChanged(imgIContainer *aContainer,
|
||||
nsRect r = SourceRectToDest(*aDirtyRect);
|
||||
|
||||
// Update border+content to account for image change
|
||||
Invalidate(r, PR_FALSE);
|
||||
Invalidate(r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -849,7 +849,7 @@ nsImageFrame::Reflow(nsPresContext* aPresContext,
|
||||
// we have no way to detect when mRect changes (since SetRect is non-virtual,
|
||||
// so this is the best we can do).
|
||||
if (mRect.width != aMetrics.width || mRect.height != aMetrics.height) {
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height), PR_FALSE);
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
||||
}
|
||||
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||
|
||||
@@ -1024,7 +1024,7 @@ nsImageMap::ChangeFocus(nsIDOMEvent* aEvent, PRBool aFocus)
|
||||
if (imgFrame) {
|
||||
nsRect dmgRect;
|
||||
area->GetRect(imgFrame, dmgRect);
|
||||
imgFrame->Invalidate(dmgRect, PR_FALSE);
|
||||
imgFrame->Invalidate(dmgRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2756,7 +2756,7 @@ NS_IMETHODIMP nsBlinkTimer::Notify(nsITimer *timer)
|
||||
// Determine damaged area and tell view manager to redraw it
|
||||
// blink doesn't blink outline ... I hope
|
||||
nsRect bounds(nsPoint(0, 0), frameData->mFrame->GetSize());
|
||||
frameData->mFrame->Invalidate(bounds, PR_FALSE);
|
||||
frameData->mFrame->Invalidate(bounds);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -4700,7 +4700,7 @@ nsTextFrame::SetSelected(nsPresContext* aPresContext,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
// Selection might change anything. Invalidate the overflow area.
|
||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
}
|
||||
if (aSpread == eSpreadDown)
|
||||
{
|
||||
|
||||
@@ -182,7 +182,7 @@ nsVideoFrame::Reflow(nsPresContext* aPresContext,
|
||||
FinishAndStoreOverflow(&aMetrics);
|
||||
|
||||
if (mRect.width != aMetrics.width || mRect.height != aMetrics.height) {
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height), PR_FALSE);
|
||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
||||
}
|
||||
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||
|
||||
@@ -321,7 +321,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
|
||||
// If we were dirty then do a repaint
|
||||
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
||||
nsRect damageRect(0, 0, aDesiredSize.width, aDesiredSize.height);
|
||||
Invalidate(damageRect, PR_FALSE);
|
||||
Invalidate(damageRect);
|
||||
}
|
||||
|
||||
// XXX Should we do something to clip our children to this?
|
||||
@@ -348,15 +348,19 @@ ViewportFrame::IsContainingBlock() const
|
||||
void
|
||||
ViewportFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
nsRect r = aDamageRect + nsPoint(aX, aY);
|
||||
PresContext()->NotifyInvalidation(r, (aFlags & INVALIDATE_CROSS_DOC) != 0);
|
||||
|
||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
||||
if (parent) {
|
||||
nsPoint pt = GetOffsetTo(parent);
|
||||
parent->InvalidateInternal(aDamageRect, aX + pt.x, aY + pt.y, this, aImmediate);
|
||||
parent->InvalidateInternal(r, pt.x, pt.y, this,
|
||||
aFlags | INVALIDATE_CROSS_DOC);
|
||||
return;
|
||||
}
|
||||
InvalidateRoot(aDamageRect, aX, aY, aImmediate);
|
||||
InvalidateRoot(r, aFlags);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||
|
||||
@@ -172,12 +172,14 @@ void
|
||||
nsSVGForeignObjectFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY,
|
||||
nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (mParent->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
|
||||
return;
|
||||
|
||||
mDirtyRegion.Or(mDirtyRegion, aDamageRect + nsPoint(aX, aY));
|
||||
nsRegion* region = (aFlags & INVALIDATE_CROSS_DOC)
|
||||
? &mCrossDocDirtyRegion : &mSameDocDirtyRegion;
|
||||
region->Or(*region, aDamageRect + nsPoint(aX, aY));
|
||||
FlushDirtyRegion();
|
||||
}
|
||||
|
||||
@@ -595,7 +597,8 @@ void nsSVGForeignObjectFrame::UpdateGraphic()
|
||||
nsSVGUtils::UpdateGraphic(this);
|
||||
|
||||
// Clear any layout dirty region since we invalidated our whole area.
|
||||
mDirtyRegion.SetEmpty();
|
||||
mSameDocDirtyRegion.SetEmpty();
|
||||
mCrossDocDirtyRegion.SetEmpty();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -688,10 +691,33 @@ nsSVGForeignObjectFrame::DoReflow()
|
||||
FlushDirtyRegion();
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGForeignObjectFrame::InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter,
|
||||
const nsRect& aRect, PRUint32 aFlags)
|
||||
{
|
||||
if (aRect.IsEmpty())
|
||||
return;
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tm = GetTMIncludingOffset();
|
||||
nsIntRect r = aRect;
|
||||
r.ScaleRoundOut(1.0f / presContext->AppUnitsPerDevPixel());
|
||||
float x = r.x, y = r.y, w = r.width, h = r.height;
|
||||
nsRect rect = GetTransformedRegion(x, y, w, h, tm, presContext);
|
||||
|
||||
// XXX invalidate the entire covered region
|
||||
// See bug 418063
|
||||
rect.UnionRect(rect, mRect);
|
||||
|
||||
rect = nsSVGUtils::FindFilterInvalidation(this, rect);
|
||||
aOuter->InvalidateWithFlags(rect, aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGForeignObjectFrame::FlushDirtyRegion()
|
||||
{
|
||||
if (mDirtyRegion.IsEmpty() || mInReflow)
|
||||
if ((mSameDocDirtyRegion.IsEmpty() && mCrossDocDirtyRegion.IsEmpty()) ||
|
||||
mInReflow)
|
||||
return;
|
||||
|
||||
nsSVGOuterSVGFrame *outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
|
||||
@@ -703,18 +729,9 @@ nsSVGForeignObjectFrame::FlushDirtyRegion()
|
||||
if (outerSVGFrame->IsRedrawSuspended())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tm = GetTMIncludingOffset();
|
||||
nsIntRect r = mDirtyRegion.GetBounds();
|
||||
r.ScaleRoundOut(1.0f / PresContext()->AppUnitsPerDevPixel());
|
||||
float x = r.x, y = r.y, w = r.width, h = r.height;
|
||||
nsRect rect = GetTransformedRegion(x, y, w, h, tm, PresContext());
|
||||
InvalidateDirtyRect(outerSVGFrame, mSameDocDirtyRegion.GetBounds(), 0);
|
||||
InvalidateDirtyRect(outerSVGFrame, mCrossDocDirtyRegion.GetBounds(), INVALIDATE_CROSS_DOC);
|
||||
|
||||
// XXX invalidate the entire covered region
|
||||
// See bug 418063
|
||||
rect.UnionRect(rect, mRect);
|
||||
|
||||
rect = nsSVGUtils::FindFilterInvalidation(this, rect);
|
||||
outerSVGFrame->Invalidate(rect);
|
||||
|
||||
mDirtyRegion.SetEmpty();
|
||||
mSameDocDirtyRegion.SetEmpty();
|
||||
mCrossDocDirtyRegion.SetEmpty();
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include "nsRegion.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
class nsSVGOuterSVGFrame;
|
||||
|
||||
typedef nsContainerFrame nsSVGForeignObjectFrameBase;
|
||||
|
||||
class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase,
|
||||
@@ -108,7 +110,7 @@ public:
|
||||
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
@@ -153,6 +155,8 @@ protected:
|
||||
void UpdateGraphic();
|
||||
already_AddRefed<nsIDOMSVGMatrix> GetTMIncludingOffset();
|
||||
nsresult TransformPointFromOuterPx(const nsPoint &aIn, nsPoint* aOut);
|
||||
void InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter,
|
||||
const nsRect& aRect, PRUint32 aFlags);
|
||||
void FlushDirtyRegion();
|
||||
|
||||
// If width or height is less than or equal to zero we must disable rendering
|
||||
@@ -160,7 +164,10 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM;
|
||||
nsRegion mDirtyRegion;
|
||||
// Damage area due to in-this-doc invalidation
|
||||
nsRegion mSameDocDirtyRegion;
|
||||
// Damage area due to cross-doc invalidation
|
||||
nsRegion mCrossDocDirtyRegion;
|
||||
|
||||
PRPackedBool mPropagateTransform;
|
||||
PRPackedBool mInReflow;
|
||||
|
||||
@@ -592,13 +592,22 @@ nsSVGOuterSVGFrame::Paint(nsIRenderingContext& aRenderingContext,
|
||||
// odd document is probably no worse than printing horribly for all
|
||||
// documents. Better to fix things so we don't need fallback.
|
||||
nsIFrame* frame = this;
|
||||
nsPresContext* presContext = PresContext();
|
||||
PRUint32 flags = 0;
|
||||
while (PR_TRUE) {
|
||||
nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(frame);
|
||||
if (!next)
|
||||
break;
|
||||
if (frame->GetParent() != next) {
|
||||
// We're crossing a document boundary. Logically, the invalidation is
|
||||
// being triggered by a subdocument of the root document. This will
|
||||
// prevent an untrusted root document being told about invalidation
|
||||
// that happened because a child was using SVG...
|
||||
flags |= INVALIDATE_CROSS_DOC;
|
||||
}
|
||||
frame = next;
|
||||
}
|
||||
frame->Invalidate(nsRect(nsPoint(0, 0), frame->GetSize()));
|
||||
frame->InvalidateWithFlags(nsRect(nsPoint(0, 0), frame->GetSize()), flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -517,7 +517,7 @@ nsTableCellFrame::SetSelected(nsPresContext* aPresContext,
|
||||
aPresContext->PresShell()->FrameSelection();
|
||||
if (frameSelection->GetTableCellSelection()) {
|
||||
// Selection can affect content, border and outline
|
||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -933,7 +933,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
// XXXbz is this invalidate actually needed, really?
|
||||
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
||||
@@ -656,7 +656,7 @@ nsIFrame::Redraw(nsBoxLayoutState& aState,
|
||||
else
|
||||
damageRect = GetOverflowRect();
|
||||
|
||||
Invalidate(damageRect, aImmediate);
|
||||
InvalidateWithFlags(damageRect, aImmediate ? INVALIDATE_IMMEDIATE : 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -684,9 +684,9 @@ nsMenuPopupFrame::HidePopup(PRBool aDeselectMenu, nsPopupState aNewState)
|
||||
void
|
||||
nsMenuPopupFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate)
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
InvalidateRoot(aDamageRect, aX, aY, aImmediate);
|
||||
InvalidateRoot(aDamageRect + nsPoint(aX, aY), aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
|
||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
||||
PRBool aImmediate);
|
||||
PRUint32 aFlags);
|
||||
|
||||
// returns true if the popup is a panel with the noautohide attribute set to
|
||||
// true. These panels do not roll up automatically.
|
||||
|
||||
@@ -684,7 +684,7 @@ nsSliderFrame::CurrentPositionChanged(nsPresContext* aPresContext,
|
||||
thumbFrame->SetRect(newThumbRect);
|
||||
|
||||
// Redraw the scrollbar
|
||||
Invalidate(clientRect, aImmediateRedraw);
|
||||
InvalidateWithFlags(clientRect, aImmediateRedraw ? INVALIDATE_IMMEDIATE : 0);
|
||||
|
||||
if (mScrollbarListener)
|
||||
mScrollbarListener->PositionChanged(aPresContext, mCurPos, curpospx);
|
||||
|
||||
@@ -692,7 +692,7 @@ nsTreeBodyFrame::Invalidate()
|
||||
if (mUpdateBatchNest)
|
||||
return NS_OK;
|
||||
|
||||
nsIFrame::Invalidate(GetOverflowRect(), PR_FALSE);
|
||||
InvalidateOverflowRect();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -719,7 +719,7 @@ nsTreeBodyFrame::InvalidateColumn(nsITreeColumn* aCol)
|
||||
|
||||
// When false then column is out of view
|
||||
if (OffsetForHorzScroll(columnRect, PR_TRUE))
|
||||
nsIFrame::Invalidate(columnRect, PR_FALSE);
|
||||
nsIFrame::Invalidate(columnRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -741,7 +741,7 @@ nsTreeBodyFrame::InvalidateRow(PRInt32 aIndex)
|
||||
return NS_OK;
|
||||
|
||||
nsRect rowRect(mInnerBox.x, mInnerBox.y+mRowHeight*aIndex, mInnerBox.width, mRowHeight);
|
||||
nsLeafBoxFrame::Invalidate(rowRect, PR_FALSE);
|
||||
nsLeafBoxFrame::Invalidate(rowRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -772,7 +772,7 @@ nsTreeBodyFrame::InvalidateCell(PRInt32 aIndex, nsITreeColumn* aCol)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (OffsetForHorzScroll(cellRect, PR_TRUE))
|
||||
nsIFrame::Invalidate(cellRect, PR_FALSE);
|
||||
nsIFrame::Invalidate(cellRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -806,7 +806,7 @@ nsTreeBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
|
||||
#endif
|
||||
|
||||
nsRect rangeRect(mInnerBox.x, mInnerBox.y+mRowHeight*(aStart-mTopRowIndex), mInnerBox.width, mRowHeight*(aEnd-aStart+1));
|
||||
nsIFrame::Invalidate(rangeRect, PR_FALSE);
|
||||
nsIFrame::Invalidate(rangeRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -850,7 +850,7 @@ nsTreeBodyFrame::InvalidateColumnRange(PRInt32 aStart, PRInt32 aEnd, nsITreeColu
|
||||
&rangeRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIFrame::Invalidate(rangeRect, PR_FALSE);
|
||||
nsIFrame::Invalidate(rangeRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "nsPoint.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsEvent.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@@ -101,6 +102,7 @@ class nsHashKey;
|
||||
#define NS_MEDIA_EVENT 34
|
||||
#endif // MOZ_MEDIA
|
||||
#define NS_DRAG_EVENT 35
|
||||
#define NS_NOTIFYPAINT_EVENT 36
|
||||
|
||||
// These flags are sort of a mess. They're sort of shared between event
|
||||
// listener flags and event flags, but only some of them. You've been
|
||||
@@ -376,6 +378,10 @@ class nsHashKey;
|
||||
#define NS_MEDIA_ERROR (NS_MEDIA_EVENT_START+21)
|
||||
#endif // MOZ_MEDIA
|
||||
|
||||
// paint notification events
|
||||
#define NS_NOTIFYPAINT_START 3400
|
||||
#define NS_AFTERPAINT (NS_NOTIFYPAINT_START)
|
||||
|
||||
/**
|
||||
* Return status for event processors, nsEventStatus, is defined in
|
||||
* nsEvent.h.
|
||||
@@ -1068,6 +1074,23 @@ public:
|
||||
PRInt32 detail;
|
||||
};
|
||||
|
||||
/**
|
||||
* NotifyPaint event
|
||||
*/
|
||||
class nsNotifyPaintEvent : public nsEvent
|
||||
{
|
||||
public:
|
||||
nsNotifyPaintEvent(PRBool isTrusted, PRUint32 msg,
|
||||
const nsRegion& aSameDocRegion, const nsRegion& aCrossDocRegion)
|
||||
: nsEvent(isTrusted, msg, NS_NOTIFYPAINT_EVENT),
|
||||
sameDocRegion(aSameDocRegion), crossDocRegion(aCrossDocRegion)
|
||||
{
|
||||
}
|
||||
|
||||
nsRegion sameDocRegion;
|
||||
nsRegion crossDocRegion;
|
||||
};
|
||||
|
||||
/**
|
||||
* PageTransition event
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user