Reviewed by Ken.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Nov 2004 21:42:05 +0000 (21:42 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Nov 2004 21:42:05 +0000 (21:42 +0000)
- merged and cleaned up HTMLCollection and HTMLFormCollection speedups from konqueror

<rdar://problem/3822992> VIP: Program listings pages at directv.com take a really long time to load [HTMLCollection]
<rdar://problem/3701991> Safari unresponsive loading (www.maxim-ic.com) (HTMLCollection)

This is also a start on fixing 5 other bugs, but those need additional work to make
HTMLFormCollection fast.

        * khtml/html/html_documentimpl.h:
        (DOM::HTMLDocumentImpl::collectionInfo):
        * khtml/html/html_formimpl.cpp:
        (DOM::HTMLFormElementImpl::~HTMLFormElementImpl):
        (DOM::HTMLFormElementImpl::isURLAttribute):
        (DOM::HTMLFormElementImpl::registerImgElement):
        (DOM::HTMLFormElementImpl::removeImgElement):
        * khtml/html/html_formimpl.h:
        * khtml/html/html_imageimpl.cpp:
        (HTMLImageElementImpl::HTMLImageElementImpl):
        (HTMLImageElementImpl::~HTMLImageElementImpl):
        * khtml/html/html_imageimpl.h:
        * khtml/html/html_miscimpl.cpp:
        (HTMLCollectionImpl::HTMLCollectionImpl):
        (HTMLCollectionImpl::~HTMLCollectionImpl):
        (HTMLCollectionImpl::updateCollectionInfo):
        (HTMLCollectionImpl::length):
        (HTMLCollectionImpl::item):
        (HTMLCollectionImpl::firstItem):
        (HTMLCollectionImpl::nextItem):
        (HTMLCollectionImpl::namedItem):
        (HTMLCollectionImpl::nextNamedItemInternal):
        (HTMLFormCollectionImpl::getNamedFormItem):
        * khtml/html/html_miscimpl.h:
        (DOM::HTMLCollectionImpl::):
        (DOM::HTMLCollectionImpl::CollectionInfo::CollectionInfo):
        * khtml/html/htmlparser.cpp:
        (KHTMLParser::getElement):
        * khtml/xml/dom_docimpl.cpp:
        (DocumentImpl::DocumentImpl):
        * khtml/xml/dom_docimpl.h:
        (DOM::DocumentImpl::incDOMTreeVersion):
        (DOM::DocumentImpl::domTreeVersion):
        * khtml/xml/dom_nodeimpl.cpp:
        (NodeImpl::attach):
        (NodeImpl::detach):

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

12 files changed:
WebCore/ChangeLog-2005-08-23
WebCore/khtml/html/html_documentimpl.h
WebCore/khtml/html/html_formimpl.cpp
WebCore/khtml/html/html_formimpl.h
WebCore/khtml/html/html_imageimpl.cpp
WebCore/khtml/html/html_imageimpl.h
WebCore/khtml/html/html_miscimpl.cpp
WebCore/khtml/html/html_miscimpl.h
WebCore/khtml/html/htmlparser.cpp
WebCore/khtml/xml/dom_docimpl.cpp
WebCore/khtml/xml/dom_docimpl.h
WebCore/khtml/xml/dom_nodeimpl.cpp

index 78730c5..2a31a7d 100644 (file)
@@ -1,3 +1,52 @@
+2004-11-18  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Ken.
+
+       - merged and cleaned up HTMLCollection and HTMLFormCollection speedups from konqueror
+
+       <rdar://problem/3822992> VIP: Program listings pages at directv.com take a really long time to load [HTMLCollection]
+       <rdar://problem/3701991> Safari unresponsive loading (www.maxim-ic.com) (HTMLCollection)
+
+       This is also a start on fixing 5 other bugs, but those need additional work to make
+       HTMLFormCollection fast.
+
+        * khtml/html/html_documentimpl.h:
+        (DOM::HTMLDocumentImpl::collectionInfo):
+        * khtml/html/html_formimpl.cpp:
+        (DOM::HTMLFormElementImpl::~HTMLFormElementImpl):
+        (DOM::HTMLFormElementImpl::isURLAttribute):
+        (DOM::HTMLFormElementImpl::registerImgElement):
+        (DOM::HTMLFormElementImpl::removeImgElement):
+        * khtml/html/html_formimpl.h:
+        * khtml/html/html_imageimpl.cpp:
+        (HTMLImageElementImpl::HTMLImageElementImpl):
+        (HTMLImageElementImpl::~HTMLImageElementImpl):
+        * khtml/html/html_imageimpl.h:
+        * khtml/html/html_miscimpl.cpp:
+        (HTMLCollectionImpl::HTMLCollectionImpl):
+        (HTMLCollectionImpl::~HTMLCollectionImpl):
+        (HTMLCollectionImpl::updateCollectionInfo):
+        (HTMLCollectionImpl::length):
+        (HTMLCollectionImpl::item):
+        (HTMLCollectionImpl::firstItem):
+        (HTMLCollectionImpl::nextItem):
+        (HTMLCollectionImpl::namedItem):
+        (HTMLCollectionImpl::nextNamedItemInternal):
+        (HTMLFormCollectionImpl::getNamedFormItem):
+        * khtml/html/html_miscimpl.h:
+        (DOM::HTMLCollectionImpl::):
+        (DOM::HTMLCollectionImpl::CollectionInfo::CollectionInfo):
+        * khtml/html/htmlparser.cpp:
+        (KHTMLParser::getElement):
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::DocumentImpl):
+        * khtml/xml/dom_docimpl.h:
+        (DOM::DocumentImpl::incDOMTreeVersion):
+        (DOM::DocumentImpl::domTreeVersion):
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::attach):
+        (NodeImpl::detach):
+
 2004-11-18  Kevin Decker  <kdecker@apple.com>
 
         Reviewed by Chris.
index c0a9ac3..06d9c82 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "xml/dom_docimpl.h"
 #include "misc/loader_client.h"
+#include "html/html_miscimpl.h"
 
 class KHTMLView;
 class QString;
@@ -64,6 +65,8 @@ public:
     void removeNamedImageOrForm(const QString &name);
     bool haveNamedImageOrForm(const QString &name);
 
+    HTMLCollectionImpl::CollectionInfo *collectionInfo(int type) { return m_collection_info+type; }
+
 protected:
     HTMLElementImpl *bodyElement;
     HTMLElementImpl *htmlElement;
@@ -74,7 +77,8 @@ protected slots:
      */
     void slotHistoryChanged();
 private:
-     // we actually store ints inside the pointer value itself; would use void *
+    HTMLCollectionImpl::CollectionInfo m_collection_info[HTMLCollectionImpl::LAST_TYPE];
+    // we actually store ints inside the pointer value itself; would use void *
     // but that makes the template unhappy.
     QDict<char> namedImageAndFormCounts;
 };
index 9a8f049..3a70d7e 100644 (file)
@@ -115,6 +115,9 @@ HTMLFormElementImpl::~HTMLFormElementImpl()
     QPtrListIterator<HTMLGenericFormElementImpl> it2(dormantFormElements);
     for (; it2.current(); ++it2)
         it2.current()->m_form = 0;
+    QPtrListIterator<HTMLImageElementImpl> it3(imgElements);
+    for (; it3.current(); ++it3)
+        it3.current()->m_form = 0;
 }
 
 NodeImpl::Id HTMLFormElementImpl::id() const
@@ -720,6 +723,16 @@ bool HTMLFormElementImpl::isURLAttribute(AttributeImpl *attr) const
     return attr->id() == ATTR_ACTION;
 }
 
+void HTMLFormElementImpl::registerImgElement(HTMLImageElementImpl *e)
+{
+    imgElements.append(e);
+}
+
+void HTMLFormElementImpl::removeImgElement(HTMLImageElementImpl *e)
+{
+    imgElements.remove(e);
+}
+
 // -------------------------------------------------------------------------
 
 HTMLGenericFormElementImpl::HTMLGenericFormElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
index a7dc2b3..85dd55f 100644 (file)
@@ -54,6 +54,7 @@ class DOMString;
 class FormDataList;
 class HTMLFormElement;
 class HTMLGenericFormElementImpl;
+class HTMLImageElementImpl;
 class HTMLImageLoader;
 class HTMLOptionElementImpl;
 class HTMLOptionsCollectionImpl;
@@ -88,6 +89,8 @@ public:
     void registerFormElement(HTMLGenericFormElementImpl *);
     void removeFormElement(HTMLGenericFormElementImpl *);
     void makeFormElementDormant(HTMLGenericFormElementImpl *);
+    void registerImgElement(HTMLImageElementImpl *);
+    void removeImgElement(HTMLImageElementImpl *);
 
     bool prepareSubmit();
     void submit(bool activateSubmitButton);
@@ -110,6 +113,7 @@ public:
 
     QPtrList<HTMLGenericFormElementImpl> formElements;
     QPtrList<HTMLGenericFormElementImpl> dormantFormElements;
+    QPtrList<HTMLImageElementImpl> imgElements;
     DOMString m_url;
     DOMString m_target;
     DOMString m_enctype;
index c19a014..a180510 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "html/html_imageimpl.h"
+#include "html/html_formimpl.h"
 #include "html/html_documentimpl.h"
 
 #include "misc/htmlhashes.h"
@@ -125,19 +126,19 @@ void HTMLImageLoader::notifyFinished(CachedObject* image)
 
 // -------------------------------------------------------------------------
 
-HTMLImageElementImpl::HTMLImageElementImpl(DocumentPtr *doc)
-    : HTMLElementImpl(doc), m_imageLoader(this)
+HTMLImageElementImpl::HTMLImageElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f)
+    : HTMLElementImpl(doc), m_imageLoader(this), ismap(false), m_form(f)
 {
-    ismap = false;
+    if (m_form)
+        m_form->registerImgElement(this);
 }
 
 HTMLImageElementImpl::~HTMLImageElementImpl()
 {
+    if (m_form)
+        m_form->removeImgElement(this);
 }
 
-
-// DOM related
-
 NodeImpl::Id HTMLImageElementImpl::id() const
 {
     return ID_IMG;
index 5c17e8a..d489ba8 100644 (file)
@@ -43,6 +43,8 @@ namespace DOM {
 
 class DOMString;
 
+class HTMLFormElementImpl;
+    
 class HTMLImageLoader: public khtml::CachedObjectClient {
 public:
     HTMLImageLoader(ElementImpl* elt);
@@ -65,13 +67,13 @@ private:
     bool m_firedLoad : 1;
     bool m_imageComplete : 1;
 };
-    
+
 class HTMLImageElementImpl
     : public HTMLElementImpl
 {
+    friend class HTMLFormElementImpl;
 public:
-    HTMLImageElementImpl(DocumentPtr *doc);
-
+    HTMLImageElementImpl(DocumentPtr *doc, HTMLFormElementImpl *f = 0);
     ~HTMLImageElementImpl();
 
     virtual Id id() const;
@@ -104,6 +106,7 @@ protected:
     HTMLImageLoader m_imageLoader;
     DOMString usemap;
     bool ismap;
+    HTMLFormElementImpl *m_form;
     QString oldIdAttr;
     QString oldNameAttr;
 #if APPLE_CHANGES
index 7384993..4c5c51d 100644 (file)
@@ -24,6 +24,8 @@
 // -------------------------------------------------------------------------
 #include "html/html_miscimpl.h"
 #include "html/html_formimpl.h"
+#include "html/html_imageimpl.h"
+#include "html/html_documentimpl.h"
 
 #include "misc/htmlhashes.h"
 #include "dom/dom_node.h"
@@ -53,15 +55,30 @@ HTMLCollectionImpl::HTMLCollectionImpl(NodeImpl *_base, int _type)
     base = _base;
     base->ref();
     type = _type;
-    currentItem = 0L;
     idsDone = false;
+    info = base->isDocumentNode() ? static_cast<HTMLDocumentImpl*>(base->getDocument())->collectionInfo(type) : new CollectionInfo;
 }
 
 HTMLCollectionImpl::~HTMLCollectionImpl()
 {
+    if (!base->isDocumentNode())
+        delete info;
     base->deref();
 }
 
+void HTMLCollectionImpl::resetCollectionInfo() const
+{
+    unsigned int docversion = static_cast<HTMLDocumentImpl*>(base->getDocument())->domTreeVersion();
+    if (info->version != docversion) {
+        version = 0;
+        current = 0;
+        position = 0;
+        length = 0;
+        hasLength = false;
+        info->version = docversion;
+    }
+}
+
 unsigned long HTMLCollectionImpl::calcLength(NodeImpl *current) const
 {
     unsigned long len = 0;
@@ -149,7 +166,12 @@ unsigned long HTMLCollectionImpl::calcLength(NodeImpl *current) const
 // calculation every time...
 unsigned long HTMLCollectionImpl::length() const
 {
-    return calcLength(base->firstChild());
+    resetCollectionInfo();
+    if (!info->haslength) {
+        info->length = calcLength(base->firstChild());
+        info->haslength = true;
+    }
+    return info->length;
 }
 
 NodeImpl *HTMLCollectionImpl::getItem(NodeImpl *current, int index, int &len) const
@@ -238,41 +260,64 @@ NodeImpl *HTMLCollectionImpl::getItem(NodeImpl *current, int index, int &len) co
 
 NodeImpl *HTMLCollectionImpl::item( unsigned long index ) const
 {
-    int pos = 0;
-    return getItem(base->firstChild(), index, pos);
+     resetCollectionInfo();
+     if (info->current && info->position == index) {
+         return info->current;
+     }
+     if (info->haslength && info->length <= index) {
+         return 0;
+     }
+     if (!info->current || info->position > index) {
+         info->current = base->firstChild();
+         info->position = 0;
+         if (!info->current)
+             return 0;
+     }
+     int pos = (int) info->position;
+     NodeImpl *node = getItem(info->current, index, pos);
+     while (!node && info->current->parentNode() && info->current->parentNode() != base) {
+         info->current = info->current->parentNode();
+         if (info->current->nextSibling())
+             node = getItem(info->current->nextSibling(), index, pos);
+         
+     }
+     info->current = node;
+     info->position = index;
+     return info->current;
 }
 
 NodeImpl *HTMLCollectionImpl::firstItem() const
 {
-    int pos = 0;
-    currentItem = getItem(base->firstChild(), 0, pos);
-    return currentItem;
+     return item(0);
 }
 
 NodeImpl *HTMLCollectionImpl::nextItem() const
 {
-    int pos = 0;
-    // Look for the 'second' item. The first one is currentItem, already given back.
-    NodeImpl *retval = getItem(currentItem, 1, pos);
-    if (retval)
-    {
-        currentItem = retval;
-        return retval;
-    }
-    // retval was 0, means we have to go up
-    while( !retval && currentItem && currentItem->parentNode()
-           && currentItem->parentNode() != base )
-    {
-        currentItem = currentItem->parentNode();
-        if (currentItem->nextSibling())
-        {
-            // ... and to take the first one from there
-            pos = 0;
-            retval = getItem(currentItem->nextSibling(), 0, pos);
-        }
-    }
-    currentItem = retval;
-    return currentItem;
+     resetCollectionInfo();
+     int pos = 0;
+     info->position = ~0;  // no position
+     // Look for the 'second' item. The first one is currentItem, already given back.
+     NodeImpl *retval = getItem(info->current, 1, pos);
+     if (retval)
+     {
+         info->current = retval;
+         return retval;
+     }
+     // retval was 0, means we have to go up
+     while( !retval && info->current->parentNode()
+            && info->current->parentNode() != base )
+     {
+         info->current = info->current->parentNode();
+         if (info->current->nextSibling())
+         {
+             // ... and to take the first one from there
+             pos = 0;
+             retval = getItem(info->current->nextSibling(), 0, pos);
+         }
+      }
+     info->current = retval;
+     return info->current;
 }
 
 NodeImpl *HTMLCollectionImpl::getNamedItem( NodeImpl *current, int attr_id,
@@ -386,13 +431,15 @@ NodeImpl *HTMLCollectionImpl::namedItem( const DOMString &name, bool caseSensiti
     // attribute. If a match is not found, the method then searches for an
     // object with a matching name attribute, but only on those elements
     // that are allowed a name attribute.
+     resetCollectionInfo();
+     info->position = ~0;  // no position
     idsDone = false;
-    currentItem = getNamedItem(base->firstChild(), ATTR_ID, name, caseSensitive);
-    if(currentItem)
-        return currentItem;
+    info->current = getNamedItem(base->firstChild(), ATTR_ID, name);
+    if(info->current)
+        return info->current;
     idsDone = true;
-    currentItem = getNamedItem(base->firstChild(), ATTR_NAME, name, caseSensitive);
-    return currentItem;
+    info->current = getNamedItem(base->firstChild(), ATTR_NAME, name);
+    return info->current;
 }
 
 NodeImpl *HTMLCollectionImpl::nextNamedItem( const DOMString &name ) const
@@ -420,38 +467,39 @@ NodeImpl *HTMLCollectionImpl::nextNamedItem( const DOMString &name ) const
 
 NodeImpl *HTMLCollectionImpl::nextNamedItemInternal( const DOMString &name ) const
 {
-    //kdDebug() << "\nHTMLCollectionImpl::nextNamedItem starting at " << currentItem << endl;
+    resetCollectionInfo();
+    //kdDebug() << "\nHTMLCollectionImpl::nextNamedItem starting at " << info->current << endl;
     // Go to next item first (to avoid returning the same)
-    currentItem = nextItem();
-    //kdDebug() << "*HTMLCollectionImpl::nextNamedItem next item is " << currentItem << endl;
+    nextItem(); // sets info->current and invalidates info->postion
+    //kdDebug() << "*HTMLCollectionImpl::nextNamedItem next item is " << info->current << endl;
 
-    if ( currentItem )
+    if ( info->current )
     {
         // Then look for next matching named item
-        NodeImpl *retval = getNamedItem(currentItem, idsDone ? ATTR_NAME : ATTR_ID, name);
+        NodeImpl *retval = getNamedItem(info->current, idsDone ? ATTR_NAME : ATTR_ID, name);
         if ( retval )
         {
             //kdDebug() << "*HTMLCollectionImpl::nextNamedItem found " << retval << endl;
-            currentItem = retval;
+            info->current = retval;
             return retval;
         }
 
         // retval was 0, means we have to go up
-        while( !retval && currentItem->parentNode()
-               && currentItem->parentNode() != base )
+        while( !retval && info->current->parentNode()
+               && info->current->parentNode() != base )
         {
-            currentItem = currentItem->parentNode();
-            if (currentItem->nextSibling())
+            info->current = info->current->parentNode();
+            if (info->current->nextSibling())
             {
                 // ... and to take the first one from there
-                retval = getNamedItem(currentItem->nextSibling(), idsDone ? ATTR_NAME : ATTR_ID, name);
+                retval = getNamedItem(info->current->nextSibling(), idsDone ? ATTR_NAME : ATTR_ID, name);
             }
         }
         if ( retval )
         {
             //kdDebug() << "*HTMLCollectionImpl::nextNamedItem found after going up " << retval << endl;
-            currentItem = retval;
-            return currentItem;
+            info->current = retval;
+            return info->current;
         }
     }
 
@@ -460,8 +508,8 @@ NodeImpl *HTMLCollectionImpl::nextNamedItemInternal( const DOMString &name ) con
     // After doing all ATTR_ID, do ATTR_NAME
     //kdDebug() << "*HTMLCollectionImpl::nextNamedItem going to ATTR_NAME now" << endl;
     idsDone = true;
-    currentItem = getNamedItem(base->firstChild(), ATTR_NAME, name);
-    return currentItem;
+    info->current = getNamedItem(base->firstChild(), ATTR_NAME, name);
+    return info->current;
 
 }
 
@@ -507,6 +555,7 @@ NodeImpl* HTMLFormCollectionImpl::getNamedFormItem(int attr_id, const DOMString&
     if(base->nodeType() == Node::ELEMENT_NODE)
     {
         HTMLElementImpl* e = static_cast<HTMLElementImpl*>(base);
+        bool foundInputElements = false;
         if(e->id() == ID_FORM)
         {
             HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(e);
@@ -519,54 +568,33 @@ NodeImpl* HTMLFormCollectionImpl::getNamedFormItem(int attr_id, const DOMString&
                     else
                         found = e->getAttribute(attr_id).domString().lower() == name.lower();
                     if (found) {
+                        foundInputElements = true;
                         if (!duplicateNumber)
                             return e;
                         --duplicateNumber;
                     }
                 }
         }
-        NodeImpl* retval = getNamedImgItem( base->firstChild(), attr_id, name, duplicateNumber, caseSensitive );
-        if ( retval )
-            return retval;
-    }
-    return 0;
-}
 
-NodeImpl* HTMLFormCollectionImpl::getNamedImgItem(NodeImpl* current, int attr_id, const DOMString& name, int& duplicateNumber, bool caseSensitive) const
-{
-    // strange case. IE and NS allow to get hold of <img> tags,
-    // but they don't include them in the elements() collection.
-    while ( current )
-    {
-        if(current->nodeType() == Node::ELEMENT_NODE)
+        if ( !foundInputElements )
         {
-            HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
-            if(e->id() == ID_IMG) {
+            HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(e);
+
+            for(HTMLImageElementImpl* e = f->imgElements.first(); e; e = f->imgElements.next())
+            {
                 bool found;
                 if (caseSensitive)
                     found = e->getAttribute(attr_id) == name;
                 else
                     found = e->getAttribute(attr_id).domString().lower() == name.lower();
-                if (found)
-                {
+                if (found) {
                     if (!duplicateNumber)
-                        return current;
+                        return e;
                     --duplicateNumber;
                 }
             }
-            if(current->firstChild())
-            {
-                // The recursion here is the reason why this is a separate method
-                NodeImpl *retval = getNamedImgItem(current->firstChild(), attr_id, name, duplicateNumber, caseSensitive);
-                if(retval)
-                {
-                    //kdDebug( 6030 ) << "got a return value " << retval << endl;
-                    return retval;
-                }
-            }
         }
-        current = current->nextSibling();
-    } // while
+    }
     return 0;
 }
 
index 7aae6c4..3786b1e 100644 (file)
@@ -50,7 +50,7 @@ class HTMLCollectionImpl : public khtml::Shared<HTMLCollectionImpl>
 public:
     enum Type {
         // from HTMLDocument
-        DOC_IMAGES,    // all IMG elements in the document
+        DOC_IMAGES = 0, // all IMG elements in the document
         DOC_APPLETS,   // all OBJECT and APPLET elements
         DOC_EMBEDS,   // all EMBED elements
         DOC_FORMS,     // all FORMS
@@ -66,7 +66,8 @@ public:
         // from HTMLMap
         MAP_AREAS,
         DOC_ALL,        // "all" elements (IE)
-        NODE_CHILDREN   // first-level children (IE)
+        NODE_CHILDREN,   // first-level children (IE)
+        LAST_TYPE
     };
 
     HTMLCollectionImpl(NodeImpl *_base, int _tagId);
@@ -82,24 +83,27 @@ public:
     // In case of multiple items named the same way
     NodeImpl *nextNamedItem( const DOMString &name ) const;
 
+    struct CollectionInfo {
+        CollectionInfo() : version(0), current(0), position(0), length(0), hasLength(false) {}
+        unsigned int version;
+        NodeImpl *current;
+        unsigned int position;
+        unsigned int length;
+        bool haslength;
+     };
+
 protected:
     virtual unsigned long calcLength(NodeImpl *current) const;
     virtual NodeImpl *getItem(NodeImpl *current, int index, int &pos) const;
     virtual NodeImpl *getNamedItem(NodeImpl *current, int attr_id, const DOMString &name, bool caseSensitive = true) const;
     virtual NodeImpl *nextNamedItemInternal( const DOMString &name ) const;
+    void resetCollectionInfo() const;
     // the base node, the collection refers to
     NodeImpl *base;
     // The collection list the following elements
     int type;
+    mutable CollectionInfo *info;
 
-    // ### add optimization, so that a linear loop through the
-    // Collection [using item(i)] is O(n) and not O(n^2)!
-    // But for that we need to get notified in case of changes in the dom structure...
-    //NodeImpl *current;
-    //int currentPos;
-
-    // For firstItem()/nextItem()
-    mutable NodeImpl *currentItem;
     // For nextNamedItem()
     mutable bool idsDone;
 };
@@ -125,7 +129,6 @@ protected:
     virtual NodeImpl *nextNamedItemInternal( const DOMString &name ) const;
 private:
     NodeImpl* getNamedFormItem(int attr_id, const DOMString& name, int duplicateNumber, bool caseSensitive) const;
-    NodeImpl* getNamedImgItem(NodeImpl* current, int attr_id, const DOMString& name, int& duplicateNumber, bool caseSensitive) const;
     mutable int currentPos;
 };
 
index 9b2b2c8..f9046b0 100644 (file)
@@ -1000,7 +1000,7 @@ NodeImpl *KHTMLParser::getElement(Token* t)
 
 // images
     case ID_IMG:
-        n = new HTMLImageElementImpl(document);
+        n = new HTMLImageElementImpl(document, form);
         break;
     case ID_MAP:
         map = new HTMLMapElementImpl(document);
index e54758e..77e40f3 100644 (file)
@@ -262,6 +262,7 @@ QPtrList<DocumentImpl> * DocumentImpl::changedDocuments = 0;
 // KHTMLView might be 0
 DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
     : NodeBaseImpl( new DocumentPtr() )
+      , m_domtree_version(0)
       , m_imageLoadEventTimer(0)
 #ifndef KHTML_NO_XBL
       , m_bindingManager(new XBLBindingManager(this))
index 342b58e..5a26e24 100644 (file)
@@ -579,6 +579,9 @@ public:
     XBL::XBLBindingManager* bindingManager() const { return m_bindingManager; }
 #endif
 
+    void incDOMTreeVersion() { ++m_domtree_version; }
+    unsigned int domTreeVersion() const { return m_domtree_version; }
+
 signals:
     void finishedParsing();
 
@@ -622,6 +625,8 @@ protected:
 
     NodeImpl *m_focusNode;
     NodeImpl *m_hoverNode;
+
+    unsigned int m_domtree_version;
     
     // ### replace me with something more efficient
     // in lookup and insertion.
index c030756..4fdd90d 100644 (file)
@@ -1168,6 +1168,7 @@ void NodeImpl::attach()
 {
     assert(!attached());
     assert(!m_render || (m_render->style() && m_render->parent()));
+    getDocument()->incDOMTreeVersion();
     m_attached = true;
 }
 
@@ -1179,6 +1180,7 @@ void NodeImpl::detach()
         m_render->detach();
 
     m_render = 0;
+    getDocument()->incDOMTreeVersion();
     m_attached = false;
 }