Closed
Bug 1366
Opened 26 years ago
Closed 26 years ago
valid removeChild crashes
Categories
(Core :: DOM: Core & HTML, defect, P1)
Tracking
()
VERIFIED
FIXED
People
(Reporter: buster, Assigned: joki)
References
()
Details
the problem seems to be that the remove is getting dispatched twice. It only
seems to happen when removing the last child in a container.
To see the crash, click on the "delete RG" button. There is a single row group,
and it is removed twice. You can verify this by setting a breakpoint in
nsGenericHTMLContainerElement::RemoveChild
==================== Test Case ==================
<HTML>
<HEAD>
<SCRIPT>
function insertCaption() {
var table = document.getElementsByTagName("TABLE")[0];
var caption = document.createElement("CAPTION", null);
var text = document.createTextNode("here is the new caption text\n");
caption.appendChild(text);
table.appendChild(caption);
}
function deleteCaption() {
var table = document.getElementsByTagName("TABLE")[0];
var caption = document.getElementsByTagName("CAPTION")[0];
table.removeChild(caption);
}
function changeCaptionStyle() {
var caption = document.getElementsByTagName("CAPTION")[0];
caption.align="bottom";
dump("SCRIPT: changed caption align to bottom\n");
}
function changeTableStyle() {
var table = document.getElementsByTagName("TABLE")[0];
table.width="600";
dump("SCRIPT: changed table width to 600\n");
}
function insertColGroup() {
var table = document.getElementsByTagName("TABLE")[0];
var refColGroup = document.getElementsByTagName("COLGROUP")[0];
var colGroup = document.createElement("COLGROUP", null);
colGroup.width=100;
colGroup.span=1;
table.insertBefore(colGroup, refColGroup);
dump("SCRIPT: inserted COLGROUP with span=1 width=200 as first colgroup in
table\n");
}
function appendColGroup() {
var table = document.getElementsByTagName("TABLE")[0];
var colGroup = document.createElement("COLGROUP", null);
colGroup.width=300;
colGroup.span=1;
table.appendChild(colGroup);
dump("SCRIPT: appended COLGROUP with span=1 width=300\n");
}
function deleteColGroup() {
var table = document.getElementsByTagName("TABLE")[0];
var colGroup = document.getElementsByTagName("COLGROUP")[0];
table.removeChild(colGroup);
dump("SCRIPT: deleted first COLGROUP\n");
}
function changeColGroupStyle() {
var colGroup = document.getElementsByTagName("COLGROUP")[0];
colGroup.width="200";
dump("SCRIPT: changed default width for first COLGROUP to 200\n");
}
function insertCol() {
var table = document.getElementsByTagName("TABLE")[0];
var refCol = table.getElementsByTagName("COL")[0];
var col = document.createElement("COL", null);
col.width=200;
col.span=1;
table.insertBefore(col, refCol);
dump("SCRIPT: inserted COL with span=1 width=200 as first col in first col
group\n");
}
function appendCol() {
var table = document.getElementsByTagName("TABLE")[0];
var col = document.createElement("COL", null);
table.appendChild(col);
dump("SCRIPT: appended COL with span=1 width=300\n");
}
function deleteCol() {
var table = document.getElementsByTagName("TABLE")[0];
var col = document.getElementsByTagName("COL")[0];
table.removeChild(col);
dump("SCRIPT: deleted first COL in first COLGROUP\n");
}
function changeColStyle() {
var col = document.getElementsByTagName("COL")[0];
col.width="200";
dump("SCRIPT: changed default width for first COL to 200\n");
}
function insertRowGroup() {
var table = document.getElementsByTagName("TABLE")[0];
var refRowGroup = document.getElementsByTagName("TBODY")[0];
var rowGroup = document.createElement("TBODY", null);
table.insertBefore(rowGroup, refRowGroup);
dump("SCRIPT: inserted empty ROWGROUP as first rowgroup in table\n");
}
function appendRowGroup() {
var table = document.getElementsByTagName("TABLE")[0];
var rowGroup = document.createElement("TBODY", null);
table.appendChild(rowGroup);
dump("SCRIPT: appended empty ROWGROUP\n");
}
function appendRowGroupWithContent() {
dump("\nSCRIPT: starting appendRowGroupWithContent\n");
var table = document.getElementsByTagName("TABLE")[0];
var rowGroup = document.createElement("TBODY", null);
var row = document.createElement("TR", null);
var cell = document.createElement("TD", null);
var text = document.createTextNode("here is content in the cell from the
script appendRowGroupWithContent\n");
cell.appendChild(text);
row.appendChild(cell);
rowGroup.appendChild(row);
table.appendChild(rowGroup);
dump("SCRIPT: appended ROWGROUP with 1 row and 1 cell\n");
}
function deleteRowGroup() {
var table = document.getElementsByTagName("TABLE")[0];
var rowGroup = document.getElementsByTagName("TBODY")[0];
table.removeChild(rowGroup);
dump("SCRIPT: deleted first ROWGROUP\n");
}
function changeRowGroupStyle() {
var rowGroup = document.getElementsByTagName("TBODY")[0];
rowGroup.align="right";
dump("SCRIPT: changed default align for first ROWGROUP to right\n");
}
function insertRow() {
var rg = document.getElementsByTagName("TBODY")[0];
var refRow = document.getElementsByTagName("TR")[0];
var row = document.createElement("TR", null);
rg.insertBefore(row, refRow);
dump("SCRIPT: inserted empty ROW as first row in first rowgroup in table\n");
}
function appendRow() {
var rg = document.getElementsByTagName("TBODY")[0];
var row = document.createElement("TR", null);
rg.appendChild(row);
dump("SCRIPT: appended empty ROW in first ROWGROUP\n");
}
function appendRowWithContent() {
dump("\nSCRIPT: starting appendRowWithContent\n");
var rg = document.getElementsByTagName("TBODY")[0];
var row = document.createElement("TR", null);
var cell = document.createElement("TD", null);
var text = document.createTextNode("x\n");
cell.appendChild(text);
row.appendChild(cell);
rg.appendChild(row);
dump("SCRIPT: appended ROW with 1 cell in first ROWGROUP\n");
}
function deleteRow() {
var rg = document.getElementsByTagName("TBODY")[0];
var row = document.getElementsByTagName("TR")[0];
rg.removeChild(row);
dump("SCRIPT: deleted first ROW in first ROWGROUP\n");
}
function changeRowStyle() {
var row = document.getElementsByTagName("TR")[0];
row.vAlign="top";
dump("SCRIPT: changed default align for first ROW to right\n");
}
function insertCell() {
var row = document.getElementsByTagName("TR")[0];
var refCell = document.getElementsByTagName("TD")[0];
var cell = document.createElement("TD", null);
var text = document.createTextNode("inserted Cell");
cell.colSpan=2;
cell.appendChild(text);
row.insertBefore(cell, refCell);
dump("SCRIPT: inserted CELL as first cell in first row\n");
}
function appendCell() {
var row = document.getElementsByTagName("TR")[0];
var cell = document.createElement("TD", null);
var text = document.createTextNode("appended Cell");
cell.appendChild(text);
row.appendChild(cell);
dump("SCRIPT: appended CELL in first ROW\n");
}
function deleteCell() {
var row = document.getElementsByTagName("TR")[0];
var cell = document.getElementsByTagName("TD")[0];
row.removeChild(cell);
dump("SCRIPT: deleted first CELL in first ROW\n");
}
function changeCellStyle() {
var cell = document.getElementsByTagName("TD")[0];
cell.width=400;
dump("SCRIPT: changed width for first CELL to 400\n");
}
function AddALot() {
dump("\nSCRIPT: starting AddALot\n");
var table = document.getElementsByTagName("TABLE")[0];
var rowGroup = document.createElement("TBODY", null);
var row = document.createElement("TR", null);
var row1 = document.createElement("TR", null);
var cell1 = document.createElement("TD", null);
var cell2 = document.createElement("TD", null);
var cell3 = document.createElement("TD", null);
var cell4 = document.createElement("TD", null);
var text1 = document.createTextNode("cell1\n");
var text2 = document.createTextNode("cell2\n");
var text3 = document.createTextNode("cell3 has the most content, and will be
the tallest cell in the row\n");
var text4 = document.createTextNode("cell4\n");
cell1.appendChild(text1); cell2.appendChild(text2);
cell3.appendChild(text3); cell4.appendChild(text4);
row.appendChild(cell3); row.appendChild(cell4);
row.insertBefore(cell2, cell3); row.insertBefore(cell1, cell2);
row1.appendChild(cell2); row1.appendChild(cell1);
row1.insertBefore(cell3, cell2); row1.insertBefore(cell4, cell3);
rowGroup.appendChild(row);
rowGroup.appendChild(row);
rowGroup.appendChild(row1);
rowGroup.appendChild(row1);
table.appendChild(rowGroup);
dump("SCRIPT: finished adding\n");
}
</SCRIPT>
</HEAD>
<BODY>
delete removes the first object of [type].
<table width=150 border>
<tbody>
<tr>
<td>cell content</td>
</tr>
</tbody>
</table>
<p>
<form>
<INPUT TYPE="button" NAME="Ins Caption" VALUE="InsertCaption"
onClick="insertCaption()" width=100>
<INPUT TYPE="button" NAME="Del Caption" VALUE="DeleteCaption"
onClick="deleteCaption()" width=100>
<br>
<INPUT TYPE="button" NAME="Ins ColGroup" VALUE="InsertCG"
onClick="insertColGroup()" width=100>
<INPUT TYPE="button" NAME="App ColGroup" VALUE="AppendCG"
onClick="appendColGroup()" width=100>
<INPUT TYPE="button" NAME="Del ColGroup" VALUE="DeleteCG"
onClick="deleteColGroup()" width=100>
<br>
<INPUT TYPE="button" NAME="Ins Col" VALUE="InsertCol" onClick="insertCol()"
width=100>
<INPUT TYPE="button" NAME="App Col" VALUE="AppendCol" onClick="appendCol()"
width=100>
<INPUT TYPE="button" NAME="Del Col" VALUE="DeleteCol" onClick="deleteCol()"
width=100>
<br>
<INPUT TYPE="button" NAME="Ins RowGroup" VALUE="InsertRG"
onClick="insertRowGroup()" width=100>
<INPUT TYPE="button" NAME="App RowGroup" VALUE="AppendRG"
onClick="appendRowGroup()" width=100>
<INPUT TYPE="button" NAME="Del RowGroup" VALUE="DeleteRG"
onClick="deleteRowGroup()" width=100>
<INPUT TYPE="button" NAME="App RowGroup with content" VALUE="AppendRG with
content" onClick="appendRowGroupWithContent()" width=100>
<br>
<INPUT TYPE="button" NAME="Ins Row" VALUE="InsertRow" onClick="insertRow()"
width=100>
<INPUT TYPE="button" NAME="App Row" VALUE="AppendRow" onClick="appendRow()"
width=100>
<INPUT TYPE="button" NAME="Del Row" VALUE="DeleteRow" onClick="deleteRow()"
width=100>
<INPUT TYPE="button" NAME="App Row with content" VALUE="AppendRow with content"
onClick="appendRowWithContent()" width=100>
<br>
<INPUT TYPE="button" NAME="Ins Cell" VALUE="InsertCell" onClick="insertCell()"
width=100>
<INPUT TYPE="button" NAME="App Cell" VALUE="AppendCell" onClick="appendCell()"
width=100>
<INPUT TYPE="button" NAME="Del Cell" VALUE="DeleteCell" onClick="deleteCell()"
width=100>
<br>
<INPUT TYPE="button" NAME="Add a lot" VALUE="AddALot" onClick="AddALot()"
width=100>
<br>
<INPUT TYPE="button" NAME="Change Table Style" VALUE="ChangeTableStyle"
onClick="changeTableStyle()" width=100>
<INPUT TYPE="button" NAME="Change Caption Style" VALUE="ChangeCaptionStyle"
onClick="changeCaptionStyle()" width=100>
<INPUT TYPE="button" NAME="Change ColGroup Style" VALUE="ChangeColGroupStyle"
onClick="changeColGroupStyle()" width=100>
<INPUT TYPE="button" NAME="Change Col Style" VALUE="ChangeColStyle"
onClick="changeColStyle()" width=100>
<INPUT TYPE="button" NAME="Change RowGroup Style" VALUE="ChangeRowGroupStyle"
onClick="changeRowGroupStyle()" width=100>
<INPUT TYPE="button" NAME="Change Row Style" VALUE="ChangeRowStyle"
onClick="changeRowStyle()" width=100>
<INPUT TYPE="button" NAME="Change Cell Style" VALUE="ChangeCellStyle"
onClick="changeCellStyle()" width=100>
</form>
</BODY></HTML>
Assignee | ||
Updated•26 years ago
|
Status: NEW → RESOLVED
Closed: 26 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 1•26 years ago
|
||
Okay. Well I fixed a bug today that dealt with the double firing of the click.
But I went back and tried this on the pre-fix code and, though the click fired
twice, I didn't crash. So maybe Kipp's removeChild fix caught that and the
second click was incidental. Regardless, I'm marking this fixed.
Updated•26 years ago
|
QA Contact: 3829
Comment 2•26 years ago
|
||
Steve -- can you verify this? thanks
Comment 3•26 years ago
|
||
When I select the DeleteRG button, there is a JavaScript error reported:
JavaScript error: deleteRowGroup is not defined
URL :(null), LineNo :0
Line text: (null), Error text: (null)
used 2/03/99 build on win95 -- it does not crash. Should this be written up as a
new bug or is this an acceptable statement?
Sounds like the DOM is more broken then when this bug was submitted. Joki
should look into it.
Comment 5•26 years ago
|
||
The test works. When you copied the test out of the bug report, some of the
lines wrapped incorrectly. Specifically, new lines are statement terminators in
JavaScript and some of the strings were split across lines. Fixing this will fix
the test. BTW, I caught this by looking at the console window after the document
had loaded in. Script processing stopped for the main SCRIPT block after the
following error:
JavaScript error: unterminated string literal
URL :file://C:/TEMP/tabletest.html, LineNo :40
Line text: ' dump("SCRIPT: inserted COLGROUP with span=1 width=200 as first col
group in ', Error text: '"SCRIPT: inserted COLGROUP with span=1 width=200 as fir
st colgroup in '
Updated•26 years ago
|
Status: RESOLVED → VERIFIED
QA Contact: 3829 → 3849
Comment 6•26 years ago
|
||
recopied test, reviewed all line breaks (thanks Vidur), works perfectly, tested
on ein95 - 2/8/99 build.
Comment 7•18 years ago
|
||
RCS file: /cvsroot/mozilla/testing/mochitest/tests/test_bug1366.html,v
done
Checking in test_bug1366.html;
/cvsroot/mozilla/testing/mochitest/tests/test_bug1366.html,v <-- test_bug1366.html
initial revision: 1.1
done
Flags: in-testsuite+
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•