From 6c393ae2f44948157dc23be5019cf8c46b417a2e Mon Sep 17 00:00:00 2001 From: "hyatt%netscape.com" Date: Mon, 4 Jun 2001 00:22:43 +0000 Subject: [PATCH] Fixes for 80512 and 83707. r=blake, sr=waterson, a=asa --- layout/base/nsCSSFrameConstructor.cpp | 14 ++++-- layout/base/nsFrameManager.cpp | 49 ++++++++++--------- layout/base/nsPresShell.cpp | 40 ++++++++------- layout/base/public/nsIFrameManager.h | 2 +- layout/html/base/src/nsFrameManager.cpp | 49 ++++++++++--------- layout/html/base/src/nsPresShell.cpp | 40 ++++++++------- .../html/style/src/nsCSSFrameConstructor.cpp | 14 ++++-- layout/xul/base/src/nsMenuBarFrame.cpp | 4 +- 8 files changed, 120 insertions(+), 92 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index de13170e973c..62fac6bce087 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -7978,6 +7978,16 @@ nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext, // Get the frame associated with the content nsIFrame* parentFrame = GetFrameFor(shell, aPresContext, aContainer); if (nsnull != parentFrame) { + // See if we have an XBL insertion point. If so, then see if the + // frame for it has been built yet. If it hasn't been built yet, + // then we just bail. + nsCOMPtr frameManager; + shell->GetFrameManager(getter_AddRefs(frameManager)); + nsIFrame* insertionPoint = nsnull; + frameManager->GetInsertionPoint(shell, parentFrame, nsnull, &insertionPoint); + if (!insertionPoint) + return NS_OK; // Don't build the frames. + // If the frame we are manipulating is a ``special'' frame (that // is, one that's been created as a result of a block-in-inline // situation) then do something different instead of just @@ -8003,9 +8013,7 @@ nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext, // Since we're appending, we'll walk to the last anonymous frame // that was created for the broken inline frame. - nsCOMPtr frameManager; - shell->GetFrameManager(getter_AddRefs(frameManager)); - + while (1) { nsIFrame* sibling; GetSpecialSibling(frameManager, parentFrame, &sibling); diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index 4827c6521711..bf82b036e9ec 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -317,7 +317,7 @@ public: NS_IMETHOD RemoveFrameProperty(nsIFrame* aFrame, nsIAtom* aPropertyName); - NS_IMETHOD GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult); + NS_IMETHOD GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIContent* aChild, nsIFrame** aResult); #ifdef NS_DEBUG NS_IMETHOD DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame); @@ -806,8 +806,10 @@ FrameManager::AppendFrames(nsIPresContext* aPresContext, { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); nsIFrame* insertionPoint = nsnull; - GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint); - if (insertionPoint) { + nsCOMPtr child; + aFrameList->GetContent(getter_AddRefs(child)); + GetInsertionPoint(&aPresShell, aParentFrame, child, &insertionPoint); + if (insertionPoint && (insertionPoint != aParentFrame)) { // First append the frames. nsresult rv = insertionPoint->AppendFrames(aPresContext, aPresShell, aListName, aFrameList); @@ -837,8 +839,10 @@ FrameManager::InsertFrames(nsIPresContext* aPresContext, { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); nsIFrame* insertionPoint = nsnull; - GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint); - if (insertionPoint) { + nsCOMPtr child; + aFrameList->GetContent(getter_AddRefs(child)); + GetInsertionPoint(&aPresShell, aParentFrame, child, &insertionPoint); + if (insertionPoint && (insertionPoint != aParentFrame)) { // First insert the frames. nsresult rv = insertionPoint->InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList); @@ -881,8 +885,10 @@ FrameManager::RemoveFrame(nsIPresContext* aPresContext, { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); nsIFrame* insertionPoint = nsnull; - GetInsertionPoint(&aPresShell, aParentFrame, aOldFrame, &insertionPoint); - if (insertionPoint) + nsCOMPtr child; + aOldFrame->GetContent(getter_AddRefs(child)); + GetInsertionPoint(&aPresShell, aParentFrame, child, &insertionPoint); + if (insertionPoint && (insertionPoint != aParentFrame)) return insertionPoint->RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame); #ifdef IBMBIDI @@ -2615,10 +2621,10 @@ FrameManager::RemoveFrameProperty(nsIFrame* aFrame, } NS_IMETHODIMP -FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult) +FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIContent* aChild, nsIFrame** aResult) { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); - *aResult = nsnull; + *aResult = aParent; nsCOMPtr content; aParent->GetContent(getter_AddRefs(content)); @@ -2637,30 +2643,26 @@ FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFram nsCOMPtr insertionElement; nsIFrame* frame = nsnull; if (aChild) { - nsCOMPtr currContent; - aChild->GetContent(getter_AddRefs(currContent)); - // Check to see if the content is anonymous. nsCOMPtr bindingParent; - currContent->GetBindingParent(getter_AddRefs(bindingParent)); + aChild->GetBindingParent(getter_AddRefs(bindingParent)); if (bindingParent == content) return NS_OK; // It is anonymous. Don't use the insertion point, since that's only // for the explicit kids. PRUint32 index; - bindingManager->GetInsertionPoint(content, currContent, getter_AddRefs(insertionElement), &index); + bindingManager->GetInsertionPoint(content, aChild, getter_AddRefs(insertionElement), &index); if (insertionElement) { aShell->GetPrimaryFrameFor(insertionElement, &frame); if (frame) { nsCOMPtr scroll(do_QueryInterface(frame)); if (scroll) scroll->GetScrolledFrame(nsnull, frame); - if (frame != aParent) { - nsIFrame* nestedPoint = nsnull; - GetInsertionPoint(aShell, frame, aChild, &nestedPoint); - *aResult = nestedPoint ? nestedPoint : frame; - } + if (frame != aParent) + GetInsertionPoint(aShell, frame, aChild, aResult); } + else + *aResult = nsnull; // There was no frame created yet for the insertion point. return NS_OK; } } @@ -2674,12 +2676,11 @@ FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFram nsCOMPtr scroll(do_QueryInterface(frame)); if (scroll) scroll->GetScrolledFrame(nsnull, frame); - if (frame != aParent) { - nsIFrame* nestedPoint = nsnull; - GetInsertionPoint(aShell, frame, aChild, &nestedPoint); - *aResult = nestedPoint ? nestedPoint : frame; - } + if (frame != aParent) + GetInsertionPoint(aShell, frame, aChild, aResult); } + else + *aResult = nsnull; // No frame yet. return NS_OK; } } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index c73d20fb4225..085c782822e9 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2384,23 +2384,15 @@ PresShell::EndObservingDocument() char* nsPresShell_ReflowStackPointerTop; #endif -static void CheckForFocus(nsIDocument* aDocument) +static void CheckForFocus(nsPIDOMWindow* aOurWindow, nsIFocusController* aFocusController, nsIDocument* aDocument) { // Now that we have a root frame, set focus in to the presshell, but // only do this if our window is currently focused // Restore focus if we're the active window or a parent of a previously // active window. - nsCOMPtr globalObject; - aDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); - nsCOMPtr ourWindow = do_QueryInterface(globalObject); - nsCOMPtr focusController; - ourWindow->GetRootFocusController(getter_AddRefs(focusController)); - - if (focusController) { - // Suppress the command dispatcher. - focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads"); + if (aFocusController) { nsCOMPtr focusedWindow; - focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); + aFocusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); // See if the command dispatcher is holding on to an orphan window. // This happens when you move from an inner frame to an outer frame @@ -2411,23 +2403,22 @@ static void CheckForFocus(nsIDocument* aDocument) if (!domDoc) { // We're pointing to garbage. Go ahead and let this // presshell take the focus. - focusedWindow = do_QueryInterface(ourWindow); - focusController->SetFocusedWindow(focusedWindow); + focusedWindow = do_QueryInterface(aOurWindow); + aFocusController->SetFocusedWindow(focusedWindow); } } - nsCOMPtr domWindow = do_QueryInterface(ourWindow); + nsCOMPtr domWindow = do_QueryInterface(aOurWindow); if (domWindow == focusedWindow) { PRBool active; - focusController->GetActive(&active); - focusController->SetFocusedElement(nsnull); + aFocusController->GetActive(&active); + aFocusController->SetFocusedElement(nsnull); if(active) { // We need to restore focus and make sure we null // out the focused element. domWindow->Focus(); } } - focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads"); } } @@ -4461,6 +4452,16 @@ PresShell::IsPaintingSuppressed(PRBool* aResult) void PresShell::UnsuppressAndInvalidate() { + nsCOMPtr globalObject; + mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); + nsCOMPtr ourWindow = do_QueryInterface(globalObject); + nsCOMPtr focusController; + ourWindow->GetRootFocusController(getter_AddRefs(focusController)); + if (focusController) + // Suppress focus. The act of tearing down the old content viewer + // causes us to blur incorrectly. + focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads"); + nsCOMPtr container; nsCOMPtr cv; nsCOMPtr dv; @@ -4488,7 +4489,10 @@ PresShell::UnsuppressAndInvalidate() ((nsFrame*)rootFrame)->Invalidate(mPresContext, rect, PR_FALSE); } - CheckForFocus(mDocument); + CheckForFocus(ourWindow, focusController, mDocument); + + if (focusController) // Unsuppress now that we've shown the new window and focused it. + focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads"); } NS_IMETHODIMP diff --git a/layout/base/public/nsIFrameManager.h b/layout/base/public/nsIFrameManager.h index 38f43701d663..99ec03365dcc 100644 --- a/layout/base/public/nsIFrameManager.h +++ b/layout/base/public/nsIFrameManager.h @@ -245,7 +245,7 @@ public: NS_IMETHOD RemoveFrameProperty(nsIFrame* aFrame, nsIAtom* aPropertyName) = 0; - NS_IMETHOD GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult)=0; + NS_IMETHOD GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIContent* aChild, nsIFrame** aResult)=0; #ifdef NS_DEBUG /** diff --git a/layout/html/base/src/nsFrameManager.cpp b/layout/html/base/src/nsFrameManager.cpp index 4827c6521711..bf82b036e9ec 100644 --- a/layout/html/base/src/nsFrameManager.cpp +++ b/layout/html/base/src/nsFrameManager.cpp @@ -317,7 +317,7 @@ public: NS_IMETHOD RemoveFrameProperty(nsIFrame* aFrame, nsIAtom* aPropertyName); - NS_IMETHOD GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult); + NS_IMETHOD GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIContent* aChild, nsIFrame** aResult); #ifdef NS_DEBUG NS_IMETHOD DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame); @@ -806,8 +806,10 @@ FrameManager::AppendFrames(nsIPresContext* aPresContext, { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); nsIFrame* insertionPoint = nsnull; - GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint); - if (insertionPoint) { + nsCOMPtr child; + aFrameList->GetContent(getter_AddRefs(child)); + GetInsertionPoint(&aPresShell, aParentFrame, child, &insertionPoint); + if (insertionPoint && (insertionPoint != aParentFrame)) { // First append the frames. nsresult rv = insertionPoint->AppendFrames(aPresContext, aPresShell, aListName, aFrameList); @@ -837,8 +839,10 @@ FrameManager::InsertFrames(nsIPresContext* aPresContext, { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); nsIFrame* insertionPoint = nsnull; - GetInsertionPoint(&aPresShell, aParentFrame, aFrameList, &insertionPoint); - if (insertionPoint) { + nsCOMPtr child; + aFrameList->GetContent(getter_AddRefs(child)); + GetInsertionPoint(&aPresShell, aParentFrame, child, &insertionPoint); + if (insertionPoint && (insertionPoint != aParentFrame)) { // First insert the frames. nsresult rv = insertionPoint->InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList); @@ -881,8 +885,10 @@ FrameManager::RemoveFrame(nsIPresContext* aPresContext, { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); nsIFrame* insertionPoint = nsnull; - GetInsertionPoint(&aPresShell, aParentFrame, aOldFrame, &insertionPoint); - if (insertionPoint) + nsCOMPtr child; + aOldFrame->GetContent(getter_AddRefs(child)); + GetInsertionPoint(&aPresShell, aParentFrame, child, &insertionPoint); + if (insertionPoint && (insertionPoint != aParentFrame)) return insertionPoint->RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame); #ifdef IBMBIDI @@ -2615,10 +2621,10 @@ FrameManager::RemoveFrameProperty(nsIFrame* aFrame, } NS_IMETHODIMP -FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFrame* aChild, nsIFrame** aResult) +FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIContent* aChild, nsIFrame** aResult) { NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); - *aResult = nsnull; + *aResult = aParent; nsCOMPtr content; aParent->GetContent(getter_AddRefs(content)); @@ -2637,30 +2643,26 @@ FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFram nsCOMPtr insertionElement; nsIFrame* frame = nsnull; if (aChild) { - nsCOMPtr currContent; - aChild->GetContent(getter_AddRefs(currContent)); - // Check to see if the content is anonymous. nsCOMPtr bindingParent; - currContent->GetBindingParent(getter_AddRefs(bindingParent)); + aChild->GetBindingParent(getter_AddRefs(bindingParent)); if (bindingParent == content) return NS_OK; // It is anonymous. Don't use the insertion point, since that's only // for the explicit kids. PRUint32 index; - bindingManager->GetInsertionPoint(content, currContent, getter_AddRefs(insertionElement), &index); + bindingManager->GetInsertionPoint(content, aChild, getter_AddRefs(insertionElement), &index); if (insertionElement) { aShell->GetPrimaryFrameFor(insertionElement, &frame); if (frame) { nsCOMPtr scroll(do_QueryInterface(frame)); if (scroll) scroll->GetScrolledFrame(nsnull, frame); - if (frame != aParent) { - nsIFrame* nestedPoint = nsnull; - GetInsertionPoint(aShell, frame, aChild, &nestedPoint); - *aResult = nestedPoint ? nestedPoint : frame; - } + if (frame != aParent) + GetInsertionPoint(aShell, frame, aChild, aResult); } + else + *aResult = nsnull; // There was no frame created yet for the insertion point. return NS_OK; } } @@ -2674,12 +2676,11 @@ FrameManager::GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aParent, nsIFram nsCOMPtr scroll(do_QueryInterface(frame)); if (scroll) scroll->GetScrolledFrame(nsnull, frame); - if (frame != aParent) { - nsIFrame* nestedPoint = nsnull; - GetInsertionPoint(aShell, frame, aChild, &nestedPoint); - *aResult = nestedPoint ? nestedPoint : frame; - } + if (frame != aParent) + GetInsertionPoint(aShell, frame, aChild, aResult); } + else + *aResult = nsnull; // No frame yet. return NS_OK; } } diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index c73d20fb4225..085c782822e9 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -2384,23 +2384,15 @@ PresShell::EndObservingDocument() char* nsPresShell_ReflowStackPointerTop; #endif -static void CheckForFocus(nsIDocument* aDocument) +static void CheckForFocus(nsPIDOMWindow* aOurWindow, nsIFocusController* aFocusController, nsIDocument* aDocument) { // Now that we have a root frame, set focus in to the presshell, but // only do this if our window is currently focused // Restore focus if we're the active window or a parent of a previously // active window. - nsCOMPtr globalObject; - aDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); - nsCOMPtr ourWindow = do_QueryInterface(globalObject); - nsCOMPtr focusController; - ourWindow->GetRootFocusController(getter_AddRefs(focusController)); - - if (focusController) { - // Suppress the command dispatcher. - focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads"); + if (aFocusController) { nsCOMPtr focusedWindow; - focusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); + aFocusController->GetFocusedWindow(getter_AddRefs(focusedWindow)); // See if the command dispatcher is holding on to an orphan window. // This happens when you move from an inner frame to an outer frame @@ -2411,23 +2403,22 @@ static void CheckForFocus(nsIDocument* aDocument) if (!domDoc) { // We're pointing to garbage. Go ahead and let this // presshell take the focus. - focusedWindow = do_QueryInterface(ourWindow); - focusController->SetFocusedWindow(focusedWindow); + focusedWindow = do_QueryInterface(aOurWindow); + aFocusController->SetFocusedWindow(focusedWindow); } } - nsCOMPtr domWindow = do_QueryInterface(ourWindow); + nsCOMPtr domWindow = do_QueryInterface(aOurWindow); if (domWindow == focusedWindow) { PRBool active; - focusController->GetActive(&active); - focusController->SetFocusedElement(nsnull); + aFocusController->GetActive(&active); + aFocusController->SetFocusedElement(nsnull); if(active) { // We need to restore focus and make sure we null // out the focused element. domWindow->Focus(); } } - focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads"); } } @@ -4461,6 +4452,16 @@ PresShell::IsPaintingSuppressed(PRBool* aResult) void PresShell::UnsuppressAndInvalidate() { + nsCOMPtr globalObject; + mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); + nsCOMPtr ourWindow = do_QueryInterface(globalObject); + nsCOMPtr focusController; + ourWindow->GetRootFocusController(getter_AddRefs(focusController)); + if (focusController) + // Suppress focus. The act of tearing down the old content viewer + // causes us to blur incorrectly. + focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads"); + nsCOMPtr container; nsCOMPtr cv; nsCOMPtr dv; @@ -4488,7 +4489,10 @@ PresShell::UnsuppressAndInvalidate() ((nsFrame*)rootFrame)->Invalidate(mPresContext, rect, PR_FALSE); } - CheckForFocus(mDocument); + CheckForFocus(ourWindow, focusController, mDocument); + + if (focusController) // Unsuppress now that we've shown the new window and focused it. + focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads"); } NS_IMETHODIMP diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index de13170e973c..62fac6bce087 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -7978,6 +7978,16 @@ nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext, // Get the frame associated with the content nsIFrame* parentFrame = GetFrameFor(shell, aPresContext, aContainer); if (nsnull != parentFrame) { + // See if we have an XBL insertion point. If so, then see if the + // frame for it has been built yet. If it hasn't been built yet, + // then we just bail. + nsCOMPtr frameManager; + shell->GetFrameManager(getter_AddRefs(frameManager)); + nsIFrame* insertionPoint = nsnull; + frameManager->GetInsertionPoint(shell, parentFrame, nsnull, &insertionPoint); + if (!insertionPoint) + return NS_OK; // Don't build the frames. + // If the frame we are manipulating is a ``special'' frame (that // is, one that's been created as a result of a block-in-inline // situation) then do something different instead of just @@ -8003,9 +8013,7 @@ nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext, // Since we're appending, we'll walk to the last anonymous frame // that was created for the broken inline frame. - nsCOMPtr frameManager; - shell->GetFrameManager(getter_AddRefs(frameManager)); - + while (1) { nsIFrame* sibling; GetSpecialSibling(frameManager, parentFrame, &sibling); diff --git a/layout/xul/base/src/nsMenuBarFrame.cpp b/layout/xul/base/src/nsMenuBarFrame.cpp index 9dca4b09124b..8351c360d7e9 100644 --- a/layout/xul/base/src/nsMenuBarFrame.cpp +++ b/layout/xul/base/src/nsMenuBarFrame.cpp @@ -218,7 +218,9 @@ static void GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aFrame, nsIFrame* { nsCOMPtr frameManager; aShell->GetFrameManager(getter_AddRefs(frameManager)); - frameManager->GetInsertionPoint(aShell, aFrame, aChild, aResult); + nsCOMPtr child; + aChild->GetContent(getter_AddRefs(child)); + frameManager->GetInsertionPoint(aShell, aFrame, child, aResult); } nsIMenuFrame*