From 7c69c70b1bb65691c783413d977979f8e47ecabf Mon Sep 17 00:00:00 2001 From: "ben%netscape.com" Date: Tue, 20 Jun 2000 05:43:52 +0000 Subject: [PATCH] fix for 41657, r=waterson, hyatt --- content/xul/document/src/nsXULDocument.cpp | 81 +++++++++++++++++++--- content/xul/document/src/nsXULDocument.h | 2 + rdf/content/src/nsXULDocument.cpp | 81 +++++++++++++++++++--- rdf/content/src/nsXULDocument.h | 2 + 4 files changed, 146 insertions(+), 20 deletions(-) diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 43cef32c7b37..ab5c468f53fa 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -22,6 +22,7 @@ * * Contributor(s): * Pierre Phaneuf + * Ben Goodger */ /* @@ -207,6 +208,8 @@ nsIAtom* nsXULDocument::kOpenAtom; nsIAtom* nsXULDocument::kOverlayAtom; nsIAtom* nsXULDocument::kPersistAtom; nsIAtom* nsXULDocument::kPositionAtom; +nsIAtom* nsXULDocument::kInsertAfterAtom; +nsIAtom* nsXULDocument::kInsertBeforeAtom; nsIAtom* nsXULDocument::kPopupAtom; nsIAtom* nsXULDocument::kRefAtom; nsIAtom* nsXULDocument::kRuleAtom; @@ -491,6 +494,8 @@ nsXULDocument::~nsXULDocument() NS_IF_RELEASE(kOverlayAtom); NS_IF_RELEASE(kPersistAtom); NS_IF_RELEASE(kPositionAtom); + NS_IF_RELEASE(kInsertAfterAtom); + NS_IF_RELEASE(kInsertBeforeAtom); NS_IF_RELEASE(kPopupAtom); NS_IF_RELEASE(kRefAtom); NS_IF_RELEASE(kRuleAtom); @@ -4007,6 +4012,8 @@ nsXULDocument::Init() kPersistAtom = NS_NewAtom("persist"); kPopupAtom = NS_NewAtom("popup"); kPositionAtom = NS_NewAtom("position"); + kInsertAfterAtom = NS_NewAtom("insertafter"); + kInsertBeforeAtom = NS_NewAtom("insertbefore"); kRefAtom = NS_NewAtom("ref"); kRuleAtom = NS_NewAtom("rule"); kStyleAtom = NS_NewAtom("style"); @@ -6426,19 +6433,73 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild) nsresult rv; nsAutoString posStr; - rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr); - if (NS_FAILED(rv)) return rv; - PRBool wasInserted = PR_FALSE; - if (rv == NS_CONTENT_ATTR_HAS_VALUE) { - // Positions are one-indexed. - PRInt32 pos = posStr.ToInteger(NS_REINTERPRET_CAST(PRInt32*, &rv)); - if (NS_SUCCEEDED(rv)) { - rv = aParent->InsertChildAt(aChild, pos - 1, PR_FALSE); - if (NS_FAILED(rv)) return rv; + // insert after an element of a given id + rv = aChild->GetAttribute(kNameSpaceID_None, kInsertAfterAtom, posStr); + if (NS_FAILED(rv)) return rv; + PRBool isInsertAfter = PR_TRUE; - wasInserted = PR_TRUE; + if (rv != NS_CONTENT_ATTR_HAS_VALUE) { + rv = aChild->GetAttribute(kNameSpaceID_None, kInsertBeforeAtom, posStr); + if (NS_FAILED(rv)) return rv; + isInsertAfter = PR_FALSE; + } + + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + nsCOMPtr document; + rv = aParent->GetDocument(*getter_AddRefs(document)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr xulDocument(do_QueryInterface(document)); + nsCOMPtr domElement; + + char* str = posStr.ToNewCString(); + char* remainder; + char* token = nsCRT::strtok(str, ", ", &remainder); + + while (token) { + rv = xulDocument->GetElementById(NS_ConvertASCIItoUCS2(token), getter_AddRefs(domElement)); + if (domElement) break; + + token = nsCRT::strtok(remainder, ", ", &remainder); + } + nsMemory::Free(str); + if (NS_FAILED(rv)) return rv; + + if (domElement) { + nsCOMPtr content(do_QueryInterface(domElement)); + NS_ASSERTION(content != nsnull, "null ptr"); + if (!content) + return NS_ERROR_UNEXPECTED; + + PRInt32 pos; + aParent->IndexOf(content, pos); + + if (pos != -1) { + pos = isInsertAfter ? pos + 1 : pos; + rv = aParent->InsertChildAt(aChild, pos, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + wasInserted = PR_TRUE; + } + } + } + + if (!wasInserted) { + + rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + // Positions are one-indexed. + PRInt32 pos = posStr.ToInteger(NS_REINTERPRET_CAST(PRInt32*, &rv)); + if (NS_SUCCEEDED(rv)) { + rv = aParent->InsertChildAt(aChild, pos - 1, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + wasInserted = PR_TRUE; + } } } diff --git a/content/xul/document/src/nsXULDocument.h b/content/xul/document/src/nsXULDocument.h index f8c3d177a9b4..2d8d5d8ef1d6 100644 --- a/content/xul/document/src/nsXULDocument.h +++ b/content/xul/document/src/nsXULDocument.h @@ -504,6 +504,8 @@ protected: static nsIAtom* kPersistAtom; static nsIAtom* kPopupAtom; static nsIAtom* kPositionAtom; + static nsIAtom* kInsertAfterAtom; + static nsIAtom* kInsertBeforeAtom; static nsIAtom* kRefAtom; static nsIAtom* kRuleAtom; static nsIAtom* kStyleAtom; diff --git a/rdf/content/src/nsXULDocument.cpp b/rdf/content/src/nsXULDocument.cpp index 43cef32c7b37..ab5c468f53fa 100644 --- a/rdf/content/src/nsXULDocument.cpp +++ b/rdf/content/src/nsXULDocument.cpp @@ -22,6 +22,7 @@ * * Contributor(s): * Pierre Phaneuf + * Ben Goodger */ /* @@ -207,6 +208,8 @@ nsIAtom* nsXULDocument::kOpenAtom; nsIAtom* nsXULDocument::kOverlayAtom; nsIAtom* nsXULDocument::kPersistAtom; nsIAtom* nsXULDocument::kPositionAtom; +nsIAtom* nsXULDocument::kInsertAfterAtom; +nsIAtom* nsXULDocument::kInsertBeforeAtom; nsIAtom* nsXULDocument::kPopupAtom; nsIAtom* nsXULDocument::kRefAtom; nsIAtom* nsXULDocument::kRuleAtom; @@ -491,6 +494,8 @@ nsXULDocument::~nsXULDocument() NS_IF_RELEASE(kOverlayAtom); NS_IF_RELEASE(kPersistAtom); NS_IF_RELEASE(kPositionAtom); + NS_IF_RELEASE(kInsertAfterAtom); + NS_IF_RELEASE(kInsertBeforeAtom); NS_IF_RELEASE(kPopupAtom); NS_IF_RELEASE(kRefAtom); NS_IF_RELEASE(kRuleAtom); @@ -4007,6 +4012,8 @@ nsXULDocument::Init() kPersistAtom = NS_NewAtom("persist"); kPopupAtom = NS_NewAtom("popup"); kPositionAtom = NS_NewAtom("position"); + kInsertAfterAtom = NS_NewAtom("insertafter"); + kInsertBeforeAtom = NS_NewAtom("insertbefore"); kRefAtom = NS_NewAtom("ref"); kRuleAtom = NS_NewAtom("rule"); kStyleAtom = NS_NewAtom("style"); @@ -6426,19 +6433,73 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild) nsresult rv; nsAutoString posStr; - rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr); - if (NS_FAILED(rv)) return rv; - PRBool wasInserted = PR_FALSE; - if (rv == NS_CONTENT_ATTR_HAS_VALUE) { - // Positions are one-indexed. - PRInt32 pos = posStr.ToInteger(NS_REINTERPRET_CAST(PRInt32*, &rv)); - if (NS_SUCCEEDED(rv)) { - rv = aParent->InsertChildAt(aChild, pos - 1, PR_FALSE); - if (NS_FAILED(rv)) return rv; + // insert after an element of a given id + rv = aChild->GetAttribute(kNameSpaceID_None, kInsertAfterAtom, posStr); + if (NS_FAILED(rv)) return rv; + PRBool isInsertAfter = PR_TRUE; - wasInserted = PR_TRUE; + if (rv != NS_CONTENT_ATTR_HAS_VALUE) { + rv = aChild->GetAttribute(kNameSpaceID_None, kInsertBeforeAtom, posStr); + if (NS_FAILED(rv)) return rv; + isInsertAfter = PR_FALSE; + } + + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + nsCOMPtr document; + rv = aParent->GetDocument(*getter_AddRefs(document)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr xulDocument(do_QueryInterface(document)); + nsCOMPtr domElement; + + char* str = posStr.ToNewCString(); + char* remainder; + char* token = nsCRT::strtok(str, ", ", &remainder); + + while (token) { + rv = xulDocument->GetElementById(NS_ConvertASCIItoUCS2(token), getter_AddRefs(domElement)); + if (domElement) break; + + token = nsCRT::strtok(remainder, ", ", &remainder); + } + nsMemory::Free(str); + if (NS_FAILED(rv)) return rv; + + if (domElement) { + nsCOMPtr content(do_QueryInterface(domElement)); + NS_ASSERTION(content != nsnull, "null ptr"); + if (!content) + return NS_ERROR_UNEXPECTED; + + PRInt32 pos; + aParent->IndexOf(content, pos); + + if (pos != -1) { + pos = isInsertAfter ? pos + 1 : pos; + rv = aParent->InsertChildAt(aChild, pos, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + wasInserted = PR_TRUE; + } + } + } + + if (!wasInserted) { + + rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + // Positions are one-indexed. + PRInt32 pos = posStr.ToInteger(NS_REINTERPRET_CAST(PRInt32*, &rv)); + if (NS_SUCCEEDED(rv)) { + rv = aParent->InsertChildAt(aChild, pos - 1, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + wasInserted = PR_TRUE; + } } } diff --git a/rdf/content/src/nsXULDocument.h b/rdf/content/src/nsXULDocument.h index f8c3d177a9b4..2d8d5d8ef1d6 100644 --- a/rdf/content/src/nsXULDocument.h +++ b/rdf/content/src/nsXULDocument.h @@ -504,6 +504,8 @@ protected: static nsIAtom* kPersistAtom; static nsIAtom* kPopupAtom; static nsIAtom* kPositionAtom; + static nsIAtom* kInsertAfterAtom; + static nsIAtom* kInsertBeforeAtom; static nsIAtom* kRefAtom; static nsIAtom* kRuleAtom; static nsIAtom* kStyleAtom;