diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 304eb4a8687..04f9c7079a5 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -587,7 +587,7 @@ nsresult nsDocument::CreateElement(nsString &aTagName, nsIDOMAttributeList *aAttributes, nsIDOMElement **aElement) { - //XXX TBI + //XXX TBI (currently there's a cheesy implementation in nsHTMLDocument) return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index f9ba236cbf4..f37763f5ae8 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -26,8 +26,11 @@ #include "nsIPresShell.h" #include "nsIPresContext.h" #include "nsIImageMap.h" +#include "nsIHTMLContent.h" +#include "nsIDOMElement.h" static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); NS_LAYOUT nsresult @@ -184,6 +187,27 @@ void nsHTMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet } } +nsresult nsHTMLDocument::CreateElement(nsString &aTagName, + nsIDOMAttributeList *aAttributes, + nsIDOMElement **aElement) +{ + nsIHTMLContent* container = nsnull; + nsAutoString tmp(aTagName); + nsIAtom* atom; + nsresult rv; + + tmp.ToUpperCase(); + atom = NS_NewAtom(tmp); + + rv = NS_NewHTMLContainer(&container, atom); + if (NS_OK == rv) { + rv = container->QueryInterface(kIDOMElementIID, (void**)aElement); + } + + NS_RELEASE(atom); + return rv; +} + //---------------------------------------------------------------------- // Aggregation class to give nsHTMLDocument the nsIHTMLDocument interface diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 9505de62920..e6ac9d4a9f9 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -42,6 +42,10 @@ public: return offsetof(nsHTMLDocument,mIHTMLDocument); } + virtual nsresult CreateElement(nsString &aTagName, + nsIDOMAttributeList *aAttributes, + nsIDOMElement **aElement); + protected: virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet); diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index 304eb4a8687..04f9c7079a5 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -587,7 +587,7 @@ nsresult nsDocument::CreateElement(nsString &aTagName, nsIDOMAttributeList *aAttributes, nsIDOMElement **aElement) { - //XXX TBI + //XXX TBI (currently there's a cheesy implementation in nsHTMLDocument) return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 36fb68ba71a..97d80160ded 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -1127,8 +1127,7 @@ nsBlockFrame::ContentInserted(nsIPresShell* aShell, nsIContent* aChild, PRInt32 aIndexInParent) { - nsresult rv = NS_OK; - return rv; + return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer); } NS_METHOD diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 36fb68ba71a..97d80160ded 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -1127,8 +1127,7 @@ nsBlockFrame::ContentInserted(nsIPresShell* aShell, nsIContent* aChild, PRInt32 aIndexInParent) { - nsresult rv = NS_OK; - return rv; + return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer); } NS_METHOD diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index 36fb68ba71a..97d80160ded 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -1127,8 +1127,7 @@ nsBlockFrame::ContentInserted(nsIPresShell* aShell, nsIContent* aChild, PRInt32 aIndexInParent) { - nsresult rv = NS_OK; - return rv; + return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer); } NS_METHOD diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.cpp b/mozilla/layout/generic/nsHTMLContainerFrame.cpp index f85fe800b8d..bf2877f5c30 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/generic/nsHTMLContainerFrame.cpp @@ -186,12 +186,53 @@ NS_METHOD nsHTMLContainerFrame::ContentAppended(nsIPresShell* aShell, return NS_OK; } -#if 0 -void nsHTMLContainerFrame::AdjustIndexInParents(nsIContent* aChild, - PRInt32 aIndexInParent, - ContentChange aChange) +static PRBool +HasSameMapping(nsIFrame* aFrame, nsIContent* aContent) { - // Walk each child + nsIContent* content; + PRBool result; + + aFrame->GetContent(content); + result = content == aContent; + NS_RELEASE(content); + return result; +} + +enum ContentChangeType {ContentInserted, ContentDeleted}; + +static void AdjustIndexInParents(nsIFrame* aContainerFrame, + nsIContent* aContainer, + PRInt32 aIndexInParent, + ContentChangeType aChange) +{ + // Walk each child and check if its index-in-parent needs to be + // adjusted + nsIFrame* childFrame; + for (aContainerFrame->FirstChild(childFrame); + nsnull != childFrame; + childFrame->GetNextSibling(childFrame)) + { + // Is the child a pseudo-frame? + if (HasSameMapping(childFrame, aContainer)) { + // Don't change the pseudo frame's index-in-parent, but go change the + // index-in-parent of its children + AdjustIndexInParents(childFrame, aContainer, aIndexInParent, aChange); + } else { + PRInt32 index; + + childFrame->GetIndexInParent(index); + + if (::ContentInserted == aChange) { + if (index >= aIndexInParent) { + childFrame->SetIndexInParent(index + 1); + } + } else { + if (index > aIndexInParent) { + childFrame->SetIndexInParent(index - 1); + } + } + } + } } NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, @@ -202,9 +243,28 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, { // Adjust the index-in-parent of each frame that follows the child that was // inserted - AdjustIndexInParents(aChild, aIndexInParent, ContentInserted); + PRBool isPseudoFrame = IsPseudoFrame(); + nsHTMLContainerFrame* frame = this; + + while (nsnull != frame) { + // Do a quick check to see whether any of the child frames need their + // index-in-parent adjusted. Note that this assumes a linear mapping of + // content to frame + if (mLastContentOffset >= aIndexInParent) { + AdjustIndexInParents(frame, aContainer, aIndexInParent, ::ContentInserted); + + // If the frame is being used as a pseudo-frame then make sure to propagate + // the content offsets back up the tree + if (isPseudoFrame) { + frame->PropagateContentOffsets(); + } + } + + frame->GetNextInFlow((nsIFrame*&)frame); + } + + return NS_OK; } -#endif #if 0 nsIFrame::ReflowStatus diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.h b/mozilla/layout/generic/nsHTMLContainerFrame.h index e89ab1a5182..627803cd997 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.h +++ b/mozilla/layout/generic/nsHTMLContainerFrame.h @@ -46,6 +46,12 @@ public: nsIPresContext* aPresContext, nsIContent* aContainer); + NS_IMETHOD ContentInserted(nsIPresShell* aShell, + nsIPresContext* aPresContext, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInParent); + protected: virtual ~nsHTMLContainerFrame(); diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 36fb68ba71a..97d80160ded 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -1127,8 +1127,7 @@ nsBlockFrame::ContentInserted(nsIPresShell* aShell, nsIContent* aChild, PRInt32 aIndexInParent) { - nsresult rv = NS_OK; - return rv; + return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer); } NS_METHOD diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 36fb68ba71a..97d80160ded 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -1127,8 +1127,7 @@ nsBlockFrame::ContentInserted(nsIPresShell* aShell, nsIContent* aChild, PRInt32 aIndexInParent) { - nsresult rv = NS_OK; - return rv; + return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer); } NS_METHOD diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index 36fb68ba71a..97d80160ded 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -1127,8 +1127,7 @@ nsBlockFrame::ContentInserted(nsIPresShell* aShell, nsIContent* aChild, PRInt32 aIndexInParent) { - nsresult rv = NS_OK; - return rv; + return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer); } NS_METHOD diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp index f85fe800b8d..bf2877f5c30 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -186,12 +186,53 @@ NS_METHOD nsHTMLContainerFrame::ContentAppended(nsIPresShell* aShell, return NS_OK; } -#if 0 -void nsHTMLContainerFrame::AdjustIndexInParents(nsIContent* aChild, - PRInt32 aIndexInParent, - ContentChange aChange) +static PRBool +HasSameMapping(nsIFrame* aFrame, nsIContent* aContent) { - // Walk each child + nsIContent* content; + PRBool result; + + aFrame->GetContent(content); + result = content == aContent; + NS_RELEASE(content); + return result; +} + +enum ContentChangeType {ContentInserted, ContentDeleted}; + +static void AdjustIndexInParents(nsIFrame* aContainerFrame, + nsIContent* aContainer, + PRInt32 aIndexInParent, + ContentChangeType aChange) +{ + // Walk each child and check if its index-in-parent needs to be + // adjusted + nsIFrame* childFrame; + for (aContainerFrame->FirstChild(childFrame); + nsnull != childFrame; + childFrame->GetNextSibling(childFrame)) + { + // Is the child a pseudo-frame? + if (HasSameMapping(childFrame, aContainer)) { + // Don't change the pseudo frame's index-in-parent, but go change the + // index-in-parent of its children + AdjustIndexInParents(childFrame, aContainer, aIndexInParent, aChange); + } else { + PRInt32 index; + + childFrame->GetIndexInParent(index); + + if (::ContentInserted == aChange) { + if (index >= aIndexInParent) { + childFrame->SetIndexInParent(index + 1); + } + } else { + if (index > aIndexInParent) { + childFrame->SetIndexInParent(index - 1); + } + } + } + } } NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, @@ -202,9 +243,28 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, { // Adjust the index-in-parent of each frame that follows the child that was // inserted - AdjustIndexInParents(aChild, aIndexInParent, ContentInserted); + PRBool isPseudoFrame = IsPseudoFrame(); + nsHTMLContainerFrame* frame = this; + + while (nsnull != frame) { + // Do a quick check to see whether any of the child frames need their + // index-in-parent adjusted. Note that this assumes a linear mapping of + // content to frame + if (mLastContentOffset >= aIndexInParent) { + AdjustIndexInParents(frame, aContainer, aIndexInParent, ::ContentInserted); + + // If the frame is being used as a pseudo-frame then make sure to propagate + // the content offsets back up the tree + if (isPseudoFrame) { + frame->PropagateContentOffsets(); + } + } + + frame->GetNextInFlow((nsIFrame*&)frame); + } + + return NS_OK; } -#endif #if 0 nsIFrame::ReflowStatus diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h index e89ab1a5182..627803cd997 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h @@ -46,6 +46,12 @@ public: nsIPresContext* aPresContext, nsIContent* aContainer); + NS_IMETHOD ContentInserted(nsIPresShell* aShell, + nsIPresContext* aPresContext, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInParent); + protected: virtual ~nsHTMLContainerFrame(); diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index f9ba236cbf4..f37763f5ae8 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -26,8 +26,11 @@ #include "nsIPresShell.h" #include "nsIPresContext.h" #include "nsIImageMap.h" +#include "nsIHTMLContent.h" +#include "nsIDOMElement.h" static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); NS_LAYOUT nsresult @@ -184,6 +187,27 @@ void nsHTMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet } } +nsresult nsHTMLDocument::CreateElement(nsString &aTagName, + nsIDOMAttributeList *aAttributes, + nsIDOMElement **aElement) +{ + nsIHTMLContent* container = nsnull; + nsAutoString tmp(aTagName); + nsIAtom* atom; + nsresult rv; + + tmp.ToUpperCase(); + atom = NS_NewAtom(tmp); + + rv = NS_NewHTMLContainer(&container, atom); + if (NS_OK == rv) { + rv = container->QueryInterface(kIDOMElementIID, (void**)aElement); + } + + NS_RELEASE(atom); + return rv; +} + //---------------------------------------------------------------------- // Aggregation class to give nsHTMLDocument the nsIHTMLDocument interface diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h index 9505de62920..e6ac9d4a9f9 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.h +++ b/mozilla/layout/html/document/src/nsHTMLDocument.h @@ -42,6 +42,10 @@ public: return offsetof(nsHTMLDocument,mIHTMLDocument); } + virtual nsresult CreateElement(nsString &aTagName, + nsIDOMAttributeList *aAttributes, + nsIDOMElement **aElement); + protected: virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet);