Bug 332893. <form>.elements['x'] order is not updated after reordering element using DOM. r=bzbarsky

This commit is contained in:
David Zbarsky 2009-07-24 09:33:20 -04:00
parent 09eadb9ca6
commit 029d5ee3dc
8 changed files with 151 additions and 43 deletions

View File

@ -130,17 +130,6 @@ nsBaseContentList::GetNodeAt(PRUint32 aIndex)
return mElements.SafeObjectAt(aIndex);
}
void
nsBaseContentList::AppendElement(nsIContent *aContent)
{
mElements.AppendObject(aContent);
}
void
nsBaseContentList::RemoveElement(nsIContent *aContent)
{
mElements.RemoveObject(aContent);
}
PRInt32
nsBaseContentList::IndexOf(nsIContent *aContent, PRBool aDoFlush)
@ -154,20 +143,27 @@ nsBaseContentList::IndexOf(nsIContent* aContent)
return IndexOf(aContent, PR_TRUE);
}
void
nsBaseContentList::Reset()
void nsBaseContentList::AppendElement(nsIContent *aContent)
{
mElements.Clear();
mElements.AppendObject(aContent);
}
// static
void
nsBaseContentList::Shutdown()
void nsBaseContentList::RemoveElement(nsIContent *aContent)
{
mElements.RemoveObject(aContent);
}
void nsBaseContentList::InsertElementAt(nsIContent* aContent, PRInt32 aIndex)
{
NS_ASSERTION(aContent, "Element to insert must not be null");
mElements.InsertObjectAt(aContent, aIndex);
}
//static
void nsBaseContentList::Shutdown() {
NS_IF_RELEASE(gCachedContentList);
}
// nsFormContentList
nsFormContentList::nsFormContentList(nsIDOMHTMLFormElement *aForm,

View File

@ -89,12 +89,30 @@ public:
virtual nsIContent* GetNodeAt(PRUint32 aIndex);
virtual PRInt32 IndexOf(nsIContent* aContent);
PRUint32 Length() const {
return mElements.Count();
}
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsBaseContentList, nsINodeList)
void AppendElement(nsIContent *aContent);
void RemoveElement(nsIContent *aContent);
/**
* Insert the element at a given index, shifting the objects at
* the given index and later to make space.
* @param aContent Element to insert, must not be null
* @param aIndex Index to insert the element at.
*/
void InsertElementAt(nsIContent* aContent, PRInt32 aIndex);
void RemoveElement(nsIContent *aContent);
void Reset() {
mElements.Clear();
}
virtual PRInt32 IndexOf(nsIContent *aContent, PRBool aDoFlush);
void Reset();
static void Shutdown();

View File

@ -2253,10 +2253,14 @@ nsFormControlList::AddElementToTable(nsIFormControl* aChild,
nsBaseContentList *list = new nsBaseContentList();
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
list->AppendElement(content);
NS_ASSERTION(content->GetParent(), "Item in list without parent");
// Determine the ordering between the new and old element.
PRBool newFirst = nsContentUtils::PositionIsBefore(newChild, content);
list->AppendElement(newFirst ? newChild : content);
list->AppendElement(newFirst ? content : newChild);
// Add the new child too
list->AppendElement(newChild);
nsCOMPtr<nsISupports> listSupports =
do_QueryInterface(static_cast<nsIDOMNodeList*>(list));
@ -2273,12 +2277,31 @@ nsFormControlList::AddElementToTable(nsIFormControl* aChild,
nsBaseContentList *list = static_cast<nsBaseContentList *>
((nsIDOMNodeList *)nodeList.get());
PRInt32 oldIndex = list->IndexOf(newChild, PR_FALSE);
NS_ASSERTION(list->Length() > 1,
"List should have been converted back to a single element");
// Add the new child only if it's not in our list already
if (oldIndex < 0) {
list->AppendElement(newChild);
if(nsContentUtils::PositionIsBefore(list->GetNodeAt(list->Length() - 1), newChild)) {
list->AppendElement(newChild);
return NS_OK;
}
// first is the first possible insertion index, last is the last possible
// insertion index
PRUint32 first = 0;
PRUint32 last = list->Length() - 1;
PRUint32 mid;
//Stop when there is only one index in our range
while (last != first) {
mid = (first + last) / 2;
if (nsContentUtils::PositionIsBefore(newChild, list->GetNodeAt(mid)))
last = mid;
else
first = mid + 1;
}
list->InsertElementAt(newChild, first);
}
}

View File

@ -83,6 +83,7 @@ _TEST_FILES = test_bug589.html \
test_bug332893-4.html \
test_bug332893-5.html \
test_bug332893-6.html \
test_bug332893-7.html \
bug340800_iframe.txt \
test_bug340800.html \
test_bug353415-1.html \

View File

@ -18,13 +18,13 @@
form1.insertBefore(input2, input1);
is(form1.elements["input"].length, "3", "Form 1 'input' has the correct length");
todo(form1.elements["input"][0].value == "2", "Form 1 element 1 is correct");
todo(form1.elements["input"][1].value == "1", "Form 1 element 2 is correct");
todo(form1.elements["input"][2].value == "3", "Form 1 element 3 is correct");
is(form1.elements["input"][0].value, "2", "Form 1 element 1 is correct");
is(form1.elements["input"][1].value, "1", "Form 1 element 2 is correct");
is(form1.elements["input"][2].value, "3", "Form 1 element 3 is correct");
todo(form1.elements["input"][0].id == "input2", "Form 1 element 1 id is correct");
todo(form1.elements["input"][1].id == "input1", "Form 1 element 2 id is correct");
todo(form1.elements["input"][2].id == "input3", "Form 1 element 3 id is correct");
is(form1.elements["input"][0].id, "input2", "Form 1 element 1 id is correct");
is(form1.elements["input"][1].id, "input1", "Form 1 element 2 id is correct");
is(form1.elements["input"][2].id, "input3", "Form 1 element 3 id is correct");
</script>
</body>
</html>

View File

@ -18,13 +18,13 @@
form1.insertBefore(input2, input1);
is(form1.elements["input"].length, "3", "Form 1 'input' has the correct length");
todo(form1.elements["input"][0].value == "2", "Form 1 element 1 is correct");
todo(form1.elements["input"][1].value == "1", "Form 1 element 2 is correct");
todo(form1.elements["input"][2].value == "3", "Form 1 element 3 is correct");
is(form1.elements["input"][0].value, "2", "Form 1 element 1 is correct");
is(form1.elements["input"][1].value, "1", "Form 1 element 2 is correct");
is(form1.elements["input"][2].value, "3", "Form 1 element 3 is correct");
todo(form1.elements["input"][0].id == "input", "Form 1 element 1 id is correct");
todo(form1.elements["input"][1].id == "input1", "Form 1 element 2 id is correct");
todo(form1.elements["input"][2].id == "input3", "Form 1 element 3 id is correct");
is(form1.elements["input"][0].id, "input", "Form 1 element 1 id is correct");
is(form1.elements["input"][1].id, "input1", "Form 1 element 2 id is correct");
is(form1.elements["input"][2].id, "input3", "Form 1 element 3 id is correct");
</script>
</body>
</html>

View File

@ -18,11 +18,11 @@
form1.insertBefore(input2, input1);
is(form1.elements["input"].length, "3", "Form 1 'input' has the correct length");
todo(form1.elements["input"][0].value == "2", "Form 1 element 1 is correct");
todo(form1.elements["input"][1].value == "1", "Form 1 element 2 is correct");
is(form1.elements["input"][0].value, "2", "Form 1 element 1 is correct");
is(form1.elements["input"][1].value, "1", "Form 1 element 2 is correct");
todo(form1.elements["input"][0].id == "input", "Form 1 element 1 id is correct");
todo(form1.elements["input"][1].id == "input1", "Form 1 element 2 id is correct");
is(form1.elements["input"][0].id, "input", "Form 1 element 1 id is correct");
is(form1.elements["input"][1].id, "input1", "Form 1 element 2 id is correct");
</script>
</body>
</html>

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<form id="form1">
<input id="input1" type="input" name="input" value="1"/>
<input id="input2" type="input" name="input" value="2"/>
<input id="input3" type="input" name="input" value="3"/>
<input id="input4" type="input" name="input" value="4"/>
<input id="input5" type="input" name="input" value="5"/>
<input id="input6" type="input" name="input" value="6"/>
<input id="input7" type="input" name="input" value="7"/>
<input id="input8" type="input" name="input" value="8"/>
<input id="input9" type="input" name="input" value="9"/>
<input id="input10" type="input" name="input" value="10"/>
</form>
<script>
var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");
var input3 = document.getElementById("input3");
var input4 = document.getElementById("input4");
var input5 = document.getElementById("input5");
var input6 = document.getElementById("input6");
var input7 = document.getElementById("input7");
var input8 = document.getElementById("input8");
var input9 = document.getElementById("input9");
var input10 = document.getElementById("input10");
var form1 = document.getElementById("form1");
form1.insertBefore(input2, input1);
form1.insertBefore(input10, input6);
form1.insertBefore(input8, input4);
form1.insertBefore(input9, input2);
is(form1.elements["input"].length, "10", "Form 1 'input' has the correct length");
is(form1.elements["input"][0].value, "9", "Form 1 element 1 is correct");
is(form1.elements["input"][1].value, "2", "Form 1 element 2 is correct");
is(form1.elements["input"][2].value, "1", "Form 1 element 3 is correct");
is(form1.elements["input"][3].value, "3", "Form 1 element 4 is correct");
is(form1.elements["input"][4].value, "8", "Form 1 element 5 is correct");
is(form1.elements["input"][5].value, "4", "Form 1 element 6 is correct");
is(form1.elements["input"][6].value, "5", "Form 1 element 7 is correct");
is(form1.elements["input"][7].value, "10", "Form 1 element 8 is correct");
is(form1.elements["input"][8].value, "6", "Form 1 element 9 is correct");
is(form1.elements["input"][9].value, "7", "Form 1 element 10 is correct");
is(form1.elements["input"][0].id, "input9", "Form 1 element 1 id is correct");
is(form1.elements["input"][1].id, "input2", "Form 1 element 2 id is correct");
is(form1.elements["input"][2].id, "input1", "Form 1 element 3 id is correct");
is(form1.elements["input"][3].id, "input3", "Form 1 element 4 id is correct");
is(form1.elements["input"][4].id, "input8", "Form 1 element 5 id is correct");
is(form1.elements["input"][5].id, "input4", "Form 1 element 6 id is correct");
is(form1.elements["input"][6].id, "input5", "Form 1 element 7 id is correct");
is(form1.elements["input"][7].id, "input10", "Form 1 element 8 id is correct");
is(form1.elements["input"][8].id, "input6", "Form 1 element 9 id is correct");
is(form1.elements["input"][9].id, "input7", "Form 1 element 10 id is correct");
</script>
</body>
</html>