diff --git a/mozilla/layout/base/nsLayoutUtils.cpp b/mozilla/layout/base/nsLayoutUtils.cpp index 0887594c4fe..bcae0ad49e5 100644 --- a/mozilla/layout/base/nsLayoutUtils.cpp +++ b/mozilla/layout/base/nsLayoutUtils.cpp @@ -228,14 +228,25 @@ nsLayoutUtils::CompareTreePosition(nsIContent* aContent1, nsIContent* aContent2, NS_PRECONDITION(aContent2, "aContent2 must not be null"); nsAutoVoidArray content1Ancestors; - nsAutoVoidArray content2Ancestors; - nsIContent* c; - - for (c = aContent1; c != aCommonAncestor; c = c->GetParent()) { - content1Ancestors.AppendElement(c); + nsIContent* c1; + for (c1 = aContent1; c1 && c1 != aCommonAncestor; c1 = c1->GetParent()) { + content1Ancestors.AppendElement(c1); } - for (c = aContent2; c != aCommonAncestor; c = c->GetParent()) { - content2Ancestors.AppendElement(c); + if (!c1 && aCommonAncestor) { + // So, it turns out aCommonAncestor was not an ancestor of c1. Oops. + // Never mind. We can continue as if aCommonAncestor was null. + aCommonAncestor = nsnull; + } + + nsAutoVoidArray content2Ancestors; + nsIContent* c2; + for (c2 = aContent2; c2 && c2 != aCommonAncestor; c2 = c2->GetParent()) { + content2Ancestors.AppendElement(c2); + } + if (!c2 && aCommonAncestor) { + // So, it turns out aCommonAncestor was not an ancestor of c2. + // We need to retry with no common ancestor hint. + return CompareTreePosition(aContent1, aContent2, nsnull); } int last1 = content1Ancestors.Count() - 1; diff --git a/mozilla/layout/base/nsLayoutUtils.h b/mozilla/layout/base/nsLayoutUtils.h index 726aeaa4777..77d17931605 100644 --- a/mozilla/layout/base/nsLayoutUtils.h +++ b/mozilla/layout/base/nsLayoutUtils.h @@ -108,6 +108,8 @@ public: * a preorder traversal of the content tree. * * @param aCommonAncestor either null, or a common ancestor of aContent1 and aContent2 + * Actually this is only a hint; if it's not an ancestor of aContent1 or aContent2, + * this function will still work, but it will be slower than normal. * @return < 0 if aContent1 is before aContent2, > 0 if aContent1 is after aContent2, * 0 otherwise (meaning they're the same, or they're in different documents) */ diff --git a/mozilla/layout/base/public/nsLayoutUtils.h b/mozilla/layout/base/public/nsLayoutUtils.h index 726aeaa4777..77d17931605 100644 --- a/mozilla/layout/base/public/nsLayoutUtils.h +++ b/mozilla/layout/base/public/nsLayoutUtils.h @@ -108,6 +108,8 @@ public: * a preorder traversal of the content tree. * * @param aCommonAncestor either null, or a common ancestor of aContent1 and aContent2 + * Actually this is only a hint; if it's not an ancestor of aContent1 or aContent2, + * this function will still work, but it will be slower than normal. * @return < 0 if aContent1 is before aContent2, > 0 if aContent1 is after aContent2, * 0 otherwise (meaning they're the same, or they're in different documents) */ diff --git a/mozilla/layout/base/src/nsLayoutUtils.cpp b/mozilla/layout/base/src/nsLayoutUtils.cpp index 0887594c4fe..bcae0ad49e5 100644 --- a/mozilla/layout/base/src/nsLayoutUtils.cpp +++ b/mozilla/layout/base/src/nsLayoutUtils.cpp @@ -228,14 +228,25 @@ nsLayoutUtils::CompareTreePosition(nsIContent* aContent1, nsIContent* aContent2, NS_PRECONDITION(aContent2, "aContent2 must not be null"); nsAutoVoidArray content1Ancestors; - nsAutoVoidArray content2Ancestors; - nsIContent* c; - - for (c = aContent1; c != aCommonAncestor; c = c->GetParent()) { - content1Ancestors.AppendElement(c); + nsIContent* c1; + for (c1 = aContent1; c1 && c1 != aCommonAncestor; c1 = c1->GetParent()) { + content1Ancestors.AppendElement(c1); } - for (c = aContent2; c != aCommonAncestor; c = c->GetParent()) { - content2Ancestors.AppendElement(c); + if (!c1 && aCommonAncestor) { + // So, it turns out aCommonAncestor was not an ancestor of c1. Oops. + // Never mind. We can continue as if aCommonAncestor was null. + aCommonAncestor = nsnull; + } + + nsAutoVoidArray content2Ancestors; + nsIContent* c2; + for (c2 = aContent2; c2 && c2 != aCommonAncestor; c2 = c2->GetParent()) { + content2Ancestors.AppendElement(c2); + } + if (!c2 && aCommonAncestor) { + // So, it turns out aCommonAncestor was not an ancestor of c2. + // We need to retry with no common ancestor hint. + return CompareTreePosition(aContent1, aContent2, nsnull); } int last1 = content1Ancestors.Count() - 1;