Fix the case when a binding's single insertion point is a node that is itself bound by a binding with insertion points. Bug 403962, r+sr=sicking

This commit is contained in:
bzbarsky@mit.edu 2007-11-19 20:18:59 -08:00
Родитель 09bbed0a03
Коммит 39e4684fad
5 изменённых файлов: 109 добавлений и 5 удалений

Просмотреть файл

@ -1285,7 +1285,7 @@ nsBindingManager::GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChil
PRUint32 index; PRUint32 index;
nsIContent *insertionElement = GetInsertionPoint(aParent, aChild, &index); nsIContent *insertionElement = GetInsertionPoint(aParent, aChild, &index);
if (insertionElement != aParent) { if (insertionElement && insertionElement != aParent) {
// See if we nest even further in. // See if we nest even further in.
nsIContent* nestedPoint = GetNestedInsertionPoint(insertionElement, aChild); nsIContent* nestedPoint = GetNestedInsertionPoint(insertionElement, aChild);
if (nestedPoint) if (nestedPoint)
@ -1295,6 +1295,30 @@ nsBindingManager::GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChil
return insertionElement; return insertionElement;
} }
nsIContent*
nsBindingManager::GetNestedSingleInsertionPoint(nsIContent* aParent,
PRBool* aMultipleInsertionPoints)
{
*aMultipleInsertionPoints = PR_FALSE;
PRUint32 index;
nsIContent *insertionElement =
GetSingleInsertionPoint(aParent, &index, aMultipleInsertionPoints);
if (*aMultipleInsertionPoints) {
return nsnull;
}
if (insertionElement && insertionElement != aParent) {
// See if we nest even further in.
nsIContent* nestedPoint =
GetNestedSingleInsertionPoint(insertionElement,
aMultipleInsertionPoints);
if (nestedPoint)
insertionElement = nestedPoint;
}
return insertionElement;
}
// Note: We don't hold a reference to the document observer; we assume // Note: We don't hold a reference to the document observer; we assume
// that it has a live reference to the document. // that it has a live reference to the document.
void void
@ -1350,10 +1374,8 @@ nsBindingManager::ContentAppended(nsIDocument* aDocument,
if (aNewIndexInContainer != -1 && if (aNewIndexInContainer != -1 &&
(mContentListTable.ops || mAnonymousNodesTable.ops)) { (mContentListTable.ops || mAnonymousNodesTable.ops)) {
// It's not anonymous. // It's not anonymous.
PRUint32 singleIndex;
PRBool multiple; PRBool multiple;
nsIContent* ins = GetSingleInsertionPoint(aContainer, &singleIndex, nsIContent* ins = GetNestedSingleInsertionPoint(aContainer, &multiple);
&multiple);
if (multiple) { if (multiple) {
// Do each kid individually // Do each kid individually
@ -1381,7 +1403,6 @@ nsBindingManager::ContentAppended(nsIDocument* aDocument,
nsXBLInsertionPoint* point = contentList->GetInsertionPointAt(i); nsXBLInsertionPoint* point = contentList->GetInsertionPointAt(i);
PRInt32 index = point->GetInsertionIndex(); PRInt32 index = point->GetInsertionIndex();
if (index != -1) { if (index != -1) {
NS_ASSERTION(PRUint32(index) == singleIndex, "Unexpected index");
// We're real. Jam all the kids in. // We're real. Jam all the kids in.
PRInt32 childCount = aContainer->GetChildCount(); PRInt32 childCount = aContainer->GetChildCount();
for (PRInt32 j = aNewIndexInContainer; j < childCount; j++) { for (PRInt32 j = aNewIndexInContainer; j < childCount; j++) {

Просмотреть файл

@ -224,6 +224,8 @@ protected:
PRBool* aIsAnonymousContentList); PRBool* aIsAnonymousContentList);
nsIContent* GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild); nsIContent* GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild);
nsIContent* GetNestedSingleInsertionPoint(nsIContent* aParent,
PRBool* aMultipleInsertionPoints);
// Called by ContentAppended and ContentInserted to handle a single child // Called by ContentAppended and ContentInserted to handle a single child
// insertion. aChild must not be null. aContainer may be null. // insertion. aChild must not be null. aContainer may be null.

Просмотреть файл

@ -0,0 +1,15 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
div { color: green; }
</style>
</head>
<body>
<div>
<span>test</span>
</div>
<div>
<span>test</span>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,65 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head>
<!--
The binding attached to #test1 and #test2 is:
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="test">
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml"
style="color: red; -moz-binding: url(data:text/xml,%3Cbindings%20xmlns%3D%22http%3A%2F%2Fwww.mozilla.org%2Fxbl%22%3E%0D%0A%20%20%3Cbinding%20id%3D%22test-base%22%3E%0D%0A%20%20%20%20%3Ccontent%3E%0D%0A%20%20%20%20%20%20%3Chtml%3Adiv%20xmlns%3Ahtml%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20style%3D%22color%3A%20green%22%3E%0D%0A%20%20%20%20%20%20%20%20%3Cchildren%20includes%3D%22span%22%2F%3E%0D%0A%20%20%20%20%20%20%3C%2Fhtml%3Adiv%3E%0D%0A%20%20%20%20%20%20%3Chtml%3Adiv%20xmlns%3Ahtml%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20style%3D%22color%3A%20red%22%3E%0D%0A%20%20%20%20%20%20%20%20%3Cchildren%2F%3E%0D%0A%20%20%20%20%20%20%3C%2Fhtml%3Adiv%3E%0D%0A%20%20%20%20%3C%2Fcontent%3E%0D%0A%20%20%3C%2Fbinding%3E%0D%0A%3C%2Fbindings%3E%0D%0A)">
<children/>
</html:div>
</content>
</binding>
</bindings>
where the binding attached to the content div is:
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="test-base">
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml" style="color: green">
<children includes="span"/>
</html:div>
<html:div xmlns:html="http://www.w3.org/1999/xhtml" style="color: red">
<children/>
</html:div>
</content>
</binding>
</bindings>
-->
<style>
div { color: green; }
#test1, #test2 {
-moz-binding: url("data:text/xml,%3Cbindings%20xmlns%3D%22http%3A%2F%2Fwww.mozilla.org%2Fxbl%22%3E%0D%0A%20%20%3Cbinding%20id%3D%22test%22%3E%0D%0A%20%20%20%20%3Ccontent%3E%0D%0A%20%20%20%20%20%20%3Chtml%3Adiv%20xmlns%3Ahtml%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20style%3D%22color%3A%20red%3B%20-moz-binding%3A%20url(data%3Atext%2Fxml%2C%253Cbindings%2520xmlns%253D%2522http%253A%252F%252Fwww.mozilla.org%252Fxbl%2522%253E%250D%250A%2520%2520%253Cbinding%2520id%253D%2522test-base%2522%253E%250D%250A%2520%2520%2520%2520%253Ccontent%253E%250D%250A%2520%2520%2520%2520%2520%2520%253Chtml%253Adiv%2520xmlns%253Ahtml%253D%2522http%253A%252F%252Fwww.w3.org%252F1999%252Fxhtml%2522%2520style%253D%2522color%253A%2520green%2522%253E%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cchildren%2520includes%253D%2522span%2522%252F%253E%250D%250A%2520%2520%2520%2520%2520%2520%253C%252Fhtml%253Adiv%253E%250D%250A%2520%2520%2520%2520%2520%2520%253Chtml%253Adiv%2520xmlns%253Ahtml%253D%2522http%253A%252F%252Fwww.w3.org%252F1999%252Fxhtml%2522%2520style%253D%2522color%253A%2520red%2522%253E%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cchildren%252F%253E%250D%250A%2520%2520%2520%2520%2520%2520%253C%252Fhtml%253Adiv%253E%250D%250A%2520%2520%2520%2520%253C%252Fcontent%253E%250D%250A%2520%2520%253C%252Fbinding%253E%250D%250A%253C%252Fbindings%253E%250D%250A)%22%3E%0D%0A%20%20%20%20%20%20%20%20%3Cchildren%2F%3E%0D%0A%20%20%20%20%20%20%3C%2Fhtml%3Adiv%3E%0D%0A%20%20%20%20%3C%2Fcontent%3E%0D%0A%20%20%3C%2Fbinding%3E%0D%0A%3C%2Fbindings%3E%0D%0A");
}
</style>
</head>
<body onload="runTest()">
<div id="test1"/>
<div id="test2">
<!-- Make the script load, so the binding loads first -->
<script src="data:text/javascript,document.body.offsetWidth;"/>
<!-- The whitespace here is important... or this comment will do
the trick too -->
<span>test</span>
</div>
<script>
function runTest() {
var n = document.getElementById("test1");
n.appendChild(makeSpan());
document.documentElement.className = "";
}
function makeSpan() {
var s = document.createElementNS("http://www.w3.org/1999/xhtml",
"span");
s.appendChild(document.createTextNode("test"));
return s;
}
</script>
</body>
</html>

Просмотреть файл

@ -468,6 +468,7 @@ fails == 386310-1d.html 386310-1-ref.html
== 403656-4.html 403656-4-ref.html == 403656-4.html 403656-4-ref.html
== 403656-5.html 403656-5-ref.html == 403656-5.html 403656-5-ref.html
== 403733-1.html 403733-1-ref.html == 403733-1.html 403733-1-ref.html
== 403962-1.xhtml 403962-1-ref.xhtml
== 404030-1.html 404030-1-ref.html == 404030-1.html 404030-1-ref.html
!= 404030-1-notref.html 404030-1.html != 404030-1-notref.html 404030-1.html
!= 404030-1-notref2.html 404030-1.html != 404030-1-notref2.html 404030-1.html