WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Jan 2008 01:25:51 +0000 (01:25 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Jan 2008 01:25:51 +0000 (01:25 +0000)
        Reviewed by Maciej.

        - fix http://bugs.webkit.org/show_bug.cgi?id=16657
          Acid3 failure since table.caption and table.thead do not work for nodes added by appendChild
        - fix http://bugs.webkit.org/show_bug.cgi?id=16659
          Acid3 expects HTMLTableElement.rows to include a <tr> element that is an immediate child of the <table>

        Tests: dom/html/level2/html/HTMLCollection07.html
               dom/html/level2/html/HTMLCollection08.html
               dom/html/level2/xhtml/HTMLCollection07.xhtml
               dom/html/level2/xhtml/HTMLCollection08.xhtml
               fast/dom/HTMLTableElement/early-acid3-65-excerpt.html
               fast/dom/HTMLTableElement/early-acid3-66-excerpt.html

        * GNUmakefile.am: Added HTMLTableRowsCollection.
        * WebCore.pro: Ditto.
        * WebCore.vcproj/WebCore.vcproj: Ditto.
        * WebCore.xcodeproj/project.pbxproj: Ditto.
        * WebCoreSources.bkl: Ditto.

        * dom/XMLTokenizer.cpp: Took out stray include.

        * html/HTMLCollection.cpp:
        (WebCore::HTMLCollection::itemAfter): Removed all the table rows code, since we now use
        a separate class for that collection. Also got rid of the distinct types for custom collections
        that don't need them (use Other for both).
        * html/HTMLCollection.h: Also made firstItem non-virtual because it doesn't need to be virtual.

        * html/HTMLFormCollection.cpp:
        (WebCore::HTMLFormCollection::HTMLFormCollection): Use Other instead of FormElements
        for the HTMLCollection type.

        * html/HTMLTableElement.cpp:
        (WebCore::HTMLTableElement::HTMLTableElement): Eliminated m_head, m_foot, m_firstBody, and m_caption.
        (WebCore::HTMLTableElement::caption): Added non-inline version. Finds the caption rather than
        keeping a pointer to it.
        (WebCore::HTMLTableElement::setCaption): Rewrote.
        (WebCore::HTMLTableElement::tHead): Ditto.
        (WebCore::HTMLTableElement::setTHead): Ditto.
        (WebCore::HTMLTableElement::tFoot): Ditto.
        (WebCore::HTMLTableElement::setTFoot): Ditto.
        (WebCore::HTMLTableElement::createTHead): Ditto.
        (WebCore::HTMLTableElement::deleteTHead): Ditto.
        (WebCore::HTMLTableElement::createTFoot): Ditto.
        (WebCore::HTMLTableElement::deleteTFoot): Ditto.
        (WebCore::HTMLTableElement::createCaption): Ditto.
        (WebCore::HTMLTableElement::deleteCaption): Ditto.
        (WebCore::HTMLTableElement::lastBody): Added.
        (WebCore::HTMLTableElement::insertRow): Rewrote to use a loop based on code in HTMLTableRowsCollection.
        This is different from the old code mainly in how it handles rows outside any section.
        (WebCore::HTMLTableElement::deleteRow): Ditto.
        (WebCore::HTMLTableElement::addChild): Removed code to set the various members. Keeping pointers to
        these was a possible source of serious bugs too, including crashes with stale pointers, although I
        didn't write any test cases to prove those bugs existed.
        (WebCore::HTMLTableElement::parseMappedAttribute): Changed the rules code to visit all cells, not
        just the cells of the first body. I believe this fixed rendering on some table tests. I think the code
        visits too many cells and also the use of recursion is overkill, but I didn't try to fix that.
        (WebCore::HTMLTableElement::rows): Changed to use the new HTMLTableRowsCollection.
        * html/HTMLTableElement.h: Changed functions to return PassRefPtr, which can be important if strange
        things like DOM mutation events take things ot of the tree before they are safely referenced by
        JavaScript wrappers. Also changed functions to take PassRefPtr and added exceptions. Removed unneeded
        firstTBody and setTBody functions and childrenChanged function override, as well as unused Rules and
        Frame enums. Removed m_head, m_foot, m_firstBody, and m_caption, and added lastBody function. Removed
        unneeded friend declaration for HTMLTableCellElement.
        * html/HTMLTableElement.idl: Allow the setteres for caption, tHead, and tFoot to raise exceptions.

        * html/HTMLTableRowsCollection.cpp: Added. Implements the HTML 5 rule for which rows are in the
        collection in which order.
        * html/HTMLTableRowsCollection.h: Added.

        * loader/FTPDirectoryDocument.cpp:
        (WebCore::FTPDirectoryTokenizer::appendEntry): Use the standard insertRow function instead of
        coming up with our own way of inserting a row. Simplifies things -- we can remove the code to
        create a tbody element.

LayoutTests:

        Reviewed by Maciej.

        - test for http://bugs.webkit.org/show_bug.cgi?id=16657
          Acid3 failure since table.caption and table.thead do not work for nodes added by appendChild
        - test for http://bugs.webkit.org/show_bug.cgi?id=16659
          Acid3 expects HTMLTableElement.rows to include a <tr> element that is an immediate child of the <table>

        * fast/dom/HTMLTableElement/early-acid3-65-excerpt-expected.txt: Added.
        * fast/dom/HTMLTableElement/early-acid3-65-excerpt.html: Added.
        * fast/dom/HTMLTableElement/early-acid3-66-excerpt-expected.txt: Added.
        * fast/dom/HTMLTableElement/early-acid3-66-excerpt.html: Added.
        * fast/dom/HTMLTableElement/resources/early-acid3-65-excerpt.js: Added.
        * fast/dom/HTMLTableElement/resources/early-acid3-66-excerpt.js: Added.

        * dom/html/level2/html/HTMLCollection07-expected.txt: Updated to reflect success.
        * dom/html/level2/html/HTMLCollection08-expected.txt: Updated to reflect success.
        * dom/xhtml/level2/html/HTMLCollection07-expected.txt: Updated to reflect success.
        * dom/xhtml/level2/html/HTMLCollection08-expected.txt: Updated to reflect success.

        * fast/dom/HTMLTableElement/resources/rows.js: Changed to expect HTML 5 behavior for rows outside
        table sections.
        * fast/dom/HTMLTableElement/rows-expected.txt: Updated.

        * platform/mac/tables/mozilla/bugs/bug30418-expected.checksum: Updated to reflect better results.
        * platform/mac/tables/mozilla/bugs/bug30418-expected.png: Ditto.
        * platform/mac/tables/mozilla/bugs/bug30418-expected.txt: Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@29101 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
LayoutTests/ChangeLog
LayoutTests/dom/html/level2/html/HTMLCollection07-expected.txt
LayoutTests/dom/html/level2/html/HTMLCollection08-expected.txt
LayoutTests/dom/xhtml/level2/html/HTMLCollection07-expected.txt
LayoutTests/dom/xhtml/level2/html/HTMLCollection08-expected.txt
LayoutTests/fast/dom/HTMLTableElement/early-acid3-65-excerpt-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTableElement/early-acid3-65-excerpt.html [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTableElement/early-acid3-66-excerpt-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTableElement/early-acid3-66-excerpt.html [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTableElement/resources/early-acid3-65-excerpt.js [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTableElement/resources/early-acid3-66-excerpt.js [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTableElement/resources/rows.js
LayoutTests/fast/dom/HTMLTableElement/rows-expected.txt
LayoutTests/platform/mac/tables/mozilla/bugs/bug30418-expected.checksum
LayoutTests/platform/mac/tables/mozilla/bugs/bug30418-expected.png
LayoutTests/platform/mac/tables/mozilla/bugs/bug30418-expected.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/dom/XMLTokenizer.cpp
WebCore/html/HTMLCollection.cpp
WebCore/html/HTMLCollection.h
WebCore/html/HTMLFormCollection.cpp
WebCore/html/HTMLTableElement.cpp
WebCore/html/HTMLTableElement.h
WebCore/html/HTMLTableElement.idl
WebCore/html/HTMLTableRowsCollection.cpp [new file with mode: 0644]
WebCore/html/HTMLTableRowsCollection.h [new file with mode: 0644]
WebCore/loader/FTPDirectoryDocument.cpp

index d5b7949..280ef1e 100644 (file)
@@ -1,3 +1,32 @@
+2008-01-02  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - test for http://bugs.webkit.org/show_bug.cgi?id=16657
+          Acid3 failure since table.caption and table.thead do not work for nodes added by appendChild
+        - test for http://bugs.webkit.org/show_bug.cgi?id=16659
+          Acid3 expects HTMLTableElement.rows to include a <tr> element that is an immediate child of the <table>
+
+        * fast/dom/HTMLTableElement/early-acid3-65-excerpt-expected.txt: Added.
+        * fast/dom/HTMLTableElement/early-acid3-65-excerpt.html: Added.
+        * fast/dom/HTMLTableElement/early-acid3-66-excerpt-expected.txt: Added.
+        * fast/dom/HTMLTableElement/early-acid3-66-excerpt.html: Added.
+        * fast/dom/HTMLTableElement/resources/early-acid3-65-excerpt.js: Added.
+        * fast/dom/HTMLTableElement/resources/early-acid3-66-excerpt.js: Added.
+
+        * dom/html/level2/html/HTMLCollection07-expected.txt: Updated to reflect success.
+        * dom/html/level2/html/HTMLCollection08-expected.txt: Updated to reflect success.
+        * dom/xhtml/level2/html/HTMLCollection07-expected.txt: Updated to reflect success.
+        * dom/xhtml/level2/html/HTMLCollection08-expected.txt: Updated to reflect success.
+
+        * fast/dom/HTMLTableElement/resources/rows.js: Changed to expect HTML 5 behavior for rows outside
+        table sections.
+        * fast/dom/HTMLTableElement/rows-expected.txt: Updated.
+
+        * platform/mac/tables/mozilla/bugs/bug30418-expected.checksum: Updated to reflect better results.
+        * platform/mac/tables/mozilla/bugs/bug30418-expected.png: Ditto.
+        * platform/mac/tables/mozilla/bugs/bug30418-expected.txt: Ditto.
+
 2008-01-02  Alice Liu  <alice.liu@apple.com>
 
         Reviewed by Maciej.
index ff86194..8674304 100644 (file)
@@ -1,3 +1,2 @@
-Test:  http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLCollection07      
-Status:        failure
-Detail:        rowIndexLink: assertEquals failed, actual 2, expected 3.
+Test:  http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLCollection07
+Status:        Success
index ec88f4e..6a729b3 100644 (file)
@@ -1,3 +1,2 @@
-Test:  http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLCollection08      
-Status:        failure
-Detail:        rowIndexLink: assertEquals failed, actual 1, expected 2.
+Test:  http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLCollection08
+Status:        Success
index aa6bc15..0291bf7 100644 (file)
@@ -1,3 +1,2 @@
 Test   http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLCollection07
-Status failure
-Message        rowIndexLink: assertEquals failed, actual 2, expected 3.
+Status Success
index 59eedbe..1bdf45b 100644 (file)
@@ -1,3 +1,2 @@
 Test   http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLCollection08
-Status failure
-Message        rowIndexLink: assertEquals failed, actual 1, expected 2.
+Status Success
diff --git a/LayoutTests/fast/dom/HTMLTableElement/early-acid3-65-excerpt-expected.txt b/LayoutTests/fast/dom/HTMLTableElement/early-acid3-65-excerpt-expected.txt
new file mode 100644 (file)
index 0000000..df9c958
--- /dev/null
@@ -0,0 +1,25 @@
+An excerpt from an early Acid3 test 65: construct a table, and see if the table is as expected
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS table.tBodies[0].rows[0].rowIndex is 0
+PASS table.tBodies[0].rows[0].sectionRowIndex is 0
+PASS table.childNodes.length is 3
+PASS !!table.caption is true
+PASS !!table.tHead is true
+PASS table.tFoot is null
+PASS table.tBodies.length is 1
+PASS table.rows.length is 1
+PASS tr1.parentNode is null
+PASS table.caption is table.createCaption()
+PASS table.tFoot is null
+PASS table.tHead is table.createTHead()
+PASS table.createTFoot() is table.tFoot
+PASS table.rows[0] is table.tHead.firstChild
+PASS table.rows.length is 2
+PASS table.rows[1] is table.tBodies[0].firstChild
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/HTMLTableElement/early-acid3-65-excerpt.html b/LayoutTests/fast/dom/HTMLTableElement/early-acid3-65-excerpt.html
new file mode 100644 (file)
index 0000000..4a2a11d
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/early-acid3-65-excerpt.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/HTMLTableElement/early-acid3-66-excerpt-expected.txt b/LayoutTests/fast/dom/HTMLTableElement/early-acid3-66-excerpt-expected.txt
new file mode 100644 (file)
index 0000000..559a432
--- /dev/null
@@ -0,0 +1,26 @@
+An excerpt from an early Acid3 test 66: test the ordering and creation of rows
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS table.rows.length is 6
+PASS table.getElementsByTagName('tr').length is 6
+PASS table.childNodes.length is 3
+PASS table.tHead is table.childNodes[0]
+PASS table.tHead.childNodes[0] is table.getElementsByTagName('tr')[0]
+PASS table.tHead.childNodes[1] is table.getElementsByTagName('tr')[1]
+PASS rows[2] is table.getElementsByTagName('tr')[1]
+PASS table.tHead.childNodes[2] is table.getElementsByTagName('tr')[2]
+PASS rows[3] is table.getElementsByTagName('tr')[2]
+PASS table.tFoot is table.childNodes[1]
+PASS table.tFoot.childNodes[0] is table.getElementsByTagName('tr')[3]
+PASS rows[0] is table.getElementsByTagName('tr')[3]
+PASS table.tFoot.childNodes[1] is table.getElementsByTagName('tr')[4]
+PASS rows[6] is table.getElementsByTagName('tr')[4]
+PASS table.childNodes[2] is table.getElementsByTagName('tr')[5]
+PASS rows[1] is table.getElementsByTagName('tr')[5]
+PASS table.tBodies.length is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/HTMLTableElement/early-acid3-66-excerpt.html b/LayoutTests/fast/dom/HTMLTableElement/early-acid3-66-excerpt.html
new file mode 100644 (file)
index 0000000..365aa08
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/early-acid3-66-excerpt.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/HTMLTableElement/resources/early-acid3-65-excerpt.js b/LayoutTests/fast/dom/HTMLTableElement/resources/early-acid3-65-excerpt.js
new file mode 100644 (file)
index 0000000..eb05dc0
--- /dev/null
@@ -0,0 +1,38 @@
+description('An excerpt from an early Acid3 test 65: construct a table, and see if the table is as expected');
+
+var table = document.createElement('table');
+table.appendChild(document.createElement('tbody'));
+var tr1 = document.createElement('tr');
+table.appendChild(tr1);
+table.appendChild(document.createElement('caption'));
+table.appendChild(document.createElement('thead'));
+// <table><tbody/><tr/><caption/><thead/>
+table.insertBefore(table.firstChild.nextSibling, null); // move the <tr/> to the end
+// <table><tbody/><caption/><thead/><tr/>
+table.replaceChild(table.firstChild, table.lastChild); // move the <tbody/> to the end and remove the <tr>
+// <table><caption/><thead/><tbody/>
+var tr2 = table.tBodies[0].insertRow(0);
+// <table><caption/><thead/><tbody><tr/></tbody>
+shouldBe("table.tBodies[0].rows[0].rowIndex", "0");
+shouldBe("table.tBodies[0].rows[0].sectionRowIndex", "0");
+shouldBe("table.childNodes.length", "3");
+shouldBe("!!table.caption", "true");
+shouldBe("!!table.tHead", "true");
+shouldBe("table.tFoot", "null");
+shouldBe("table.tBodies.length", "1");
+shouldBe("table.rows.length", "1");
+shouldBe("tr1.parentNode", "null");
+shouldBe("table.caption", "table.createCaption()");
+shouldBe("table.tFoot", "null");
+shouldBe("table.tHead", "table.createTHead()");
+shouldBe("table.createTFoot()", "table.tFoot");
+// either: <table><caption/><thead/><tbody><tr/></tbody><tfoot/>
+//     or: <table><caption/><thead/><tfoot/><tbody><tr/></tbody>
+table.tHead.appendChild(tr1);
+// either: <table><caption/><thead><tr/></thead><tbody><tr/></tbody><tfoot/>
+//     or: <table><caption/><thead><tr/></thead><tfoot/><tbody><tr/></tbody>
+shouldBe("table.rows[0]", "table.tHead.firstChild");
+shouldBe("table.rows.length", "2");
+shouldBe("table.rows[1]", "table.tBodies[0].firstChild");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/HTMLTableElement/resources/early-acid3-66-excerpt.js b/LayoutTests/fast/dom/HTMLTableElement/resources/early-acid3-66-excerpt.js
new file mode 100644 (file)
index 0000000..65c126e
--- /dev/null
@@ -0,0 +1,40 @@
+description('An excerpt from an early Acid3 test 66: test the ordering and creation of rows');
+
+var table = document.createElement('table');
+var rows = [
+    document.createElement('tr'),    // 0: ends up first child of the tfoot
+    document.createElement('tr'),    // 1: goes at the end of the table
+    document.createElement('tr'),    // 2: becomes second child of thead
+    document.createElement('tr'),    // 3: becomes third child of the thead
+    document.createElement('tr'),    // 4: not in the table
+    table.insertRow(0),              // 5: not in the table
+    table.createTFoot().insertRow(0) // 6: ends up second in the tfoot
+];
+rows[6].parentNode.appendChild(rows[0]);
+table.appendChild(rows[1]);
+table.insertBefore(document.createElement('thead'), table.firstChild);
+table.firstChild.appendChild(rows[2]);
+rows[2].parentNode.appendChild(rows[3]);
+rows[4].appendChild(rows[5].parentNode);
+table.insertRow(0);
+table.tFoot.appendChild(rows[6]);
+
+shouldBe("table.rows.length", "6");
+shouldBe("table.getElementsByTagName('tr').length", "6");
+shouldBe("table.childNodes.length", "3");
+shouldBe("table.tHead", "table.childNodes[0]");
+shouldBe("table.tHead.childNodes[0]", "table.getElementsByTagName('tr')[0]");
+shouldBe("table.tHead.childNodes[1]", "table.getElementsByTagName('tr')[1]");
+shouldBe("rows[2]", "table.getElementsByTagName('tr')[1]");
+shouldBe("table.tHead.childNodes[2]", "table.getElementsByTagName('tr')[2]");
+shouldBe("rows[3]", "table.getElementsByTagName('tr')[2]");
+shouldBe("table.tFoot", "table.childNodes[1]");
+shouldBe("table.tFoot.childNodes[0]", "table.getElementsByTagName('tr')[3]");
+shouldBe("rows[0]", "table.getElementsByTagName('tr')[3]");
+shouldBe("table.tFoot.childNodes[1]", "table.getElementsByTagName('tr')[4]");
+shouldBe("rows[6]", "table.getElementsByTagName('tr')[4]");
+shouldBe("table.childNodes[2]", "table.getElementsByTagName('tr')[5]");
+shouldBe("rows[1]", "table.getElementsByTagName('tr')[5]");
+shouldBe("table.tBodies.length", "0");
+
+var successfullyParsed = true;
index fe164c5..c7e10c4 100644 (file)
@@ -63,7 +63,7 @@ for (i = 0; i < sectionTags.length; ++i)
 
 debug('');
 
-shouldBe('checkNoBodyRowNesting("tr")', '0');
+shouldBe('checkNoBodyRowNesting("tr")', '1');
 
 debug('');
 
index 84e2a6c..04946c5 100644 (file)
@@ -31,7 +31,7 @@ PASS checkNoBodyRowNesting("tbody") is 1
 PASS checkNoBodyRowNesting("tfoot") is 1
 PASS checkNoBodyRowNesting("thead") is 1
 
-PASS checkNoBodyRowNesting("tr") is 0
+PASS checkNoBodyRowNesting("tr") is 1
 
 PASS successfullyParsed is true
 
index eeb9ad5..7ea9903 100644 (file)
Binary files a/LayoutTests/platform/mac/tables/mozilla/bugs/bug30418-expected.png and b/LayoutTests/platform/mac/tables/mozilla/bugs/bug30418-expected.png differ
index 503ceb4..a4b2bf4 100644 (file)
@@ -1,84 +1,84 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x96
-  RenderBlock {HTML} at (0,0) size 800x96
-    RenderBody {BODY} at (8,8) size 784x80
-      RenderTable {TABLE} at (0,0) size 266x80 [border: (4px outset #808080)]
-        RenderTableSection {TBODY} at (4,28) size 258x24
-          RenderTableRow {TR} at (0,2) size 258x20
-            RenderTableCell {TD} at (2,2) size 30x20 [r=0 c=0 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c0"
-            RenderTableCell {TD} at (34,2) size 30x20 [r=0 c=1 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c1"
-            RenderTableCell {TD} at (66,2) size 30x20 [r=0 c=2 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c2"
-            RenderTableCell {TD} at (98,2) size 30x20 [r=0 c=3 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c3"
-            RenderTableCell {TD} at (130,2) size 30x20 [r=0 c=4 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c4"
-            RenderTableCell {TD} at (162,2) size 30x20 [r=0 c=5 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c5"
-            RenderTableCell {TD} at (194,2) size 30x20 [r=0 c=6 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c6"
-            RenderTableCell {TD} at (226,2) size 30x20 [r=0 c=7 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 28x18
-                text run at (1,1) width 28: "r0c7"
-        RenderTableSection {THEAD} at (4,4) size 258x24
-          RenderTableRow {TR} at (0,2) size 258x20
-            RenderTableCell {TD} at (2,2) size 30x20 [r=0 c=0 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h0"
-            RenderTableCell {TD} at (34,2) size 30x20 [r=0 c=1 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h1"
-            RenderTableCell {TD} at (66,2) size 30x20 [r=0 c=2 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h2"
-            RenderTableCell {TD} at (98,2) size 30x20 [r=0 c=3 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h3"
-            RenderTableCell {TD} at (130,2) size 30x20 [r=0 c=4 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h4"
-            RenderTableCell {TD} at (162,2) size 30x20 [r=0 c=5 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h5"
-            RenderTableCell {TD} at (194,2) size 30x20 [r=0 c=6 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h6"
-            RenderTableCell {TD} at (226,2) size 30x20 [r=0 c=7 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 16x18
-                text run at (1,1) width 16: "h7"
-        RenderTableSection {TFOOT} at (4,52) size 258x24
-          RenderTableRow {TR} at (0,2) size 258x20
-            RenderTableCell {TD} at (2,2) size 30x20 [r=0 c=0 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f0"
-            RenderTableCell {TD} at (34,2) size 30x20 [r=0 c=1 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f1"
-            RenderTableCell {TD} at (66,2) size 30x20 [r=0 c=2 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f2"
-            RenderTableCell {TD} at (98,2) size 30x20 [r=0 c=3 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f3"
-            RenderTableCell {TD} at (130,2) size 30x20 [r=0 c=4 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f4"
-            RenderTableCell {TD} at (162,2) size 30x20 [r=0 c=5 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f5"
-            RenderTableCell {TD} at (194,2) size 30x20 [r=0 c=6 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f6"
-            RenderTableCell {TD} at (226,2) size 30x20 [r=0 c=7 rs=1 cs=1]
-              RenderText {#text} at (1,1) size 13x18
-                text run at (1,1) width 13: "f7"
+layer at (0,0) size 800x102
+  RenderBlock {HTML} at (0,0) size 800x102
+    RenderBody {BODY} at (8,8) size 784x86
+      RenderTable {TABLE} at (0,0) size 282x86 [border: (4px outset #808080)]
+        RenderTableSection {THEAD} at (4,4) size 274x26
+          RenderTableRow {TR} at (0,2) size 274x22
+            RenderTableCell {TD} at (2,2) size 32x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h0"
+            RenderTableCell {TD} at (36,2) size 32x22 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h1"
+            RenderTableCell {TD} at (70,2) size 32x22 [border: (1px inset #808080)] [r=0 c=2 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h2"
+            RenderTableCell {TD} at (104,2) size 32x22 [border: (1px inset #808080)] [r=0 c=3 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h3"
+            RenderTableCell {TD} at (138,2) size 32x22 [border: (1px inset #808080)] [r=0 c=4 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h4"
+            RenderTableCell {TD} at (172,2) size 32x22 [border: (1px inset #808080)] [r=0 c=5 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h5"
+            RenderTableCell {TD} at (206,2) size 32x22 [border: (1px inset #808080)] [r=0 c=6 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h6"
+            RenderTableCell {TD} at (240,2) size 32x22 [border: (1px inset #808080)] [r=0 c=7 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 16x18
+                text run at (2,2) width 16: "h7"
+        RenderTableSection {TFOOT} at (4,56) size 274x26
+          RenderTableRow {TR} at (0,2) size 274x22
+            RenderTableCell {TD} at (2,2) size 32x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f0"
+            RenderTableCell {TD} at (36,2) size 32x22 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f1"
+            RenderTableCell {TD} at (70,2) size 32x22 [border: (1px inset #808080)] [r=0 c=2 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f2"
+            RenderTableCell {TD} at (104,2) size 32x22 [border: (1px inset #808080)] [r=0 c=3 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f3"
+            RenderTableCell {TD} at (138,2) size 32x22 [border: (1px inset #808080)] [r=0 c=4 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f4"
+            RenderTableCell {TD} at (172,2) size 32x22 [border: (1px inset #808080)] [r=0 c=5 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f5"
+            RenderTableCell {TD} at (206,2) size 32x22 [border: (1px inset #808080)] [r=0 c=6 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f6"
+            RenderTableCell {TD} at (240,2) size 32x22 [border: (1px inset #808080)] [r=0 c=7 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 13x18
+                text run at (2,2) width 13: "f7"
+        RenderTableSection {TBODY} at (4,30) size 274x26
+          RenderTableRow {TR} at (0,2) size 274x22
+            RenderTableCell {TD} at (2,2) size 32x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c0"
+            RenderTableCell {TD} at (36,2) size 32x22 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c1"
+            RenderTableCell {TD} at (70,2) size 32x22 [border: (1px inset #808080)] [r=0 c=2 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c2"
+            RenderTableCell {TD} at (104,2) size 32x22 [border: (1px inset #808080)] [r=0 c=3 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c3"
+            RenderTableCell {TD} at (138,2) size 32x22 [border: (1px inset #808080)] [r=0 c=4 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c4"
+            RenderTableCell {TD} at (172,2) size 32x22 [border: (1px inset #808080)] [r=0 c=5 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c5"
+            RenderTableCell {TD} at (206,2) size 32x22 [border: (1px inset #808080)] [r=0 c=6 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c6"
+            RenderTableCell {TD} at (240,2) size 32x22 [border: (1px inset #808080)] [r=0 c=7 rs=1 cs=1]
+              RenderText {#text} at (2,2) size 28x18
+                text run at (2,2) width 28: "r0c7"
index d8208db..957cd87 100644 (file)
@@ -1,5 +1,82 @@
 2008-01-02  Darin Adler  <darin@apple.com>
 
+        Reviewed by Maciej.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=16657
+          Acid3 failure since table.caption and table.thead do not work for nodes added by appendChild
+        - fix http://bugs.webkit.org/show_bug.cgi?id=16659
+          Acid3 expects HTMLTableElement.rows to include a <tr> element that is an immediate child of the <table>
+
+        Tests: dom/html/level2/html/HTMLCollection07.html
+               dom/html/level2/html/HTMLCollection08.html
+               dom/html/level2/xhtml/HTMLCollection07.xhtml
+               dom/html/level2/xhtml/HTMLCollection08.xhtml
+               fast/dom/HTMLTableElement/early-acid3-65-excerpt.html
+               fast/dom/HTMLTableElement/early-acid3-66-excerpt.html
+
+        * GNUmakefile.am: Added HTMLTableRowsCollection.
+        * WebCore.pro: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * WebCoreSources.bkl: Ditto.
+
+        * dom/XMLTokenizer.cpp: Took out stray include.
+
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::itemAfter): Removed all the table rows code, since we now use
+        a separate class for that collection. Also got rid of the distinct types for custom collections
+        that don't need them (use Other for both).
+        * html/HTMLCollection.h: Also made firstItem non-virtual because it doesn't need to be virtual.
+
+        * html/HTMLFormCollection.cpp:
+        (WebCore::HTMLFormCollection::HTMLFormCollection): Use Other instead of FormElements
+        for the HTMLCollection type.
+
+        * html/HTMLTableElement.cpp:
+        (WebCore::HTMLTableElement::HTMLTableElement): Eliminated m_head, m_foot, m_firstBody, and m_caption.
+        (WebCore::HTMLTableElement::caption): Added non-inline version. Finds the caption rather than
+        keeping a pointer to it.
+        (WebCore::HTMLTableElement::setCaption): Rewrote.
+        (WebCore::HTMLTableElement::tHead): Ditto.
+        (WebCore::HTMLTableElement::setTHead): Ditto.
+        (WebCore::HTMLTableElement::tFoot): Ditto.
+        (WebCore::HTMLTableElement::setTFoot): Ditto.
+        (WebCore::HTMLTableElement::createTHead): Ditto.
+        (WebCore::HTMLTableElement::deleteTHead): Ditto.
+        (WebCore::HTMLTableElement::createTFoot): Ditto.
+        (WebCore::HTMLTableElement::deleteTFoot): Ditto.
+        (WebCore::HTMLTableElement::createCaption): Ditto.
+        (WebCore::HTMLTableElement::deleteCaption): Ditto.
+        (WebCore::HTMLTableElement::lastBody): Added.
+        (WebCore::HTMLTableElement::insertRow): Rewrote to use a loop based on code in HTMLTableRowsCollection.
+        This is different from the old code mainly in how it handles rows outside any section.
+        (WebCore::HTMLTableElement::deleteRow): Ditto.
+        (WebCore::HTMLTableElement::addChild): Removed code to set the various members. Keeping pointers to
+        these was a possible source of serious bugs too, including crashes with stale pointers, although I
+        didn't write any test cases to prove those bugs existed.
+        (WebCore::HTMLTableElement::parseMappedAttribute): Changed the rules code to visit all cells, not
+        just the cells of the first body. I believe this fixed rendering on some table tests. I think the code
+        visits too many cells and also the use of recursion is overkill, but I didn't try to fix that.
+        (WebCore::HTMLTableElement::rows): Changed to use the new HTMLTableRowsCollection.
+        * html/HTMLTableElement.h: Changed functions to return PassRefPtr, which can be important if strange
+        things like DOM mutation events take things ot of the tree before they are safely referenced by
+        JavaScript wrappers. Also changed functions to take PassRefPtr and added exceptions. Removed unneeded
+        firstTBody and setTBody functions and childrenChanged function override, as well as unused Rules and
+        Frame enums. Removed m_head, m_foot, m_firstBody, and m_caption, and added lastBody function. Removed
+        unneeded friend declaration for HTMLTableCellElement.
+        * html/HTMLTableElement.idl: Allow the setteres for caption, tHead, and tFoot to raise exceptions.
+
+        * html/HTMLTableRowsCollection.cpp: Added. Implements the HTML 5 rule for which rows are in the
+        collection in which order.
+        * html/HTMLTableRowsCollection.h: Added.
+
+        * loader/FTPDirectoryDocument.cpp:
+        (WebCore::FTPDirectoryTokenizer::appendEntry): Use the standard insertRow function instead of
+        coming up with our own way of inserting a row. Simplifies things -- we can remove the code to
+        create a tbody element.
+
+2008-01-02  Darin Adler  <darin@apple.com>
+
         Reviewed by Alice and Tim.
 
         - try to fix GTK and Qt builds
index 3a612b4..5aaf6bb 100644 (file)
@@ -728,6 +728,7 @@ webcore_sources += \
        WebCore/html/HTMLTableElement.cpp \
        WebCore/html/HTMLTablePartElement.cpp \
        WebCore/html/HTMLTableRowElement.cpp \
+       WebCore/html/HTMLTableRowsCollection.cpp \
        WebCore/html/HTMLTableSectionElement.cpp \
        WebCore/html/HTMLTextAreaElement.cpp \
        WebCore/html/HTMLTextFieldInnerElement.cpp \
index 60c7d58..7b56146 100644 (file)
@@ -657,6 +657,7 @@ SOURCES += \
     html/HTMLTableElement.cpp \
     html/HTMLTablePartElement.cpp \
     html/HTMLTableRowElement.cpp \
+    html/HTMLTableRowsCollection.cpp \
     html/HTMLTableSectionElement.cpp \
     html/HTMLTextAreaElement.cpp \
     html/HTMLTextFieldInnerElement.cpp \
index c0c672b..46de568 100644 (file)
                                RelativePath="..\html\HTMLTableRowElement.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\html\HTMLTableRowsCollection.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\html\HTMLTableRowsCollection.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\html\HTMLTableSectionElement.cpp"\r
                                >\r
index 70cad4d..012ce67 100644 (file)
                933A14AA0B7D1D0900A53FFD /* DOMTextEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 933A14A90B7D1D0900A53FFD /* DOMTextEvent.mm */; };
                933A14B80B7D1D5200A53FFD /* JSTextEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 933A14B60B7D1D5200A53FFD /* JSTextEvent.cpp */; };
                933A14B90B7D1D5200A53FFD /* JSTextEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A14B70B7D1D5200A53FFD /* JSTextEvent.h */; };
+               93442C9E0D2B335C00338FF9 /* HTMLTableRowsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 93442C9D0D2B335C00338FF9 /* HTMLTableRowsCollection.h */; };
+               93442CA00D2B336000338FF9 /* HTMLTableRowsCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93442C9F0D2B336000338FF9 /* HTMLTableRowsCollection.cpp */; };
                934D9BA50B8C116B007B42A9 /* WebCoreNSStringExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 934D9BA40B8C116B007B42A9 /* WebCoreNSStringExtras.mm */; };
                934D9BA70B8C1175007B42A9 /* WebCoreNSStringExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 934D9BA60B8C1175007B42A9 /* WebCoreNSStringExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
                934FE9E50B5CA539003E4A73 /* FileChooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 934FE9E40B5CA539003E4A73 /* FileChooser.cpp */; };
                933A14A90B7D1D0900A53FFD /* DOMTextEvent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMTextEvent.mm; sourceTree = "<group>"; };
                933A14B60B7D1D5200A53FFD /* JSTextEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextEvent.cpp; sourceTree = "<group>"; };
                933A14B70B7D1D5200A53FFD /* JSTextEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTextEvent.h; sourceTree = "<group>"; };
+               93442C9D0D2B335C00338FF9 /* HTMLTableRowsCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTableRowsCollection.h; sourceTree = "<group>"; };
+               93442C9F0D2B336000338FF9 /* HTMLTableRowsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLTableRowsCollection.cpp; sourceTree = "<group>"; };
                934D9BA40B8C116B007B42A9 /* WebCoreNSStringExtras.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSStringExtras.mm; sourceTree = "<group>"; };
                934D9BA60B8C1175007B42A9 /* WebCoreNSStringExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCoreNSStringExtras.h; sourceTree = "<group>"; };
                934FE9E40B5CA539003E4A73 /* FileChooser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileChooser.cpp; sourceTree = "<group>"; };
                                A871DB220A150BD600B12A68 /* HTMLTableRowElement.cpp */,
                                A871DB230A150BD600B12A68 /* HTMLTableRowElement.h */,
                                8555425B0AA48B1E00BA89F2 /* HTMLTableRowElement.idl */,
+                               93442C9D0D2B335C00338FF9 /* HTMLTableRowsCollection.h */,
+                               93442C9F0D2B336000338FF9 /* HTMLTableRowsCollection.cpp */,
                                A871DB180A150BD600B12A68 /* HTMLTableSectionElement.cpp */,
                                A871DB170A150BD600B12A68 /* HTMLTableSectionElement.h */,
                                8555425C0AA48B1E00BA89F2 /* HTMLTableSectionElement.idl */,
                                BCE3BEC30D222B1D007E06E4 /* TagNodeList.h in Headers */,
                                BC60D6E90D28D83400B9918F /* DOMCoreException.h in Headers */,
                                BC60D7C10D29A46300B9918F /* JSDOMCoreException.h in Headers */,
+                               93442C9E0D2B335C00338FF9 /* HTMLTableRowsCollection.h in Headers */,
                                BC60D8F30D2A11E000B9918F /* ExceptionBase.h in Headers */,
                                BC60D90C0D2A17CE00B9918F /* EventException.h in Headers */,
                                BC60D9C00D2A269A00B9918F /* JSEventException.h in Headers */,
                                BC7FA6820D1F167900DB22A9 /* SelectorNodeList.cpp in Sources */,
                                BCE3BEC20D222B1D007E06E4 /* TagNodeList.cpp in Sources */,
                                BC60D7C00D29A46300B9918F /* JSDOMCoreException.cpp in Sources */,
+                               93442CA00D2B336000338FF9 /* HTMLTableRowsCollection.cpp in Sources */,
                                BC60D8F20D2A11E000B9918F /* ExceptionBase.cpp in Sources */,
                                BC60D9BF0D2A269A00B9918F /* JSEventException.cpp in Sources */,
                                BC60DA390D2A302800B9918F /* JSXMLHttpRequestException.cpp in Sources */,
index 395046c..23c4c23 100644 (file)
@@ -483,6 +483,7 @@ This file contains the list of files needed to build WebCore.
         html/HTMLTableElement.cpp
         html/HTMLTablePartElement.cpp
         html/HTMLTableRowElement.cpp
+        html/HTMLTableRowsCollection.cpp
         html/HTMLTableSectionElement.cpp
         html/HTMLTextAreaElement.cpp
         html/HTMLTextFieldInnerElement.cpp
index dbd42fa..0f36389 100644 (file)
@@ -42,7 +42,6 @@
 #include "HTMLNames.h"
 #include "HTMLScriptElement.h"
 #include "HTMLStyleElement.h"
-#include "HTMLTableSectionElement.h"
 #include "HTMLTokenizer.h"
 #include "ProcessingInstruction.h"
 #include "ResourceHandle.h"
index c6043a9..4774d84 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -138,11 +138,6 @@ void HTMLCollection::resetCollectionInfo() const
     }
 }
 
-static bool isTableSection(Element* element)
-{
-    return element->hasLocalName(tbodyTag) || element->hasLocalName(tfootTag) || element->hasLocalName(theadTag);
-}
-
 static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
 {
     return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
@@ -163,8 +158,8 @@ Element* HTMLCollection::itemAfter(Element* previous) const
         case DocObjects:
         case DocScripts:
         case DocumentNamedItems:
-        case FormElements:
         case MapAreas:
+        case Other:
         case SelectOptions:
         case WindowNamedItems:
             break;
@@ -174,11 +169,6 @@ Element* HTMLCollection::itemAfter(Element* previous) const
         case TableTBodies:
             deep = false;
             break;
-        case TableRows:
-            // Look for table rows inside table sections that are immediately inside
-            // the table, but not in nested table sections.
-            deep = previous && previous->parent() == m_base && isTableSection(previous);
-            break;
     }
 
     Node* current;
@@ -212,18 +202,6 @@ Element* HTMLCollection::itemAfter(Element* previous) const
                 if (e->hasLocalName(tdTag) || e->hasLocalName(thTag))
                     return e;
                 break;
-            case TableRows:
-                // Look for table rows inside table sections that are immediately inside
-                // the table, but not in nested table sections. Accept only rows that are
-                // in those table sections.
-                if (e->parent() == m_base)
-                    deep = isTableSection(e);
-                else {
-                    if (e->hasLocalName(trTag))
-                        return e;
-                    deep = false;
-                }
-                break;
             case TSectionRows:
                 if (e->hasLocalName(trTag))
                     return e;
@@ -262,7 +240,7 @@ Element* HTMLCollection::itemAfter(Element* previous) const
             case NodeChildren:
                 return e;
             case DocumentNamedItems:
-            case FormElements:
+            case Other:
             case WindowNamedItems:
                 ASSERT_NOT_REACHED();
                 break;
index 194572c..d992c81 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -61,13 +61,13 @@ public:
 
         // types not cached in the document; these are types that can't be used on a document
 
-        TableRows,    // all rows in this table or table section
         TableTBodies, // all <tbody> elements in this table
         TSectionRows, // all row elements in this table section
         TRCells,      // all cells in this row
         SelectOptions,
         MapAreas,
-        FormElements
+
+        Other
     };
 
     static const Type FirstUnnamedDocumentCachedType = DocImages;
@@ -82,12 +82,13 @@ public:
     unsigned length() const;
     
     virtual Node* item(unsigned index) const;
-    virtual Node* firstItem() const;
     virtual Node* nextItem() const;
 
     virtual Node* namedItem(const String& name, bool caseSensitive = true) const;
     virtual Node* nextNamedItem(const String& name) const; // In case of multiple items named the same way
 
+    Node* firstItem() const;
+
     void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const;
 
     PassRefPtr<NodeList> tags(const String&);
index a3d2ce3..fa69710 100644 (file)
@@ -43,7 +43,7 @@ inline HTMLCollection::CollectionInfo* HTMLFormCollection::formCollectionInfo(HT
 }
 
 HTMLFormCollection::HTMLFormCollection(PassRefPtr<HTMLFormElement> form)
-    : HTMLCollection(form.get(), FormElements, formCollectionInfo(form.get()))
+    : HTMLCollection(form.get(), Other, formCollectionInfo(form.get()))
 {
 }
 
index 4152a7c..20ffef2 100644 (file)
@@ -1,12 +1,10 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
+/*
  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
  *           (C) 1997 Torben Weis (weis@kde.org)
  *           (C) 1998 Waldo Bastian (bastian@kde.org)
  *           (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
  */
+
 #include "config.h"
 #include "HTMLTableElement.h"
 
-#include "CSSHelper.h"
 #include "CSSPropertyNames.h"
 #include "CSSStyleSheet.h"
 #include "CSSValueKeywords.h"
-#include "Document.h"
 #include "ExceptionCode.h"
-#include "HTMLCollection.h"
 #include "HTMLNames.h"
 #include "HTMLTableCaptionElement.h"
+#include "HTMLTableRowsCollection.h"
+#include "HTMLTableRowElement.h"
 #include "HTMLTableSectionElement.h"
 #include "RenderTable.h"
 #include "Text.h"
@@ -45,10 +43,6 @@ using namespace HTMLNames;
 
 HTMLTableElement::HTMLTableElement(Document *doc)
     : HTMLElement(tableTag, doc)
-    , m_head(0)
-    , m_foot(0)
-    , m_firstBody(0)
-    , m_caption(0)
     , m_borderAttr(false)
     , m_borderColorAttr(false)
     , m_frameAttr(false)
@@ -57,12 +51,6 @@ HTMLTableElement::HTMLTableElement(Document *doc)
 {
 }
 
-HTMLTableElement::~HTMLTableElement()
-{
-    if (m_firstBody)
-        m_firstBody->deref();
-}
-
 bool HTMLTableElement::checkDTD(const Node* newChild)
 {
     if (newChild->isTextNode())
@@ -74,215 +62,181 @@ bool HTMLTableElement::checkDTD(const Node* newChild)
            newChild->hasTagName(scriptTag);
 }
 
-Node* HTMLTableElement::setCaption(HTMLTableCaptionElement* c)
+HTMLTableCaptionElement* HTMLTableElement::caption() const
 {
-    ExceptionCode ec = 0;
-    if (Node* oc = m_caption)
-        replaceChild(c, oc, ec);
-    else
-        insertBefore(c, firstChild(), ec);
-    m_caption = c;
-    return m_caption;
+    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+        if (child->hasTagName(captionTag))
+            return static_cast<HTMLTableCaptionElement*>(child);
+    }
+    return 0;
 }
 
-Node* HTMLTableElement::setTHead(HTMLTableSectionElement* s)
+void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionCode& ec)
 {
-    ExceptionCode ec = 0;
-    if (Node* h = m_head)
-        replaceChild(s, h, ec);
-    else if (m_foot)
-        insertBefore(s, m_foot, ec);
-    else if (m_firstBody)
-        insertBefore(s, m_firstBody, ec);
-    else
-        appendChild(s, ec);
-    m_head = s;
-    return m_head;
+    deleteCaption();
+    insertBefore(newCaption, firstChild(), ec);
 }
 
-Node* HTMLTableElement::setTFoot(HTMLTableSectionElement *s)
+HTMLTableSectionElement* HTMLTableElement::tHead() const
 {
-    ExceptionCode ec = 0;
-    if (Node *f = m_foot)
-        replaceChild(s, f, ec);
-    else if (m_firstBody)
-        insertBefore(s, m_firstBody, ec);
-    else
-        appendChild(s, ec);
-    m_foot = s;
-    return m_foot;
+    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+        if (child->hasTagName(theadTag))
+            return static_cast<HTMLTableSectionElement*>(child);
+    }
+    return 0;
 }
 
-Node* HTMLTableElement::setTBody(HTMLTableSectionElement *s)
+void HTMLTableElement::setTHead(PassRefPtr<HTMLTableSectionElement> newHead, ExceptionCode& ec)
 {
-    ExceptionCode ec = 0;
-    Node* r;
-    s->ref();
-    if (Node *fb = m_firstBody) {
-        replaceChild(s, fb, ec);
-        fb->deref();
-        r = s;
-    } else
-        appendChild(s, ec);
-    m_firstBody = s;
-    return m_firstBody;
+    deleteTHead();
+
+    Node* child;
+    for (child = firstChild(); child; child = child->nextSibling())
+        if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
+            break;
+
+    insertBefore(newHead, child, ec);
 }
 
-HTMLElement *HTMLTableElement::createTHead()
+HTMLTableSectionElement* HTMLTableElement::tFoot() const
 {
-    if (!m_head) {
-        ExceptionCode ec = 0;
-        m_head = new HTMLTableSectionElement(theadTag, document());
-        if (m_foot)
-            insertBefore(m_head, m_foot, ec);
-        else if (m_firstBody)
-            insertBefore(m_head, m_firstBody, ec);
-        else
-            appendChild(m_head, ec);
+    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+        if (child->hasTagName(tfootTag))
+            return static_cast<HTMLTableSectionElement*>(child);
     }
-    return m_head;
+    return 0;
+}
+
+void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, ExceptionCode& ec)
+{
+    deleteTFoot();
+
+    Node* child;
+    for (child = firstChild(); child; child = child->nextSibling())
+        if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
+            break;
+
+    insertBefore(newFoot, child, ec);
+}
+
+PassRefPtr<HTMLElement> HTMLTableElement::createTHead()
+{
+    if (HTMLTableSectionElement* existingHead = tHead())
+        return existingHead;
+    RefPtr<HTMLTableSectionElement> head = new HTMLTableSectionElement(theadTag, document());
+    ExceptionCode ec;
+    setTHead(head, ec);
+    return head.release();
 }
 
 void HTMLTableElement::deleteTHead()
 {
-    if (m_head) {
-        ExceptionCode ec = 0;
-        m_head->ref();
-        HTMLElement::removeChild(m_head, ec);
-        m_head->deref();
-    }
-    m_head = 0;
+    ExceptionCode ec;
+    removeChild(tHead(), ec);
 }
 
-HTMLElement *HTMLTableElement::createTFoot()
+PassRefPtr<HTMLElement> HTMLTableElement::createTFoot()
 {
-    if (!m_foot) {
-        ExceptionCode ec = 0;
-        m_foot = new HTMLTableSectionElement(tfootTag, document());
-        if (m_firstBody)
-            insertBefore(m_foot, m_firstBody, ec);
-        else
-            appendChild(m_foot, ec);
-    }
-    return m_foot;
+    if (HTMLTableSectionElement* existingFoot = tFoot())
+        return existingFoot;
+    RefPtr<HTMLTableSectionElement> foot = new HTMLTableSectionElement(tfootTag, document());
+    ExceptionCode ec;
+    setTFoot(foot, ec);
+    return foot.release();
 }
 
 void HTMLTableElement::deleteTFoot()
 {
-    if (m_foot) {
-        ExceptionCode ec = 0;
-        m_foot->ref();
-        HTMLElement::removeChild(m_foot, ec);
-        m_foot->deref();
-    }
-    m_foot = 0;
+    ExceptionCode ec;
+    removeChild(tFoot(), ec);
 }
 
-HTMLElement *HTMLTableElement::createCaption()
+PassRefPtr<HTMLElement> HTMLTableElement::createCaption()
 {
-    if (!m_caption) {
-        ExceptionCode ec = 0;
-        m_caption = new HTMLTableCaptionElement(document());
-        insertBefore(m_caption, firstChild(), ec);
-    }
-    return m_caption;
+    if (HTMLTableCaptionElement* existingCaption = caption())
+        return existingCaption;
+    RefPtr<HTMLTableCaptionElement> caption = new HTMLTableCaptionElement(document());
+    ExceptionCode ec;
+    setCaption(caption, ec);
+    return caption.release();
 }
 
 void HTMLTableElement::deleteCaption()
 {
-    if (m_caption) {
-        ExceptionCode ec = 0;
-        m_caption->ref();
-        HTMLElement::removeChild(m_caption, ec);
-        m_caption->deref();
+    ExceptionCode ec;
+    removeChild(caption(), ec);
+}
+
+HTMLTableSectionElement* HTMLTableElement::lastBody() const
+{
+    for (Node* child = lastChild(); child; child = child->previousSibling()) {
+        if (child->hasTagName(tbodyTag))
+            return static_cast<HTMLTableSectionElement*>(child);
     }
-    m_caption = 0;
+    return 0;
 }
 
 PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
 {
-    // The DOM requires that we create a tbody if the table is empty
-    // (cf DOM2TS HTMLTableElement31 test)
-    // (note: this is different from "if the table has no sections", since we can have
-    // <TABLE><TR>)
-    if (!m_firstBody && !m_head && !m_foot)
-        setTBody(new HTMLTableSectionElement(tbodyTag, document()));
-
-    // IE treats index=-1 as default value meaning 'append after last'
-    // This isn't in the DOM. So, not implemented yet.
-    HTMLTableSectionElement* section = 0L;
-    HTMLTableSectionElement* lastSection = 0L;
-    Node *node = firstChild();
-    bool append = (index == -1);
-    bool found = false;
-    for (; node && (index>=0 || append) ; node = node->nextSibling())
-    {
-        // there could be 2 tfoot elements in the table. Only the first one is the "foot", that's why we have the more
-        // complicated if statement below.
-        if (node != m_foot && (node->hasTagName(theadTag) || node->hasTagName(tfootTag) || node->hasTagName(tbodyTag))) {
-            section = static_cast<HTMLTableSectionElement*>(node);
-            lastSection = section;
-            if (!append) {
-                int rows = section->numRows();
-                if (rows >= index) {
-                    found = true;
-                    break;
-                } else
-                    index -= rows;
+    if (index < -1) {
+        ec = INDEX_SIZE_ERR;
+        return 0;
+    }
+
+    HTMLTableRowElement* lastRow = 0;
+    HTMLTableRowElement* row = 0;
+    if (index == -1)
+        lastRow = HTMLTableRowsCollection::lastRow(this);
+    else {
+        for (int i = 0; i <= index; ++i) {
+            row = HTMLTableRowsCollection::rowAfter(this, lastRow);
+            if (!row) {
+                if (i != index) {
+                    ec = INDEX_SIZE_ERR;
+                    return 0;
+                }
+                break;
             }
+            lastRow = row;
         }
     }
-    if (!found && m_foot)
-        section = static_cast<HTMLTableSectionElement*>(m_foot);
-
-    // Index == 0 means "insert before first row in current section"
-    // or "append after last row" (if there's no current section anymore)
-    if (!section && (index == 0 || append)) {
-        section = lastSection;
-        index = section ? section->numRows() : 0;
-    }
-    if (section && (index >= 0 || append))
-        return section->insertRow(index, ec);
+
+    Node* parent;
+    if (lastRow)
+        parent = row ? row->parent() : lastRow->parent();
     else {
-        // No more sections => index is too big
-        ec = INDEX_SIZE_ERR;
-        return 0;
+        parent = lastBody();
+        if (!parent) {
+            RefPtr<HTMLTableSectionElement> newBody = new HTMLTableSectionElement(tbodyTag, document());
+            RefPtr<HTMLTableRowElement> newRow = new HTMLTableRowElement(document());
+            newBody->appendChild(newRow, ec);
+            appendChild(newBody.release(), ec);
+            return newRow.release();
+        }
     }
+
+    RefPtr<HTMLTableRowElement> newRow = new HTMLTableRowElement(document());
+    parent->insertBefore(newRow, row, ec);
+    return newRow.release();
 }
 
 void HTMLTableElement::deleteRow(int index, ExceptionCode& ec)
 {
-    HTMLTableSectionElement* section = 0L;
-    Node *node = firstChild();
-    bool lastRow = index == -1;
-    HTMLTableSectionElement* lastSection = 0L;
-    bool found = false;
-    for (; node ; node = node->nextSibling())
-    {
-        if (node != m_foot && (node->hasTagName(theadTag) || node->hasTagName(tfootTag) || 
-            node->hasTagName(tbodyTag))) {
-            section = static_cast<HTMLTableSectionElement*>(node);
-            lastSection = section;
-            int rows = section->numRows();
-            if (!lastRow) {
-                if (rows > index) {
-                    found = true;
-                    break;
-                } else
-                    index -= rows;
-            }
+    HTMLTableRowElement* row = 0;
+    if (index == -1)
+        row = HTMLTableRowsCollection::lastRow(this);
+    else {
+        for (int i = 0; i <= index; ++i) {
+            row = HTMLTableRowsCollection::rowAfter(this, row);
+            if (!row)
+                break;
         }
-        section = 0L;
     }
-    if (!found && m_foot)
-        section = static_cast<HTMLTableSectionElement*>(m_foot);
-
-    if (lastRow && lastSection)
-        lastSection->deleteRow(-1, ec);
-    else if (section && index >= 0 && index < section->numRows())
-        section->deleteRow(index, ec);
-    else
+    if (!row) {
         ec = INDEX_SIZE_ERR;
+        return;
+    }
+    row->remove(ec);
 }
 
 ContainerNode* HTMLTableElement::addChild(PassRefPtr<Node> child)
@@ -296,38 +250,9 @@ ContainerNode* HTMLTableElement::addChild(PassRefPtr<Node> child)
         return this;
     }
 
-    // The creation of <tbody> elements relies on the "childAllowed" check,
-    // so we need to do it even for XML documents.
-    ASSERT(child->nodeType() != DOCUMENT_FRAGMENT_NODE);
-    if (!document()->isHTMLDocument() && !childAllowed(child.get()))
-        return 0;
-
-    ContainerNode* container = HTMLElement::addChild(child.get());
-    if (container) {
-        if (!m_caption && child->hasTagName(captionTag))
-            m_caption = static_cast<HTMLTableCaptionElement*>(child.get());
-        else if (!m_head && child->hasTagName(theadTag))
-            m_head = static_cast<HTMLTableSectionElement*>(child.get());
-        else if (!m_foot && child->hasTagName(tfootTag))
-            m_foot = static_cast<HTMLTableSectionElement*>(child.get());
-        else if (!m_firstBody && child->hasTagName(tbodyTag)) {
-            m_firstBody = static_cast<HTMLTableSectionElement*>(child.get());
-            m_firstBody->ref();
-        }
-    }
-    return container;
+    return HTMLElement::addChild(child.get());
 }
 
-void HTMLTableElement::childrenChanged()
-{
-    HTMLElement::childrenChanged();
-    
-    if (m_firstBody && m_firstBody->parentNode() != this) {
-        m_firstBody->deref();
-        m_firstBody = 0;
-    }
-} 
-
 bool HTMLTableElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
 {
     if (attrName == backgroundAttr) {
@@ -389,7 +314,7 @@ static bool setTableCellsChanged(Node* n)
     return cellChanged;
 }
 
-void HTMLTableElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTableElement::parseMappedAttribute(MappedAttributeattr)
 {
     if (attr->name() == widthAttr)
         addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
@@ -491,9 +416,13 @@ void HTMLTableElement::parseMappedAttribute(MappedAttribute *attr)
         // The presence of a valid rules attribute causes border collapsing to be enabled.
         if (m_rulesAttr != UnsetRules)
             addCSSProperty(attr, CSS_PROP_BORDER_COLLAPSE, CSS_VAL_COLLAPSE);
-        if (oldRules != m_rulesAttr && m_firstBody)
-            if (setTableCellsChanged(m_firstBody))
+        if (oldRules != m_rulesAttr) {
+            bool cellChanged = false;
+            for (Node* child = firstChild(); child; child = child->nextSibling())
+                cellChanged |= setTableCellsChanged(child);
+            if (cellChanged)
                 setChanged();
+        }
     } else if (attr->name() == cellspacingAttr) {
         if (!attr->value().isEmpty())
             addCSSLength(attr, CSS_PROP_BORDER_SPACING, attr->value());
@@ -652,7 +581,7 @@ bool HTMLTableElement::isURLAttribute(Attribute *attr) const
 
 PassRefPtr<HTMLCollection> HTMLTableElement::rows()
 {
-    return new HTMLCollection(this, HTMLCollection::TableRows);
+    return new HTMLTableRowsCollection(this);
 }
 
 PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
index d26ef2e..0f2ff49 100644 (file)
@@ -1,12 +1,10 @@
 /*
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
  *           (C) 1997 Torben Weis (weis@kde.org)
  *           (C) 1998 Waldo Bastian (bastian@kde.org)
  *           (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 namespace WebCore {
 
 class HTMLCollection;
-class HTMLTableSectionElement;
-class HTMLTableCellElement;
 class HTMLTableCaptionElement;
+class HTMLTableSectionElement;
 
 class HTMLTableElement : public HTMLElement {
 public:
-    enum Rules {
-        None    = 0x00,
-        RGroups = 0x01,
-        CGroups = 0x02,
-        Groups  = 0x03,
-        Rows    = 0x05,
-        Cols    = 0x0a,
-        All     = 0x0f
-    };
-    enum Frame {
-        Void   = 0x00,
-        Above  = 0x01,
-        Below  = 0x02,
-        Lhs    = 0x04,
-        Rhs    = 0x08,
-        Hsides = 0x03,
-        Vsides = 0x0c,
-        Box    = 0x0f
-    };
-
     HTMLTableElement(Document*);
-    ~HTMLTableElement();
 
     virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
     virtual int tagPriority() const { return 9; }
     virtual bool checkDTD(const Node*);
 
-    HTMLTableCaptionElement* caption() const { return m_caption; }
-    Node* setCaption(HTMLTableCaptionElement*);
-
-    HTMLTableSectionElement* tHead() const { return m_head; }
-    Node* setTHead(HTMLTableSectionElement*);
+    HTMLTableCaptionElement* caption() const;
+    void setCaption(PassRefPtr<HTMLTableCaptionElement>, ExceptionCode&);
 
-    HTMLTableSectionElement* tFoot() const { return m_foot; }
-    Node* setTFoot(HTMLTableSectionElement*);
+    HTMLTableSectionElement* tHead() const;
+    void setTHead(PassRefPtr<HTMLTableSectionElement>, ExceptionCode&);
 
-    HTMLTableSectionElement* firstTBody() const { return m_firstBody; }
-    Node* setTBody(HTMLTableSectionElement*);
+    HTMLTableSectionElement* tFoot() const;
+    void setTFoot(PassRefPtr<HTMLTableSectionElement>, ExceptionCode&);
 
-    HTMLElement* createTHead();
+    PassRefPtr<HTMLElement> createTHead();
     void deleteTHead();
-    HTMLElement* createTFoot();
+    PassRefPtr<HTMLElement> createTFoot();
     void deleteTFoot();
-    HTMLElement* createCaption();
+    PassRefPtr<HTMLElement> createCaption();
     void deleteCaption();
     PassRefPtr<HTMLElement> insertRow(int index, ExceptionCode&);
     void deleteRow(int index, ExceptionCode&);
@@ -117,12 +90,11 @@ public:
     String width() const;
     void setWidth(const String&);
 
-    // overrides
     virtual ContainerNode* addChild(PassRefPtr<Node>);
-    virtual void childrenChanged();
-    
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
     virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void attach();
+    virtual bool isURLAttribute(Attribute*) const;
 
     // Used to obtain either a solid or outset border decl and to deal with the frame
     // and rules attributes.
@@ -130,17 +102,10 @@ public:
     CSSMutableStyleDeclaration* getSharedCellDecl();
     CSSMutableStyleDeclaration* getSharedGroupDecl(bool rows);
 
-    virtual void attach();
-    
-    virtual bool isURLAttribute(Attribute*) const;
-
+private:
     enum TableRules { UnsetRules, NoneRules, GroupsRules, RowsRules, ColsRules, AllRules };
 
-protected:
-    HTMLTableSectionElement* m_head;
-    HTMLTableSectionElement* m_foot;
-    HTMLTableSectionElement* m_firstBody;
-    HTMLTableCaptionElement* m_caption;
+    HTMLTableSectionElement* lastBody() const;
 
     bool m_borderAttr;          // Sets a precise border width and creates an outset border for the table and for its cells.
     bool m_borderColorAttr;     // Overrides the outset border and makes it solid for the table and cells instead.
@@ -149,7 +114,6 @@ protected:
                                 // are present, to none otherwise).
    
     unsigned short m_padding;
-    friend class HTMLTableCellElement;
 };
 
 } //namespace
index b548cf7..7092be0 100644 (file)
@@ -26,14 +26,13 @@ module html {
         ImplementationUUID=159bb8fe-ffee-4ff9-b507-76741118143f
     ] HTMLTableElement : HTMLElement {
 
-        // FIXME: the dom spec states that the following 3 attributes
         // could raise excepetions on setting.
                  attribute HTMLTableCaptionElement caption
-                     /*setter raises(DOMException)*/;
+                     setter raises(DOMException);
                  attribute HTMLTableSectionElement tHead
-                     /*setter raises(DOMException)*/;
+                     setter raises(DOMException);
                  attribute HTMLTableSectionElement tFoot
-                     /*setter raises(DOMException)*/;
+                     setter raises(DOMException);
 
         readonly attribute HTMLCollection rows;
         readonly attribute HTMLCollection tBodies;
diff --git a/WebCore/html/HTMLTableRowsCollection.cpp b/WebCore/html/HTMLTableRowsCollection.cpp
new file mode 100644 (file)
index 0000000..3630fdc
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLTableRowsCollection.h"
+
+#include "HTMLNames.h"
+#include "HTMLTableElement.h"
+#include "HTMLTableRowElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static bool isInHead(Element* row)
+{
+    return row->parent() && static_cast<Element*>(row->parent())->hasLocalName(theadTag);
+}
+
+static bool isInBody(Element* row)
+{
+    return row->parent() && static_cast<Element*>(row->parent())->hasLocalName(tbodyTag);
+}
+
+static bool isInFoot(Element* row)
+{
+    return row->parent() && static_cast<Element*>(row->parent())->hasLocalName(tfootTag);
+}
+
+HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
+{
+    Node* child = 0;
+
+    // Start by looking for the next row in this section.
+    // Continue only if there is none.
+    if (previous && previous->parent() != table) {
+        for (child = previous->nextSibling(); child; child = child->nextSibling()) {
+            if (child->hasTagName(trTag))
+                return static_cast<HTMLTableRowElement*>(child);
+        }
+    }
+
+    // If still looking at head sections, find the first row in the next head section.
+    if (!previous)
+        child = table->firstChild();
+    else if (isInHead(previous))
+        child = previous->parent()->nextSibling();
+    for (; child; child = child->nextSibling()) {
+        if (child->hasTagName(theadTag)) {
+            for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
+                if (grandchild->hasTagName(trTag))
+                    return static_cast<HTMLTableRowElement*>(grandchild);
+            }
+        }
+    }
+
+    // If still looking at top level and bodies, find the next row in top level or the first in the next body section.
+    if (!previous || isInHead(previous))
+        child = table->firstChild();
+    else if (previous->parent() == table)
+        child = previous->nextSibling();
+    else if (isInBody(previous))
+        child = previous->parent()->nextSibling();
+    for (; child; child = child->nextSibling()) {
+        if (child->hasTagName(trTag))
+            return static_cast<HTMLTableRowElement*>(child);
+        if (child->hasTagName(tbodyTag)) {
+            for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
+                if (grandchild->hasTagName(trTag))
+                    return static_cast<HTMLTableRowElement*>(grandchild);
+            }
+        }
+    }
+
+    // Find the first row in the next foot section.
+    if (!previous || !isInFoot(previous))
+        child = table->firstChild();
+    else
+        child = previous->parent()->nextSibling();
+    for (; child; child = child->nextSibling()) {
+        if (child->hasTagName(tfootTag)) {
+            for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
+                if (grandchild->hasTagName(trTag))
+                    return static_cast<HTMLTableRowElement*>(grandchild);
+            }
+        }
+    }
+
+    return 0;
+}
+
+HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
+{
+    for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+        if (child->hasTagName(tfootTag)) {
+            for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
+                if (grandchild->hasTagName(trTag))
+                    return static_cast<HTMLTableRowElement*>(grandchild);
+            }
+        }
+    }
+
+    for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+        if (child->hasTagName(trTag))
+            return static_cast<HTMLTableRowElement*>(child);
+        if (child->hasTagName(tbodyTag)) {
+            for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
+                if (grandchild->hasTagName(trTag))
+                    return static_cast<HTMLTableRowElement*>(grandchild);
+            }
+        }
+    }
+
+    for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+        if (child->hasTagName(theadTag)) {
+            for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
+                if (grandchild->hasTagName(trTag))
+                    return static_cast<HTMLTableRowElement*>(grandchild);
+            }
+        }
+    }
+
+    return 0;
+}
+
+HTMLTableRowsCollection::HTMLTableRowsCollection(PassRefPtr<HTMLTableElement> table)
+    : HTMLCollection(table, Other)
+{
+}
+
+Element* HTMLTableRowsCollection::itemAfter(Element* previous) const
+{
+    ASSERT(!previous || previous->hasLocalName(trTag));
+    return rowAfter(static_cast<HTMLTableElement*>(base()), static_cast<HTMLTableRowElement*>(previous));
+}
+
+}
diff --git a/WebCore/html/HTMLTableRowsCollection.h b/WebCore/html/HTMLTableRowsCollection.h
new file mode 100644 (file)
index 0000000..9acce69
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLTableRowsCollection_h
+#define HTMLTableRowsCollection_h
+
+#include "HTMLCollection.h"
+
+namespace WebCore {
+
+class HTMLTableElement;
+class HTMLTableRowElement;
+
+class HTMLTableRowsCollection : public HTMLCollection {
+public:
+    HTMLTableRowsCollection(PassRefPtr<HTMLTableElement>);
+
+    static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
+    static HTMLTableRowElement* lastRow(HTMLTableElement*);
+
+private:
+    virtual Element* itemAfter(Element*) const;
+};
+
+} // namespace
+
+#endif
index fa6cb00..6e8a02a 100644 (file)
@@ -115,7 +115,7 @@ void FTPDirectoryTokenizer::appendEntry(const String& filename, const String& si
 {
     ExceptionCode ec;
 
-    RefPtr<Element> rowElement = m_doc->createElementNS(xhtmlNamespaceURI, "tr", ec);
+    RefPtr<Element> rowElement = m_tableElement->insertRow(-1, ec);
     rowElement->setAttribute("class", "ftpDirectoryEntryRow", ec);
    
     RefPtr<Element> element = m_doc->createElementNS(xhtmlNamespaceURI, "td", ec);
@@ -139,15 +139,6 @@ void FTPDirectoryTokenizer::appendEntry(const String& filename, const String& si
     element->appendChild(new Text(m_doc, size), ec);
     element->setAttribute("class", "ftpDirectoryFileSize", ec);
     rowElement->appendChild(element, ec);
-    
-    // Append the new row to the first tbody if it exists.  
-    // Many <TABLE> elements end up having an implicit <TBODY> created for them and in those
-    // cases, it's more correct to append to the tbody instead of the table itself
-    HTMLTableSectionElement* body = m_tableElement->firstTBody();
-    if (body)
-        body->appendChild(rowElement, ec);
-    else
-        m_tableElement->appendChild(rowElement, ec);
 }
 
 PassRefPtr<Element> FTPDirectoryTokenizer::createTDForFilename(const String& filename)