зеркало из https://github.com/mozilla/pjs.git
Bug 363253. Move scrollframe attribute-setting out of reflow to a post-reflow callback. r+sr=dbaron
This commit is contained in:
Родитель
2444f84d7f
Коммит
d9a0686127
|
@ -98,10 +98,10 @@ class nsIScrollableFrame;
|
|||
|
||||
typedef short SelectionType;
|
||||
|
||||
// e94790d4-e93d-45a9-ab2f-a0c86081abc0
|
||||
// 7C398278-8523-4E5C-8268-4E4BC8B0C5CA
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0xe94790d4, 0xe93d, 0x45a9, \
|
||||
{ 0xab, 0x2f, 0xa0, 0xc8, 0x60, 0x81, 0xab, 0xc0 } }
|
||||
{ 0x7C398278, 0x8523, 0x4E5C, \
|
||||
{ 0x82, 0x68, 0x4E, 0x4B, 0xC8, 0xB0, 0xC5, 0xCA } }
|
||||
|
||||
// Constants uses for ScrollFrameIntoView() function
|
||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||
|
@ -122,12 +122,6 @@ typedef short SelectionType;
|
|||
#define VERIFY_REFLOW_INCLUDE_SPACE_MANAGER 0x40
|
||||
#define VERIFY_REFLOW_DURING_RESIZE_REFLOW 0x80
|
||||
|
||||
// for PostAttributeChanged
|
||||
enum nsAttributeChangeType {
|
||||
eChangeType_Set = 0, // Set attribute
|
||||
eChangeType_Remove = 1 // Remove attribute
|
||||
};
|
||||
|
||||
/**
|
||||
* Presentation shell interface. Presentation shells are the
|
||||
* controlling point for managing the presentation of a document. The
|
||||
|
@ -389,16 +383,6 @@ public:
|
|||
*/
|
||||
NS_IMETHOD FlushPendingNotifications(mozFlushType aType) = 0;
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType) = 0;
|
||||
|
||||
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback) = 0;
|
||||
NS_IMETHOD CancelReflowCallback(nsIReflowCallback* aCallback) = 0;
|
||||
|
||||
|
|
|
@ -38,22 +38,20 @@
|
|||
#ifndef nsIReflowCallback_h___
|
||||
#define nsIReflowCallback_h___
|
||||
|
||||
// {03E6FD70-889C-44b1-8639-A7EF5A80ED5C}
|
||||
#define NS_IREFLOWCALLBACK_IID \
|
||||
{ 0x3e6fd70, 0x889c, 0x44b1, { 0x86, 0x39, 0xa7, 0xef, 0x5a, 0x80, 0xed, 0x5c } }
|
||||
|
||||
class nsIPresShell;
|
||||
|
||||
/**
|
||||
* Reflow callback interface
|
||||
* Reflow callback interface.
|
||||
* These are not refcounted. Objects must be removed from the presshell
|
||||
* callback list before they die.
|
||||
*/
|
||||
class nsIReflowCallback : public nsISupports {
|
||||
class nsIReflowCallback {
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IREFLOWCALLBACK_IID)
|
||||
|
||||
NS_IMETHOD ReflowFinished(nsIPresShell* aShell, PRBool* aFlushFlag) = 0;
|
||||
/**
|
||||
* The presshell calls this when reflow has finished. Return PR_TRUE if
|
||||
* you need a Flush_Layout to happen after this.
|
||||
*/
|
||||
virtual PRBool ReflowFinished() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIReflowCallback, NS_IREFLOWCALLBACK_IID)
|
||||
|
||||
#endif /* nsIFrameUtil_h___ */
|
||||
|
|
|
@ -773,24 +773,6 @@ private:
|
|||
PRInt32 mCallCount;
|
||||
};
|
||||
|
||||
struct nsDOMEventRequest
|
||||
{
|
||||
nsIContent* content;
|
||||
nsEvent* event;
|
||||
nsDOMEventRequest* next;
|
||||
};
|
||||
|
||||
struct nsAttributeChangeRequest
|
||||
{
|
||||
nsIContent* content;
|
||||
PRInt32 nameSpaceID;
|
||||
nsIAtom* name;
|
||||
nsAutoString value;
|
||||
PRBool notify;
|
||||
nsAttributeChangeType type;
|
||||
nsAttributeChangeRequest* next;
|
||||
};
|
||||
|
||||
struct nsCallbackEventRequest
|
||||
{
|
||||
nsIReflowCallback* callback;
|
||||
|
@ -862,16 +844,6 @@ public:
|
|||
*/
|
||||
NS_IMETHOD RecreateFramesFor(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType);
|
||||
|
||||
/**
|
||||
* Post a callback that should be handled after reflow has finished.
|
||||
*/
|
||||
|
@ -1042,8 +1014,6 @@ public:
|
|||
protected:
|
||||
virtual ~PresShell();
|
||||
|
||||
void HandlePostedDOMEvents();
|
||||
void HandlePostedAttributeChanges();
|
||||
void HandlePostedReflowCallbacks();
|
||||
|
||||
void UnsuppressAndInvalidate();
|
||||
|
@ -1146,9 +1116,6 @@ protected:
|
|||
|
||||
nsRevocableEventPtr<ReflowEvent> mReflowEvent;
|
||||
|
||||
// used for list of posted attribute changes. To be done after reflow.
|
||||
nsAttributeChangeRequest* mFirstAttributeRequest;
|
||||
nsAttributeChangeRequest* mLastAttributeRequest;
|
||||
nsCallbackEventRequest* mFirstCallbackEventRequest;
|
||||
nsCallbackEventRequest* mLastCallbackEventRequest;
|
||||
|
||||
|
@ -1410,9 +1377,7 @@ PresShell::~PresShell()
|
|||
|
||||
NS_ASSERTION(mCurrentEventContentStack.Count() == 0,
|
||||
"Huh, event content left on the stack in pres shell dtor!");
|
||||
NS_ASSERTION(mFirstAttributeRequest == nsnull &&
|
||||
mLastAttributeRequest == nsnull &&
|
||||
mFirstCallbackEventRequest == nsnull &&
|
||||
NS_ASSERTION(mFirstCallbackEventRequest == nsnull &&
|
||||
mLastCallbackEventRequest == nsnull,
|
||||
"post-reflow queues not empty. This means we're leaking");
|
||||
|
||||
|
@ -4422,7 +4387,6 @@ PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
|
|||
nsCallbackEventRequest* request = (nsCallbackEventRequest*)result;
|
||||
|
||||
request->callback = aCallback;
|
||||
NS_ADDREF(aCallback);
|
||||
request->next = nsnull;
|
||||
|
||||
if (mLastCallbackEventRequest) {
|
||||
|
@ -4461,7 +4425,6 @@ PresShell::CancelReflowCallback(nsIReflowCallback* aCallback)
|
|||
}
|
||||
|
||||
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
|
||||
NS_RELEASE(callback);
|
||||
} else {
|
||||
before = node;
|
||||
node = node->next;
|
||||
|
@ -4471,47 +4434,6 @@ PresShell::CancelReflowCallback(nsIReflowCallback* aCallback)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
PresShell::PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType)
|
||||
{
|
||||
// ok we have a list of events to handle. Queue them up and handle them
|
||||
// after we finish reflow.
|
||||
|
||||
void* result = AllocateFrame(sizeof(nsAttributeChangeRequest));
|
||||
if (NS_UNLIKELY(!result)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsAttributeChangeRequest* request = new (result) nsAttributeChangeRequest();
|
||||
|
||||
request->content = aContent;
|
||||
NS_ADDREF(aContent);
|
||||
|
||||
request->nameSpaceID = aNameSpaceID;
|
||||
request->name = aName;
|
||||
request->value = aValue;
|
||||
request->notify = aNotify;
|
||||
request->type = aType;
|
||||
request->next = nsnull;
|
||||
|
||||
if (mLastAttributeRequest) {
|
||||
mLastAttributeRequest = mLastAttributeRequest->next = request;
|
||||
} else {
|
||||
mFirstAttributeRequest = request;
|
||||
mLastAttributeRequest = request;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PresShell::HandlePostedReflowCallbacks()
|
||||
{
|
||||
|
@ -4525,40 +4447,17 @@ PresShell::HandlePostedReflowCallbacks()
|
|||
}
|
||||
nsIReflowCallback* callback = node->callback;
|
||||
FreeFrame(sizeof(nsCallbackEventRequest), node);
|
||||
if (callback)
|
||||
callback->ReflowFinished(this, &shouldFlush);
|
||||
NS_IF_RELEASE(callback);
|
||||
if (callback) {
|
||||
if (callback->ReflowFinished()) {
|
||||
shouldFlush = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldFlush)
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::HandlePostedAttributeChanges()
|
||||
{
|
||||
while(mFirstAttributeRequest)
|
||||
{
|
||||
/* pull the node from the request list. Be prepared for reentrant access to the list
|
||||
from within SetAttribute/UnsetAttribute and its callees! */
|
||||
nsAttributeChangeRequest* node = mFirstAttributeRequest;
|
||||
|
||||
mFirstAttributeRequest = node->next;
|
||||
if (nsnull == mFirstAttributeRequest) {
|
||||
mLastAttributeRequest = nsnull;
|
||||
}
|
||||
|
||||
if (node->type == eChangeType_Set)
|
||||
node->content->SetAttr(node->nameSpaceID, node->name, node->value, node->notify);
|
||||
else
|
||||
node->content->UnsetAttr(node->nameSpaceID, node->name, node->notify);
|
||||
|
||||
NS_RELEASE(node->content);
|
||||
node->nsAttributeChangeRequest::~nsAttributeChangeRequest();
|
||||
FreeFrame(sizeof(nsAttributeChangeRequest), node);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::IsSafeToFlush(PRBool& aIsSafeToFlush)
|
||||
{
|
||||
|
@ -5840,7 +5739,6 @@ PresShell::WillDoReflow()
|
|||
void
|
||||
PresShell::DidDoReflow()
|
||||
{
|
||||
HandlePostedAttributeChanges();
|
||||
HandlePostedReflowCallbacks();
|
||||
// Null-check mViewManager in case this happens during Destroy. See
|
||||
// bugs 244435 and 238546.
|
||||
|
|
|
@ -153,12 +153,6 @@ nsHTMLScrollFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
|||
void
|
||||
nsHTMLScrollFrame::Destroy()
|
||||
{
|
||||
mInner.mScrollEvent.Revoke();
|
||||
mInner.mAsyncScrollPortEvent.Revoke();
|
||||
nsIScrollableView *view = mInner.GetScrollableView();
|
||||
NS_ASSERTION(view, "unexpected null pointer");
|
||||
if (view)
|
||||
view->RemoveScrollPositionListener(&mInner);
|
||||
mInner.Destroy();
|
||||
nsHTMLContainerFrame::Destroy();
|
||||
}
|
||||
|
@ -965,12 +959,6 @@ nsXULScrollFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
|||
void
|
||||
nsXULScrollFrame::Destroy()
|
||||
{
|
||||
mInner.mScrollEvent.Revoke();
|
||||
mInner.mAsyncScrollPortEvent.Revoke();
|
||||
nsIScrollableView *view = mInner.GetScrollableView();
|
||||
NS_ASSERTION(view, "unexpected null pointer");
|
||||
if (view)
|
||||
view->RemoveScrollPositionListener(&mInner);
|
||||
mInner.Destroy();
|
||||
nsBoxFrame::Destroy();
|
||||
}
|
||||
|
@ -1248,7 +1236,8 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
|
|||
mHistoryVScrollbarHint(PR_FALSE),
|
||||
mHadNonInitialReflow(PR_FALSE),
|
||||
mHorizontalOverflow(PR_FALSE),
|
||||
mVerticalOverflow(PR_FALSE)
|
||||
mVerticalOverflow(PR_FALSE),
|
||||
mPostedReflowCallback(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1718,6 +1707,17 @@ nsGfxScrollFrameInner::Destroy()
|
|||
nsContentUtils::DestroyAnonymousContent(&mHScrollbarContent);
|
||||
nsContentUtils::DestroyAnonymousContent(&mVScrollbarContent);
|
||||
nsContentUtils::DestroyAnonymousContent(&mScrollCornerContent);
|
||||
|
||||
mScrollEvent.Revoke();
|
||||
mAsyncScrollPortEvent.Revoke();
|
||||
if (mPostedReflowCallback) {
|
||||
mOuter->GetPresContext()->PresShell()->CancelReflowCallback(this);
|
||||
mPostedReflowCallback = PR_FALSE;
|
||||
}
|
||||
nsIScrollableView *view = GetScrollableView();
|
||||
NS_ASSERTION(view, "unexpected null pointer");
|
||||
if (view)
|
||||
view->RemoveScrollPositionListener(this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2302,16 +2302,17 @@ nsXULScrollFrame::Layout(nsBoxLayoutState& aState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
const nsRect& aContentArea,
|
||||
const nsRect& aOldScrollArea,
|
||||
const nsRect& aScrollArea)
|
||||
PRBool
|
||||
nsGfxScrollFrameInner::ReflowFinished()
|
||||
{
|
||||
NS_ASSERTION(!mSupppressScrollbarUpdate,
|
||||
"This should have been suppressed");
|
||||
|
||||
nsPresContext* presContext = aState.PresContext();
|
||||
mPostedReflowCallback = PR_FALSE;
|
||||
|
||||
// Update scrollbar attributes.
|
||||
nsPresContext* presContext = mOuter->GetPresContext();
|
||||
|
||||
nsIScrollableView* scrollable = GetScrollableView();
|
||||
nsRect scrollArea = scrollable->View()->GetBounds();
|
||||
|
||||
const nsStyleFont* font = mOuter->GetStyleFont();
|
||||
const nsFont& f = font->mFont;
|
||||
nsCOMPtr<nsIFontMetrics> fm = presContext->GetMetricsFor(f);
|
||||
|
@ -2319,20 +2320,16 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||
NS_ASSERTION(fm,"FontMetrics is null assuming fontHeight == 1");
|
||||
if (fm)
|
||||
fm->GetHeight(fontHeight);
|
||||
|
||||
nsRect scrolledContentRect = GetScrolledRect(aScrollArea.Size());
|
||||
|
||||
nscoord minX = scrolledContentRect.x;
|
||||
nscoord maxX = scrolledContentRect.XMost() - aScrollArea.width;
|
||||
|
||||
nscoord minY = scrolledContentRect.y;
|
||||
nscoord maxY = scrolledContentRect.YMost() - aScrollArea.height;
|
||||
|
||||
nsIScrollableView* scrollable = GetScrollableView();
|
||||
scrollable->SetLineHeight(fontHeight);
|
||||
|
||||
nsRect scrolledContentRect = GetScrolledRect(scrollArea.Size());
|
||||
nscoord minX = scrolledContentRect.x;
|
||||
nscoord maxX = scrolledContentRect.XMost() - scrollArea.width;
|
||||
nscoord minY = scrolledContentRect.y;
|
||||
nscoord maxY = scrolledContentRect.YMost() - scrollArea.height;
|
||||
|
||||
// Suppress handling of the curpos attribute changes we make here.
|
||||
PRBool oldFrameInitiatedScroll = mFrameInitiatedScroll;
|
||||
NS_ASSERTION(!mFrameInitiatedScroll, "We shouldn't be reentering here");
|
||||
mFrameInitiatedScroll = PR_TRUE;
|
||||
|
||||
if (mVScrollbarBox) {
|
||||
|
@ -2343,18 +2340,10 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||
SetCoordAttribute(mVScrollbarBox, nsGkAtoms::curpos, curPosY - minY);
|
||||
SetScrollbarEnabled(mVScrollbarBox, maxY - minY);
|
||||
SetCoordAttribute(mVScrollbarBox, nsGkAtoms::maxpos, maxY - minY);
|
||||
SetCoordAttribute(mVScrollbarBox, nsGkAtoms::pageincrement, nscoord(aScrollArea.height - fontHeight));
|
||||
SetCoordAttribute(mVScrollbarBox, nsGkAtoms::pageincrement, nscoord(scrollArea.height - fontHeight));
|
||||
SetCoordAttribute(mVScrollbarBox, nsGkAtoms::increment, fontHeight);
|
||||
|
||||
nsRect vRect(aScrollArea);
|
||||
vRect.width = aContentArea.width - aScrollArea.width;
|
||||
vRect.x = IsScrollbarOnRight() ? aScrollArea.XMost() : aContentArea.x;
|
||||
nsMargin margin;
|
||||
mVScrollbarBox->GetMargin(margin);
|
||||
vRect.Deflate(margin);
|
||||
nsBoxFrame::LayoutChildAt(aState, mVScrollbarBox, vRect);
|
||||
}
|
||||
|
||||
|
||||
if (mHScrollbarBox) {
|
||||
NS_PRECONDITION(mHScrollbarBox->IsBoxFrame(), "Must be a box frame!");
|
||||
nscoord curPosX, curPosY;
|
||||
|
@ -2363,19 +2352,11 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||
SetCoordAttribute(mHScrollbarBox, nsGkAtoms::curpos, curPosX - minX);
|
||||
SetScrollbarEnabled(mHScrollbarBox, maxX - minX);
|
||||
SetCoordAttribute(mHScrollbarBox, nsGkAtoms::maxpos, maxX - minX);
|
||||
SetCoordAttribute(mHScrollbarBox, nsGkAtoms::pageincrement, nscoord(float(aScrollArea.width)*0.8));
|
||||
SetCoordAttribute(mHScrollbarBox, nsGkAtoms::pageincrement, nscoord(float(scrollArea.width)*0.8));
|
||||
SetCoordAttribute(mHScrollbarBox, nsGkAtoms::increment, nsPresContext::CSSPixelsToAppUnits(10));
|
||||
|
||||
nsRect hRect(aScrollArea);
|
||||
hRect.height = aContentArea.height - aScrollArea.height;
|
||||
hRect.y = PR_TRUE ? aScrollArea.YMost() : aContentArea.y;
|
||||
nsMargin margin;
|
||||
mHScrollbarBox->GetMargin(margin);
|
||||
hRect.Deflate(margin);
|
||||
nsBoxFrame::LayoutChildAt(aState, mHScrollbarBox, hRect);
|
||||
}
|
||||
|
||||
mFrameInitiatedScroll = oldFrameInitiatedScroll;
|
||||
mFrameInitiatedScroll = PR_FALSE;
|
||||
// We used to rely on the curpos attribute changes above to scroll the
|
||||
// view. However, for scrolling to the left of the viewport, we
|
||||
// rescale the curpos attribute, which means that operations like
|
||||
|
@ -2387,9 +2368,43 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||
// nsSliderFrame::AttributeChanged's handling of maxpos, but not when
|
||||
// we hide the scrollbar on a large size change, such as
|
||||
// maximization.)
|
||||
if (mHScrollbarBox || mVScrollbarBox)
|
||||
CurPosAttributeChanged(mVScrollbarBox ? mVScrollbarBox->GetContent()
|
||||
: mHScrollbarBox->GetContent());
|
||||
if (!mHScrollbarBox && !mVScrollbarBox)
|
||||
return PR_FALSE;
|
||||
CurPosAttributeChanged(mVScrollbarBox ? mVScrollbarBox->GetContent()
|
||||
: mHScrollbarBox->GetContent());
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
const nsRect& aContentArea,
|
||||
const nsRect& aOldScrollArea,
|
||||
const nsRect& aScrollArea)
|
||||
{
|
||||
NS_ASSERTION(!mSupppressScrollbarUpdate,
|
||||
"This should have been suppressed");
|
||||
|
||||
if (mVScrollbarBox) {
|
||||
NS_PRECONDITION(mVScrollbarBox->IsBoxFrame(), "Must be a box frame!");
|
||||
nsRect vRect(aScrollArea);
|
||||
vRect.width = aContentArea.width - aScrollArea.width;
|
||||
vRect.x = IsScrollbarOnRight() ? aScrollArea.XMost() : aContentArea.x;
|
||||
nsMargin margin;
|
||||
mVScrollbarBox->GetMargin(margin);
|
||||
vRect.Deflate(margin);
|
||||
nsBoxFrame::LayoutChildAt(aState, mVScrollbarBox, vRect);
|
||||
}
|
||||
|
||||
if (mHScrollbarBox) {
|
||||
NS_PRECONDITION(mHScrollbarBox->IsBoxFrame(), "Must be a box frame!");
|
||||
nsRect hRect(aScrollArea);
|
||||
hRect.height = aContentArea.height - aScrollArea.height;
|
||||
hRect.y = PR_TRUE ? aScrollArea.YMost() : aContentArea.y;
|
||||
nsMargin margin;
|
||||
mHScrollbarBox->GetMargin(margin);
|
||||
hRect.Deflate(margin);
|
||||
nsBoxFrame::LayoutChildAt(aState, mHScrollbarBox, hRect);
|
||||
}
|
||||
|
||||
// place the scrollcorner
|
||||
if (mScrollCornerBox) {
|
||||
|
@ -2434,10 +2449,16 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||
// force a reflow of the fixed child
|
||||
fixedChild->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
|
||||
// XXX Will this work given where we currently are in reflow?
|
||||
mOuter->GetPresContext()->PresShell()->
|
||||
aState.PresContext()->PresShell()->
|
||||
FrameNeedsReflow(fixedChild, nsIPresShell::eResize);
|
||||
}
|
||||
}
|
||||
|
||||
// post reflow callback to modify scrollbar attributes
|
||||
if (!mPostedReflowCallback) {
|
||||
aState.PresContext()->PresShell()->PostReflowCallback(this);
|
||||
mPostedReflowCallback = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2449,38 +2470,34 @@ nsGfxScrollFrameInner::ScrollbarChanged(nsPresContext* aPresContext, nscoord aX,
|
|||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::SetScrollbarEnabled(nsIBox* aBox, nscoord aMaxPos, PRBool aReflow)
|
||||
nsGfxScrollFrameInner::SetScrollbarEnabled(nsIBox* aBox, nscoord aMaxPos)
|
||||
{
|
||||
mOuter->GetPresContext()->PresShell()->PostAttributeChange(
|
||||
aBox->GetContent(),
|
||||
kNameSpaceID_None,
|
||||
nsGkAtoms::disabled,
|
||||
NS_LITERAL_STRING("true"),
|
||||
aReflow,
|
||||
aMaxPos ? eChangeType_Remove : eChangeType_Set);
|
||||
nsIContent* content = aBox->GetContent();
|
||||
if (aMaxPos) {
|
||||
content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, PR_TRUE);
|
||||
} else {
|
||||
content->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
|
||||
NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether it actually needed to change the attribute
|
||||
*/
|
||||
PRBool
|
||||
nsGfxScrollFrameInner::SetCoordAttribute(nsIBox* aBox, nsIAtom* aAtom, nscoord aSize, PRBool aReflow)
|
||||
void
|
||||
nsGfxScrollFrameInner::SetCoordAttribute(nsIBox* aBox, nsIAtom* aAtom,
|
||||
nscoord aSize)
|
||||
{
|
||||
// convert to pixels
|
||||
aSize = nsPresContext::AppUnitsToIntCSSPixels(aSize);
|
||||
|
||||
// only set the attribute if it changed.
|
||||
|
||||
nsIContent *content = aBox->GetContent();
|
||||
|
||||
nsAutoString newValue;
|
||||
newValue.AppendInt(aSize);
|
||||
|
||||
nsIContent* content = aBox->GetContent();
|
||||
if (content->AttrValueIs(kNameSpaceID_None, aAtom, newValue, eCaseMatters))
|
||||
return PR_FALSE;
|
||||
return;
|
||||
|
||||
content->SetAttr(kNameSpaceID_None, aAtom, newValue, aReflow);
|
||||
return PR_TRUE;
|
||||
content->SetAttr(kNameSpaceID_None, aAtom, newValue, PR_TRUE);
|
||||
}
|
||||
|
||||
nsRect
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIReflowCallback.h"
|
||||
|
||||
class nsPresContext;
|
||||
class nsIPresShell;
|
||||
|
@ -60,7 +61,8 @@ class nsIScrollFrameInternal;
|
|||
class nsPresState;
|
||||
struct ScrollReflowState;
|
||||
|
||||
class nsGfxScrollFrameInner : public nsIScrollPositionListener {
|
||||
class nsGfxScrollFrameInner : public nsIScrollPositionListener,
|
||||
public nsIReflowCallback {
|
||||
public:
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
|
@ -92,6 +94,9 @@ public:
|
|||
virtual void InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY,
|
||||
nsIFrame* aForChild, PRBool aImmediate);
|
||||
|
||||
// nsIReflowCallback
|
||||
virtual PRBool ReflowFinished();
|
||||
|
||||
// nsIScrollPositionListener
|
||||
|
||||
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
|
||||
|
@ -120,8 +125,8 @@ public:
|
|||
nsGfxScrollFrameInner *mInner;
|
||||
};
|
||||
|
||||
void SetScrollbarEnabled(nsIBox* aBox, nscoord aMaxPos, PRBool aReflow=PR_TRUE);
|
||||
PRBool SetCoordAttribute(nsIBox* aBox, nsIAtom* aAtom, nscoord aSize, PRBool aReflow=PR_TRUE);
|
||||
void SetScrollbarEnabled(nsIBox* aBox, nscoord aMaxPos);
|
||||
void SetCoordAttribute(nsIBox* aBox, nsIAtom* aAtom, nscoord aSize);
|
||||
nscoord GetCoordAttribute(nsIBox* aFrame, nsIAtom* atom, nscoord defaultValue);
|
||||
|
||||
// Like ScrollPositionDidChange, but initiated by this frame rather than from the
|
||||
|
@ -218,6 +223,7 @@ public:
|
|||
// which overflow states have changed.
|
||||
PRPackedBool mHorizontalOverflow:1;
|
||||
PRPackedBool mVerticalOverflow:1;
|
||||
PRPackedBool mPostedReflowCallback:1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -226,7 +226,6 @@ nsListBoxBodyFrame::Release(void)
|
|||
NS_INTERFACE_MAP_BEGIN(nsListBoxBodyFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIListBoxObject)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollbarMediator)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIReflowCallback)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
|
||||
|
@ -487,8 +486,8 @@ nsListBoxBodyFrame::ScrollbarButtonPressed(nsISupports* aScrollbar, PRInt32 aOld
|
|||
|
||||
///////////// nsIReflowCallback ///////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsListBoxBodyFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag)
|
||||
PRBool
|
||||
nsListBoxBodyFrame::ReflowFinished()
|
||||
{
|
||||
// now create or destroy any rows as needed
|
||||
CreateRows();
|
||||
|
@ -512,9 +511,7 @@ nsListBoxBodyFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag)
|
|||
}
|
||||
|
||||
mReflowCallbackPosted = PR_FALSE;
|
||||
*aFlushFlag = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///////// nsIListBoxObject ///////////////
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
NS_IMETHOD VisibilityChanged(nsISupports* aScrollbar, PRBool aVisible);
|
||||
|
||||
// nsIReflowCallback
|
||||
NS_IMETHOD ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag);
|
||||
virtual PRBool ReflowFinished();
|
||||
|
||||
// nsIBox
|
||||
NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
|
||||
|
|
|
@ -138,7 +138,6 @@ NS_INTERFACE_MAP_BEGIN(nsTreeBodyFrame)
|
|||
NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICSSPseudoComparator)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollbarMediator)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIReflowCallback)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsLeafBoxFrame)
|
||||
|
||||
|
||||
|
@ -418,8 +417,8 @@ nsTreeBodyFrame::SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRec
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeBodyFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag)
|
||||
PRBool
|
||||
nsTreeBodyFrame::ReflowFinished()
|
||||
{
|
||||
if (mView) {
|
||||
CalcInnerBox();
|
||||
|
@ -449,9 +448,7 @@ nsTreeBodyFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag)
|
|||
}
|
||||
|
||||
mReflowCallbackPosted = PR_FALSE;
|
||||
*aFlushFlag = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
PRBool aRemoveOverflowArea = PR_FALSE);
|
||||
|
||||
// nsIReflowCallback
|
||||
NS_IMETHOD ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag);
|
||||
virtual PRBool ReflowFinished();
|
||||
|
||||
// nsICSSPseudoComparator
|
||||
NS_IMETHOD PseudoMatches(nsIAtom* aTag, nsCSSSelector* aSelector, PRBool* aResult);
|
||||
|
|
Загрузка…
Ссылка в новой задаче