From 1349b5dad47083b5978b3cccc3cd41ea23cbafda Mon Sep 17 00:00:00 2001 From: "vidur%netscape.com" Date: Wed, 3 Feb 1999 19:38:16 +0000 Subject: [PATCH] Added additional key argument to string parsing routine. Improved Reset handling for document to include style sets and frame construction. Modified root frame construction. Got out-of-line document.write to work git-svn-id: svn://10.0.0.236/trunk@19537 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/base/public/nsIDocumentObserver.h | 12 + mozilla/content/base/src/nsContentList.h | 2 + mozilla/content/base/src/nsDocument.cpp | 36 ++- .../html/content/src/nsHTMLBodyElement.cpp | 14 +- .../html/document/src/nsHTMLDocument.cpp | 57 +++-- .../html/document/src/nsHTMLDocument.h | 3 + .../html/style/src/nsHTMLCSSStyleSheet.cpp | 10 + .../html/style/src/nsHTMLStyleSheet.cpp | 237 +++++++++++------- .../html/style/src/nsIHTMLCSSStyleSheet.h | 1 + mozilla/layout/base/nsPresShell.cpp | 34 ++- .../layout/base/public/nsIDocumentObserver.h | 12 + mozilla/layout/base/src/nsContentList.h | 2 + mozilla/layout/base/src/nsDocument.cpp | 36 ++- mozilla/layout/base/src/nsFrameUtil.cpp | 2 +- mozilla/layout/generic/nsFrameUtil.cpp | 2 +- mozilla/layout/generic/nsImageMap.cpp | 7 + mozilla/layout/generic/nsImageMap.h | 2 + mozilla/layout/html/base/src/nsImageMap.cpp | 7 + mozilla/layout/html/base/src/nsImageMap.h | 2 + mozilla/layout/html/base/src/nsPresShell.cpp | 34 ++- .../html/content/src/nsHTMLBodyElement.cpp | 14 +- .../html/document/src/nsHTMLDocument.cpp | 57 +++-- .../layout/html/document/src/nsHTMLDocument.h | 3 + .../html/style/src/nsHTMLCSSStyleSheet.cpp | 10 + .../html/style/src/nsHTMLStyleSheet.cpp | 237 +++++++++++------- .../html/style/src/nsIHTMLCSSStyleSheet.h | 1 + .../layout/html/style/src/nsIHTMLStyleSheet.h | 1 + mozilla/layout/style/nsHTMLCSSStyleSheet.cpp | 10 + mozilla/layout/style/nsHTMLStyleSheet.cpp | 237 +++++++++++------- mozilla/layout/style/nsIHTMLCSSStyleSheet.h | 1 + 30 files changed, 745 insertions(+), 338 deletions(-) diff --git a/mozilla/content/base/public/nsIDocumentObserver.h b/mozilla/content/base/public/nsIDocumentObserver.h index ac3d75d14e1..a27b9ac4d69 100644 --- a/mozilla/content/base/public/nsIDocumentObserver.h +++ b/mozilla/content/base/public/nsIDocumentObserver.h @@ -190,6 +190,18 @@ public: NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet) = 0; + /** + * A StyleSheet has just been removed from the document. + * This method is called automatically when a StyleSheet gets removed + * from the document. The notification is passed on to all of the + * document observers. + * + * @param aDocument The document being observed + * @param aStyleSheet the StyleSheet that has been removed + */ + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) = 0; + /** * A StyleSheet has just disabled or enabled. * This method is called automatically when the disabled state diff --git a/mozilla/content/base/src/nsContentList.h b/mozilla/content/base/src/nsContentList.h index b765f8882a3..36eff279842 100644 --- a/mozilla/content/base/src/nsContentList.h +++ b/mozilla/content/base/src/nsContentList.h @@ -93,6 +93,8 @@ public: PRInt32 aIndexInContainer); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet) { return NS_OK; } + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) { return NS_OK; } NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 5fae01eb66b..703628c6791 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -141,6 +141,8 @@ public: PRInt32 aIndexInContainer) { return NS_OK; } NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet); + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } @@ -327,6 +329,21 @@ nsDOMStyleSheetCollection::StyleSheetAdded(nsIDocument *aDocument, return NS_OK; } +NS_IMETHODIMP +nsDOMStyleSheetCollection::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + if (-1 != mLength) { + nsIDOMStyleSheet *domss; + if (NS_OK == aStyleSheet->QueryInterface(kIDOMStyleSheetIID, (void **)&domss)) { + mLength--; + NS_RELEASE(domss); + } + } + + return NS_OK; +} + NS_IMETHODIMP nsDOMStyleSheetCollection::DocumentWillBeDestroyed(nsIDocument *aDocument) { @@ -699,13 +716,30 @@ nsDocument::Reset(nsIURL *aURL) NS_RELEASE(subdoc); } - NS_IF_RELEASE(mRootContent); + if (nsnull != mRootContent) { + ContentRemoved(nsnull, mRootContent, 0); + NS_IF_RELEASE(mRootContent); + } // Delete references to style sheets index = mStyleSheets.Count(); while (--index >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); sheet->SetOwningDocument(nsnull); + + PRInt32 pscount = mPresShells.Count(); + PRInt32 psindex; + for (psindex = 0; psindex < pscount; psindex++) { + nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(psindex); + nsIStyleSet* set = shell->GetStyleSet(); + if (nsnull != set) { + set->RemoveDocStyleSheet(sheet); + NS_RELEASE(set); + } + } + + // XXX Tell observers? + NS_RELEASE(sheet); } mStyleSheets.Clear(); diff --git a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp index 0c26ef1d049..260adf980b8 100644 --- a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp @@ -819,6 +819,18 @@ nsHTMLBodyElement::GetStyleHintForAttributeChange( const nsIAtom* aAttribute, PRInt32 *aHint) const { - nsGenericHTMLElement::SetStyleHintForCommonAttributes(this, aAttribute, aHint); + if ((aAttribute == nsHTMLAtoms::link) || + (aAttribute == nsHTMLAtoms::vlink) || + (aAttribute == nsHTMLAtoms::alink) || + (aAttribute == nsHTMLAtoms::bgcolor) || + (aAttribute == nsHTMLAtoms::background) || + (aAttribute == nsHTMLAtoms::text)) + { + *aHint = NS_STYLE_HINT_VISUAL; + } + else { + nsGenericHTMLElement::SetStyleHintForCommonAttributes(this, aAttribute, aHint); + } + return NS_OK; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index 0fa2e55fb39..657d7175ef7 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -181,7 +181,8 @@ nsHTMLDocument::nsHTMLDocument() mChildStack = (nsIDOMNode**) new PRUint32[32]; mBodyContent = nsnull; mForms = nsnull; - + mIsWriting = 0; + mWriteLevel = 0; } nsHTMLDocument::~nsHTMLDocument() @@ -288,20 +289,21 @@ nsHTMLDocument::Reset(nsIURL *aURL) } NS_IF_RELEASE(mForms); - if (nsnull != mAttrStyleSheet) { - mAttrStyleSheet->SetOwningDocument(nsnull); - NS_RELEASE(mAttrStyleSheet); + if (nsnull == mAttrStyleSheet) { + result = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this); } - if (nsnull != mStyleAttrStyleSheet) { - mStyleAttrStyleSheet->SetOwningDocument(nsnull); - NS_RELEASE(mStyleAttrStyleSheet); + else { + result = mAttrStyleSheet->Reset(aURL); } - - result = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this); if (NS_OK == result) { AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet - - result = NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL, this); + + if (nsnull == mStyleAttrStyleSheet) { + result = NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL, this); + } + else { + result = mStyleAttrStyleSheet->Reset(aURL); + } if (NS_OK == result) { AddStyleSheet(mStyleAttrStyleSheet); // tell the world about our new style sheet } @@ -707,7 +709,7 @@ nsHTMLDocument::ContentRemoved(nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { - if (nsnull != mNamedItems) { + if ((nsnull != mNamedItems) && (nsnull != aContainer)) { nsIAtom *name; aContainer->GetTag(name); @@ -1178,7 +1180,6 @@ NS_IMETHODIMP nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc) { nsresult result = NS_OK; -#if 0 // The open occurred after the document finished loading. // So we reset the document and create a new one. if (nsnull == mParser) { @@ -1197,11 +1198,13 @@ nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc) nsnull, kCParserIID, (void **)&mParser); - + mIsWriting = 1; + if (NS_OK == result) { nsIHTMLContentSink* sink; nsIWebShell* webShell = nsnull; + // Get the webshell of our primary presentation shell nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); if (nsnull != shell) { nsIPresContext* cx = shell->GetPresContext(); @@ -1228,14 +1231,26 @@ nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc) NS_RELEASE(blankURL); } } -#endif return result; } +#define NS_GENERATE_PARSER_KEY() (void*)((mIsWriting << 31) | (mWriteLevel & 0x7fffffff)) + NS_IMETHODIMP nsHTMLDocument::Close() { - return NS_ERROR_NOT_IMPLEMENTED; + nsresult result = NS_OK; + + if ((nsnull != mParser) && mIsWriting) { + nsAutoString emptyStr(""); + mWriteLevel++; + result = mParser->Parse(emptyStr, NS_GENERATE_PARSER_KEY(), + PR_TRUE, PR_FALSE, PR_TRUE); + mWriteLevel--; + mIsWriting = 0; + } + + return NS_OK; } nsresult @@ -1249,7 +1264,9 @@ nsHTMLDocument::WriteCommon(JSContext *cx, // XXX Right now, we only deal with inline document.writes if (nsnull == mParser) { result = Open(cx, argv, argc); - return NS_ERROR_NOT_IMPLEMENTED; + if (NS_OK != result) { + return result; + } } if (argc > 0) { @@ -1268,7 +1285,11 @@ nsHTMLDocument::WriteCommon(JSContext *cx, str.Append('\n'); } - result = mParser->Parse(str, PR_TRUE,PR_FALSE,PR_TRUE); + mWriteLevel++; + result = mParser->Parse(str, NS_GENERATE_PARSER_KEY(), + PR_TRUE, PR_FALSE, + (!mIsWriting || (mWriteLevel > 1))); + mWriteLevel--; if (NS_OK != result) { return result; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 6fd2d6765bb..624913b04ac 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -189,6 +189,9 @@ protected: PLHashTable *mNamedItems; nsIParser *mParser; + + PRUint32 mIsWriting : 1; + PRUint32 mWriteLevel : 31; }; #endif /* nsHTMLDocument_h___ */ diff --git a/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp index 489cafacb9a..d77c9baceb0 100644 --- a/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -51,6 +51,7 @@ public: // basic style sheet data NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument); + NS_IMETHOD Reset(nsIURL* aURL); NS_IMETHOD GetURL(nsIURL*& aURL) const; NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD GetType(nsString& aType) const; @@ -239,6 +240,15 @@ HTMLCSSStyleSheetImpl::Init(nsIURL* aURL, nsIDocument* aDocument) return NS_OK; } +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::Reset(nsIURL* aURL) +{ + NS_IF_RELEASE(mURL); + mURL = aURL; + NS_ADDREF(mURL); + return NS_OK; +} + NS_IMETHODIMP HTMLCSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index 710074692f8..7a32dcd2642 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -318,6 +318,7 @@ public: nsISupportsArray* aResults); NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument); + NS_IMETHOD Reset(nsIURL* aURL); NS_IMETHOD SetLinkColor(nscolor aColor); NS_IMETHOD SetActiveLinkColor(nscolor aColor); NS_IMETHOD SetVisitedLinkColor(nscolor aColor); @@ -654,6 +655,7 @@ protected: nsIHTMLAttributes* mRecycledAttrs; nsIFrame* mInitialContainingBlock; nsIFrame* mFixedContainingBlock; + nsIFrame* mDocElementContainingBlock; }; @@ -701,7 +703,8 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(void) mVisitedRule(nsnull), mActiveRule(nsnull), mRecycledAttrs(nsnull), - mInitialContainingBlock(nsnull) + mInitialContainingBlock(nsnull), + mDocElementContainingBlock(nsnull) { NS_INIT_REFCNT(); #ifdef INCLUDE_XUL @@ -945,6 +948,29 @@ NS_IMETHODIMP HTMLStyleSheetImpl::Init(nsIURL* aURL, nsIDocument* aDocument) return NS_OK; } +NS_IMETHODIMP HTMLStyleSheetImpl::Reset(nsIURL* aURL) +{ + NS_IF_RELEASE(mURL); + mURL = aURL; + NS_ADDREF(mURL); + + if (nsnull != mLinkRule) { + mLinkRule->mSheet = nsnull; + NS_RELEASE(mLinkRule); + } + if (nsnull != mVisitedRule) { + mVisitedRule->mSheet = nsnull; + NS_RELEASE(mVisitedRule); + } + if (nsnull != mActiveRule) { + mActiveRule->mSheet = nsnull; + NS_RELEASE(mActiveRule); + } + mAttrTable.Reset(); + + return NS_OK; +} + NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) { if (nsnull == mLinkRule) { @@ -2299,16 +2325,13 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, pageFrame->Init(*aPresContext, nsnull, pageSequenceFrame, rootPseudoStyle); nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageFrame, rootPseudoStyle, PR_TRUE); - - // Create frames for the document element and its child elements - nsIFrame* docElementFrame; - nsAbsoluteItems fixedItems(pageFrame); - ConstructDocElementFrame(aPresContext, aDocElement, pageFrame, - rootPseudoStyle, docElementFrame, fixedItems); NS_RELEASE(rootPseudoStyle); + // The eventual parent of the document element frame + mDocElementContainingBlock = pageFrame; + + // Set the initial child lists - pageFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame); pageSequenceFrame->SetInitialChildList(*aPresContext, nsnull, pageFrame); if (isScrollable) { scrollFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame); @@ -2317,12 +2340,6 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, viewportFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame); } - // Tell the page about its 'fixed' frames - if (nsnull != fixedItems.childList) { - pageFrame->SetInitialChildList(*aPresContext, nsLayoutAtoms::fixedList, - fixedItems.childList); - } - } else { // The viewport is the containing block for 'fixed' elements mFixedContainingBlock = viewportFrame; @@ -2343,28 +2360,18 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, rootFrame, rootPseudoStyle, PR_TRUE); } - - // Create frames for the document element and its child elements - nsIFrame* docElementFrame; - nsAbsoluteItems fixedItems(viewportFrame); - ConstructDocElementFrame(aPresContext, aDocElement, rootFrame, - rootPseudoStyle, docElementFrame, fixedItems); NS_RELEASE(rootPseudoStyle); + // The eventual parent of the document element frame + mDocElementContainingBlock = rootFrame; + // Set the initial child lists - rootFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame); if (isScrollable) { scrollFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame); viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame); } else { viewportFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame); } - - // Tell the viewport about its 'fixed' frames - if (nsnull != fixedItems.childList) { - viewportFrame->SetInitialChildList(*aPresContext, nsLayoutAtoms::fixedList, - fixedItems.childList); - } } aNewFrame = viewportFrame; @@ -3935,80 +3942,122 @@ HTMLStyleSheetImpl::ContentInserted(nsIPresContext* aPresContext, PRInt32 aIndexInContainer) { nsIPresShell* shell = aPresContext->GetShell(); + nsresult rv = NS_OK; - // Find the frame that precedes the insertion point. - nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer); - nsIFrame* nextSibling = nsnull; - PRBool isAppend = PR_FALSE; + // If we have a null parent, then this must be the document element + // being inserted + if (nsnull == aContainer) { - // If there is no previous sibling, then find the frame that follows - if (nsnull == prevSibling) { - nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer); - } + NS_PRECONDITION(nsnull == mInitialContainingBlock, "initial containing block already created"); + nsIStyleContext* rootPseudoStyle; + nsIContent* docElement = nsnull; - // Get the geometric parent. - nsIFrame* parentFrame; - if ((nsnull == prevSibling) && (nsnull == nextSibling)) { - // No previous or next sibling so treat this like an appended frame. - // XXX This won't always be true if there's auto-generated before/after - // content - isAppend = PR_TRUE; - shell->GetPrimaryFrameFor(aContainer, parentFrame); + docElement = mDocument->GetRootContent(); - } else { - // Use the prev sibling if we have it; otherwise use the next sibling - if (nsnull != prevSibling) { - prevSibling->GetParent(parentFrame); - } else { - nextSibling->GetParent(parentFrame); - } - } - - // Construct a new frame - nsresult rv = NS_OK; - if (nsnull != parentFrame) { - // Get the containing block for absolutely positioned elements - nsIFrame* absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, - parentFrame); - - nsAbsoluteItems absoluteItems(absoluteContainingBlock); - nsFrameItems frameItems; + // Create a pseudo element style context + // XXX Use a different pseudo style context... + rootPseudoStyle = aPresContext->ResolvePseudoStyleContextFor(nsnull, + nsHTMLAtoms::rootPseudo, nsnull); + + // Create frames for the document element and its child elements + nsIFrame* docElementFrame; nsAbsoluteItems fixedItems(mFixedContainingBlock); - rv = ConstructFrame(aPresContext, aChild, parentFrame, absoluteItems, frameItems, - fixedItems); + ConstructDocElementFrame(aPresContext, + docElement, + mDocElementContainingBlock, + rootPseudoStyle, + docElementFrame, + fixedItems); + NS_RELEASE(rootPseudoStyle); + NS_IF_RELEASE(docElement); + + // Set the initial child list for the parent + mDocElementContainingBlock->SetInitialChildList(*aPresContext, + nsnull, + docElementFrame); + + // Tell the fixed containing block about its 'fixed' frames + if (nsnull != fixedItems.childList) { + mFixedContainingBlock->SetInitialChildList(*aPresContext, + nsLayoutAtoms::fixedList, + fixedItems.childList); + } + + } + else { + // Find the frame that precedes the insertion point. + nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer); + nsIFrame* nextSibling = nsnull; + PRBool isAppend = PR_FALSE; + + // If there is no previous sibling, then find the frame that follows + if (nsnull == prevSibling) { + nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer); + } - nsIFrame* newFrame = frameItems.childList; - - if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { - nsIReflowCommand* reflowCmd = nsnull; - - // Notify the parent frame - if (isAppend) { - rv = parentFrame->AppendFrames(*aPresContext, *shell, - nsnull, newFrame); + // Get the geometric parent. + nsIFrame* parentFrame; + if ((nsnull == prevSibling) && (nsnull == nextSibling)) { + // No previous or next sibling so treat this like an appended frame. + // XXX This won't always be true if there's auto-generated before/after + // content + isAppend = PR_TRUE; + shell->GetPrimaryFrameFor(aContainer, parentFrame); + + } else { + // Use the prev sibling if we have it; otherwise use the next sibling + if (nsnull != prevSibling) { + prevSibling->GetParent(parentFrame); } else { - rv = parentFrame->InsertFrames(*aPresContext, *shell, nsnull, - prevSibling, newFrame); + nextSibling->GetParent(parentFrame); } + } - // If there are new absolutely positioned child frames, then notify - // the parent - // XXX We can't just assume these frames are being appended, we need to - // determine where in the list they should be inserted... - if (nsnull != absoluteItems.childList) { - rv = absoluteItems.containingBlock->AppendFrames(*aPresContext, *shell, - nsLayoutAtoms::absoluteList, - absoluteItems.childList); - } - - // If there are new fixed positioned child frames, then notify - // the parent - // XXX We can't just assume these frames are being appended, we need to - // determine where in the list they should be inserted... - if (nsnull != fixedItems.childList) { - rv = fixedItems.containingBlock->AppendFrames(*aPresContext, *shell, - nsLayoutAtoms::fixedList, - fixedItems.childList); + // Construct a new frame + if (nsnull != parentFrame) { + // Get the containing block for absolutely positioned elements + nsIFrame* absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, + parentFrame); + + nsAbsoluteItems absoluteItems(absoluteContainingBlock); + nsFrameItems frameItems; + nsAbsoluteItems fixedItems(mFixedContainingBlock); + rv = ConstructFrame(aPresContext, aChild, parentFrame, absoluteItems, frameItems, + fixedItems); + + nsIFrame* newFrame = frameItems.childList; + + if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { + nsIReflowCommand* reflowCmd = nsnull; + + // Notify the parent frame + if (isAppend) { + rv = parentFrame->AppendFrames(*aPresContext, *shell, + nsnull, newFrame); + } else { + rv = parentFrame->InsertFrames(*aPresContext, *shell, nsnull, + prevSibling, newFrame); + } + + // If there are new absolutely positioned child frames, then notify + // the parent + // XXX We can't just assume these frames are being appended, we need to + // determine where in the list they should be inserted... + if (nsnull != absoluteItems.childList) { + rv = absoluteItems.containingBlock->AppendFrames(*aPresContext, *shell, + nsLayoutAtoms::absoluteList, + absoluteItems.childList); + } + + // If there are new fixed positioned child frames, then notify + // the parent + // XXX We can't just assume these frames are being appended, we need to + // determine where in the list they should be inserted... + if (nsnull != fixedItems.childList) { + rv = fixedItems.containingBlock->AppendFrames(*aPresContext, *shell, + nsLayoutAtoms::fixedList, + fixedItems.childList); + } } } } @@ -4083,6 +4132,10 @@ HTMLStyleSheetImpl::ContentRemoved(nsIPresContext* aPresContext, rv = parentFrame->RemoveFrame(*aPresContext, *shell, nsnull, childFrame); } + + if (mInitialContainingBlock == childFrame) { + mInitialContainingBlock = nsnull; + } } NS_RELEASE(shell); diff --git a/mozilla/content/html/style/src/nsIHTMLCSSStyleSheet.h b/mozilla/content/html/style/src/nsIHTMLCSSStyleSheet.h index f09044a1946..3c553a8d922 100644 --- a/mozilla/content/html/style/src/nsIHTMLCSSStyleSheet.h +++ b/mozilla/content/html/style/src/nsIHTMLCSSStyleSheet.h @@ -28,6 +28,7 @@ class nsIHTMLCSSStyleSheet : public nsIStyleSheet { public: NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument) = 0; + NS_IMETHOD Reset(nsIURL* aURL) = 0; }; // XXX for convenience and backward compatibility diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 7cf5c4b404d..8c61731ba98 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -208,6 +208,8 @@ public: PRInt32 aIndexInContainer); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet); + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled); @@ -671,7 +673,7 @@ PresShell::EndObservingDocument() NS_IMETHODIMP PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) { - NS_PRECONDITION(nsnull == mRootFrame, "unexpected root frame"); + nsIContent* root = nsnull; EnterReflowLock(); @@ -680,16 +682,21 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) mPresContext->SetVisibleArea(r); } - if (nsnull == mRootFrame) { - if (nsnull != mDocument) { - nsIContent* root = mDocument->GetRootContent(); - if (nsnull != root) { - // Have style sheet processor construct a frame for the - // root content object - mStyleSet->ConstructRootFrame(mPresContext, root, mRootFrame); - NS_RELEASE(root); - } + if (nsnull != mDocument) { + root = mDocument->GetRootContent(); + } + + if (nsnull != root) { + if (nsnull == mRootFrame) { + // Have style sheet processor construct a frame for the + // precursors to the root content object's frame + mStyleSet->ConstructRootFrame(mPresContext, root, mRootFrame); } + + // Have the style sheet processor construct frame for the root + // content object down + mStyleSet->ContentInserted(mPresContext, nsnull, root, 0); + NS_RELEASE(root); } if (nsnull != mRootFrame) { @@ -1203,6 +1210,13 @@ PresShell::StyleSheetAdded(nsIDocument *aDocument, return ReconstructFrames(); } +NS_IMETHODIMP +PresShell::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + return ReconstructFrames(); +} + NS_IMETHODIMP PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, diff --git a/mozilla/layout/base/public/nsIDocumentObserver.h b/mozilla/layout/base/public/nsIDocumentObserver.h index ac3d75d14e1..a27b9ac4d69 100644 --- a/mozilla/layout/base/public/nsIDocumentObserver.h +++ b/mozilla/layout/base/public/nsIDocumentObserver.h @@ -190,6 +190,18 @@ public: NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet) = 0; + /** + * A StyleSheet has just been removed from the document. + * This method is called automatically when a StyleSheet gets removed + * from the document. The notification is passed on to all of the + * document observers. + * + * @param aDocument The document being observed + * @param aStyleSheet the StyleSheet that has been removed + */ + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) = 0; + /** * A StyleSheet has just disabled or enabled. * This method is called automatically when the disabled state diff --git a/mozilla/layout/base/src/nsContentList.h b/mozilla/layout/base/src/nsContentList.h index b765f8882a3..36eff279842 100644 --- a/mozilla/layout/base/src/nsContentList.h +++ b/mozilla/layout/base/src/nsContentList.h @@ -93,6 +93,8 @@ public: PRInt32 aIndexInContainer); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet) { return NS_OK; } + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) { return NS_OK; } NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index 5fae01eb66b..703628c6791 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -141,6 +141,8 @@ public: PRInt32 aIndexInContainer) { return NS_OK; } NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet); + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled) { return NS_OK; } @@ -327,6 +329,21 @@ nsDOMStyleSheetCollection::StyleSheetAdded(nsIDocument *aDocument, return NS_OK; } +NS_IMETHODIMP +nsDOMStyleSheetCollection::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + if (-1 != mLength) { + nsIDOMStyleSheet *domss; + if (NS_OK == aStyleSheet->QueryInterface(kIDOMStyleSheetIID, (void **)&domss)) { + mLength--; + NS_RELEASE(domss); + } + } + + return NS_OK; +} + NS_IMETHODIMP nsDOMStyleSheetCollection::DocumentWillBeDestroyed(nsIDocument *aDocument) { @@ -699,13 +716,30 @@ nsDocument::Reset(nsIURL *aURL) NS_RELEASE(subdoc); } - NS_IF_RELEASE(mRootContent); + if (nsnull != mRootContent) { + ContentRemoved(nsnull, mRootContent, 0); + NS_IF_RELEASE(mRootContent); + } // Delete references to style sheets index = mStyleSheets.Count(); while (--index >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); sheet->SetOwningDocument(nsnull); + + PRInt32 pscount = mPresShells.Count(); + PRInt32 psindex; + for (psindex = 0; psindex < pscount; psindex++) { + nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(psindex); + nsIStyleSet* set = shell->GetStyleSet(); + if (nsnull != set) { + set->RemoveDocStyleSheet(sheet); + NS_RELEASE(set); + } + } + + // XXX Tell observers? + NS_RELEASE(sheet); } mStyleSheets.Clear(); diff --git a/mozilla/layout/base/src/nsFrameUtil.cpp b/mozilla/layout/base/src/nsFrameUtil.cpp index ebd2ee14a0e..dc816f16efc 100644 --- a/mozilla/layout/base/src/nsFrameUtil.cpp +++ b/mozilla/layout/base/src/nsFrameUtil.cpp @@ -496,7 +496,7 @@ nsFrameUtil::LoadFrameRegressionData(nsIURL* aURL, nsIXMLContent** aResult) NS_NewWellFormed_DTD(&theDTD); parser->RegisterDTD(theDTD); parser->SetContentSink(sink); - parser->Parse(theWholeDarnThing, PR_FALSE, PR_FALSE, PR_TRUE); + parser->Parse(theWholeDarnThing, this, PR_FALSE, PR_FALSE, PR_TRUE); NS_RELEASE(parser); *aResult = sink->GetRoot(); diff --git a/mozilla/layout/generic/nsFrameUtil.cpp b/mozilla/layout/generic/nsFrameUtil.cpp index ebd2ee14a0e..dc816f16efc 100644 --- a/mozilla/layout/generic/nsFrameUtil.cpp +++ b/mozilla/layout/generic/nsFrameUtil.cpp @@ -496,7 +496,7 @@ nsFrameUtil::LoadFrameRegressionData(nsIURL* aURL, nsIXMLContent** aResult) NS_NewWellFormed_DTD(&theDTD); parser->RegisterDTD(theDTD); parser->SetContentSink(sink); - parser->Parse(theWholeDarnThing, PR_FALSE, PR_FALSE, PR_TRUE); + parser->Parse(theWholeDarnThing, this, PR_FALSE, PR_FALSE, PR_TRUE); NS_RELEASE(parser); *aResult = sink->GetRoot(); diff --git a/mozilla/layout/generic/nsImageMap.cpp b/mozilla/layout/generic/nsImageMap.cpp index 63b0207b770..6242cfcbc85 100644 --- a/mozilla/layout/generic/nsImageMap.cpp +++ b/mozilla/layout/generic/nsImageMap.cpp @@ -972,6 +972,13 @@ nsImageMap::StyleSheetAdded(nsIDocument *aDocument, return NS_OK; } +NS_IMETHODIMP +nsImageMap::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + return NS_OK; +} + NS_IMETHODIMP nsImageMap::StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, diff --git a/mozilla/layout/generic/nsImageMap.h b/mozilla/layout/generic/nsImageMap.h index 44945690ddc..28a04a50675 100644 --- a/mozilla/layout/generic/nsImageMap.h +++ b/mozilla/layout/generic/nsImageMap.h @@ -96,6 +96,8 @@ public: PRInt32 aIndexInContainer); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet); + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled); diff --git a/mozilla/layout/html/base/src/nsImageMap.cpp b/mozilla/layout/html/base/src/nsImageMap.cpp index 63b0207b770..6242cfcbc85 100644 --- a/mozilla/layout/html/base/src/nsImageMap.cpp +++ b/mozilla/layout/html/base/src/nsImageMap.cpp @@ -972,6 +972,13 @@ nsImageMap::StyleSheetAdded(nsIDocument *aDocument, return NS_OK; } +NS_IMETHODIMP +nsImageMap::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + return NS_OK; +} + NS_IMETHODIMP nsImageMap::StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, diff --git a/mozilla/layout/html/base/src/nsImageMap.h b/mozilla/layout/html/base/src/nsImageMap.h index 44945690ddc..28a04a50675 100644 --- a/mozilla/layout/html/base/src/nsImageMap.h +++ b/mozilla/layout/html/base/src/nsImageMap.h @@ -96,6 +96,8 @@ public: PRInt32 aIndexInContainer); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet); + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled); diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 7cf5c4b404d..8c61731ba98 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -208,6 +208,8 @@ public: PRInt32 aIndexInContainer); NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet); + NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet); NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, PRBool aDisabled); @@ -671,7 +673,7 @@ PresShell::EndObservingDocument() NS_IMETHODIMP PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) { - NS_PRECONDITION(nsnull == mRootFrame, "unexpected root frame"); + nsIContent* root = nsnull; EnterReflowLock(); @@ -680,16 +682,21 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) mPresContext->SetVisibleArea(r); } - if (nsnull == mRootFrame) { - if (nsnull != mDocument) { - nsIContent* root = mDocument->GetRootContent(); - if (nsnull != root) { - // Have style sheet processor construct a frame for the - // root content object - mStyleSet->ConstructRootFrame(mPresContext, root, mRootFrame); - NS_RELEASE(root); - } + if (nsnull != mDocument) { + root = mDocument->GetRootContent(); + } + + if (nsnull != root) { + if (nsnull == mRootFrame) { + // Have style sheet processor construct a frame for the + // precursors to the root content object's frame + mStyleSet->ConstructRootFrame(mPresContext, root, mRootFrame); } + + // Have the style sheet processor construct frame for the root + // content object down + mStyleSet->ContentInserted(mPresContext, nsnull, root, 0); + NS_RELEASE(root); } if (nsnull != mRootFrame) { @@ -1203,6 +1210,13 @@ PresShell::StyleSheetAdded(nsIDocument *aDocument, return ReconstructFrames(); } +NS_IMETHODIMP +PresShell::StyleSheetRemoved(nsIDocument *aDocument, + nsIStyleSheet* aStyleSheet) +{ + return ReconstructFrames(); +} + NS_IMETHODIMP PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument, nsIStyleSheet* aStyleSheet, diff --git a/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp b/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp index 0c26ef1d049..260adf980b8 100644 --- a/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp @@ -819,6 +819,18 @@ nsHTMLBodyElement::GetStyleHintForAttributeChange( const nsIAtom* aAttribute, PRInt32 *aHint) const { - nsGenericHTMLElement::SetStyleHintForCommonAttributes(this, aAttribute, aHint); + if ((aAttribute == nsHTMLAtoms::link) || + (aAttribute == nsHTMLAtoms::vlink) || + (aAttribute == nsHTMLAtoms::alink) || + (aAttribute == nsHTMLAtoms::bgcolor) || + (aAttribute == nsHTMLAtoms::background) || + (aAttribute == nsHTMLAtoms::text)) + { + *aHint = NS_STYLE_HINT_VISUAL; + } + else { + nsGenericHTMLElement::SetStyleHintForCommonAttributes(this, aAttribute, aHint); + } + return NS_OK; } diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index 0fa2e55fb39..657d7175ef7 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -181,7 +181,8 @@ nsHTMLDocument::nsHTMLDocument() mChildStack = (nsIDOMNode**) new PRUint32[32]; mBodyContent = nsnull; mForms = nsnull; - + mIsWriting = 0; + mWriteLevel = 0; } nsHTMLDocument::~nsHTMLDocument() @@ -288,20 +289,21 @@ nsHTMLDocument::Reset(nsIURL *aURL) } NS_IF_RELEASE(mForms); - if (nsnull != mAttrStyleSheet) { - mAttrStyleSheet->SetOwningDocument(nsnull); - NS_RELEASE(mAttrStyleSheet); + if (nsnull == mAttrStyleSheet) { + result = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this); } - if (nsnull != mStyleAttrStyleSheet) { - mStyleAttrStyleSheet->SetOwningDocument(nsnull); - NS_RELEASE(mStyleAttrStyleSheet); + else { + result = mAttrStyleSheet->Reset(aURL); } - - result = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL, this); if (NS_OK == result) { AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet - - result = NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL, this); + + if (nsnull == mStyleAttrStyleSheet) { + result = NS_NewHTMLCSSStyleSheet(&mStyleAttrStyleSheet, aURL, this); + } + else { + result = mStyleAttrStyleSheet->Reset(aURL); + } if (NS_OK == result) { AddStyleSheet(mStyleAttrStyleSheet); // tell the world about our new style sheet } @@ -707,7 +709,7 @@ nsHTMLDocument::ContentRemoved(nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { - if (nsnull != mNamedItems) { + if ((nsnull != mNamedItems) && (nsnull != aContainer)) { nsIAtom *name; aContainer->GetTag(name); @@ -1178,7 +1180,6 @@ NS_IMETHODIMP nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc) { nsresult result = NS_OK; -#if 0 // The open occurred after the document finished loading. // So we reset the document and create a new one. if (nsnull == mParser) { @@ -1197,11 +1198,13 @@ nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc) nsnull, kCParserIID, (void **)&mParser); - + mIsWriting = 1; + if (NS_OK == result) { nsIHTMLContentSink* sink; nsIWebShell* webShell = nsnull; + // Get the webshell of our primary presentation shell nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); if (nsnull != shell) { nsIPresContext* cx = shell->GetPresContext(); @@ -1228,14 +1231,26 @@ nsHTMLDocument::Open(JSContext *cx, jsval *argv, PRUint32 argc) NS_RELEASE(blankURL); } } -#endif return result; } +#define NS_GENERATE_PARSER_KEY() (void*)((mIsWriting << 31) | (mWriteLevel & 0x7fffffff)) + NS_IMETHODIMP nsHTMLDocument::Close() { - return NS_ERROR_NOT_IMPLEMENTED; + nsresult result = NS_OK; + + if ((nsnull != mParser) && mIsWriting) { + nsAutoString emptyStr(""); + mWriteLevel++; + result = mParser->Parse(emptyStr, NS_GENERATE_PARSER_KEY(), + PR_TRUE, PR_FALSE, PR_TRUE); + mWriteLevel--; + mIsWriting = 0; + } + + return NS_OK; } nsresult @@ -1249,7 +1264,9 @@ nsHTMLDocument::WriteCommon(JSContext *cx, // XXX Right now, we only deal with inline document.writes if (nsnull == mParser) { result = Open(cx, argv, argc); - return NS_ERROR_NOT_IMPLEMENTED; + if (NS_OK != result) { + return result; + } } if (argc > 0) { @@ -1268,7 +1285,11 @@ nsHTMLDocument::WriteCommon(JSContext *cx, str.Append('\n'); } - result = mParser->Parse(str, PR_TRUE,PR_FALSE,PR_TRUE); + mWriteLevel++; + result = mParser->Parse(str, NS_GENERATE_PARSER_KEY(), + PR_TRUE, PR_FALSE, + (!mIsWriting || (mWriteLevel > 1))); + mWriteLevel--; if (NS_OK != result) { return result; } diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h index 6fd2d6765bb..624913b04ac 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.h +++ b/mozilla/layout/html/document/src/nsHTMLDocument.h @@ -189,6 +189,9 @@ protected: PLHashTable *mNamedItems; nsIParser *mParser; + + PRUint32 mIsWriting : 1; + PRUint32 mWriteLevel : 31; }; #endif /* nsHTMLDocument_h___ */ diff --git a/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp index 489cafacb9a..d77c9baceb0 100644 --- a/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -51,6 +51,7 @@ public: // basic style sheet data NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument); + NS_IMETHOD Reset(nsIURL* aURL); NS_IMETHOD GetURL(nsIURL*& aURL) const; NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD GetType(nsString& aType) const; @@ -239,6 +240,15 @@ HTMLCSSStyleSheetImpl::Init(nsIURL* aURL, nsIDocument* aDocument) return NS_OK; } +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::Reset(nsIURL* aURL) +{ + NS_IF_RELEASE(mURL); + mURL = aURL; + NS_ADDREF(mURL); + return NS_OK; +} + NS_IMETHODIMP HTMLCSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index 710074692f8..7a32dcd2642 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -318,6 +318,7 @@ public: nsISupportsArray* aResults); NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument); + NS_IMETHOD Reset(nsIURL* aURL); NS_IMETHOD SetLinkColor(nscolor aColor); NS_IMETHOD SetActiveLinkColor(nscolor aColor); NS_IMETHOD SetVisitedLinkColor(nscolor aColor); @@ -654,6 +655,7 @@ protected: nsIHTMLAttributes* mRecycledAttrs; nsIFrame* mInitialContainingBlock; nsIFrame* mFixedContainingBlock; + nsIFrame* mDocElementContainingBlock; }; @@ -701,7 +703,8 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(void) mVisitedRule(nsnull), mActiveRule(nsnull), mRecycledAttrs(nsnull), - mInitialContainingBlock(nsnull) + mInitialContainingBlock(nsnull), + mDocElementContainingBlock(nsnull) { NS_INIT_REFCNT(); #ifdef INCLUDE_XUL @@ -945,6 +948,29 @@ NS_IMETHODIMP HTMLStyleSheetImpl::Init(nsIURL* aURL, nsIDocument* aDocument) return NS_OK; } +NS_IMETHODIMP HTMLStyleSheetImpl::Reset(nsIURL* aURL) +{ + NS_IF_RELEASE(mURL); + mURL = aURL; + NS_ADDREF(mURL); + + if (nsnull != mLinkRule) { + mLinkRule->mSheet = nsnull; + NS_RELEASE(mLinkRule); + } + if (nsnull != mVisitedRule) { + mVisitedRule->mSheet = nsnull; + NS_RELEASE(mVisitedRule); + } + if (nsnull != mActiveRule) { + mActiveRule->mSheet = nsnull; + NS_RELEASE(mActiveRule); + } + mAttrTable.Reset(); + + return NS_OK; +} + NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) { if (nsnull == mLinkRule) { @@ -2299,16 +2325,13 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, pageFrame->Init(*aPresContext, nsnull, pageSequenceFrame, rootPseudoStyle); nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageFrame, rootPseudoStyle, PR_TRUE); - - // Create frames for the document element and its child elements - nsIFrame* docElementFrame; - nsAbsoluteItems fixedItems(pageFrame); - ConstructDocElementFrame(aPresContext, aDocElement, pageFrame, - rootPseudoStyle, docElementFrame, fixedItems); NS_RELEASE(rootPseudoStyle); + // The eventual parent of the document element frame + mDocElementContainingBlock = pageFrame; + + // Set the initial child lists - pageFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame); pageSequenceFrame->SetInitialChildList(*aPresContext, nsnull, pageFrame); if (isScrollable) { scrollFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame); @@ -2317,12 +2340,6 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, viewportFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame); } - // Tell the page about its 'fixed' frames - if (nsnull != fixedItems.childList) { - pageFrame->SetInitialChildList(*aPresContext, nsLayoutAtoms::fixedList, - fixedItems.childList); - } - } else { // The viewport is the containing block for 'fixed' elements mFixedContainingBlock = viewportFrame; @@ -2343,28 +2360,18 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, rootFrame, rootPseudoStyle, PR_TRUE); } - - // Create frames for the document element and its child elements - nsIFrame* docElementFrame; - nsAbsoluteItems fixedItems(viewportFrame); - ConstructDocElementFrame(aPresContext, aDocElement, rootFrame, - rootPseudoStyle, docElementFrame, fixedItems); NS_RELEASE(rootPseudoStyle); + // The eventual parent of the document element frame + mDocElementContainingBlock = rootFrame; + // Set the initial child lists - rootFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame); if (isScrollable) { scrollFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame); viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame); } else { viewportFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame); } - - // Tell the viewport about its 'fixed' frames - if (nsnull != fixedItems.childList) { - viewportFrame->SetInitialChildList(*aPresContext, nsLayoutAtoms::fixedList, - fixedItems.childList); - } } aNewFrame = viewportFrame; @@ -3935,80 +3942,122 @@ HTMLStyleSheetImpl::ContentInserted(nsIPresContext* aPresContext, PRInt32 aIndexInContainer) { nsIPresShell* shell = aPresContext->GetShell(); + nsresult rv = NS_OK; - // Find the frame that precedes the insertion point. - nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer); - nsIFrame* nextSibling = nsnull; - PRBool isAppend = PR_FALSE; + // If we have a null parent, then this must be the document element + // being inserted + if (nsnull == aContainer) { - // If there is no previous sibling, then find the frame that follows - if (nsnull == prevSibling) { - nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer); - } + NS_PRECONDITION(nsnull == mInitialContainingBlock, "initial containing block already created"); + nsIStyleContext* rootPseudoStyle; + nsIContent* docElement = nsnull; - // Get the geometric parent. - nsIFrame* parentFrame; - if ((nsnull == prevSibling) && (nsnull == nextSibling)) { - // No previous or next sibling so treat this like an appended frame. - // XXX This won't always be true if there's auto-generated before/after - // content - isAppend = PR_TRUE; - shell->GetPrimaryFrameFor(aContainer, parentFrame); + docElement = mDocument->GetRootContent(); - } else { - // Use the prev sibling if we have it; otherwise use the next sibling - if (nsnull != prevSibling) { - prevSibling->GetParent(parentFrame); - } else { - nextSibling->GetParent(parentFrame); - } - } - - // Construct a new frame - nsresult rv = NS_OK; - if (nsnull != parentFrame) { - // Get the containing block for absolutely positioned elements - nsIFrame* absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, - parentFrame); - - nsAbsoluteItems absoluteItems(absoluteContainingBlock); - nsFrameItems frameItems; + // Create a pseudo element style context + // XXX Use a different pseudo style context... + rootPseudoStyle = aPresContext->ResolvePseudoStyleContextFor(nsnull, + nsHTMLAtoms::rootPseudo, nsnull); + + // Create frames for the document element and its child elements + nsIFrame* docElementFrame; nsAbsoluteItems fixedItems(mFixedContainingBlock); - rv = ConstructFrame(aPresContext, aChild, parentFrame, absoluteItems, frameItems, - fixedItems); + ConstructDocElementFrame(aPresContext, + docElement, + mDocElementContainingBlock, + rootPseudoStyle, + docElementFrame, + fixedItems); + NS_RELEASE(rootPseudoStyle); + NS_IF_RELEASE(docElement); + + // Set the initial child list for the parent + mDocElementContainingBlock->SetInitialChildList(*aPresContext, + nsnull, + docElementFrame); + + // Tell the fixed containing block about its 'fixed' frames + if (nsnull != fixedItems.childList) { + mFixedContainingBlock->SetInitialChildList(*aPresContext, + nsLayoutAtoms::fixedList, + fixedItems.childList); + } + + } + else { + // Find the frame that precedes the insertion point. + nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer); + nsIFrame* nextSibling = nsnull; + PRBool isAppend = PR_FALSE; + + // If there is no previous sibling, then find the frame that follows + if (nsnull == prevSibling) { + nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer); + } - nsIFrame* newFrame = frameItems.childList; - - if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { - nsIReflowCommand* reflowCmd = nsnull; - - // Notify the parent frame - if (isAppend) { - rv = parentFrame->AppendFrames(*aPresContext, *shell, - nsnull, newFrame); + // Get the geometric parent. + nsIFrame* parentFrame; + if ((nsnull == prevSibling) && (nsnull == nextSibling)) { + // No previous or next sibling so treat this like an appended frame. + // XXX This won't always be true if there's auto-generated before/after + // content + isAppend = PR_TRUE; + shell->GetPrimaryFrameFor(aContainer, parentFrame); + + } else { + // Use the prev sibling if we have it; otherwise use the next sibling + if (nsnull != prevSibling) { + prevSibling->GetParent(parentFrame); } else { - rv = parentFrame->InsertFrames(*aPresContext, *shell, nsnull, - prevSibling, newFrame); + nextSibling->GetParent(parentFrame); } + } - // If there are new absolutely positioned child frames, then notify - // the parent - // XXX We can't just assume these frames are being appended, we need to - // determine where in the list they should be inserted... - if (nsnull != absoluteItems.childList) { - rv = absoluteItems.containingBlock->AppendFrames(*aPresContext, *shell, - nsLayoutAtoms::absoluteList, - absoluteItems.childList); - } - - // If there are new fixed positioned child frames, then notify - // the parent - // XXX We can't just assume these frames are being appended, we need to - // determine where in the list they should be inserted... - if (nsnull != fixedItems.childList) { - rv = fixedItems.containingBlock->AppendFrames(*aPresContext, *shell, - nsLayoutAtoms::fixedList, - fixedItems.childList); + // Construct a new frame + if (nsnull != parentFrame) { + // Get the containing block for absolutely positioned elements + nsIFrame* absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, + parentFrame); + + nsAbsoluteItems absoluteItems(absoluteContainingBlock); + nsFrameItems frameItems; + nsAbsoluteItems fixedItems(mFixedContainingBlock); + rv = ConstructFrame(aPresContext, aChild, parentFrame, absoluteItems, frameItems, + fixedItems); + + nsIFrame* newFrame = frameItems.childList; + + if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { + nsIReflowCommand* reflowCmd = nsnull; + + // Notify the parent frame + if (isAppend) { + rv = parentFrame->AppendFrames(*aPresContext, *shell, + nsnull, newFrame); + } else { + rv = parentFrame->InsertFrames(*aPresContext, *shell, nsnull, + prevSibling, newFrame); + } + + // If there are new absolutely positioned child frames, then notify + // the parent + // XXX We can't just assume these frames are being appended, we need to + // determine where in the list they should be inserted... + if (nsnull != absoluteItems.childList) { + rv = absoluteItems.containingBlock->AppendFrames(*aPresContext, *shell, + nsLayoutAtoms::absoluteList, + absoluteItems.childList); + } + + // If there are new fixed positioned child frames, then notify + // the parent + // XXX We can't just assume these frames are being appended, we need to + // determine where in the list they should be inserted... + if (nsnull != fixedItems.childList) { + rv = fixedItems.containingBlock->AppendFrames(*aPresContext, *shell, + nsLayoutAtoms::fixedList, + fixedItems.childList); + } } } } @@ -4083,6 +4132,10 @@ HTMLStyleSheetImpl::ContentRemoved(nsIPresContext* aPresContext, rv = parentFrame->RemoveFrame(*aPresContext, *shell, nsnull, childFrame); } + + if (mInitialContainingBlock == childFrame) { + mInitialContainingBlock = nsnull; + } } NS_RELEASE(shell); diff --git a/mozilla/layout/html/style/src/nsIHTMLCSSStyleSheet.h b/mozilla/layout/html/style/src/nsIHTMLCSSStyleSheet.h index f09044a1946..3c553a8d922 100644 --- a/mozilla/layout/html/style/src/nsIHTMLCSSStyleSheet.h +++ b/mozilla/layout/html/style/src/nsIHTMLCSSStyleSheet.h @@ -28,6 +28,7 @@ class nsIHTMLCSSStyleSheet : public nsIStyleSheet { public: NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument) = 0; + NS_IMETHOD Reset(nsIURL* aURL) = 0; }; // XXX for convenience and backward compatibility diff --git a/mozilla/layout/html/style/src/nsIHTMLStyleSheet.h b/mozilla/layout/html/style/src/nsIHTMLStyleSheet.h index 6b2eee6a353..fef4406ec05 100644 --- a/mozilla/layout/html/style/src/nsIHTMLStyleSheet.h +++ b/mozilla/layout/html/style/src/nsIHTMLStyleSheet.h @@ -36,6 +36,7 @@ class nsIDocument; class nsIHTMLStyleSheet : public nsIStyleSheet { public: NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument) = 0; + NS_IMETHOD Reset(nsIURL* aURL) = 0; NS_IMETHOD SetLinkColor(nscolor aColor) = 0; NS_IMETHOD SetActiveLinkColor(nscolor aColor) = 0; NS_IMETHOD SetVisitedLinkColor(nscolor aColor) = 0; diff --git a/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp b/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp index 489cafacb9a..d77c9baceb0 100644 --- a/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp @@ -51,6 +51,7 @@ public: // basic style sheet data NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument); + NS_IMETHOD Reset(nsIURL* aURL); NS_IMETHOD GetURL(nsIURL*& aURL) const; NS_IMETHOD GetTitle(nsString& aTitle) const; NS_IMETHOD GetType(nsString& aType) const; @@ -239,6 +240,15 @@ HTMLCSSStyleSheetImpl::Init(nsIURL* aURL, nsIDocument* aDocument) return NS_OK; } +NS_IMETHODIMP +HTMLCSSStyleSheetImpl::Reset(nsIURL* aURL) +{ + NS_IF_RELEASE(mURL); + mURL = aURL; + NS_ADDREF(mURL); + return NS_OK; +} + NS_IMETHODIMP HTMLCSSStyleSheetImpl::GetURL(nsIURL*& aURL) const { diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index 710074692f8..7a32dcd2642 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -318,6 +318,7 @@ public: nsISupportsArray* aResults); NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument); + NS_IMETHOD Reset(nsIURL* aURL); NS_IMETHOD SetLinkColor(nscolor aColor); NS_IMETHOD SetActiveLinkColor(nscolor aColor); NS_IMETHOD SetVisitedLinkColor(nscolor aColor); @@ -654,6 +655,7 @@ protected: nsIHTMLAttributes* mRecycledAttrs; nsIFrame* mInitialContainingBlock; nsIFrame* mFixedContainingBlock; + nsIFrame* mDocElementContainingBlock; }; @@ -701,7 +703,8 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(void) mVisitedRule(nsnull), mActiveRule(nsnull), mRecycledAttrs(nsnull), - mInitialContainingBlock(nsnull) + mInitialContainingBlock(nsnull), + mDocElementContainingBlock(nsnull) { NS_INIT_REFCNT(); #ifdef INCLUDE_XUL @@ -945,6 +948,29 @@ NS_IMETHODIMP HTMLStyleSheetImpl::Init(nsIURL* aURL, nsIDocument* aDocument) return NS_OK; } +NS_IMETHODIMP HTMLStyleSheetImpl::Reset(nsIURL* aURL) +{ + NS_IF_RELEASE(mURL); + mURL = aURL; + NS_ADDREF(mURL); + + if (nsnull != mLinkRule) { + mLinkRule->mSheet = nsnull; + NS_RELEASE(mLinkRule); + } + if (nsnull != mVisitedRule) { + mVisitedRule->mSheet = nsnull; + NS_RELEASE(mVisitedRule); + } + if (nsnull != mActiveRule) { + mActiveRule->mSheet = nsnull; + NS_RELEASE(mActiveRule); + } + mAttrTable.Reset(); + + return NS_OK; +} + NS_IMETHODIMP HTMLStyleSheetImpl::SetLinkColor(nscolor aColor) { if (nsnull == mLinkRule) { @@ -2299,16 +2325,13 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, pageFrame->Init(*aPresContext, nsnull, pageSequenceFrame, rootPseudoStyle); nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageFrame, rootPseudoStyle, PR_TRUE); - - // Create frames for the document element and its child elements - nsIFrame* docElementFrame; - nsAbsoluteItems fixedItems(pageFrame); - ConstructDocElementFrame(aPresContext, aDocElement, pageFrame, - rootPseudoStyle, docElementFrame, fixedItems); NS_RELEASE(rootPseudoStyle); + // The eventual parent of the document element frame + mDocElementContainingBlock = pageFrame; + + // Set the initial child lists - pageFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame); pageSequenceFrame->SetInitialChildList(*aPresContext, nsnull, pageFrame); if (isScrollable) { scrollFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame); @@ -2317,12 +2340,6 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, viewportFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame); } - // Tell the page about its 'fixed' frames - if (nsnull != fixedItems.childList) { - pageFrame->SetInitialChildList(*aPresContext, nsLayoutAtoms::fixedList, - fixedItems.childList); - } - } else { // The viewport is the containing block for 'fixed' elements mFixedContainingBlock = viewportFrame; @@ -2343,28 +2360,18 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, rootFrame, rootPseudoStyle, PR_TRUE); } - - // Create frames for the document element and its child elements - nsIFrame* docElementFrame; - nsAbsoluteItems fixedItems(viewportFrame); - ConstructDocElementFrame(aPresContext, aDocElement, rootFrame, - rootPseudoStyle, docElementFrame, fixedItems); NS_RELEASE(rootPseudoStyle); + // The eventual parent of the document element frame + mDocElementContainingBlock = rootFrame; + // Set the initial child lists - rootFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame); if (isScrollable) { scrollFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame); viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame); } else { viewportFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame); } - - // Tell the viewport about its 'fixed' frames - if (nsnull != fixedItems.childList) { - viewportFrame->SetInitialChildList(*aPresContext, nsLayoutAtoms::fixedList, - fixedItems.childList); - } } aNewFrame = viewportFrame; @@ -3935,80 +3942,122 @@ HTMLStyleSheetImpl::ContentInserted(nsIPresContext* aPresContext, PRInt32 aIndexInContainer) { nsIPresShell* shell = aPresContext->GetShell(); + nsresult rv = NS_OK; - // Find the frame that precedes the insertion point. - nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer); - nsIFrame* nextSibling = nsnull; - PRBool isAppend = PR_FALSE; + // If we have a null parent, then this must be the document element + // being inserted + if (nsnull == aContainer) { - // If there is no previous sibling, then find the frame that follows - if (nsnull == prevSibling) { - nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer); - } + NS_PRECONDITION(nsnull == mInitialContainingBlock, "initial containing block already created"); + nsIStyleContext* rootPseudoStyle; + nsIContent* docElement = nsnull; - // Get the geometric parent. - nsIFrame* parentFrame; - if ((nsnull == prevSibling) && (nsnull == nextSibling)) { - // No previous or next sibling so treat this like an appended frame. - // XXX This won't always be true if there's auto-generated before/after - // content - isAppend = PR_TRUE; - shell->GetPrimaryFrameFor(aContainer, parentFrame); + docElement = mDocument->GetRootContent(); - } else { - // Use the prev sibling if we have it; otherwise use the next sibling - if (nsnull != prevSibling) { - prevSibling->GetParent(parentFrame); - } else { - nextSibling->GetParent(parentFrame); - } - } - - // Construct a new frame - nsresult rv = NS_OK; - if (nsnull != parentFrame) { - // Get the containing block for absolutely positioned elements - nsIFrame* absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, - parentFrame); - - nsAbsoluteItems absoluteItems(absoluteContainingBlock); - nsFrameItems frameItems; + // Create a pseudo element style context + // XXX Use a different pseudo style context... + rootPseudoStyle = aPresContext->ResolvePseudoStyleContextFor(nsnull, + nsHTMLAtoms::rootPseudo, nsnull); + + // Create frames for the document element and its child elements + nsIFrame* docElementFrame; nsAbsoluteItems fixedItems(mFixedContainingBlock); - rv = ConstructFrame(aPresContext, aChild, parentFrame, absoluteItems, frameItems, - fixedItems); + ConstructDocElementFrame(aPresContext, + docElement, + mDocElementContainingBlock, + rootPseudoStyle, + docElementFrame, + fixedItems); + NS_RELEASE(rootPseudoStyle); + NS_IF_RELEASE(docElement); + + // Set the initial child list for the parent + mDocElementContainingBlock->SetInitialChildList(*aPresContext, + nsnull, + docElementFrame); + + // Tell the fixed containing block about its 'fixed' frames + if (nsnull != fixedItems.childList) { + mFixedContainingBlock->SetInitialChildList(*aPresContext, + nsLayoutAtoms::fixedList, + fixedItems.childList); + } + + } + else { + // Find the frame that precedes the insertion point. + nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer); + nsIFrame* nextSibling = nsnull; + PRBool isAppend = PR_FALSE; + + // If there is no previous sibling, then find the frame that follows + if (nsnull == prevSibling) { + nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer); + } - nsIFrame* newFrame = frameItems.childList; - - if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { - nsIReflowCommand* reflowCmd = nsnull; - - // Notify the parent frame - if (isAppend) { - rv = parentFrame->AppendFrames(*aPresContext, *shell, - nsnull, newFrame); + // Get the geometric parent. + nsIFrame* parentFrame; + if ((nsnull == prevSibling) && (nsnull == nextSibling)) { + // No previous or next sibling so treat this like an appended frame. + // XXX This won't always be true if there's auto-generated before/after + // content + isAppend = PR_TRUE; + shell->GetPrimaryFrameFor(aContainer, parentFrame); + + } else { + // Use the prev sibling if we have it; otherwise use the next sibling + if (nsnull != prevSibling) { + prevSibling->GetParent(parentFrame); } else { - rv = parentFrame->InsertFrames(*aPresContext, *shell, nsnull, - prevSibling, newFrame); + nextSibling->GetParent(parentFrame); } + } - // If there are new absolutely positioned child frames, then notify - // the parent - // XXX We can't just assume these frames are being appended, we need to - // determine where in the list they should be inserted... - if (nsnull != absoluteItems.childList) { - rv = absoluteItems.containingBlock->AppendFrames(*aPresContext, *shell, - nsLayoutAtoms::absoluteList, - absoluteItems.childList); - } - - // If there are new fixed positioned child frames, then notify - // the parent - // XXX We can't just assume these frames are being appended, we need to - // determine where in the list they should be inserted... - if (nsnull != fixedItems.childList) { - rv = fixedItems.containingBlock->AppendFrames(*aPresContext, *shell, - nsLayoutAtoms::fixedList, - fixedItems.childList); + // Construct a new frame + if (nsnull != parentFrame) { + // Get the containing block for absolutely positioned elements + nsIFrame* absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, + parentFrame); + + nsAbsoluteItems absoluteItems(absoluteContainingBlock); + nsFrameItems frameItems; + nsAbsoluteItems fixedItems(mFixedContainingBlock); + rv = ConstructFrame(aPresContext, aChild, parentFrame, absoluteItems, frameItems, + fixedItems); + + nsIFrame* newFrame = frameItems.childList; + + if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { + nsIReflowCommand* reflowCmd = nsnull; + + // Notify the parent frame + if (isAppend) { + rv = parentFrame->AppendFrames(*aPresContext, *shell, + nsnull, newFrame); + } else { + rv = parentFrame->InsertFrames(*aPresContext, *shell, nsnull, + prevSibling, newFrame); + } + + // If there are new absolutely positioned child frames, then notify + // the parent + // XXX We can't just assume these frames are being appended, we need to + // determine where in the list they should be inserted... + if (nsnull != absoluteItems.childList) { + rv = absoluteItems.containingBlock->AppendFrames(*aPresContext, *shell, + nsLayoutAtoms::absoluteList, + absoluteItems.childList); + } + + // If there are new fixed positioned child frames, then notify + // the parent + // XXX We can't just assume these frames are being appended, we need to + // determine where in the list they should be inserted... + if (nsnull != fixedItems.childList) { + rv = fixedItems.containingBlock->AppendFrames(*aPresContext, *shell, + nsLayoutAtoms::fixedList, + fixedItems.childList); + } } } } @@ -4083,6 +4132,10 @@ HTMLStyleSheetImpl::ContentRemoved(nsIPresContext* aPresContext, rv = parentFrame->RemoveFrame(*aPresContext, *shell, nsnull, childFrame); } + + if (mInitialContainingBlock == childFrame) { + mInitialContainingBlock = nsnull; + } } NS_RELEASE(shell); diff --git a/mozilla/layout/style/nsIHTMLCSSStyleSheet.h b/mozilla/layout/style/nsIHTMLCSSStyleSheet.h index f09044a1946..3c553a8d922 100644 --- a/mozilla/layout/style/nsIHTMLCSSStyleSheet.h +++ b/mozilla/layout/style/nsIHTMLCSSStyleSheet.h @@ -28,6 +28,7 @@ class nsIHTMLCSSStyleSheet : public nsIStyleSheet { public: NS_IMETHOD Init(nsIURL* aURL, nsIDocument* aDocument) = 0; + NS_IMETHOD Reset(nsIURL* aURL) = 0; }; // XXX for convenience and backward compatibility