<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre, #msg p { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[28868] trunk/WebCore</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/28868">28868</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2007-12-19 12:11:09 -0800 (Wed, 19 Dec 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>        Reviewed by Maciej.

        http://bugs.webkit.org/show_bug.cgi?id=16511
        Speed up ClassNodeList and NamedNodeList by using the caching mechanism employed by ChildNodeList.
        - This give a ~2.15x speedup on the native test @ http://ejohn.org/apps/classname/

        * dom/ChildNodeList.cpp: Use the caching NodeList constructor to turn on caching.
        (WebCore::ChildNodeList::ChildNodeList):
        * dom/ClassNodeList.cpp:
        (WebCore::ClassNodeList::ClassNodeList):
        * dom/ClassNodeList.h:

        Move getElementsByName and getElementsByClassName to Node so they
        can use easily employ the caching already used by ChildNodeLists.  In the case of 
        getElementsByClassName, this reduces code duplication in Element as well
        * dom/Document.cpp:
        * dom/Document.h:

        Move getElementsByClassName to Node.
        * dom/Element.cpp:
        * dom/Element.h:

        * dom/NameNodeList.cpp: Use the caching NodeList constructor to turn on caching.
        (WebCore::NameNodeList::NameNodeList):
        (WebCore::NameNodeList::item):
        * dom/NameNodeList.h:

        Add maps of caches for ClassNodeLists and NameNodeList to NodeListsNodeData.
        * dom/Node.cpp:
        (WebCore::TagNodeList::TagNodeList):
        (WebCore::Node::Node):
        (WebCore::Node::~Node):
        (WebCore::Node::childNodes):
        (WebCore::Node::registerNodeList):
        (WebCore::Node::getElementsByName):
        (WebCore::Node::getElementsByClassName):
        * dom/Node.h: Make m_nodeLists an OwnPtr.  Moved getElementsByName and getElementsByClassName here

        Allow subclasses to choose whether they want to receive the notifications using a new bit.
        * dom/NodeList.cpp:
        (WebCore::NodeList::NodeList):
        * dom/NodeList.h:
        (WebCore::NodeList::needsNotifications):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebCoreChangeLog">trunk/WebCore/ChangeLog</a></li>
<li><a href="#trunkWebCoredomChildNodeListcpp">trunk/WebCore/dom/ChildNodeList.cpp</a></li>
<li><a href="#trunkWebCoredomClassNodeListcpp">trunk/WebCore/dom/ClassNodeList.cpp</a></li>
<li><a href="#trunkWebCoredomClassNodeListh">trunk/WebCore/dom/ClassNodeList.h</a></li>
<li><a href="#trunkWebCoredomDocumentcpp">trunk/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkWebCoredomDocumenth">trunk/WebCore/dom/Document.h</a></li>
<li><a href="#trunkWebCoredomElementcpp">trunk/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkWebCoredomElementh">trunk/WebCore/dom/Element.h</a></li>
<li><a href="#trunkWebCoredomNameNodeListcpp">trunk/WebCore/dom/NameNodeList.cpp</a></li>
<li><a href="#trunkWebCoredomNameNodeListh">trunk/WebCore/dom/NameNodeList.h</a></li>
<li><a href="#trunkWebCoredomNodecpp">trunk/WebCore/dom/Node.cpp</a></li>
<li><a href="#trunkWebCoredomNodeh">trunk/WebCore/dom/Node.h</a></li>
<li><a href="#trunkWebCoredomNodeListcpp">trunk/WebCore/dom/NodeList.cpp</a></li>
<li><a href="#trunkWebCoredomNodeListh">trunk/WebCore/dom/NodeList.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/ChangeLog (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/ChangeLog        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/ChangeLog        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2007-12-19  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Reviewed by Maciej.
+
+        http://bugs.webkit.org/show_bug.cgi?id=16511
+        Speed up ClassNodeList and NamedNodeList by using the caching mechanism employed by ChildNodeList.
+        - This give a ~2.15x speedup on the native test @ http://ejohn.org/apps/classname/
+
+        * dom/ChildNodeList.cpp: Use the caching NodeList constructor to turn on caching.
+        (WebCore::ChildNodeList::ChildNodeList):
+        * dom/ClassNodeList.cpp:
+        (WebCore::ClassNodeList::ClassNodeList):
+        * dom/ClassNodeList.h:
+
+        Move getElementsByName and getElementsByClassName to Node so they
+        can use easily employ the caching already used by ChildNodeLists.  In the case of 
+        getElementsByClassName, this reduces code duplication in Element as well
+        * dom/Document.cpp:
+        * dom/Document.h:
+
+        Move getElementsByClassName to Node.
+        * dom/Element.cpp:
+        * dom/Element.h:
+
+        * dom/NameNodeList.cpp: Use the caching NodeList constructor to turn on caching.
+        (WebCore::NameNodeList::NameNodeList):
+        (WebCore::NameNodeList::item):
+        * dom/NameNodeList.h:
+
+        Add maps of caches for ClassNodeLists and NameNodeList to NodeListsNodeData.
+        * dom/Node.cpp:
+        (WebCore::TagNodeList::TagNodeList):
+        (WebCore::Node::Node):
+        (WebCore::Node::~Node):
+        (WebCore::Node::childNodes):
+        (WebCore::Node::registerNodeList):
+        (WebCore::Node::getElementsByName):
+        (WebCore::Node::getElementsByClassName):
+        * dom/Node.h: Make m_nodeLists an OwnPtr.  Moved getElementsByName and getElementsByClassName here
+
+        Allow subclasses to choose whether they want to receive the notifications using a new bit.
+        * dom/NodeList.cpp:
+        (WebCore::NodeList::NodeList):
+        * dom/NodeList.h:
+        (WebCore::NodeList::needsNotifications):
+
</ins><span class="cx"> 2007-12-19  Dave Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add support for GDI text rendering to WebKit.
</span></span></pre></div>
<a id="trunkWebCoredomChildNodeListcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/ChildNodeList.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/ChildNodeList.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/ChildNodeList.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> ChildNodeList::ChildNodeList(Node* n, NodeList::Caches* info)
</span><del>-    : NodeList(n, info)
</del><ins>+    : NodeList(n, info, false)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoredomClassNodeListcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/ClassNodeList.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/ClassNodeList.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/ClassNodeList.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -36,10 +36,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-ClassNodeList::ClassNodeList(PassRefPtr&lt;Node&gt; rootNode, const AtomicString&amp; className)
-    : NodeList(rootNode)
</del><ins>+ClassNodeList::ClassNodeList(PassRefPtr&lt;Node&gt; rootNode, const String&amp; classNames, NodeList::Caches* caches)
+    : NodeList(rootNode, caches, true)
</ins><span class="cx"> {
</span><del>-    m_classNames.parseClassAttribute(className, m_rootNode-&gt;document()-&gt;inCompatMode());
</del><ins>+    m_classNames.parseClassAttribute(classNames, m_rootNode-&gt;document()-&gt;inCompatMode());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned ClassNodeList::length() const
</span></span></pre></div>
<a id="trunkWebCoredomClassNodeListh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/ClassNodeList.h (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/ClassNodeList.h        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/ClassNodeList.h        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -30,15 +30,16 @@
</span><span class="cx"> #ifndef ClassNodeList_h
</span><span class="cx"> #define ClassNodeList_h
</span><span class="cx"> 
</span><del>-#include &quot;AtomicString.h&quot;
</del><span class="cx"> #include &quot;ClassNames.h&quot;
</span><span class="cx"> #include &quot;NodeList.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+    class String;
+
</ins><span class="cx">     class ClassNodeList : public NodeList {
</span><span class="cx">     public:
</span><del>-        ClassNodeList(PassRefPtr&lt;Node&gt; rootNode, const AtomicString&amp; className);
</del><ins>+        ClassNodeList(PassRefPtr&lt;Node&gt; rootNode, const String&amp; classNames, NodeList::Caches*);
</ins><span class="cx"> 
</span><span class="cx">         virtual unsigned length() const;
</span><span class="cx">         virtual Node* item(unsigned index) const;
</span></span></pre></div>
<a id="trunkWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/Document.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/Document.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/Document.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -3496,16 +3496,6 @@
</span><span class="cx">     return iter-&gt;second;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;NameNodeList&gt; Document::getElementsByName(const String&amp; elementName)
-{
-    return new NameNodeList(this, elementName);
-}
-
-PassRefPtr&lt;NodeList&gt; Document::getElementsByClassName(const String&amp; className)
-{
-    return new ClassNodeList(this, className);
-}
-
</del><span class="cx"> void Document::finishedParsing()
</span><span class="cx"> {
</span><span class="cx">     setParsing(false);
</span></span></pre></div>
<a id="trunkWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/Document.h (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/Document.h        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/Document.h        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -211,9 +211,6 @@
</span><span class="cx">     virtual String baseURI() const;
</span><span class="cx"> 
</span><span class="cx">     PassRefPtr&lt;Node&gt; adoptNode(PassRefPtr&lt;Node&gt; source, ExceptionCode&amp;);
</span><del>-    
-    PassRefPtr&lt;NameNodeList&gt; getElementsByName(const String&amp; elementName);
-    PassRefPtr&lt;NodeList&gt; getElementsByClassName(const String&amp; className);
</del><span class="cx"> 
</span><span class="cx">     PassRefPtr&lt;HTMLCollection&gt; images();
</span><span class="cx">     PassRefPtr&lt;HTMLCollection&gt; embeds();
</span></span></pre></div>
<a id="trunkWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/Element.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/Element.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/Element.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -1123,11 +1123,6 @@
</span><span class="cx">     return rd-&gt;m_computedStyle;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;NodeList&gt; Element::getElementsByClassName(const String&amp; className)
-{
-    return new ClassNodeList(this, className);
-}
-
</del><span class="cx"> void Element::cancelFocusAppearanceUpdate()
</span><span class="cx"> {
</span><span class="cx">     if (ElementRareData* rd = rareData())
</span></span></pre></div>
<a id="trunkWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/Element.h (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/Element.h        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/Element.h        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -162,8 +162,6 @@
</span><span class="cx">     virtual void focus(bool restorePreviousSelection = true);
</span><span class="cx">     virtual void updateFocusAppearance(bool restorePreviousSelection);
</span><span class="cx">     void blur();
</span><del>-    
-    PassRefPtr&lt;NodeList&gt; getElementsByClassName(const String&amp;);
</del><span class="cx"> 
</span><span class="cx"> #ifndef NDEBUG
</span><span class="cx">     virtual void dump(TextStream* , DeprecatedString ind = &quot;&quot;) const;
</span></span></pre></div>
<a id="trunkWebCoredomNameNodeListcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/NameNodeList.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/NameNodeList.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/NameNodeList.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -30,8 +30,8 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx"> 
</span><del>-NameNodeList::NameNodeList(Node* root, const String&amp; name)
-    : NodeList(root)
</del><ins>+NameNodeList::NameNodeList(Node* root, const String&amp; name, NodeList::Caches* caches)
+    : NodeList(root, caches, true)
</ins><span class="cx">     , m_nodeName(name)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx">     return recursiveLength();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Node* NameNodeList::item (unsigned index) const
</del><ins>+Node* NameNodeList::item(unsigned index) const
</ins><span class="cx"> {
</span><span class="cx">     return recursiveItem(index);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkWebCoredomNameNodeListh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/NameNodeList.h (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/NameNodeList.h        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/NameNodeList.h        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx">  */
</span><span class="cx"> class NameNodeList : public NodeList {
</span><span class="cx"> public:
</span><del>-    NameNodeList(Node* root, const String&amp; name);
</del><ins>+    NameNodeList(Node* root, const String&amp; name, NodeList::Caches*);
</ins><span class="cx"> 
</span><span class="cx">     // DOM methods overridden from  parent classes
</span><span class="cx"> 
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx">     virtual Node* item(unsigned index) const;
</span><span class="cx"> 
</span><span class="cx">     // Other methods (not part of DOM)
</span><ins>+    
</ins><span class="cx">     virtual void rootNodeAttributeChanged() { NodeList::rootNodeChildrenChanged(); }
</span><span class="cx"> 
</span><span class="cx"> protected:
</span></span></pre></div>
<a id="trunkWebCoredomNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/Node.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/Node.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/Node.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -26,14 +26,17 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CString.h&quot;
</span><span class="cx"> #include &quot;ChildNodeList.h&quot;
</span><ins>+#include &quot;ClassNodeList.h&quot;
</ins><span class="cx"> #include &quot;DOMImplementation.h&quot;
</span><span class="cx"> #include &quot;Document.h&quot;
</span><span class="cx"> #include &quot;Element.h&quot;
</span><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><ins>+#include &quot;HTMLNames.h&quot;
</ins><span class="cx"> #include &quot;KURL.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><ins>+#include &quot;NameNodeList.h&quot;
</ins><span class="cx"> #include &quot;NamedAttrMap.h&quot;
</span><span class="cx"> #include &quot;RenderObject.h&quot;
</span><span class="cx"> #include &quot;Text.h&quot;
</span><span class="lines">@@ -50,6 +53,8 @@
</span><span class="cx"> struct NodeListsNodeData {
</span><span class="cx">     NodeListSet m_listsToNotify;
</span><span class="cx">     NodeList::Caches m_childNodeListCaches;
</span><ins>+    HashMap&lt;String, NodeList::Caches&gt; m_classNodeListCaches;
+    HashMap&lt;String, NodeList::Caches&gt; m_nameNodeListCaches;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // NodeList that limits to a particular tag.
</span><span class="lines">@@ -68,7 +73,9 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline TagNodeList::TagNodeList(PassRefPtr&lt;Node&gt; rootNode, const AtomicString&amp; namespaceURI, const AtomicString&amp; localName)
</span><del>-    : NodeList(rootNode), m_namespaceURI(namespaceURI), m_localName(localName)
</del><ins>+    : NodeList(rootNode, true)
+    , m_namespaceURI(namespaceURI)
+    , m_localName(localName)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
</span><span class="cx"> }
</span><span class="lines">@@ -138,7 +145,6 @@
</span><span class="cx">       m_previous(0),
</span><span class="cx">       m_next(0),
</span><span class="cx">       m_renderer(0),
</span><del>-      m_nodeLists(0),
</del><span class="cx">       m_tabIndex(0),
</span><span class="cx">       m_hasId(false),
</span><span class="cx">       m_hasClass(false),
</span><span class="lines">@@ -191,7 +197,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     if (renderer())
</span><span class="cx">         detach();
</span><del>-    delete m_nodeLists;
</del><ins>+
</ins><span class="cx">     if (m_previous)
</span><span class="cx">         m_previous-&gt;setNextSibling(0);
</span><span class="cx">     if (m_next)
</span><span class="lines">@@ -217,7 +223,7 @@
</span><span class="cx"> PassRefPtr&lt;NodeList&gt; Node::childNodes()
</span><span class="cx"> {
</span><span class="cx">     if (!m_nodeLists)
</span><del>-        m_nodeLists = new NodeListsNodeData;
</del><ins>+        m_nodeLists.set(new NodeListsNodeData);
</ins><span class="cx"> 
</span><span class="cx">     return new ChildNodeList(this, &amp;m_nodeLists-&gt;m_childNodeListCaches);
</span><span class="cx"> }
</span><span class="lines">@@ -438,7 +444,7 @@
</span><span class="cx"> void Node::registerNodeList(NodeList* list)
</span><span class="cx"> {
</span><span class="cx">     if (!m_nodeLists)
</span><del>-        m_nodeLists = new NodeListsNodeData;
</del><ins>+        m_nodeLists.set(new NodeListsNodeData);
</ins><span class="cx">     else if (!m_document-&gt;hasNodeLists())
</span><span class="cx">         // We haven't been receiving notifications while there were no registered lists, so the cache is invalid now.
</span><span class="cx">         m_nodeLists-&gt;m_childNodeListCaches.reset();
</span><span class="lines">@@ -1207,6 +1213,22 @@
</span><span class="cx">     return new TagNodeList(this, namespaceURI.isEmpty() ? nullAtom : AtomicString(namespaceURI), name);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PassRefPtr&lt;NodeList&gt; Node::getElementsByName(const String&amp; elementName)
+{
+    if (!m_nodeLists)
+        m_nodeLists.set(new NodeListsNodeData);
+
+    return new NameNodeList(this, elementName, &amp;m_nodeLists-&gt;m_nameNodeListCaches.add(elementName, NodeList::Caches()).first-&gt;second);
+}
+
+PassRefPtr&lt;NodeList&gt; Node::getElementsByClassName(const String&amp; classNames)
+{
+    if (!m_nodeLists)
+        m_nodeLists.set(new NodeListsNodeData);
+
+    return new ClassNodeList(this, classNames, &amp;m_nodeLists-&gt;m_classNodeListCaches.add(classNames, NodeList::Caches()).first-&gt;second);
+}
+
</ins><span class="cx"> Document *Node::ownerDocument() const
</span><span class="cx"> {
</span><span class="cx">     Document *doc = document();
</span></span></pre></div>
<a id="trunkWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/Node.h (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/Node.h        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/Node.h        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -24,12 +24,13 @@
</span><span class="cx"> #ifndef Node_h
</span><span class="cx"> #define Node_h
</span><span class="cx"> 
</span><ins>+#include &quot;DeprecatedString.h&quot;
</ins><span class="cx"> #include &quot;DocPtr.h&quot;
</span><del>-#include &quot;DeprecatedString.h&quot;
</del><span class="cx"> #include &quot;PlatformString.h&quot;
</span><span class="cx"> #include &quot;TreeShared.h&quot;
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><ins>+#include &lt;wtf/OwnPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -44,7 +45,6 @@
</span><span class="cx"> class KeyboardEvent;
</span><span class="cx"> class NamedAttrMap;
</span><span class="cx"> class NodeList;
</span><del>-struct NodeListsNodeData;
</del><span class="cx"> class PlatformKeyboardEvent;
</span><span class="cx"> class PlatformMouseEvent;
</span><span class="cx"> class PlatformWheelEvent;
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx"> class RenderObject;
</span><span class="cx"> class RenderStyle;
</span><span class="cx"> class TextStream;
</span><ins>+struct NodeListsNodeData;
</ins><span class="cx"> 
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx"> 
</span><span class="lines">@@ -451,6 +452,9 @@
</span><span class="cx">     PassRefPtr&lt;NodeList&gt; getElementsByTagName(const String&amp;);
</span><span class="cx">     PassRefPtr&lt;NodeList&gt; getElementsByTagNameNS(const String&amp; namespaceURI, const String&amp; localName);
</span><span class="cx"> 
</span><ins>+    PassRefPtr&lt;NodeList&gt; getElementsByName(const String&amp; elementName);
+    PassRefPtr&lt;NodeList&gt; getElementsByClassName(const String&amp; classNames);
+
</ins><span class="cx"> private: // members
</span><span class="cx">     DocPtr&lt;Document&gt; m_document;
</span><span class="cx">     Node* m_previous;
</span><span class="lines">@@ -461,7 +465,7 @@
</span><span class="cx">     virtual void willMoveToNewOwnerDocument() { }
</span><span class="cx">     virtual void didMoveToNewOwnerDocument() { }
</span><span class="cx">     
</span><del>-    NodeListsNodeData* m_nodeLists;
</del><ins>+    OwnPtr&lt;NodeListsNodeData&gt; m_nodeLists;
</ins><span class="cx"> 
</span><span class="cx">     short m_tabIndex;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoredomNodeListcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/NodeList.cpp (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/NodeList.cpp        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/NodeList.cpp        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -30,18 +30,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-NodeList::NodeList(PassRefPtr&lt;Node&gt; rootNode)
</del><ins>+NodeList::NodeList(PassRefPtr&lt;Node&gt; rootNode, bool needsNotifications)
</ins><span class="cx">     : m_rootNode(rootNode)
</span><span class="cx">     , m_caches(new Caches)
</span><span class="cx">     , m_ownsCaches(true)
</span><ins>+    , m_needsNotifications(needsNotifications)
</ins><span class="cx"> {
</span><span class="cx">     m_rootNode-&gt;registerNodeList(this);
</span><span class="cx"> }    
</span><span class="cx"> 
</span><del>-NodeList::NodeList(PassRefPtr&lt;Node&gt; rootNode, NodeList::Caches* info)
</del><ins>+NodeList::NodeList(PassRefPtr&lt;Node&gt; rootNode, NodeList::Caches* info, bool needsNotifications)
</ins><span class="cx">     : m_rootNode(rootNode)
</span><span class="cx">     , m_caches(info)
</span><span class="cx">     , m_ownsCaches(false)
</span><ins>+    , m_needsNotifications(needsNotifications)
</ins><span class="cx"> {
</span><span class="cx">     m_rootNode-&gt;registerNodeList(this);
</span><span class="cx"> }    
</span></span></pre></div>
<a id="trunkWebCoredomNodeListh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/NodeList.h (28867 => 28868)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/NodeList.h        2007-12-19 19:24:10 UTC (rev 28867)
+++ trunk/WebCore/dom/NodeList.h        2007-12-19 20:11:09 UTC (rev 28868)
</span><span class="lines">@@ -49,11 +49,11 @@
</span><span class="cx">         bool isItemCacheValid : 1;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    NodeList(PassRefPtr&lt;Node&gt; rootNode);
-    NodeList(PassRefPtr&lt;Node&gt; rootNode, Caches*);
</del><ins>+    NodeList(PassRefPtr&lt;Node&gt; rootNode, bool needsNotifications);
+    NodeList(PassRefPtr&lt;Node&gt; rootNode, Caches*, bool needsNotifications);
</ins><span class="cx">     virtual ~NodeList();
</span><span class="cx"> 
</span><del>-    bool needsNotifications() const { return m_ownsCaches; }
</del><ins>+    bool needsNotifications() const { return m_needsNotifications; }
</ins><span class="cx"> 
</span><span class="cx">     // DOM methods &amp; attributes for NodeList
</span><span class="cx">     virtual unsigned length() const = 0;
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     RefPtr&lt;Node&gt; m_rootNode;
</span><span class="cx">     mutable Caches* m_caches;
</span><span class="cx">     bool m_ownsCaches;
</span><ins>+    bool m_needsNotifications;
</ins><span class="cx"> 
</span><span class="cx">  private:
</span><span class="cx">     Node* itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const;
</span></span></pre>
</div>
</div>

</body>
</html>