From db5d475217c92f59b4b6edc15035c77cedca0533 Mon Sep 17 00:00:00 2001 From: Shawn Wilsher Date: Thu, 31 Dec 2009 09:31:49 -0800 Subject: [PATCH 01/40] Disabled test_browserGlue_smartBookmarks.js due to bug 510219. --- .../places/tests/unit/test_browserGlue_smartBookmarks.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js b/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js index 29a4d3c71d0..5efad4b3834 100644 --- a/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js +++ b/browser/components/places/tests/unit/test_browserGlue_smartBookmarks.js @@ -210,6 +210,9 @@ function next_test() { } function run_test() { + // XXX disabled due to bug 510219 + return; + // Clean up database from all bookmarks. remove_all_bookmarks(); From 989819833a62c0ca27d006e67a6585100809cb00 Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Thu, 31 Dec 2009 12:36:56 -0500 Subject: [PATCH 02/40] Bug 536486, remove IsDestroyingFrames check now that frames are available from content nodes, fixes possible leak, r=roc --- layout/base/nsPresShell.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index f6685950c71..6430c2b4796 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -4374,21 +4374,8 @@ PresShell::ClearMouseCapture(nsIView* aView) if (gCaptureInfo.mContent) { if (aView) { // if a view was specified, ensure that the captured content is within - // this view. Get the frame for the captured content from the right - // presshell first. - nsIFrame* frame = nsnull; - nsIDocument* doc = gCaptureInfo.mContent->GetCurrentDoc(); - if (doc) { - nsIPresShell *shell = doc->GetPrimaryShell(); - if (shell) { - // not much can happen if frames are being destroyed so just return. - if (shell->FrameManager()->IsDestroyingFrames()) - return; - - frame = gCaptureInfo.mContent->GetPrimaryFrame(); - } - } - + // this view. + nsIFrame* frame = gCaptureInfo.mContent->GetPrimaryFrame(); if (frame) { nsIView* view = frame->GetClosestView(); // if there is no view, capturing won't be handled any more, so From 61bd9cfc5612d4372813250766fca1609436c56a Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Thu, 31 Dec 2009 12:49:22 -0500 Subject: [PATCH 03/40] Revert bulk of changeset 67ddbe030ab6 (originally for bug 457809) now that bug 253354 is fixed. --- layout/base/tests/test_bug416896.html | 7 ------- 1 file changed, 7 deletions(-) diff --git a/layout/base/tests/test_bug416896.html b/layout/base/tests/test_bug416896.html index ea071e179bd..a058c349955 100644 --- a/layout/base/tests/test_bug416896.html +++ b/layout/base/tests/test_bug416896.html @@ -23,13 +23,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=416896 + + + +
+ + diff --git a/layout/base/crashtests/537141-1.xhtml b/layout/base/crashtests/537141-1.xhtml new file mode 100644 index 00000000000..c9b3a7abaec --- /dev/null +++ b/layout/base/crashtests/537141-1.xhtml @@ -0,0 +1,6 @@ + + + + + + diff --git a/layout/base/crashtests/537141.xml b/layout/base/crashtests/537141.xml new file mode 100644 index 00000000000..5e9ee844524 --- /dev/null +++ b/layout/base/crashtests/537141.xml @@ -0,0 +1,2 @@ + + diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index 3840a76b057..797544373a5 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -268,3 +268,5 @@ load 503936-1.html load 526378-1.xul load 535721-1.xhtml load 535911-1.xhtml +load 536623-1.xhtml +load 537141-1.xhtml diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index ce6676f32c1..4aa5b3151bd 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2161,6 +2161,8 @@ static PRBool NeedFrameFor(nsIFrame* aParentFrame, nsIContent* aChildContent) { + NS_PRECONDITION(!aChildContent->GetPrimaryFrame(), "Why did we get called?"); + // don't create a whitespace frame if aParentFrame doesn't want it. // always create frames for children in generated content. counter(), // quotes, and attr() content can easily change dynamically and we don't @@ -6292,9 +6294,11 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer, } nsIAtom* frameType = parentFrame->GetType(); - + PRBool haveNoXBLChildren = + mDocument->BindingManager()->GetXBLChildNodesFor(aContainer) == nsnull; FrameConstructionItemList items; - if (aNewIndexInContainer > 0 && GetParentType(frameType) == eTypeBlock) { + if (aNewIndexInContainer > 0 && GetParentType(frameType) == eTypeBlock && + haveNoXBLChildren) { // If there's a text node in the normal content list just before the new // items, and it has no frame, make a frame construction item for it. If it // doesn't need a frame, ConstructFramesFromItemList below won't give it @@ -6345,8 +6349,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer, // To suppress whitespace-only text frames, we have to verify that // our container's DOM child list matches its flattened tree child list. // This is guaranteed to be true if GetXBLChildNodesFor() returns null. - items.SetParentHasNoXBLChildren( - !mDocument->BindingManager()->GetXBLChildNodesFor(aContainer)); + items.SetParentHasNoXBLChildren(haveNoXBLChildren); nsFrameItems frameItems; ConstructFramesFromItemList(state, items, parentFrame, frameItems); @@ -6673,7 +6676,9 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer, FrameConstructionItemList items; ParentType parentType = GetParentType(frameType); - if (aIndexInContainer > 0 && parentType == eTypeBlock) { + PRBool haveNoXBLChildren = + mDocument->BindingManager()->GetXBLChildNodesFor(aContainer) == nsnull; + if (aIndexInContainer > 0 && parentType == eTypeBlock && haveNoXBLChildren) { // If there's a text node in the normal content list just before the // new node, and it has no frame, make a frame construction item for // it, because it might need a frame now. No need to do this if our @@ -6686,7 +6691,7 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer, AddFrameConstructionItems(state, aChild, aIndexInContainer, parentFrame, items); if (aIndexInContainer + 1 < PRInt32(aContainer->GetChildCount()) && - parentType == eTypeBlock) { + parentType == eTypeBlock && haveNoXBLChildren) { // If there's a text node in the normal content list just after the // new node, and it has no frame, make a frame construction item for // it, because it might need a frame now. No need to do this if our @@ -11294,6 +11299,7 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run() PRBool nsCSSFrameConstructor::FrameConstructionItem::IsWhitespace() const { + NS_PRECONDITION(!mContent->GetPrimaryFrame(), "How did that happen?"); if (!mIsText) { return PR_FALSE; } From 5e1384376d0a7f78df4e8761012d84cf428407d7 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 31 Dec 2009 14:07:57 -0500 Subject: [PATCH 07/40] Bug 528306 part 1. Don't stop the refresh driver timer on observer removal; instead just stop it if it fires when there are no observers. r=dbaron --- layout/base/nsRefreshDriver.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 80bb2e03359..85621fab82b 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -94,13 +94,7 @@ nsRefreshDriver::RemoveRefreshObserver(nsARefreshObserver *aObserver, mozFlushType aFlushType) { ObserverArray& array = ArrayFor(aFlushType); - PRBool success = array.RemoveElement(aObserver); - - if (ObserverCount() == 0) { - StopTimer(); - } - - return success; + return array.RemoveElement(aObserver); } void @@ -189,8 +183,14 @@ nsRefreshDriver::Notify(nsITimer *aTimer) return NS_OK; } nsCOMPtr presShell = mPresContext->GetPresShell(); - if (!presShell) { - // Things are being destroyed. + if (!presShell || ObserverCount() == 0) { + // Things are being destroyed, or we no longer have any observers. + // We don't want to stop the timer when observers are initially + // removed, because sometimes observers can be added and removed + // often depending on what other things are going on and in that + // situation we don't want to thrash our timer. So instead we + // wait until we get a Notify() call when we have no observers + // before stopping the timer. StopTimer(); return NS_OK; } @@ -225,9 +225,5 @@ nsRefreshDriver::Notify(nsITimer *aTimer) } } - if (ObserverCount() == 0) { - StopTimer(); - } - return NS_OK; } From ef3cef478b6474b3219e72315889984278798160 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 31 Dec 2009 14:07:57 -0500 Subject: [PATCH 08/40] Bug 528306 part 2. Make nsCSSFrameConstructor reference-counted. r=dbaron --- layout/base/nsCSSFrameConstructor.cpp | 3 +++ layout/base/nsCSSFrameConstructor.h | 9 +++++++++ layout/base/nsIPresShell.h | 2 +- layout/base/nsPresShell.cpp | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 4aa5b3151bd..25bdea540b5 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1362,6 +1362,9 @@ MoveChildrenTo(nsPresContext* aPresContext, //---------------------------------------------------------------------- +NS_IMPL_ADDREF(nsCSSFrameConstructor) +NS_IMPL_RELEASE(nsCSSFrameConstructor) + nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument, nsIPresShell *aPresShell) : mDocument(aDocument) diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 7479f8eeb6d..ad3939759b2 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -86,6 +86,15 @@ public: NS_ASSERTION(mUpdateCount == 0, "Dying in the middle of our own update?"); } + // Matches signature on nsARefreshObserver. Just like + // NS_DECL_ISUPPORTS, but without the QI part. + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); +protected: + nsAutoRefCnt mRefCnt; + NS_DECL_OWNINGTHREAD +public: + struct RestyleData; friend struct RestyleData; diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 84c6d58e065..4ec6c285a9e 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -936,7 +936,7 @@ protected: nsIDocument* mDocument; // [STRONG] nsPresContext* mPresContext; // [STRONG] nsStyleSet* mStyleSet; // [OWNS] - nsCSSFrameConstructor* mFrameConstructor; // [OWNS] + nsCSSFrameConstructor* mFrameConstructor; // [STRONG] nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to nsFrameSelection* mSelection; nsFrameManagerBase mFrameManager; // [OWNS] diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 6430c2b4796..8a91a4f0135 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1553,7 +1553,7 @@ PresShell::~PresShell() #endif delete mStyleSet; - delete mFrameConstructor; + NS_IF_RELEASE(mFrameConstructor); mCurrentEventContent = nsnull; @@ -1600,6 +1600,7 @@ PresShell::Init(nsIDocument* aDocument, // Create our frame constructor. mFrameConstructor = new nsCSSFrameConstructor(mDocument, this); NS_ENSURE_TRUE(mFrameConstructor, NS_ERROR_OUT_OF_MEMORY); + NS_ADDREF(mFrameConstructor); // The document viewer owns both view manager and pres shell. mViewManager->SetViewObserver(this); From 06b277fcc73a9b251d9b1cd0fbbbde36bb4426a6 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 31 Dec 2009 14:07:57 -0500 Subject: [PATCH 09/40] Bug 528306 part 3. Hook up restyle processing to nsRefreshDriver. r=dbaron --- layout/base/nsCSSFrameConstructor.cpp | 63 +++++++++++++++++---------- layout/base/nsCSSFrameConstructor.h | 27 ++++-------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 25bdea540b5..142836a47b2 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1381,6 +1381,8 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument, , mIsDestroyingFrameTree(PR_FALSE) , mRebuildAllStyleData(PR_FALSE) , mHasRootAbsPosContainingBlock(PR_FALSE) + , mObservingRefreshDriver(PR_FALSE) + , mInStyleRefresh(PR_FALSE) , mHoverGeneration(0) , mRebuildAllExtraHint(nsChangeHint(0)) { @@ -7809,8 +7811,12 @@ nsCSSFrameConstructor::WillDestroyFrameTree() mQuoteList.Clear(); mCounterManager.Clear(); - // Cancel all pending re-resolves - mRestyleEvent.Revoke(); + // Remove ourselves as a refresh observer, so the refresh driver + // won't assert about us. But leave mObservingRefreshDriver true so + // we don't readd to it even if someone tries to post restyle events + // on us from this point on for some reason. + mPresShell->GetPresContext()->RefreshDriver()-> + RemoveRefreshObserver(this, Flush_Style); } //STATIC @@ -11143,6 +11149,9 @@ nsCSSFrameConstructor::ProcessPendingRestyles() // Process non-animation restyles... ProcessPendingRestyleTable(mPendingRestyles); + NS_POSTCONDITION(mPendingRestyles.Count() == 0, + "We should have processed mPendingRestyles to completion"); + // ...and then process animation restyles. This needs to happen // second because we need to start animations that resulted from the // first set of restyles (e.g., CSS transitions with negative @@ -11156,9 +11165,19 @@ nsCSSFrameConstructor::ProcessPendingRestyles() ProcessPendingRestyleTable(mPendingAnimationRestyles); presContext->SetProcessingAnimationStyleChange(PR_FALSE); + mInStyleRefresh = PR_FALSE; + + NS_POSTCONDITION(mPendingAnimationRestyles.Count() == 0, + "We should have processed mPendingAnimationRestyles to " + "completion"); + NS_POSTCONDITION(mPendingRestyles.Count() == 0, + "We should not have posted new non-animation restyles while " + "processing animation restyles"); + if (mRebuildAllStyleData) { // We probably wasted a lot of work up above, but this seems safest // and it should be rarely used. + // This might add us as a refresh observer again; that's ok. RebuildAllStyleData(nsChangeHint(0)); } } @@ -11201,17 +11220,29 @@ nsCSSFrameConstructor::PostRestyleEventCommon(nsIContent* aContent, void nsCSSFrameConstructor::PostRestyleEventInternal() { - if (!mRestyleEvent.IsPending()) { - nsRefPtr ev = new RestyleEvent(this); - if (NS_FAILED(NS_DispatchToCurrentThread(ev))) { - NS_WARNING("failed to dispatch restyle event"); - // XXXbz and what? - } else { - mRestyleEvent = ev; - } + // Make sure we're not in a style refresh; if we are, we still have + // a call to ProcessPendingRestyles coming and there's no need to + // add ourselves as a refresh observer until then. + if (!mInStyleRefresh && !mObservingRefreshDriver) { + mObservingRefreshDriver = mPresShell->GetPresContext()-> + RefreshDriver()->AddRefreshObserver(this, Flush_Style); } } +void +nsCSSFrameConstructor::WillRefresh(mozilla::TimeStamp aTime) +{ + NS_ASSERTION(mObservingRefreshDriver, "How did we get here?"); + // Stop observing the refresh driver and flag ourselves as being in + // a refresh so we don't restart due to animation-triggered + // restyles. The actual work of processing our restyles will get + // done when the refresh driver flushes styles. + mPresShell->GetPresContext()->RefreshDriver()-> + RemoveRefreshObserver(this, Flush_Style); + mObservingRefreshDriver = PR_FALSE; + mInStyleRefresh = PR_TRUE; +} + void nsCSSFrameConstructor::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint) { @@ -11225,18 +11256,6 @@ nsCSSFrameConstructor::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint) PostRestyleEventInternal(); } -NS_IMETHODIMP nsCSSFrameConstructor::RestyleEvent::Run() -{ - if (!mConstructor) - return NS_OK; // event was revoked - - // Make sure that any restyles that happen from now on will go into - // a new event. - mConstructor->mRestyleEvent.Forget(); - - return mConstructor->mPresShell->FlushPendingNotifications(Flush_Style); -} - NS_IMETHODIMP nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run() { diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index ad3939759b2..2c1b6b07377 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -53,6 +53,7 @@ #include "nsThreadUtils.h" #include "nsPageContentFrame.h" #include "nsCSSPseudoElements.h" +#include "nsRefreshDriver.h" class nsIDocument; struct nsFrameItems; @@ -78,7 +79,7 @@ typedef void (nsLazyFrameConstructionCallback) class nsFrameConstructorState; class nsFrameConstructorSaveState; -class nsCSSFrameConstructor +class nsCSSFrameConstructor : public nsARefreshObserver { public: nsCSSFrameConstructor(nsIDocument *aDocument, nsIPresShell* aPresShell); @@ -245,6 +246,9 @@ public: { PostRestyleEventCommon(aContent, aRestyleHint, aMinChangeHint, PR_TRUE); } + + // nsARefreshObserver + virtual void WillRefresh(mozilla::TimeStamp aTime); private: /** * Notify the frame constructor that a content node needs to have its @@ -1677,21 +1681,6 @@ public: nsCOMPtr mContent; }; - class RestyleEvent; - friend class RestyleEvent; - - class RestyleEvent : public nsRunnable { - public: - NS_DECL_NSIRUNNABLE - RestyleEvent(nsCSSFrameConstructor *aConstructor) - : mConstructor(aConstructor) { - NS_PRECONDITION(aConstructor, "Must have a constructor!"); - } - void Revoke() { mConstructor = nsnull; } - private: - nsCSSFrameConstructor *mConstructor; - }; - friend class nsFrameConstructorState; private: @@ -1744,11 +1733,13 @@ private: PRPackedBool mRebuildAllStyleData : 1; // This is true if mDocElementContainingBlock supports absolute positioning PRPackedBool mHasRootAbsPosContainingBlock : 1; + // True if we're already waiting for a refresh notification + PRPackedBool mObservingRefreshDriver : 1; + // True if we're in the middle of a nsRefreshDriver refresh + PRPackedBool mInStyleRefresh : 1; PRUint32 mHoverGeneration; nsChangeHint mRebuildAllExtraHint; - nsRevocableEventPtr mRestyleEvent; - nsCOMPtr mTempFrameTreeState; nsDataHashtable mPendingRestyles; From 89e73935dbb28a5b8aa8b2eeb7a45f5e0c3a6420 Mon Sep 17 00:00:00 2001 From: Taras Glek Date: Thu, 31 Dec 2009 11:27:22 -0800 Subject: [PATCH 10/40] Bug 537398 - Fix copyright headers in libjar r=reed --HG-- extra : rebase_source : 22b2082bcf17534346f833e36e3b4f9d80659782 --- modules/libjar/test/unit/test_corrupt_536911.js | 2 +- modules/libjar/test/unit/test_dirjar_bug525755.js | 7 +++++-- .../test/unit/test_jarinput_stream_zipreader_reference.js | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/libjar/test/unit/test_corrupt_536911.js b/modules/libjar/test/unit/test_corrupt_536911.js index 8cf021e4b32..ab80b33a0b7 100644 --- a/modules/libjar/test/unit/test_corrupt_536911.js +++ b/modules/libjar/test/unit/test_corrupt_536911.js @@ -14,7 +14,7 @@ * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is - * Mozilla Foundation + * Mozilla Foundation. * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. * diff --git a/modules/libjar/test/unit/test_dirjar_bug525755.js b/modules/libjar/test/unit/test_dirjar_bug525755.js index 07211554dad..2579e8a79bf 100644 --- a/modules/libjar/test/unit/test_dirjar_bug525755.js +++ b/modules/libjar/test/unit/test_dirjar_bug525755.js @@ -16,9 +16,12 @@ * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is - * Taras Glek - * Portions created by the Initial Developer are Copyright (C) 2006 + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Taras Glek * * 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 diff --git a/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js b/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js index 04340a34b26..ee0cf3b55db 100644 --- a/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js +++ b/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js @@ -16,9 +16,12 @@ * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is - * Taras Glek - * Portions created by the Initial Developer are Copyright (C) 2006 + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Taras Glek * * 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 From 55fb09bedbd838e1a8e3d8acac5014f573e7b8dc Mon Sep 17 00:00:00 2001 From: Taras Glek Date: Tue, 29 Dec 2009 14:04:38 -0800 Subject: [PATCH 11/40] Bug 537158: Make fastload more robust r=brendan --- xpcom/io/nsFastLoadFile.cpp | 51 +++++++++++++++++++++++++------------ xpcom/io/nsFastLoadFile.h | 3 +-- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/xpcom/io/nsFastLoadFile.cpp b/xpcom/io/nsFastLoadFile.cpp index e6c52e32657..9504eedbdfa 100644 --- a/xpcom/io/nsFastLoadFile.cpp +++ b/xpcom/io/nsFastLoadFile.cpp @@ -564,6 +564,9 @@ nsFastLoadFileReader::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aBytesRead) entry->mBytesLeft -= 8; } } + if (!mFileData) + return NS_BASE_STREAM_CLOSED; + PRUint32 count = PR_MIN(mFileLen - mFilePos, aCount); memcpy(aBuffer, mFileData+mFilePos, count); *aBytesRead = count; @@ -590,6 +593,9 @@ nsFastLoadFileReader::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, NS_ASSERTION(!entry || (!entry->mNeedToSeek && entry->mBytesLeft != 0), "ReadSegments called from above nsFastLoadFileReader layer?!"); + if (!mFileData) + return NS_BASE_STREAM_CLOSED; + PRUint32 count = PR_MIN(mFileLen - mFilePos, aCount); // Errors returned from the writer get ignored. @@ -860,25 +866,36 @@ nsFastLoadFileReader::Open() nsCOMPtr localFile = do_QueryInterface(mFile, &rv); if (NS_FAILED(rv)) return rv; - rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0, &mFd); + PRFileDesc *fd; // OS file-descriptor + rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); if (NS_FAILED(rv)) return rv; - PRInt64 size = PR_Available64(mFd); - if (size >= PR_INT32_MAX) + PRInt64 size = PR_Available64(fd); + if (size >= PR_INT32_MAX) { + PR_Close(fd); return NS_ERROR_FILE_TOO_BIG; + } mFileLen = (PRUint32) size; - - mFileMap = PR_CreateFileMap(mFd, mFileLen, PR_PROT_READONLY); - if (!mFileMap) + if (mFileLen < sizeof(nsFastLoadHeader)) { + PR_Close(fd); return NS_ERROR_FAILURE; + } + + mFileMap = PR_CreateFileMap(fd, mFileLen, PR_PROT_READONLY); + if (!mFileMap) { + PR_Close(fd); + return NS_ERROR_FAILURE; + } mFileData = (PRUint8*) PR_MemMap(mFileMap, 0, mFileLen); + // At this point the non-mmap file descriptor is no longer needed + PR_Close(fd); - if (mFileLen < sizeof(nsFastLoadHeader)) + if (!mFileData) return NS_ERROR_FAILURE; - + #if defined(XP_UNIX) madvise((char *)mFileData, mFileLen, MADV_WILLNEED); #endif @@ -922,16 +939,18 @@ nsFastLoadFileReader::Close() // a session not so much for reading objects as for its footer information, // which primes the updater's tables so that after the update completes, the // FastLoad file has a superset footer. - if (mFd) { - if (mFileData) - PR_MemUnmap(mFileData, mFileLen); + if (mFileData) { + PR_MemUnmap(mFileData, mFileLen); mFileData = nsnull; - if (mFileMap) - PR_CloseFileMap(mFileMap); - mFileMap = nsnull; - PR_Close(mFd); - mFd = nsnull; } + + if (mFileMap) { + PR_CloseFileMap(mFileMap); + mFileMap = nsnull; + } + + mFileLen = 0; + mFilePos = 0; if (!mFooter.mObjectMap) return NS_OK; diff --git a/xpcom/io/nsFastLoadFile.h b/xpcom/io/nsFastLoadFile.h index f24914740e6..85bcf68f4ac 100644 --- a/xpcom/io/nsFastLoadFile.h +++ b/xpcom/io/nsFastLoadFile.h @@ -263,7 +263,7 @@ class nsFastLoadFileReader { public: nsFastLoadFileReader(nsIFile *aFile) - : mCurrentDocumentMapEntry(nsnull), mFile(aFile), mFd(nsnull), + : mCurrentDocumentMapEntry(nsnull), mFile(aFile), mFileLen(0), mFilePos(0), mFileMap(nsnull), mFileData(nsnull) { MOZ_COUNT_CTOR(nsFastLoadFileReader); @@ -396,7 +396,6 @@ class nsFastLoadFileReader friend class nsFastLoadFileUpdater; nsIFile *mFile; // .mfasl file - PRFileDesc *mFd; // OS file-descriptor PRUint32 mFileLen; // length of file PRUint32 mFilePos; // current position within file PRFileMap *mFileMap;// nspr datastructure for mmap From cba4b340ad190dfb1544165cf28984461b1fff57 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 31 Dec 2009 17:12:43 -0500 Subject: [PATCH 12/40] Trying to fix orange due to landing of bug 528306 by fixing assumption in test. --- layout/base/tests/test_bug450930.xhtml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/layout/base/tests/test_bug450930.xhtml b/layout/base/tests/test_bug450930.xhtml index 496d0f7d400..83141143311 100644 --- a/layout/base/tests/test_bug450930.xhtml +++ b/layout/base/tests/test_bug450930.xhtml @@ -38,6 +38,9 @@ SimpleTest.waitForExplicitFinish(); function flash(doc, name) { var d = doc.getElementById(name); d.style.backgroundColor = d.style.backgroundColor == "blue" ? "yellow" : "blue"; + // Now flush out style changes in that document, since our event listeners + // seem to assume that things will work that way. + d.getBoundingClientRect(); } function le(v1, v2, s) { From b22600af132dbcc5bd3624c9e82f890fa721b0aa Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 31 Dec 2009 20:37:57 -0500 Subject: [PATCH 13/40] Bug 537419. mContent might be null here. r=dbaron --- layout/generic/nsSelection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index bb2e50bb260..1b658955e24 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -467,7 +467,8 @@ public: { if (mSelection && mPresContext) { - nsWeakFrame frame = mPresContext->GetPrimaryFrameFor(mContent); + nsWeakFrame frame = + mContent ? mPresContext->GetPrimaryFrameFor(mContent) : nsnull; mContent = nsnull; mFrameSelection->HandleDrag(frame, mPoint); From 86412ece0c1c91552bc53802f50846aeb72404a6 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Fri, 1 Jan 2010 23:00:18 +0900 Subject: [PATCH 14/40] Bug 535495 - build break test plugin on x64 due to changeset 9c16bf14545c. r=josh --- modules/plugin/test/testplugin/nptest_windows.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/plugin/test/testplugin/nptest_windows.cpp b/modules/plugin/test/testplugin/nptest_windows.cpp index 801c12288ef..a72d4a8223b 100644 --- a/modules/plugin/test/testplugin/nptest_windows.cpp +++ b/modules/plugin/test/testplugin/nptest_windows.cpp @@ -473,7 +473,7 @@ void ClearSubclass(HWND hWnd) { if (GetProp(hWnd, "MozillaWndProc")) { - ::SetWindowLong(hWnd, GWL_WNDPROC, (long)GetProp(hWnd, "MozillaWndProc")); + ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)GetProp(hWnd, "MozillaWndProc")); RemoveProp(hWnd, "MozillaWndProc"); RemoveProp(hWnd, "InstanceData"); } @@ -484,7 +484,7 @@ SetSubclass(HWND hWnd, InstanceData* instanceData) { // Subclass the plugin window so we can handle our own windows events. SetProp(hWnd, "InstanceData", (HANDLE)instanceData); - WNDPROC origProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC, (long)PluginWndProc); + WNDPROC origProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)PluginWndProc); SetProp(hWnd, "MozillaWndProc", (HANDLE)origProc); } From 01699b9589cef7ef10a60cda01ecc8a25761c288 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 22 Dec 2009 17:42:45 -0600 Subject: [PATCH 15/40] Bug 287088. Stop first-line styling from leaking into second and subsequent lines when a single element is split between first and second lines. r=roc --HG-- extra : rebase_source : 0dcf9009a73d5f8082c09172f4ce6840be5e6c98 --- layout/generic/nsInlineFrame.cpp | 51 ++++++++++++++------ layout/reftests/first-line/287088-1-ref.html | 18 +++++++ layout/reftests/first-line/287088-1.html | 18 +++++++ layout/reftests/first-line/287088-2-ref.html | 14 ++++++ layout/reftests/first-line/287088-2.html | 14 ++++++ layout/reftests/first-line/reftest.list | 2 + 6 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 layout/reftests/first-line/287088-1-ref.html create mode 100644 layout/reftests/first-line/287088-1.html create mode 100644 layout/reftests/first-line/287088-2-ref.html create mode 100644 layout/reftests/first-line/287088-2.html diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index fab5092e91b..ab23b14109c 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -303,6 +303,19 @@ nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer, } } +static void +ReParentChildListStyle(nsPresContext* aPresContext, + const nsFrameList::Slice& aFrames, + nsIFrame* aParentFrame) +{ + nsFrameManager *frameManager = aPresContext->FrameManager(); + + for (nsFrameList::Enumerator e(aFrames); !e.AtEnd(); e.Next()) { + NS_ASSERTION(e.get()->GetParent() == aParentFrame, "Bogus parentage"); + frameManager->ReParentStyleContext(e.get()); + } +} + NS_IMETHODIMP nsInlineFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, @@ -353,7 +366,16 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext, } // Insert the new frames at the beginning of the child list // and set their parent pointer - mFrames.InsertFrames(this, nsnull, *prevOverflowFrames); + const nsFrameList::Slice& newFrames = + mFrames.InsertFrames(this, nsnull, *prevOverflowFrames); + // If our prev in flow was under the first continuation of a first-line + // frame then we need to reparent the style contexts to remove the + // the special first-line styling. In the lazilySetParentPointer case + // we reparent the style contexts when we set their parents in + // nsInlineFrame::ReflowFrames and nsInlineFrame::ReflowInlineFrame. + if (aReflowState.mLineLayout->GetInFirstLine()) { + ReParentChildListStyle(aPresContext, newFrames, this); + } } } } @@ -455,6 +477,8 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; nsLineLayout* lineLayout = aReflowState.mLineLayout; + PRBool inFirstLine = aReflowState.mLineLayout->GetInFirstLine(); + nsFrameManager* frameManager = aPresContext->FrameManager(); PRBool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection); nscoord leftEdge = 0; // Don't offset by our start borderpadding if we have a prev continuation or @@ -497,6 +521,9 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, ReparentFloatsForInlineChild(irs.mLineContainer, frame, PR_FALSE); } frame->SetParent(this); + if (inFirstLine) { + frameManager->ReParentStyleContext(frame); + } // We also need to check if frame has a next-in-flow. If it does, then set // its parent frame pointer, too. Otherwise, if we reflow frame and it's // complete we'll fail when deleting its next-in-flow which is no longer @@ -512,6 +539,9 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, ReparentFloatsForInlineChild(irs.mLineContainer, nextInFlow, PR_FALSE); } nextInFlow->SetParent(this); + if (inFirstLine) { + frameManager->ReParentStyleContext(nextInFlow); + } } // Fix the parent pointer for ::first-letter child frame next-in-flows, @@ -528,6 +558,9 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, "unexpected frame type"); if (mFrames.ContainsFrame(nextInFlow)) { nextInFlow->SetParent(this); + if (inFirstLine) { + frameManager->ReParentStyleContext(nextInFlow); + } } else { #ifdef DEBUG @@ -710,6 +743,9 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, } for (nsIFrame* f = aFrame->GetNextSibling(); f; f = f->GetNextSibling()) { f->SetParent(this); + if (lineLayout->GetInFirstLine()) { + aPresContext->FrameManager()->ReParentStyleContext(f); + } } } } @@ -927,19 +963,6 @@ NS_IMETHODIMP nsInlineFrame::GetAccessible(nsIAccessible** aAccessible) // nsLineFrame implementation -static void -ReParentChildListStyle(nsPresContext* aPresContext, - const nsFrameList::Slice& aFrames, - nsIFrame* aParentFrame) -{ - nsFrameManager *frameManager = aPresContext->FrameManager(); - - for (nsFrameList::Enumerator e(aFrames); !e.AtEnd(); e.Next()) { - NS_ASSERTION(e.get()->GetParent() == aParentFrame, "Bogus parentage"); - frameManager->ReParentStyleContext(e.get()); - } -} - nsIFrame* NS_NewFirstLineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { diff --git a/layout/reftests/first-line/287088-1-ref.html b/layout/reftests/first-line/287088-1-ref.html new file mode 100644 index 00000000000..0411b1a1a4c --- /dev/null +++ b/layout/reftests/first-line/287088-1-ref.html @@ -0,0 +1,18 @@ + + + + + + +
+Line number one.
Line number two.
Line number three. +
+ +
+ +
+ + + diff --git a/layout/reftests/first-line/287088-1.html b/layout/reftests/first-line/287088-1.html new file mode 100644 index 00000000000..3583b860d9f --- /dev/null +++ b/layout/reftests/first-line/287088-1.html @@ -0,0 +1,18 @@ + + + + + + +
+Line number one.
Line number two.
Line number three.
+
+ +
+ +
+ + + diff --git a/layout/reftests/first-line/287088-2-ref.html b/layout/reftests/first-line/287088-2-ref.html new file mode 100644 index 00000000000..862d6e309c4 --- /dev/null +++ b/layout/reftests/first-line/287088-2-ref.html @@ -0,0 +1,14 @@ + + + + + + +
+Line number one.
Line number two.
Line number three. +
+ + + diff --git a/layout/reftests/first-line/287088-2.html b/layout/reftests/first-line/287088-2.html new file mode 100644 index 00000000000..9d470b13a2f --- /dev/null +++ b/layout/reftests/first-line/287088-2.html @@ -0,0 +1,14 @@ + + + + + + +
+Line number one.
Line number two.
Line number three.
+
+ + + diff --git a/layout/reftests/first-line/reftest.list b/layout/reftests/first-line/reftest.list index 4131a9c2fc4..976659dc1b1 100644 --- a/layout/reftests/first-line/reftest.list +++ b/layout/reftests/first-line/reftest.list @@ -26,6 +26,8 @@ fails == out-of-flow-1d.html out-of-flow-1-ref.html # bug 396645 == stress-11.xhtml stress-11-ref.xhtml == border-not-apply.html border-not-apply-ref.html +== 287088-1.html 287088-1-ref.html +== 287088-2.html 287088-2-ref.html == 403177-1.html 403177-1-ref.html == 469227-2.html 469227-2-ref.html == 469227-3.html 469227-3-ref.html From 5f6a955352781ac518ffb743386d84b50dd8b772 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 22 Dec 2009 17:44:35 -0600 Subject: [PATCH 16/40] Bug 499841. Pass the block frame that contains the first letter style to RemoveFirstLetterFrames so that the NS_BLOCK_HAS_FIRST_LETTER_CHILD bit can be unset on it. Always set the NS_BLOCK_HAS_FIRST_LETTER_CHILD bit on the first continuation only. r=bzbarsky --HG-- extra : rebase_source : 411297490d6d18244fa7caa3194facfedc28ea86 --- layout/base/nsCSSFrameConstructor.cpp | 35 ++++++++++++++++----------- layout/base/nsCSSFrameConstructor.h | 1 + layout/generic/nsBlockFrame.cpp | 9 ++++++- layout/generic/nsHTMLParts.h | 2 +- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 142836a47b2..d0a2f2fef93 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -9653,6 +9653,8 @@ nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame, SetInitialSingleChild(letterFrame, textFrame); aResult.Clear(); aResult.AddChild(letterFrame); + NS_ASSERTION(!aBlockFrame->GetPrevContinuation(), + "should have the first continuation here"); aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD); } } @@ -9871,6 +9873,7 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext, nsIPresShell* aPresShell, nsFrameManager* aFrameManager, nsIFrame* aFrame, + nsIFrame* aBlockFrame, PRBool* aStopLooking) { nsIFrame* prevSibling = nsnull; @@ -9913,13 +9916,15 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext, aFrameManager->InsertFrames(aFrame, nsnull, prevSibling, textList); *aStopLooking = PR_TRUE; - aFrame->RemoveStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD); + NS_ASSERTION(!aBlockFrame->GetPrevContinuation(), + "should have the first continuation here"); + aBlockFrame->RemoveStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD); break; } else if (IsInlineFrame(kid)) { // Look inside child inline frame for the letter frame - RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager, kid, - aStopLooking); + RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager, + kid, aBlockFrame, aStopLooking); if (*aStopLooking) { break; } @@ -9938,22 +9943,23 @@ nsCSSFrameConstructor::RemoveLetterFrames(nsPresContext* aPresContext, nsIFrame* aBlockFrame) { aBlockFrame = aBlockFrame->GetFirstContinuation(); - + nsIFrame* continuation = aBlockFrame; + PRBool stopLooking = PR_FALSE; nsresult rv; do { rv = RemoveFloatingFirstLetterFrames(aPresContext, aPresShell, aFrameManager, - aBlockFrame, &stopLooking); + continuation, &stopLooking); if (NS_SUCCEEDED(rv) && !stopLooking) { rv = RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager, - aBlockFrame, &stopLooking); + continuation, aBlockFrame, &stopLooking); } if (stopLooking) { break; } - aBlockFrame = aBlockFrame->GetNextContinuation(); - } while (aBlockFrame); + continuation = continuation->GetNextContinuation(); + } while (continuation); return rv; } @@ -9962,7 +9968,8 @@ nsresult nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame) { aBlockFrame = aBlockFrame->GetFirstContinuation(); - + nsIFrame* continuation = aBlockFrame; + nsIFrame* parentFrame = nsnull; nsIFrame* textFrame = nsnull; nsIFrame* prevFrame = nsnull; @@ -9971,9 +9978,9 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame) nsresult rv; do { // XXX shouldn't this bit be set already (bug 408493), assert instead? - aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE); - rv = WrapFramesInFirstLetterFrame(aBlockFrame, aBlockFrame, - aBlockFrame->GetFirstChild(nsnull), + continuation->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE); + rv = WrapFramesInFirstLetterFrame(aBlockFrame, continuation, + continuation->GetFirstChild(nsnull), &parentFrame, &textFrame, &prevFrame, letterFrames, &stopLooking); if (NS_FAILED(rv)) { @@ -9982,8 +9989,8 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame) if (stopLooking) { break; } - aBlockFrame = aBlockFrame->GetNextContinuation(); - } while (aBlockFrame); + continuation = continuation->GetNextContinuation(); + } while (continuation); if (parentFrame) { // Take the old textFrame out of the parents child list diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 2c1b6b07377..fd3e3edb019 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1568,6 +1568,7 @@ private: nsIPresShell* aPresShell, nsFrameManager* aFrameManager, nsIFrame* aFrame, + nsIFrame* aBlockFrame, PRBool* aStopLooking); // Special remove method for those pesky floating first-letter frames diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index ef770af1ba4..7d56402eb74 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -3520,6 +3520,9 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, (NS_BLOCK_HAS_FIRST_LETTER_STYLE & mState)) { aLineLayout.SetFirstLetterStyleOK(PR_TRUE); } + NS_ASSERTION(!((NS_BLOCK_HAS_FIRST_LETTER_CHILD & mState) && + GetPrevContinuation()), + "first letter child bit should only be on first continuation"); // Reflow the frames that are already on the line first nsresult rv = NS_OK; @@ -6318,8 +6321,12 @@ nsBlockFrame::Init(nsIContent* aContent, // Copy over the block frame type flags nsBlockFrame* blockFrame = (nsBlockFrame*)aPrevInFlow; + // Don't copy NS_BLOCK_HAS_FIRST_LETTER_CHILD as that is set on the first + // continuation only. SetFlags(blockFrame->mState & - (NS_BLOCK_FLAGS_MASK & ~NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)); + (NS_BLOCK_FLAGS_MASK & + (~NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET & + ~NS_BLOCK_HAS_FIRST_LETTER_CHILD))); } nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow); diff --git a/layout/generic/nsHTMLParts.h b/layout/generic/nsHTMLParts.h index 6f7823e4d67..a546274516c 100644 --- a/layout/generic/nsHTMLParts.h +++ b/layout/generic/nsHTMLParts.h @@ -68,7 +68,7 @@ class nsTableColFrame; * NS_BLOCK_HAS_FIRST_LETTER_CHILD means that there is an inflow first-letter * frame among the block's descendants. If there is a floating first-letter * frame, or the block has first-letter style but has no first letter, this - * bit is not set. + * bit is not set. This bit is set on the first continuation only. */ #define NS_BLOCK_NO_AUTO_MARGINS 0x00200000 #define NS_BLOCK_MARGIN_ROOT 0x00400000 From ad77d4e1d73f3ffcd30683313fe6bf83d991086a Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 22 Dec 2009 17:47:25 -0600 Subject: [PATCH 17/40] Bug 484400. When removing a positioned element use the placeholder frame to get the relevant containing block for first-letter processing. r=bzbarsky --HG-- extra : rebase_source : 9a327e8f44541ac822bc7be52caa1ceab825ccd1 --- layout/base/nsCSSFrameConstructor.cpp | 16 +++++++-------- .../reftests/first-letter/484400-1-ref.html | 11 ++++++++++ layout/reftests/first-letter/484400-1.html | 20 +++++++++++++++++++ layout/reftests/first-letter/reftest.list | 1 + 4 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 layout/reftests/first-letter/484400-1-ref.html create mode 100644 layout/reftests/first-letter/484400-1.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index d0a2f2fef93..7f6a4ca8ce8 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -6985,7 +6985,13 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, // Examine the containing-block for the removed content and see if // :first-letter style applies. - nsIFrame* containingBlock = GetFloatContainingBlock(parentFrame); + nsIFrame* inflowChild = childFrame; + if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { + inflowChild = frameManager->GetPlaceholderFrameFor(childFrame); + NS_ASSERTION(inflowChild, "No placeholder for out-of-flow?"); + } + nsIFrame* containingBlock = + GetFloatContainingBlock(inflowChild->GetParent()); PRBool haveFLS = containingBlock && HasFirstLetterStyle(containingBlock); if (haveFLS) { // Trap out to special routine that handles adjusting a blocks @@ -7057,11 +7063,6 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, } if (haveFLS && mRootElementFrame) { - NS_ASSERTION(containingBlock == GetFloatContainingBlock(parentFrame), - "What happened here?"); - nsFrameConstructorState state(mPresShell, mFixedContainingBlock, - GetAbsoluteContainingBlock(parentFrame), - containingBlock); RecoverLetterFrames(containingBlock); } @@ -7414,9 +7415,6 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent, frame->CharacterDataChanged(aInfo); if (haveFirstLetterStyle) { - nsFrameConstructorState state(mPresShell, mFixedContainingBlock, - GetAbsoluteContainingBlock(frame), - block, nsnull); RecoverLetterFrames(block); } } diff --git a/layout/reftests/first-letter/484400-1-ref.html b/layout/reftests/first-letter/484400-1-ref.html new file mode 100644 index 00000000000..0b303704832 --- /dev/null +++ b/layout/reftests/first-letter/484400-1-ref.html @@ -0,0 +1,11 @@ + + + + + +
+ T +
+ diff --git a/layout/reftests/first-letter/484400-1.html b/layout/reftests/first-letter/484400-1.html new file mode 100644 index 00000000000..e7ea6af1654 --- /dev/null +++ b/layout/reftests/first-letter/484400-1.html @@ -0,0 +1,20 @@ + + + + + + +
+ abcdefhT +
+ diff --git a/layout/reftests/first-letter/reftest.list b/layout/reftests/first-letter/reftest.list index 6c5016fc915..e1a8fc2c071 100644 --- a/layout/reftests/first-letter/reftest.list +++ b/layout/reftests/first-letter/reftest.list @@ -53,3 +53,4 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 329069-1.html 329069-1-ref.html # failu == 429968-2c.html 429968-2-ref.html == 441418-1.html 441418-1-ref.html == 469227-1.html 469227-1-ref.html +== 484400-1.html 484400-1-ref.html From 3e07c973394c6ba7087c57533d7c7a51366695de Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 22 Dec 2009 17:49:33 -0600 Subject: [PATCH 18/40] Bug 488771. Stop nsIRollUpListener from inheriting from nsISupports. r=roc --HG-- extra : rebase_source : 0af5c537b7be03c1407f4b658ba7802081ad3f01 --- layout/forms/nsComboboxControlFrame.cpp | 18 ++------------- layout/forms/nsComboboxControlFrame.h | 1 - layout/xul/base/public/nsXULPopupManager.h | 6 ++++- layout/xul/base/src/nsXULPopupManager.cpp | 8 +++---- widget/public/Makefile.in | 2 +- ...RollupListener.idl => nsIRollupListener.h} | 23 +++++++++---------- widget/public/nsIWidget.h | 4 +++- widget/src/beos/nsWindow.cpp | 19 +++++++++------ widget/src/beos/nsWindow.h | 1 + widget/src/cocoa/nsChildView.h | 3 ++- widget/src/cocoa/nsChildView.mm | 10 ++++---- widget/src/cocoa/nsCocoaWindow.h | 3 ++- widget/src/cocoa/nsCocoaWindow.mm | 10 ++++++-- widget/src/gtk2/nsWindow.cpp | 16 +++++++++---- widget/src/gtk2/nsWindow.h | 1 + widget/src/os2/nsWindow.cpp | 23 ++++++++++--------- widget/src/os2/nsWindow.h | 3 ++- widget/src/photon/nsWidget.h | 4 +++- widget/src/photon/nsWindow.cpp | 16 +++++++++---- widget/src/photon/nsWindow.h | 2 ++ widget/src/qt/nsWindow.cpp | 16 +++++++++---- widget/src/qt/nsWindow.h | 1 + widget/src/windows/nsWindow.cpp | 17 ++++++++------ widget/src/windows/nsWindow.h | 4 +++- 24 files changed, 124 insertions(+), 87 deletions(-) rename widget/public/{nsIRollupListener.idl => nsIRollupListener.h} (85%) diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index e85e050e558..01694daf08b 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -300,20 +300,6 @@ NS_QUERYFRAME_HEAD(nsComboboxControlFrame) NS_QUERYFRAME_ENTRY(nsIScrollableViewProvider) NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame) -NS_IMPL_QUERY_INTERFACE1(nsComboboxControlFrame, nsIRollupListener) - -NS_IMETHODIMP_(nsrefcnt) -nsComboboxControlFrame::AddRef() -{ - return 2; -} - -NS_IMETHODIMP_(nsrefcnt) -nsComboboxControlFrame::Release() -{ - return 1; -} - #ifdef ACCESSIBILITY NS_IMETHODIMP nsComboboxControlFrame::GetAccessible(nsIAccessible** aAccessible) { @@ -427,7 +413,7 @@ nsComboboxControlFrame::ShowList(PRBool aShowList) if (view) { nsIWidget* widget = view->GetWidget(); if (widget) - widget->CaptureRollupEvents(this, mDroppedDown, mDroppedDown); + widget->CaptureRollupEvents(this, nsnull, mDroppedDown, mDroppedDown); } } @@ -1226,7 +1212,7 @@ nsComboboxControlFrame::DestroyFrom(nsIFrame* aDestructRoot) if (view) { nsIWidget* widget = view->GetWidget(); if (widget) - widget->CaptureRollupEvents(this, PR_FALSE, PR_TRUE); + widget->CaptureRollupEvents(this, nsnull, PR_FALSE, PR_TRUE); } } } diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 252bd408083..dbc12c31de1 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -98,7 +98,6 @@ public: NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS - NS_DECL_ISUPPORTS_INHERITED // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements); diff --git a/layout/xul/base/public/nsXULPopupManager.h b/layout/xul/base/public/nsXULPopupManager.h index 927a7d74ef3..b5e9ab10660 100644 --- a/layout/xul/base/public/nsXULPopupManager.h +++ b/layout/xul/base/public/nsXULPopupManager.h @@ -310,9 +310,13 @@ public: friend class nsXULMenuCommandEvent; NS_DECL_ISUPPORTS - NS_DECL_NSIROLLUPLISTENER NS_DECL_NSITIMERCALLBACK + // nsIRollupListener + NS_IMETHOD Rollup(PRUint32 aCount, nsIContent **aContent); + NS_IMETHOD ShouldRollupOnMouseWheelEvent(PRBool *aShould); + NS_IMETHOD ShouldRollupOnMouseActivate(PRBool *aShould); + virtual PRUint32 GetSubmenuWidgetChain(nsTArray *aWidgetChain); virtual void AdjustPopupsOnWindowChange(void); diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/base/src/nsXULPopupManager.cpp index fc919f5115f..4e3ba92a52f 100644 --- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/base/src/nsXULPopupManager.cpp @@ -127,11 +127,10 @@ void nsMenuChainItem::Detach(nsMenuChainItem** aRoot) } } -NS_IMPL_ISUPPORTS5(nsXULPopupManager, +NS_IMPL_ISUPPORTS4(nsXULPopupManager, nsIDOMKeyListener, nsIDOMEventListener, nsIMenuRollup, - nsIRollupListener, nsITimerCallback) nsXULPopupManager::nsXULPopupManager() : @@ -1391,7 +1390,7 @@ nsXULPopupManager::SetCaptureState(nsIContent* aOldPopup) return; if (mWidget) { - mWidget->CaptureRollupEvents(this, PR_FALSE, PR_FALSE); + mWidget->CaptureRollupEvents(this, this, PR_FALSE, PR_FALSE); mWidget = nsnull; } @@ -1400,7 +1399,8 @@ nsXULPopupManager::SetCaptureState(nsIContent* aOldPopup) nsCOMPtr widget; popup->GetWidget(getter_AddRefs(widget)); if (widget) { - widget->CaptureRollupEvents(this, PR_TRUE, popup->ConsumeOutsideClicks()); + widget->CaptureRollupEvents(this, this, PR_TRUE, + popup->ConsumeOutsideClicks()); mWidget = widget; popup->AttachedDismissalListener(); } diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in index f7643a5f2a1..849dd614173 100644 --- a/widget/public/Makefile.in +++ b/widget/public/Makefile.in @@ -58,6 +58,7 @@ EXPORTS = \ nsINativeKeyBindings.h \ nsIDeviceContextSpec.h \ nsIMenuRollup.h \ + nsIRollupListener.h \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) @@ -97,7 +98,6 @@ XPIDLSRCS = \ nsIClipboard.idl \ nsIClipboardHelper.idl \ nsIClipboardOwner.idl \ - nsIRollupListener.idl \ nsIBaseWindow.idl \ nsIBidiKeyboard.idl \ nsIScreen.idl \ diff --git a/widget/public/nsIRollupListener.idl b/widget/public/nsIRollupListener.h similarity index 85% rename from widget/public/nsIRollupListener.idl rename to widget/public/nsIRollupListener.h index c05fc6ddd5f..38193bc2c56 100644 --- a/widget/public/nsIRollupListener.idl +++ b/widget/public/nsIRollupListener.h @@ -39,34 +39,33 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsISupports.idl" +#ifndef __nsIRollupListener_h__ +#define __nsIRollupListener_h__ -interface nsIContent; +class nsIContent; + +class nsIRollupListener { + public: -[uuid(0CA103E5-80D4-4B81-A310-BE0708F8EAA9)] -interface nsIRollupListener : nsISupports -{ /** * Notifies the object to rollup, optionally returning the node that * was just rolled up. * * aCount is the number of popups in a chain to close. If this is * PR_UINT32_MAX, then all popups are closed. - * - * @result NS_Ok if no errors */ - nsIContent Rollup(in unsigned long aCount); + NS_IMETHOD Rollup(PRUint32 aCount, nsIContent **aContent) = 0; /** * Asks the RollupListener if it should rollup on mousevents - * @result NS_Ok if no errors */ - void ShouldRollupOnMouseWheelEvent(out PRBool aShould); + NS_IMETHOD ShouldRollupOnMouseWheelEvent(PRBool *aShould) = 0; /** * Asks the RollupListener if it should rollup on mouse activate, eg. X-Mouse - * @result NS_Ok if no errors */ - void ShouldRollupOnMouseActivate(out PRBool aShould); + NS_IMETHOD ShouldRollupOnMouseActivate(PRBool *aShould) = 0; }; + +#endif /* __nsIRollupListener_h__ */ diff --git a/widget/public/nsIWidget.h b/widget/public/nsIWidget.h index eafdaf2f82f..ab43ab19792 100644 --- a/widget/public/nsIWidget.h +++ b/widget/public/nsIWidget.h @@ -60,6 +60,7 @@ class nsIRenderingContext; class nsIDeviceContext; struct nsFont; class nsIRollupListener; +class nsIMenuRollup; class nsGUIEvent; class imgIContainer; class gfxASurface; @@ -767,7 +768,8 @@ class nsIWidget : public nsISupports { * @param aConsumeRollupEvent PR_TRUE consumes the rollup event, PR_FALSE dispatches rollup event * */ - NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) = 0; + NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, PRBool aConsumeRollupEvent) = 0; /** * Bring this window to the user's attention. This is intended to be a more diff --git a/widget/src/beos/nsWindow.cpp b/widget/src/beos/nsWindow.cpp index 9cd37ff31f7..23f7416a0eb 100644 --- a/widget/src/beos/nsWindow.cpp +++ b/widget/src/beos/nsWindow.cpp @@ -92,6 +92,7 @@ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID); // Rollup Listener - static variable defintions static nsIRollupListener * gRollupListener = nsnull; +static nsIMenuRollup * gMenuRollup = nsnull; static nsIWidget * gRollupWidget = nsnull; static PRBool gRollupConsumeRollupEvent = PR_FALSE; // Tracking last activated BWindow @@ -712,7 +713,10 @@ NS_METHOD nsWindow::CaptureMouse(PRBool aCapture) //------------------------------------------------------------------------- // Capture Roolup Events //------------------------------------------------------------------------- -NS_METHOD nsWindow::CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) +NS_METHOD nsWindow::CaptureRollupEvents(nsIRollupListener * aListener, + nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, + PRBool aConsumeRollupEvent) { if (!mEnabled) return NS_OK; @@ -724,16 +728,18 @@ NS_METHOD nsWindow::CaptureRollupEvents(nsIRollupListener * aListener, PRBool aD // assure that remains true. NS_ASSERTION(!gRollupWidget, "rollup widget reassigned before release"); gRollupConsumeRollupEvent = aConsumeRollupEvent; - NS_IF_RELEASE(gRollupListener); NS_IF_RELEASE(gRollupWidget); gRollupListener = aListener; - NS_ADDREF(aListener); + NS_IF_RELEASE(gMenuRollup); + gMenuRollup = aMenuRollup; + NS_IF_ADDREF(aMenuRollup); gRollupWidget = this; NS_ADDREF(this); } else { - NS_IF_RELEASE(gRollupListener); + gRollupListener == nsnull; + NS_IF_RELEASE(gMenuRollup); NS_IF_RELEASE(gRollupWidget); } @@ -783,11 +789,10 @@ nsWindow::DealWithPopups(uint32 methodID, nsPoint pos) // want to rollup if the click is in a parent menu of the current submenu. if (rollup) { - nsCOMPtr menuRollup ( do_QueryInterface(gRollupListener) ); - if ( menuRollup ) + if ( gMenuRollup ) { nsAutoTArray widgetChain; - menuRollup->GetSubmenuWidgetChain(&widgetChain); + gMenuRollup->GetSubmenuWidgetChain(&widgetChain); for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) { diff --git a/widget/src/beos/nsWindow.h b/widget/src/beos/nsWindow.h index ee186d26ca8..7cce1bad67e 100644 --- a/widget/src/beos/nsWindow.h +++ b/widget/src/beos/nsWindow.h @@ -109,6 +109,7 @@ public: NS_IMETHOD Show(PRBool bState); NS_IMETHOD CaptureMouse(PRBool aCapture); NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, + nsIMenuRollup *aMenuRollup, PRBool aDoCapture, PRBool aConsumeRollupEvent); NS_IMETHOD IsVisible(PRBool & aState); diff --git a/widget/src/cocoa/nsChildView.h b/widget/src/cocoa/nsChildView.h index efb7029b944..334be9a11ee 100644 --- a/widget/src/cocoa/nsChildView.h +++ b/widget/src/cocoa/nsChildView.h @@ -360,7 +360,8 @@ public: NS_IMETHOD SetCursor(nsCursor aCursor); NS_IMETHOD SetCursor(imgIContainer* aCursor, PRUint32 aHotspotX, PRUint32 aHotspotY); - NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent); + NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, PRBool aConsumeRollupEvent); NS_IMETHOD SetTitle(const nsAString& title); NS_IMETHOD GetAttention(PRInt32 aCycleCount); diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index c0631e5c7d7..3cecb031ee6 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -153,6 +153,7 @@ static void blinkRgn(RgnHandle rgn); #endif nsIRollupListener * gRollupListener = nsnull; +nsIMenuRollup * gMenuRollup = nsnull; nsIWidget * gRollupWidget = nsnull; PRUint32 gLastModifierState = 0; @@ -1891,6 +1892,7 @@ nsIntPoint nsChildView::WidgetToScreenOffset() } NS_IMETHODIMP nsChildView::CaptureRollupEvents(nsIRollupListener * aListener, + nsIMenuRollup * aMenuRollup, PRBool aDoCapture, PRBool aConsumeRollupEvent) { @@ -2749,12 +2751,10 @@ NSEvent* gLastDragMouseDownEvent = nil; // we don't want to rollup if the click is in a parent menu of // the current submenu PRUint32 popupsToRollup = PR_UINT32_MAX; - nsCOMPtr menuRollup; - menuRollup = (do_QueryInterface(gRollupListener)); - if (menuRollup) { + if (gMenuRollup) { nsAutoTArray widgetChain; - menuRollup->GetSubmenuWidgetChain(&widgetChain); - PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain); + gMenuRollup->GetSubmenuWidgetChain(&widgetChain); + PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain); for (PRUint32 i = 0; i < widgetChain.Length(); i++) { nsIWidget* widget = widgetChain[i]; NSWindow* currWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW); diff --git a/widget/src/cocoa/nsCocoaWindow.h b/widget/src/cocoa/nsCocoaWindow.h index 283468a7c49..4b094ce561d 100644 --- a/widget/src/cocoa/nsCocoaWindow.h +++ b/widget/src/cocoa/nsCocoaWindow.h @@ -245,7 +245,8 @@ public: const nsTArray& aDestRects, const nsTArray& aConfigurations); NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus) ; - NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent); + NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, PRBool aConsumeRollupEvent); NS_IMETHOD GetAttention(PRInt32 aCycleCount); virtual PRBool HasPendingInputEvent(); virtual nsTransparencyMode GetTransparencyMode(); diff --git a/widget/src/cocoa/nsCocoaWindow.mm b/widget/src/cocoa/nsCocoaWindow.mm index 4fc81dc9167..9c26b5343df 100644 --- a/widget/src/cocoa/nsCocoaWindow.mm +++ b/widget/src/cocoa/nsCocoaWindow.mm @@ -66,6 +66,7 @@ #include "nsStyleConsts.h" #include "nsNativeThemeColors.h" #include "nsChildView.h" +#include "nsIMenuRollup.h" #include "gfxPlatform.h" #include "qcms.h" @@ -89,6 +90,7 @@ extern NSMenu* sApplicationMenu; // Application menu shared by all menubars // defined in nsChildView.mm extern nsIRollupListener * gRollupListener; +extern nsIMenuRollup * gMenuRollup; extern nsIWidget * gRollupWidget; extern BOOL gSomeMenuBarPainted; @@ -1344,17 +1346,21 @@ nsMenuBarX* nsCocoaWindow::GetMenuBar() } NS_IMETHODIMP nsCocoaWindow::CaptureRollupEvents(nsIRollupListener * aListener, + nsIMenuRollup * aMenuRollup, PRBool aDoCapture, PRBool aConsumeRollupEvent) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - NS_IF_RELEASE(gRollupListener); + gRollupListener = nsnull; + NS_IF_RELEASE(gMenuRollup); NS_IF_RELEASE(gRollupWidget); if (aDoCapture) { gRollupListener = aListener; - NS_ADDREF(aListener); + NS_IF_RELEASE(gMenuRollup); + gMenuRollup = aMenuRollup; + NS_IF_ADDREF(aMenuRollup); gRollupWidget = this; NS_ADDREF(this); diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index 842ed7bc677..b270adb01e5 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -290,7 +290,8 @@ static PRBool gGlobalsInitialized = PR_FALSE; static PRBool gRaiseWindows = PR_TRUE; static nsWindow *gPluginFocusWindow = NULL; -static nsCOMPtr gRollupListener; +static nsIRollupListener* gRollupListener; +static nsIMenuRollup* gMenuRollup; static nsWeakPtr gRollupWindow; static PRBool gConsumeRollupEvent; @@ -762,6 +763,7 @@ nsWindow::Destroy(void) if (static_cast(this) == rollupWidget.get()) { if (gRollupListener) gRollupListener->Rollup(nsnull, nsnull); + NS_IF_RELEASE(gMenuRollup); gRollupWindow = nsnull; gRollupListener = nsnull; } @@ -2150,6 +2152,7 @@ nsWindow::CaptureMouse(PRBool aCapture) NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener *aListener, + nsIMenuRollup *aMenuRollup, PRBool aDoCapture, PRBool aConsumeRollupEvent) { @@ -2165,6 +2168,9 @@ nsWindow::CaptureRollupEvents(nsIRollupListener *aListener, if (aDoCapture) { gConsumeRollupEvent = aConsumeRollupEvent; gRollupListener = aListener; + NS_IF_RELEASE(gMenuRollup); + gMenuRollup = aMenuRollup; + NS_IF_ADDREF(aMenuRollup); gRollupWindow = do_GetWeakReference(static_cast (this)); // real grab is only done when there is no dragging @@ -2180,6 +2186,7 @@ nsWindow::CaptureRollupEvents(nsIRollupListener *aListener, gtk_grab_remove(widget); } gRollupListener = nsnull; + NS_IF_RELEASE(gMenuRollup); gRollupWindow = nsnull; } @@ -5340,11 +5347,9 @@ check_for_rollup(GdkWindow *aWindow, gdouble aMouseX, gdouble aMouseY, // we don't want to rollup if the clickis in a parent menu of // the current submenu PRUint32 popupsToRollup = PR_UINT32_MAX; - nsCOMPtr menuRollup; - menuRollup = (do_QueryInterface(gRollupListener)); - if (menuRollup) { + if (gMenuRollup) { nsAutoTArray widgetChain; - PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain); + PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain); for (PRUint32 i=0; i menuRollup ( do_QueryInterface(gRollupListener) ); - if ( menuRollup ) { + if ( gMenuRollup ) { nsAutoTArray widgetChain; - PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain); + PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain); for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) { nsIWidget* widget = widgetChain[i]; if ( nsWindow::EventIsInsideWindow((nsWindow*)widget) ) { @@ -639,10 +641,9 @@ MRESULT EXPENTRY fnwpNSWindow( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) // If we're dealing with menus, we probably have submenus and we don't // want to rollup if the click is in a parent menu of the current submenu. if (rollup) { - nsCOMPtr menuRollup ( do_QueryInterface(gRollupListener) ); - if ( menuRollup ) { + if ( gMenuRollup ) { nsAutoTArray widgetChain; - menuRollup->GetSubmenuWidgetChain ( &widgetChain ); + gMenuRollup->GetSubmenuWidgetChain ( &widgetChain ); for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) { nsIWidget* widget = widgetChain[i]; if ( nsWindow::EventIsInsideWindow((nsWindow*)widget) ) { @@ -972,7 +973,7 @@ NS_METHOD nsWindow::Destroy() if (gRollupListener) { gRollupListener->Rollup(PR_UINT32_MAX, nsnull); } - CaptureRollupEvents(nsnull, PR_FALSE, PR_TRUE); + CaptureRollupEvents(nsnull, nsnull, PR_FALSE, PR_TRUE); } if (mWnd) { diff --git a/widget/src/os2/nsWindow.h b/widget/src/os2/nsWindow.h index c5a9d89d7c6..d13f65a5c19 100644 --- a/widget/src/os2/nsWindow.h +++ b/widget/src/os2/nsWindow.h @@ -148,7 +148,8 @@ class nsWindow : public nsBaseWidget virtual nsIntPoint WidgetToScreenOffset(); NS_IMETHOD DispatchEvent( struct nsGUIEvent *event, nsEventStatus &aStatus); - NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent); + NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, PRBool aConsumeRollupEvent); virtual PRBool HasPendingInputEvent(); diff --git a/widget/src/photon/nsWidget.h b/widget/src/photon/nsWidget.h index 060122691df..7c66ad68f29 100644 --- a/widget/src/photon/nsWidget.h +++ b/widget/src/photon/nsWidget.h @@ -92,7 +92,9 @@ public: NS_IMETHOD SetModal(PRBool aModal); NS_IMETHOD Show(PRBool state); - inline NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) { return NS_OK; } + inline NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, nsIMenuRollup *aMenuRollup, + PRBool aDoCapture, PRBool aConsumeRollupEvent) + { return NS_OK; } inline NS_IMETHOD IsVisible(PRBool &aState) { aState = mShown; return NS_OK; } diff --git a/widget/src/photon/nsWindow.cpp b/widget/src/photon/nsWindow.cpp index dd88351defc..1b7cd967985 100644 --- a/widget/src/photon/nsWindow.cpp +++ b/widget/src/photon/nsWindow.cpp @@ -59,6 +59,7 @@ #include "nsClipboard.h" #include "nsIRollupListener.h" +#include "nsIMenuRollup.h" #include "nsIServiceManager.h" #include "nsIAppShell.h" @@ -74,6 +75,7 @@ static PhTile_t *GetWindowClipping( PtWidget_t *aWidget ); nsIRollupListener *nsWindow::gRollupListener = nsnull; +nsIMenuRollup *nsWindow::gMenuRollup = nsnull; nsIWidget *nsWindow::gRollupWidget = nsnull; static PtWidget_t *gMenuRegion; @@ -171,15 +173,21 @@ void nsWindow::DestroyNativeChildren(void) } } -NS_IMETHODIMP nsWindow::CaptureRollupEvents( nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent ) { +NS_IMETHODIMP nsWindow::CaptureRollupEvents( nsIRollupListener * aListener, + nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, + PRBool aConsumeRollupEvent ) +{ PtWidget_t *grabWidget; grabWidget = mWidget; if (aDoCapture) { - NS_IF_RELEASE(gRollupListener); + gRollupListener = nsnull; NS_IF_RELEASE(gRollupWidget); gRollupListener = aListener; - NS_ADDREF(aListener); + NS_IF_RELEASE(gMenuRollup); + gMenuRollup = aMenuRollup; + NS_IF_ADDREF(aMenuRollup); gRollupWidget = this; NS_ADDREF(this); @@ -203,8 +211,8 @@ NS_IMETHODIMP nsWindow::CaptureRollupEvents( nsIRollupListener * aListener, PRBo } } else { - NS_IF_RELEASE(gRollupListener); gRollupListener = nsnull; + NS_IF_RELEASE(gMenuRollup); NS_IF_RELEASE(gRollupWidget); gRollupWidget = nsnull; diff --git a/widget/src/photon/nsWindow.h b/widget/src/photon/nsWindow.h index 4a6e26dc659..b375d11f558 100644 --- a/widget/src/photon/nsWindow.h +++ b/widget/src/photon/nsWindow.h @@ -91,6 +91,7 @@ public: } NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, + nsIMenuRollup * aMenuRollup, PRBool aDoCapture, PRBool aConsumeRollupEvent); @@ -155,6 +156,7 @@ private: PRBool mIsTooSmall; PRBool mIsDestroying; static nsIRollupListener *gRollupListener; + static nsIMenuRollup* gMenuRollup; static nsIWidget *gRollupWidget; }; diff --git a/widget/src/qt/nsWindow.cpp b/widget/src/qt/nsWindow.cpp index 32ac1c1ddfd..3b372c8eb69 100644 --- a/widget/src/qt/nsWindow.cpp +++ b/widget/src/qt/nsWindow.cpp @@ -114,7 +114,8 @@ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID); static const int WHEEL_DELTA = 120; static PRBool gGlobalsInitialized = PR_FALSE; -static nsCOMPtr gRollupListener; +static nsIRollupListener* gRollupListener; +static nsIMenuRollup* gMenuRollup; static nsWeakPtr gRollupWindow; static PRBool gConsumeRollupEvent; @@ -250,6 +251,7 @@ nsWindow::Destroy(void) gRollupListener->Rollup(nsnull, nsnull); gRollupWindow = nsnull; gRollupListener = nsnull; + NS_IF_RELEASE(gMenuRollup); } Show(PR_FALSE); @@ -802,6 +804,7 @@ nsWindow::CaptureMouse(PRBool aCapture) NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener *aListener, + nsIMenuRollup *aMenuRollup, PRBool aDoCapture, PRBool aConsumeRollupEvent) { @@ -813,10 +816,14 @@ nsWindow::CaptureRollupEvents(nsIRollupListener *aListener, if (aDoCapture) { gConsumeRollupEvent = aConsumeRollupEvent; gRollupListener = aListener; + NS_IF_RELEASE(gMenuRollup); + gMenuRollup = aMenuRollup; + NS_IF_ADDREF(aMenuRollup); gRollupWindow = do_GetWeakReference(static_cast(this)); } else { gRollupListener = nsnull; + NS_IF_RELEASE(gMenuRollup); gRollupWindow = nsnull; } @@ -844,11 +851,9 @@ check_for_rollup(double aMouseX, double aMouseY, // we don't want to rollup if the clickis in a parent menu of // the current submenu PRUint32 popupsToRollup = PR_UINT32_MAX; - nsCOMPtr menuRollup; - menuRollup = (do_QueryInterface(gRollupListener)); - if (menuRollup) { + if (gMenuRollup) { nsAutoTArray widgetChain; - PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain); + PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain); for (PRUint32 i=0; iRollup(nsnull, nsnull); - CaptureRollupEvents(nsnull, PR_FALSE, PR_TRUE); + CaptureRollupEvents(nsnull, nsnull, PR_FALSE, PR_TRUE); } // If IME is disabled, restore it. @@ -6792,10 +6796,9 @@ nsWindow::DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inLPara // want to rollup if the click is in a parent menu of the current submenu. PRUint32 popupsToRollup = PR_UINT32_MAX; if (rollup) { - nsCOMPtr menuRollup ( do_QueryInterface(sRollupListener) ); - if ( menuRollup ) { + if ( sMenuRollup ) { nsAutoTArray widgetChain; - PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain); + PRUint32 sameTypeCount = sMenuRollup->GetSubmenuWidgetChain(&widgetChain); for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) { nsIWidget* widget = widgetChain[i]; if ( nsWindow::EventIsInsideWindow(inMsg, (nsWindow*)widget) ) { diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index bf22d566ff0..04a9f5876b8 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -153,7 +153,8 @@ public: NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus); NS_IMETHOD EnableDragDrop(PRBool aEnable); NS_IMETHOD CaptureMouse(PRBool aCapture); - NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent); + NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup, + PRBool aDoCapture, PRBool aConsumeRollupEvent); NS_IMETHOD GetAttention(PRInt32 aCycleCount); virtual PRBool HasPendingInputEvent(); gfxASurface *GetThebesSurface(); @@ -462,6 +463,7 @@ protected: static nsIWidget* sRollupWidget; static PRBool sRollupConsumeEvent; static nsIRollupListener* sRollupListener; + static nsIMenuRollup* sMenuRollup; // Mouse Clicks - static variable definitions for figuring // out 1 - 3 Clicks. From bd38594159b4cff069b90b28bcab8075cc2d8738 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 22 Dec 2009 17:53:07 -0600 Subject: [PATCH 19/40] Bug 396367. Fix up some tests to be more robust. r=enndeakin --HG-- extra : rebase_source : c3aafd472aebcacfce7f778d61f5a088dd0493c4 --- toolkit/content/tests/chrome/test_showcaret.xul | 9 ++++++--- toolkit/spatial-navigation/tests/chrome/test_snav.xul | 7 ++++--- .../tests/chrome/test_snav_disabledElement.xul | 7 ++++--- .../tests/chrome/test_snav_prefDisabled.xul | 7 ++++--- .../tests/chrome/test_snav_prefKeyCode.xul | 7 ++++--- .../tests/chrome/test_snav_selects.xul | 7 ++++--- .../tests/chrome/test_snav_textFields.xul | 7 ++++--- .../tests/chrome/test_snav_tightlinks.xul | 7 ++++--- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/toolkit/content/tests/chrome/test_showcaret.xul b/toolkit/content/tests/chrome/test_showcaret.xul index fbaa9fa0e9c..62b33c10e99 100644 --- a/toolkit/content/tests/chrome/test_showcaret.xul +++ b/toolkit/content/tests/chrome/test_showcaret.xul @@ -12,8 +12,9 @@