WebCore:

        Make :first-child and :first-of-type properly dynamic when the DOM changes.  Brings the Acid3 score up
        to 66/100.

        Reviewed by olliej

        Added fast/css/first-child-pseudo-class.html, fast/css/first-of-type-pseudo-class.html, fast/css/empty-body-test.html

        * css/CSSGrammar.y:
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::checkOneSelector):
        * dom/Element.cpp:
        (WebCore::Element::recalcStyle):
        (WebCore::Element::childrenChanged):
        * rendering/RenderStyle.cpp:
        (WebCore::RenderStyle::RenderStyle):
        * rendering/RenderStyle.h:
        (WebCore::RenderStyle::childrenAffectedByFirstChildRules):
        (WebCore::RenderStyle::setChildrenAffectedByFirstChildRules):
        (WebCore::RenderStyle::childrenAffectedByLastChildRules):
        (WebCore::RenderStyle::setChildrenAffectedByLastChildRules):
        (WebCore::RenderStyle::childrenAffectedByPositionalRules):
        (WebCore::RenderStyle::setChildrenAffectedByPositionalRules):
        (WebCore::RenderStyle::firstChildState):
        (WebCore::RenderStyle::setFirstChildState):
        (WebCore::RenderStyle::lastChildState):
        (WebCore::RenderStyle::setLastChildState):

LayoutTests:

        Added tests for dynamic :first-child support (Acid3).

        Reviewed by olliej

        * fast/css/empty-body-test.html: Added.
        * fast/css/first-child-pseudo-class.html: Added.
        * fast/css/first-of-type-pseudo-class.html: Added.
        * platform/mac/fast/css/empty-body-test-expected.checksum: Added.
        * platform/mac/fast/css/empty-body-test-expected.png: Added.
        * platform/mac/fast/css/empty-body-test-expected.txt: Added.
        * platform/mac/fast/css/first-child-pseudo-class-expected.checksum: Added.
        * platform/mac/fast/css/first-child-pseudo-class-expected.png: Added.
        * platform/mac/fast/css/first-child-pseudo-class-expected.txt: Added.
        * platform/mac/fast/css/first-of-type-pseudo-class-expected.checksum: Added.
        * platform/mac/fast/css/first-of-type-pseudo-class-expected.png: Added.
        * platform/mac/fast/css/first-of-type-pseudo-class-expected.txt: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@29932 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index be3c2ce3..2d2742e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2008-02-01  David Hyatt  <hyatt@apple.com>
+
+        Added tests for dynamic :first-child support (Acid3).
+
+        Reviewed by olliej
+
+        * fast/css/empty-body-test.html: Added.
+        * fast/css/first-child-pseudo-class.html: Added.
+        * fast/css/first-of-type-pseudo-class.html: Added.
+        * platform/mac/fast/css/empty-body-test-expected.checksum: Added.
+        * platform/mac/fast/css/empty-body-test-expected.png: Added.
+        * platform/mac/fast/css/empty-body-test-expected.txt: Added.
+        * platform/mac/fast/css/first-child-pseudo-class-expected.checksum: Added.
+        * platform/mac/fast/css/first-child-pseudo-class-expected.png: Added.
+        * platform/mac/fast/css/first-child-pseudo-class-expected.txt: Added.
+        * platform/mac/fast/css/first-of-type-pseudo-class-expected.checksum: Added.
+        * platform/mac/fast/css/first-of-type-pseudo-class-expected.png: Added.
+        * platform/mac/fast/css/first-of-type-pseudo-class-expected.txt: Added.
+
 2008-02-02  Dan Bernstein  <mitz@apple.com>
 
         - added Tiger-only results for a test
diff --git a/LayoutTests/fast/css/empty-body-test.html b/LayoutTests/fast/css/empty-body-test.html
new file mode 100644
index 0000000..bedc71b
--- /dev/null
+++ b/LayoutTests/fast/css/empty-body-test.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<style type="text/css">
+body:empty { background-color:red; }
+div#appendChild { padding: 1em;}
+</style>
+</head>
+<body>
+<p>There should be no RED on the page</p>
+<div id='appendChild'></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css/first-child-pseudo-class.html b/LayoutTests/fast/css/first-child-pseudo-class.html
new file mode 100644
index 0000000..eff1797
--- /dev/null
+++ b/LayoutTests/fast/css/first-child-pseudo-class.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+

+<html>

+	<head>

+		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

+		<title>:first-child</title>

+		

+		<style type='text/css'>

+		<!--

+

+			body { background: #fff; color: 000; font-family: Arial, Helvetica, sans-serif; }

+			pre { background: #fff; padding: 0.5em; }

+			li { background: #aaa; padding: 1em; width: 80%; margin: 0 0 3em; }

+			.test { display: block; padding: 0.75em; }

+			.base, .defaultgreen { background-color: #090; }

+			.defaultred { background-color: #900; }

+			

+			.defaultred :first-child {

+				background-color: #090;

+			}

+

+			.defaultgreen :first-child {

+				background-color: #900;

+			}

+

+			blockquote {

+				margin: 0;

+			}

+

+		-->			

+		</style>

+	</head>

+

+	<body>

+		<p>This page is part of the <a href="http://www.css3.info">CSS3.info</a> <a href="http://www.css3.info/selectors-test/">CSS selectors test</a>. See more info on <a href="http://www.css3.info/preview/attribute-selectors.html">CSS3 selectors</a>.</p>

+		

+		<div class='base'></div>

+	

+		<ol>

+			<li>

+				<div class='defaultred'>

+					<div class='test required'></div>

+				</div>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt;

+   &lt;div&gt;&lt;/div&gt;

+&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the inner div element, because it is the only child of the outer div element

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultred'>

+					<div class='test'></div>

+					<blockquote></blockquote>

+				</div>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt; 

+   &lt;div&gt;&lt;/div&gt;

+   &lt;blockquote&gt;&lt;/blockquote&gt;

+&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the inner div element, because it is the first child of the outer div element

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultred'>

+					<!-- Just a comment -->

+					<div class='test'></div>

+				</div>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt; 

+   &lt;!-- Just a comment --&gt;

+   &lt;div&gt;&lt;/div&gt;

+&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the inner div element, because it is the first child of the outer div element

+					Comments are not elements, so they should not be considered when determining the first child.

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultred'>

+					.

+					<div class='test'></div>

+				</div>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt; 

+   How about regular text...

+   &lt;div&gt;&lt;/div&gt;

+&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the inner div element, because it is the first child of the outer div element.

+					Regular text is not an element, so it should not be considered when determining the first child.

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultgreen'>

+					<blockquote></blockquote>

+					<div class='test default required'></div>

+				</div>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt; 

+   &lt;blockquote&gt;&lt;/blockquote&gt;

+   &lt;div&gt;&lt;/div&gt;

+&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should not match the inner div element, because it is the second child of the outer div element

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultred'>

+					<div id='insertBefore1'></div>

+				</div>

+

+				<script type="text/javascript">

+				<!--

+

+					var ib = document.getElementById('insertBefore1');

+					var el = document.createElement("div");

+					el.className = 'test';

+					ib.parentNode.insertBefore(el, ib);

+

+				

+				//-->

+				</script>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt;

+   &lt;div id='insertBefore'&gt;&lt;/div&gt;

+&lt;/div&gt;

+

+var ib = document.getElementById('insertBefore');

+ib.parentElement.insertBefore(document.createElement("div"), ib);</pre>

+

+				<p>

+					The CSS selector should match the div element that is inserted by the Javascript code. 

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultgreen'>

+					<div id='insertBefore2' class='test default'></div>

+				</div>

+

+				<script type="text/javascript">

+				<!--

+

+					var ib = document.getElementById('insertBefore2');

+					ib.parentNode.insertBefore(document.createElement("div"), ib);

+				

+				//-->

+				</script>

+				

+				<pre>div :first-child {

+}

+

+&lt;div&gt;

+   &lt;div id='insertBefore'&gt;&lt;/div&gt;

+&lt;/div&gt;

+

+var ib = document.getElementById('insertBefore');

+ib.parentElement.insertBefore(document.createElement("div"), ib);</pre>

+

+				<p>

+					The original div element should not be a match for the :first-child selector.

+				</p>

+			</li>

+		</ol>

+	</body>

+</html>

diff --git a/LayoutTests/fast/css/first-of-type-pseudo-class.html b/LayoutTests/fast/css/first-of-type-pseudo-class.html
new file mode 100644
index 0000000..40b00df
--- /dev/null
+++ b/LayoutTests/fast/css/first-of-type-pseudo-class.html
@@ -0,0 +1,242 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

+

+<html>

+	<head>

+		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

+		<title>:first-of-type</title>

+		

+		<style type='text/css'>

+		<!--

+

+			body { background: #fff; color: 000; font-family: Arial, Helvetica, sans-serif; }

+			pre { background: #fff; padding: 0.5em; }

+			li { background: #aaa; padding: 1em; width: 80%; margin: 0 0 3em; }

+			.test { display: block; padding: 0.75em; }

+			.base, .defaultgreen { background-color: #090; }

+			.defaultred { background-color: #900; }

+			

+			.defaultred :first-of-type {

+				background-color: #090;

+			}

+

+			.defaultgreen :first-of-type {

+				background-color: #900;

+			}

+

+			blockquote {

+				margin: 0;

+			}

+

+		-->

+		</style>

+	</head>

+

+	<body>

+		<p>This page is part of the <a href="http://www.css3.info">CSS3.info</a> <a href="http://www.css3.info/selectors-test/">CSS selectors test</a>. See more info on <a href="http://www.css3.info/preview/attribute-selectors.html">CSS3 selectors</a>.</p>

+		

+		<div class='base'></div>

+	

+		<ol>

+			<li>

+				<div class='defaultred'>

+					<div class='test required'></div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div&gt;Does this element match?&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the marked div element, because it is the only element of this type

+				</p>

+			</li>

+			

+			<li>

+				<div class='defaultred'>

+					<div class='test'></div>

+					<div></div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div&gt;Does this element match?&lt;/div&gt;

+&lt;div&gt;&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the marked div element, because it is the first element of this type

+				</p>

+			</li>

+			

+			<li>

+				<div class='defaultred'>

+					<blockquote></blockquote>

+					<div class='test required'></div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;blockquote&gt;&lt;/blockquote&gt;

+&lt;div&gt;Does this element match?&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the marked div element, because it is the first element of this type

+				</p>

+			</li>

+	

+			<li>

+				<div class='defaultred'>

+					<div></div>

+					<blockquote>

+						<div class='test'></div>

+					</blockquote>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div&gt;&lt;/div&gt;

+&lt;blockquote&gt;

+   &lt;div&gt;Does this element match?&lt;/div&gt;

+&lt;/blockquote&gt;</pre>

+

+				<p>

+					The CSS selector should match the marked div element, because it is the first element of this type in this scope

+				</p>

+			</li>

+	

+			<li>

+				<div class='defaultred'>

+					<div>

+						<div class='test'></div>

+					</div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div&gt;

+   &lt;div&gt;Does this element match?&lt;/div&gt;

+&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the marked div element, because it is the first element of this type in the current scope

+				</p>

+			</li>

+			

+			<li>

+				<div class='defaultred'>

+					<blockquote>

+						<div></div>

+					</blockquote>

+					<div class='test'></div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;blockquote&gt;

+   &lt;div&gt;&lt;/div&gt;

+&lt;/blockquote&gt;

+&lt;div&gt;Does this element match?&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should match the marked div element, because it is the first element of this type in the current scope

+				</p>

+			</li>

+	

+			<li>

+				<div class='defaultgreen'>

+					<div></div>

+					<div class='test default required'></div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div&gt;&lt;/div&gt;

+&lt;div&gt;Does this element match?&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should not match the marked div element, because it is the second element of this type

+				</p>

+			</li>

+			

+			<li>

+				<div class='defaultgreen'>

+					<DIV></DIV>

+					<div class='test default'></div>

+				</div>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;DIV&gt;&lt;/DIV&gt;

+&lt;div&gt;Does this element match?&lt;/div&gt;</pre>

+

+				<p>

+					The CSS selector should not match the marked div element, because it is the second element of this type

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultred'>

+					<div id='insertBefore1'></div>

+				</div>

+

+				<script type="text/javascript">

+				<!--

+

+					var ib = document.getElementById('insertBefore1');

+					var el = document.createElement("div");

+					el.className = 'test';

+					ib.parentNode.insertBefore(el, ib);

+

+				

+				//-->

+				</script>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div id='insertBefore'&gt;&lt;/div&gt;

+

+var ib = document.getElementById('insertBefore');

+ib.parentElement.insertBefore(document.createElement("div"), ib);</pre>

+

+				<p>

+					The CSS selector should match the div element that is inserted by the Javascript code. 

+				</p>

+			</li>

+

+			<li>

+				<div class='defaultgreen'>

+					<div id='insertBefore2' class='test default'></div>

+				</div>

+

+				<script type="text/javascript">

+				<!--

+

+					var ib = document.getElementById('insertBefore2');

+					ib.parentNode.insertBefore(document.createElement("div"), ib);

+				

+				//-->

+				</script>

+				

+				<pre>div:first-of-type {

+}

+

+&lt;div id='insertBefore'&gt;&lt;/div&gt;

+

+var ib = document.getElementById('insertBefore');

+ib.parentElement.insertBefore(document.createElement("div"), ib);</pre>

+

+				<p>

+					The original div element should not be a match for the :first-of-type selector.

+				</p>

+			</li>

+		</ol>	

+	</body>

+</html>

diff --git a/LayoutTests/platform/mac/fast/css/empty-body-test-expected.checksum b/LayoutTests/platform/mac/fast/css/empty-body-test-expected.checksum
new file mode 100644
index 0000000..143be62
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/empty-body-test-expected.checksum
@@ -0,0 +1 @@
+a9689d3d3e38cffa14b833e060094e0f
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/css/empty-body-test-expected.png b/LayoutTests/platform/mac/fast/css/empty-body-test-expected.png
new file mode 100644
index 0000000..b90eba1
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/empty-body-test-expected.png
Binary files differ
diff --git a/LayoutTests/platform/mac/fast/css/empty-body-test-expected.txt b/LayoutTests/platform/mac/fast/css/empty-body-test-expected.txt
new file mode 100644
index 0000000..1373f34
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/empty-body-test-expected.txt
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x90
+  RenderBlock {HTML} at (0,0) size 800x90
+    RenderBody {BODY} at (8,16) size 784x66
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 236x18
+          text run at (0,0) width 236: "There should be no RED on the page"
+      RenderBlock {DIV} at (0,34) size 784x32
diff --git a/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.checksum b/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.checksum
new file mode 100644
index 0000000..4caf6fd
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.checksum
@@ -0,0 +1 @@
+8e07410b3e969cae315fdbf7bac24ca7
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.png b/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.png
new file mode 100644
index 0000000..936b976
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.png
Binary files differ
diff --git a/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.txt b/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.txt
new file mode 100644
index 0000000..d76d0f2
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/first-child-pseudo-class-expected.txt
@@ -0,0 +1,193 @@
+layer at (0,0) size 785x2263
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x2263
+  RenderBlock {HTML} at (0,0) size 785x2263
+    RenderBody {BODY} at (8,16) size 769x2199 [bgcolor=#FFFFFF]
+      RenderBlock {P} at (0,0) size 769x18
+        RenderText {#text} at (0,0) size 165x17
+          text run at (0,0) width 165: "This page is part of the "
+        RenderInline {A} at (0,0) size 73x17 [color=#0000EE]
+          RenderText {#text} at (165,0) size 73x17
+            text run at (165,0) width 73: "CSS3.info"
+        RenderText {#text} at (238,0) size 4x17
+          text run at (238,0) width 4: " "
+        RenderInline {A} at (0,0) size 131x17 [color=#0000EE]
+          RenderText {#text} at (242,0) size 131x17
+            text run at (242,0) width 131: "CSS selectors test"
+        RenderText {#text} at (373,0) size 133x17
+          text run at (373,0) width 133: ". See more info on "
+        RenderInline {A} at (0,0) size 111x17 [color=#0000EE]
+          RenderText {#text} at (506,0) size 111x17
+            text run at (506,0) width 111: "CSS3 selectors"
+        RenderText {#text} at (617,0) size 4x17
+          text run at (617,0) width 4: "."
+      RenderBlock {DIV} at (0,34) size 769x0 [bgcolor=#009900]
+      RenderBlock {OL} at (0,34) size 769x2165
+        RenderListItem {LI} at (40,0) size 615x242 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+          RenderBlock {PRE} at (16,53) size 583x105 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "1"
+            RenderText {#text} at (6,8) size 144x91
+              text run at (6,8) width 144: "div :first-child {"
+              text run at (150,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 40: "<div>"
+              text run at (46,54) width 0: " "
+              text run at (6,69) width 112: "   <div></div>"
+              text run at (118,69) width 0: " "
+              text run at (6,84) width 48: "</div>"
+          RenderBlock {P} at (16,174) size 583x36
+            RenderText {#text} at (0,0) size 572x35
+              text run at (0,0) width 572: "The CSS selector should match the inner div element, because it is the only child"
+              text run at (0,18) width 165: "of the outer div element"
+        RenderListItem {LI} at (40,290) size 615x257 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+            RenderBlock {BLOCKQUOTE} at (0,24) size 583x0
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "2"
+            RenderText {#text} at (6,8) size 224x106
+              text run at (6,8) width 144: "div :first-child {"
+              text run at (150,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 48: "<div> "
+              text run at (54,54) width 0: " "
+              text run at (6,69) width 112: "   <div></div>"
+              text run at (118,69) width 0: " "
+              text run at (6,84) width 224: "   <blockquote></blockquote>"
+              text run at (230,84) width 0: " "
+              text run at (6,99) width 48: "</div>"
+          RenderBlock {P} at (16,189) size 583x36
+            RenderText {#text} at (0,0) size 567x35
+              text run at (0,0) width 567: "The CSS selector should match the inner div element, because it is the first child"
+              text run at (0,18) width 165: "of the outer div element"
+        RenderListItem {LI} at (40,595) size 615x275 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "3"
+            RenderText {#text} at (6,8) size 208x106
+              text run at (6,8) width 144: "div :first-child {"
+              text run at (150,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 48: "<div> "
+              text run at (54,54) width 0: " "
+              text run at (6,69) width 208: "   <!-- Just a comment -->"
+              text run at (214,69) width 0: " "
+              text run at (6,84) width 112: "   <div></div>"
+              text run at (118,84) width 0: " "
+              text run at (6,99) width 48: "</div>"
+          RenderBlock {P} at (16,189) size 583x54
+            RenderText {#text} at (0,0) size 567x53
+              text run at (0,0) width 567: "The CSS selector should match the inner div element, because it is the first child"
+              text run at (0,18) width 169: "of the outer div element "
+              text run at (169,18) width 358: "Comments are not elements, so they should not be"
+              text run at (0,36) width 307: "considered when determining the first child."
+        RenderListItem {LI} at (40,918) size 615x290 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x42 [bgcolor=#990000]
+            RenderBlock (anonymous) at (0,0) size 583x18
+              RenderListMarker at (-37,0) size 17x17: "4"
+              RenderText {#text} at (0,0) size 4x17
+                text run at (0,0) width 4: "."
+            RenderBlock {DIV} at (0,18) size 583x24 [bgcolor=#009900]
+          RenderBlock {PRE} at (16,71) size 583x117 [bgcolor=#FFFFFF]
+            RenderText {#text} at (6,6) size 224x105
+              text run at (6,6) width 144: "div :first-child {"
+              text run at (150,6) width 0: " "
+              text run at (6,21) width 8: "}"
+              text run at (14,21) width 0: " "
+              text run at (6,36) width 0: " "
+              text run at (6,51) width 48: "<div> "
+              text run at (54,51) width 0: " "
+              text run at (6,66) width 224: "   How about regular text..."
+              text run at (230,66) width 0: " "
+              text run at (6,81) width 112: "   <div></div>"
+              text run at (118,81) width 0: " "
+              text run at (6,96) width 48: "</div>"
+          RenderBlock {P} at (16,204) size 583x54
+            RenderText {#text} at (0,0) size 567x53
+              text run at (0,0) width 567: "The CSS selector should match the inner div element, because it is the first child"
+              text run at (0,18) width 173: "of the outer div element. "
+              text run at (173,18) width 348: "Regular text is not an element, so it should not be"
+              text run at (0,36) width 307: "considered when determining the first child."
+        RenderListItem {LI} at (40,1256) size 615x257 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#009900]
+            RenderBlock {BLOCKQUOTE} at (0,0) size 583x0 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "5"
+            RenderText {#text} at (6,8) size 224x106
+              text run at (6,8) width 144: "div :first-child {"
+              text run at (150,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 48: "<div> "
+              text run at (54,54) width 0: " "
+              text run at (6,69) width 224: "   <blockquote></blockquote>"
+              text run at (230,69) width 0: " "
+              text run at (6,84) width 112: "   <div></div>"
+              text run at (118,84) width 0: " "
+              text run at (6,99) width 48: "</div>"
+          RenderBlock {P} at (16,189) size 583x36
+            RenderText {#text} at (0,0) size 582x35
+              text run at (0,0) width 582: "The CSS selector should not match the inner div element, because it is the second"
+              text run at (0,18) width 203: "child of the outer div element"
+        RenderListItem {LI} at (40,1561) size 615x287 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,24) size 583x0
+          RenderBlock {PRE} at (16,53) size 583x150 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "6"
+            RenderText {#text} at (6,8) size 520x136
+              text run at (6,8) width 144: "div :first-child {"
+              text run at (150,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 40: "<div>"
+              text run at (46,54) width 0: " "
+              text run at (6,69) width 256: "   <div id='insertBefore'></div>"
+              text run at (262,69) width 0: " "
+              text run at (6,84) width 48: "</div>"
+              text run at (54,84) width 0: " "
+              text run at (6,99) width 0: " "
+              text run at (6,114) width 392: "var ib = document.getElementById('insertBefore');"
+              text run at (398,114) width 0: " "
+              text run at (6,129) width 520: "ib.parentElement.insertBefore(document.createElement(\"div\"), ib);"
+          RenderBlock {P} at (16,219) size 583x36
+            RenderText {#text} at (0,0) size 567x35
+              text run at (0,0) width 567: "The CSS selector should match the div element that is inserted by the Javascript"
+              text run at (0,18) width 39: "code."
+        RenderListItem {LI} at (40,1896) size 615x269 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,0) size 583x0 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x150 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "7"
+            RenderText {#text} at (6,8) size 520x136
+              text run at (6,8) width 144: "div :first-child {"
+              text run at (150,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 40: "<div>"
+              text run at (46,54) width 0: " "
+              text run at (6,69) width 256: "   <div id='insertBefore'></div>"
+              text run at (262,69) width 0: " "
+              text run at (6,84) width 48: "</div>"
+              text run at (54,84) width 0: " "
+              text run at (6,99) width 0: " "
+              text run at (6,114) width 392: "var ib = document.getElementById('insertBefore');"
+              text run at (398,114) width 0: " "
+              text run at (6,129) width 520: "ib.parentElement.insertBefore(document.createElement(\"div\"), ib);"
+          RenderBlock {P} at (16,219) size 583x18
+            RenderText {#text} at (0,0) size 515x17
+              text run at (0,0) width 515: "The original div element should not be a match for the :first-child selector."
diff --git a/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.checksum b/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.checksum
new file mode 100644
index 0000000..8df87ce
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.checksum
@@ -0,0 +1 @@
+3840473f25447e19cd6cce4493f3768e
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.png b/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.png
new file mode 100644
index 0000000..a1cf3d9
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.png
Binary files differ
diff --git a/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.txt b/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.txt
new file mode 100644
index 0000000..bf464a4
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/css/first-of-type-pseudo-class-expected.txt
@@ -0,0 +1,229 @@
+layer at (0,0) size 785x2902
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x2902
+  RenderBlock {HTML} at (0,0) size 785x2902
+    RenderBody {BODY} at (8,16) size 769x2838 [bgcolor=#FFFFFF]
+      RenderBlock {P} at (0,0) size 769x18
+        RenderText {#text} at (0,0) size 165x17
+          text run at (0,0) width 165: "This page is part of the "
+        RenderInline {A} at (0,0) size 73x17 [color=#0000EE]
+          RenderText {#text} at (165,0) size 73x17
+            text run at (165,0) width 73: "CSS3.info"
+        RenderText {#text} at (238,0) size 4x17
+          text run at (238,0) width 4: " "
+        RenderInline {A} at (0,0) size 131x17 [color=#0000EE]
+          RenderText {#text} at (242,0) size 131x17
+            text run at (242,0) width 131: "CSS selectors test"
+        RenderText {#text} at (373,0) size 133x17
+          text run at (373,0) width 133: ". See more info on "
+        RenderInline {A} at (0,0) size 111x17 [color=#0000EE]
+          RenderText {#text} at (506,0) size 111x17
+            text run at (506,0) width 111: "CSS3 selectors"
+        RenderText {#text} at (617,0) size 4x17
+          text run at (617,0) width 4: "."
+      RenderBlock {DIV} at (0,34) size 769x0 [bgcolor=#009900]
+      RenderBlock {OL} at (0,34) size 769x2804
+        RenderListItem {LI} at (40,0) size 615x212 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+          RenderBlock {PRE} at (16,53) size 583x75 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "1"
+            RenderText {#text} at (6,8) size 280x61
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 280: "<div>Does this element match?</div>"
+          RenderBlock {P} at (16,144) size 583x36
+            RenderText {#text} at (0,0) size 551x35
+              text run at (0,0) width 551: "The CSS selector should match the marked div element, because it is the only"
+              text run at (0,18) width 137: "element of this type"
+        RenderListItem {LI} at (40,260) size 615x227 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,24) size 583x0
+          RenderBlock {PRE} at (16,53) size 583x90 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "2"
+            RenderText {#text} at (6,8) size 280x76
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 280: "<div>Does this element match?</div>"
+              text run at (286,54) width 0: " "
+              text run at (6,69) width 88: "<div></div>"
+          RenderBlock {P} at (16,159) size 583x36
+            RenderText {#text} at (0,0) size 546x35
+              text run at (0,0) width 546: "The CSS selector should match the marked div element, because it is the first"
+              text run at (0,18) width 137: "element of this type"
+        RenderListItem {LI} at (40,535) size 615x227 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {BLOCKQUOTE} at (0,0) size 583x0 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+          RenderBlock {PRE} at (16,53) size 583x90 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "3"
+            RenderText {#text} at (6,8) size 280x76
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 200: "<blockquote></blockquote>"
+              text run at (206,54) width 0: " "
+              text run at (6,69) width 280: "<div>Does this element match?</div>"
+          RenderBlock {P} at (16,159) size 583x36
+            RenderText {#text} at (0,0) size 546x35
+              text run at (0,0) width 546: "The CSS selector should match the marked div element, because it is the first"
+              text run at (0,18) width 137: "element of this type"
+        RenderListItem {LI} at (40,810) size 615x257 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x0 [bgcolor=#009900]
+            RenderBlock {BLOCKQUOTE} at (0,0) size 583x24 [bgcolor=#009900]
+              RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "4"
+            RenderText {#text} at (6,8) size 304x106
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 88: "<div></div>"
+              text run at (94,54) width 0: " "
+              text run at (6,69) width 96: "<blockquote>"
+              text run at (102,69) width 0: " "
+              text run at (6,84) width 304: "   <div>Does this element match?</div>"
+              text run at (310,84) width 0: " "
+              text run at (6,99) width 104: "</blockquote>"
+          RenderBlock {P} at (16,189) size 583x36
+            RenderText {#text} at (0,0) size 546x35
+              text run at (0,0) width 546: "The CSS selector should match the marked div element, because it is the first"
+              text run at (0,18) width 230: "element of this type in this scope"
+        RenderListItem {LI} at (40,1115) size 615x242 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+              RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x105 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "5"
+            RenderText {#text} at (6,8) size 304x91
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 40: "<div>"
+              text run at (46,54) width 0: " "
+              text run at (6,69) width 304: "   <div>Does this element match?</div>"
+              text run at (310,69) width 0: " "
+              text run at (6,84) width 48: "</div>"
+          RenderBlock {P} at (16,174) size 583x36
+            RenderText {#text} at (0,0) size 546x35
+              text run at (0,0) width 546: "The CSS selector should match the marked div element, because it is the first"
+              text run at (0,18) width 280: "element of this type in the current scope"
+        RenderListItem {LI} at (40,1405) size 615x257 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {BLOCKQUOTE} at (0,0) size 583x0 [bgcolor=#009900]
+              RenderBlock {DIV} at (0,0) size 583x0
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "6"
+            RenderText {#text} at (6,8) size 280x106
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 96: "<blockquote>"
+              text run at (102,54) width 0: " "
+              text run at (6,69) width 112: "   <div></div>"
+              text run at (118,69) width 0: " "
+              text run at (6,84) width 104: "</blockquote>"
+              text run at (110,84) width 0: " "
+              text run at (6,99) width 280: "<div>Does this element match?</div>"
+          RenderBlock {P} at (16,189) size 583x36
+            RenderText {#text} at (0,0) size 546x35
+              text run at (0,0) width 546: "The CSS selector should match the marked div element, because it is the first"
+              text run at (0,18) width 280: "element of this type in the current scope"
+        RenderListItem {LI} at (40,1710) size 615x227 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,0) size 583x0 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x90 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "7"
+            RenderText {#text} at (6,8) size 280x76
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 88: "<div></div>"
+              text run at (94,54) width 0: " "
+              text run at (6,69) width 280: "<div>Does this element match?</div>"
+          RenderBlock {P} at (16,159) size 583x36
+            RenderText {#text} at (0,0) size 543x35
+              text run at (0,0) width 543: "The CSS selector should not match the marked div element, because it is the"
+              text run at (0,18) width 193: "second element of this type"
+        RenderListItem {LI} at (40,1985) size 615x227 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,0) size 583x0 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x90 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "8"
+            RenderText {#text} at (6,8) size 280x76
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 88: "<DIV></DIV>"
+              text run at (94,54) width 0: " "
+              text run at (6,69) width 280: "<div>Does this element match?</div>"
+          RenderBlock {P} at (16,159) size 583x36
+            RenderText {#text} at (0,0) size 543x35
+              text run at (0,0) width 543: "The CSS selector should not match the marked div element, because it is the"
+              text run at (0,18) width 193: "second element of this type"
+        RenderListItem {LI} at (40,2260) size 615x257 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,24) size 583x0
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-37,6) size 17x17: "9"
+            RenderText {#text} at (6,8) size 520x106
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 232: "<div id='insertBefore'></div>"
+              text run at (238,54) width 0: " "
+              text run at (6,69) width 0: " "
+              text run at (6,84) width 392: "var ib = document.getElementById('insertBefore');"
+              text run at (398,84) width 0: " "
+              text run at (6,99) width 520: "ib.parentElement.insertBefore(document.createElement(\"div\"), ib);"
+          RenderBlock {P} at (16,189) size 583x36
+            RenderText {#text} at (0,0) size 567x35
+              text run at (0,0) width 567: "The CSS selector should match the div element that is inserted by the Javascript"
+              text run at (0,18) width 39: "code."
+        RenderListItem {LI} at (40,2565) size 615x239 [bgcolor=#AAAAAA]
+          RenderBlock {DIV} at (16,16) size 583x24 [bgcolor=#009900]
+            RenderBlock {DIV} at (0,0) size 583x0 [bgcolor=#990000]
+            RenderBlock {DIV} at (0,0) size 583x24
+          RenderBlock {PRE} at (16,53) size 583x120 [bgcolor=#FFFFFF]
+            RenderListMarker at (-46,6) size 26x17: "10"
+            RenderText {#text} at (6,8) size 520x106
+              text run at (6,8) width 152: "div:first-of-type {"
+              text run at (158,8) width 0: " "
+              text run at (6,24) width 8: "}"
+              text run at (14,24) width 0: " "
+              text run at (6,39) width 0: " "
+              text run at (6,54) width 232: "<div id='insertBefore'></div>"
+              text run at (238,54) width 0: " "
+              text run at (6,69) width 0: " "
+              text run at (6,84) width 392: "var ib = document.getElementById('insertBefore');"
+              text run at (398,84) width 0: " "
+              text run at (6,99) width 520: "ib.parentElement.insertBefore(document.createElement(\"div\"), ib);"
+          RenderBlock {P} at (16,189) size 583x18
+            RenderText {#text} at (0,0) size 529x17
+              text run at (0,0) width 529: "The original div element should not be a match for the :first-of-type selector."
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 164dd92..29cfac7 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2008-02-01  David Hyatt  <hyatt@apple.com>
+
+        Make :first-child and :first-of-type properly dynamic when the DOM changes.  Brings the Acid3 score up
+        to 66/100.
+
+        Reviewed by olliej
+
+        Added fast/css/first-child-pseudo-class.html, fast/css/first-of-type-pseudo-class.html, fast/css/empty-body-test.html
+
+        * css/CSSGrammar.y:
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::checkOneSelector):
+        * dom/Element.cpp:
+        (WebCore::Element::recalcStyle):
+        (WebCore::Element::childrenChanged):
+        * rendering/RenderStyle.cpp:
+        (WebCore::RenderStyle::RenderStyle):
+        * rendering/RenderStyle.h:
+        (WebCore::RenderStyle::childrenAffectedByFirstChildRules):
+        (WebCore::RenderStyle::setChildrenAffectedByFirstChildRules):
+        (WebCore::RenderStyle::childrenAffectedByLastChildRules):
+        (WebCore::RenderStyle::setChildrenAffectedByLastChildRules):
+        (WebCore::RenderStyle::childrenAffectedByPositionalRules):
+        (WebCore::RenderStyle::setChildrenAffectedByPositionalRules):
+        (WebCore::RenderStyle::firstChildState):
+        (WebCore::RenderStyle::setFirstChildState):
+        (WebCore::RenderStyle::lastChildState):
+        (WebCore::RenderStyle::setLastChildState):
+
 2008-02-02  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/WebCore/css/CSSGrammar.y b/WebCore/css/CSSGrammar.y
index 9c07b9e..04bdde3 100644
--- a/WebCore/css/CSSGrammar.y
+++ b/WebCore/css/CSSGrammar.y
@@ -855,7 +855,8 @@
         if (type == CSSSelector::PseudoUnknown)
             $$ = 0;
         else if (type == CSSSelector::PseudoEmpty ||
-                 type == CSSSelector::PseudoFirstChild) {
+                 type == CSSSelector::PseudoFirstChild ||
+                 type == CSSSelector::PseudoFirstOfType) {
             CSSParser* p = static_cast<CSSParser*>(parser);
             Document* doc = p->document();
             if (doc)
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index 9295b92..f85e9e5 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -1593,35 +1593,54 @@
                         }
                     }
                 }
-                if (m_element == e)
-                    m_style->setEmptyState(result);
-                else if (e && e->renderStyle() && (e->document()->usesSiblingRules() || e->renderStyle()->unique()))
-                    e->renderStyle()->setEmptyState(result);
+                if (!m_collectRulesOnly) {
+                    if (m_element == e)
+                        m_style->setEmptyState(result);
+                    else if (e->renderStyle() && (e->document()->usesSiblingRules() || e->renderStyle()->unique()))
+                        e->renderStyle()->setEmptyState(result);
+                }
                 return result;
             }
             case CSSSelector::PseudoFirstChild: {
-                // first-child matches the first child that is an element!
+                // first-child matches the first child that is an element
                 if (e->parentNode() && e->parentNode()->isElementNode()) {
-                    Node *n = e->previousSibling();
+                    bool result = false;
+                    Node* n = e->previousSibling();
                     while (n && !n->isElementNode())
                         n = n->previousSibling();
                     if (!n)
-                        return true;
+                        result = true;
+                    if (!m_collectRulesOnly) {
+                        RenderStyle* childStyle = (m_element == e) ? m_style : e->renderStyle();
+                        RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+                        if (parentStyle)
+                            parentStyle->setChildrenAffectedByFirstChildRules();
+                        if (result && childStyle)
+                            childStyle->setFirstChildState();
+                    }
+                    return result;
                 }
                 break;
             }
             case CSSSelector::PseudoFirstOfType: {
-                // first-of-type matches the first element of its type!
+                // first-of-type matches the first element of its type
                 if (e->parentNode() && e->parentNode()->isElementNode()) {
+                    bool result = false;
                     const QualifiedName& type = e->tagQName();
-                    Node *n = e->previousSibling();
+                    Node* n = e->previousSibling();
                     while (n) {
                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
                             break;
                         n = n->previousSibling();
                     }
                     if (!n)
-                        return true;
+                        result = true;
+                    if (!m_collectRulesOnly) {
+                        RenderStyle* parentStyle = (m_element == e) ? m_parentStyle : e->parentNode()->renderStyle();
+                        if (parentStyle)
+                            parentStyle->setChildrenAffectedByPositionalRules();
+                    }
+                    return result;
                 }
                 break;
             }
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 920b36a..42d3787 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -698,9 +698,10 @@
 
 void Element::recalcStyle(StyleChange change)
 {
-    // ### should go away and be done in renderobject
     RenderStyle* currentStyle = renderStyle();
     bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
+    bool hasPositionalChildren = currentStyle && (currentStyle->childrenAffectedByFirstChildRules() || currentStyle->childrenAffectedByLastChildRules() ||
+                                                  currentStyle->childrenAffectedByPositionalRules());
 
 #if ENABLE(SVG)
     if (!hasParentStyle && isShadowNode() && isSVGElement())
@@ -727,13 +728,20 @@
         }
 
         if (currentStyle && newStyle) {
-            // Preserve "affected by" bits that were propagated to us from descendants
+            // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
+            // style change (e.g., only inline style changed).
             if (currentStyle->affectedByHoverRules())
                 newStyle->setAffectedByHoverRules(true);
             if (currentStyle->affectedByActiveRules())
                 newStyle->setAffectedByActiveRules(true);
             if (currentStyle->affectedByDragRules())
                 newStyle->setAffectedByDragRules(true);
+            if (currentStyle->childrenAffectedByPositionalRules())
+                newStyle->setChildrenAffectedByPositionalRules();
+            if (currentStyle->childrenAffectedByFirstChildRules())
+                newStyle->setChildrenAffectedByFirstChildRules();
+            if (currentStyle->childrenAffectedByLastChildRules())
+                newStyle->setChildrenAffectedByLastChildRules();
         }
 
         if (ch != NoChange) {
@@ -753,7 +761,7 @@
         newStyle->deref(document()->renderArena());
 
         if (change != Force) {
-            if (document()->usesDescendantRules() && styleChangeType() == FullStyleChange)
+            if ((document()->usesDescendantRules() || hasPositionalChildren) && styleChangeType() == FullStyleChange)
                 change = Force;
             else
                 change = ch;
@@ -785,6 +793,55 @@
     }
 }
 
+static bool checkFirstChildRules(Element* e, RenderStyle* style)
+{
+    if (style->childrenAffectedByFirstChildRules()) {
+        // Check our first two children.  They need to be true and false respectively.
+        bool checkingFirstChild = true;
+        for (Node* n = e->firstChild(); n; n = n->nextSibling()) {
+            if (n->isElementNode()) {
+                if (checkingFirstChild) {
+                    if (n->attached() && n->renderStyle() && !n->renderStyle()->firstChildState())
+                        return true;
+                    checkingFirstChild = false;
+                } else {
+                    if (n->attached() && n->renderStyle() && n->renderStyle()->firstChildState())
+                        return true;
+                    break;
+                }
+            }
+        }
+    } 
+    return false;
+}
+
+static bool checkLastChildRules(Element* e, RenderStyle* style)
+{
+    if (style->childrenAffectedByLastChildRules()) {
+        // Check our last two children.  They need to be true and false respectively.
+        bool checkingLastChild = true;
+        for (Node* n = e->lastChild(); n; n = n->previousSibling()) {
+            if (n->isElementNode()) {
+                if (checkingLastChild) {
+                    if (n->attached() && n->renderStyle() && !n->renderStyle()->lastChildState())
+                        return true;
+                    checkingLastChild = false;
+                } else {
+                    if (n->attached() && n->renderStyle() && n->renderStyle()->lastChildState())
+                        return true;
+                    break;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+static bool checkEmptyRules(Element* e, RenderStyle* style)
+{
+    return (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()));
+}
+
 void Element::childrenChanged()
 {
     ContainerNode::childrenChanged();
@@ -796,8 +853,15 @@
     if (!style)
         return;
 
-    if (style->affectedByEmpty() && (!style->emptyState() || hasChildNodes()))
-        setChanged(); // Need to resolve style again, since our :empty state has potentially changed.
+    if (style->childrenAffectedByPositionalRules()) {
+        setChanged();
+        return;
+    }
+
+    if (checkFirstChildRules(this, style) || checkLastChildRules(this, style) || checkEmptyRules(this, style)) {
+        setChanged();
+        return;
+    }
 }
 
 void Element::dispatchAttrRemovalEvent(Attribute*)
diff --git a/WebCore/rendering/RenderStyle.cpp b/WebCore/rendering/RenderStyle.cpp
index 7d51fba..516c4fd 100644
--- a/WebCore/rendering/RenderStyle.cpp
+++ b/WebCore/rendering/RenderStyle.cpp
@@ -932,6 +932,11 @@
     , m_unique(false)
     , m_affectedByEmpty(false)
     , m_emptyState(false)
+    , m_childrenAffectedByFirstChildRules(false)
+    , m_childrenAffectedByLastChildRules(false)
+    , m_childrenAffectedByPositionalRules(false)
+    , m_firstChildState(false)
+    , m_lastChildState(false)
     , m_ref(0)
 #if ENABLE(SVG)
     , m_svgStyle(defaultStyle->m_svgStyle)
@@ -947,6 +952,11 @@
     , m_unique(false)
     , m_affectedByEmpty(false)
     , m_emptyState(false)
+    , m_childrenAffectedByFirstChildRules(false)
+    , m_childrenAffectedByLastChildRules(false)
+    , m_childrenAffectedByPositionalRules(false)
+    , m_firstChildState(false)
+    , m_lastChildState(false)
     , m_ref(1)
 {
     setBitDefaults();
@@ -984,6 +994,11 @@
     , m_unique(false)
     , m_affectedByEmpty(false)
     , m_emptyState(false)
+    , m_childrenAffectedByFirstChildRules(false)
+    , m_childrenAffectedByLastChildRules(false)
+    , m_childrenAffectedByPositionalRules(false)
+    , m_firstChildState(false)
+    , m_lastChildState(false)
     , m_ref(0)
 #if ENABLE(SVG)
     , m_svgStyle(o.m_svgStyle)
diff --git a/WebCore/rendering/RenderStyle.h b/WebCore/rendering/RenderStyle.h
index ef81db8..c8cea7c 100644
--- a/WebCore/rendering/RenderStyle.h
+++ b/WebCore/rendering/RenderStyle.h
@@ -1470,6 +1470,14 @@
     bool m_affectedByEmpty : 1;
     bool m_emptyState : 1;
     
+    // We optimize for :first-child and :last-child.  The other positional child selectors like nth-child or
+    // *-child-of-type, we will just give up and re-evaluate whenever children change at all.
+    bool m_childrenAffectedByFirstChildRules : 1;
+    bool m_childrenAffectedByLastChildRules  : 1;
+    bool m_childrenAffectedByPositionalRules : 1;
+    bool m_firstChildState : 1;
+    bool m_lastChildState : 1;
+
     int m_ref;
     
 #if ENABLE(SVG)
@@ -2116,6 +2124,16 @@
     bool affectedByEmpty() const { return m_affectedByEmpty; }
     bool emptyState() const { return m_emptyState; }
     void setEmptyState(bool b) { m_affectedByEmpty = true; m_unique = true; m_emptyState = b; }
+    bool childrenAffectedByFirstChildRules() const { return m_childrenAffectedByFirstChildRules; }
+    void setChildrenAffectedByFirstChildRules() { m_childrenAffectedByFirstChildRules = true; }
+    bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; }
+    void setChildrenAffectedByLastChildRules() { m_childrenAffectedByLastChildRules = true; }
+    bool childrenAffectedByPositionalRules() const { return m_childrenAffectedByPositionalRules; }
+    void setChildrenAffectedByPositionalRules() { m_childrenAffectedByPositionalRules = true; }
+    bool firstChildState() const { return m_firstChildState; }
+    void setFirstChildState() { m_firstChildState = true; }
+    bool lastChildState() const { return m_lastChildState; }
+    void setLastChildState() { m_lastChildState = true; }
 
     // Initial values for all the properties
     static bool initialBackgroundAttachment() { return true; }