Changeset 28327 in webkit


Ignore:
Timestamp:
Dec 2, 2007 8:57:59 PM (16 years ago)
Author:
Darin Adler
Message:

WebCore:

Reviewed by Mitz.

There were two problems here:

1) Incorrect HTMLCollection behavior led to us trying to insert a

new row inside an existing row instead of next to it. The fix for
this is to make HTMLCollection work better for table-related
collections.

2) HTMLTableRowElement::insertCell would return a bad pointer if

the insertion failed. The code should have failed, but not crashed,
so it's worth fixing that too.

While fixing the HTMLCollection issues, I did some clean-up of that
class and its derived classes.

Test: fast/dom/HTMLTableElement/rows.html
Test: fast/dom/HTMLTableElement/tBodies.html
Test: fast/dom/HTMLTableRowElement/cells.html
Test: fast/dom/HTMLTableRowElement/insertCell.html
Test: fast/dom/HTMLTableSectionElement/rows.html

  • bindings/js/JSHTMLCollectionCustom.cpp: (WebCore::toJS): Updated because collectionType() was renamed to type().
  • html/HTMLCollection.cpp: (WebCore::HTMLCollection::HTMLCollection): Updated for data member name changes. Also added a protected constructor for use by derived classes that pass in a CollectionInfo. (WebCore::HTMLCollection::CollectionInfo::copyCacheMap): Moved out of the header. (WebCore::isTableSection): Added. (WebCore::HTMLCollection::itemAfter): Renamed from traverseNextItem, because the old name was grammatically incorrect and thus a bit confusing. Changed to operate on Element* instead of Node*, and use 0 to start rather than passing in the base node (required since the base node can be a document, which is not an element). Generalized the code that made NodeChildren not descend into deeper descendants so it can be used for TRCells, TSectionRows, TableTBodies, and TableRows. Reformatted the switch statement and got rid of the "found" boolean since we can just return when we find something. Got rid of the default case, and instead listed all the enum values. Also changed to use a for loop for clarity. (WebCore::HTMLCollection::calcLength): Updated for itemAfter changes. (WebCore::HTMLCollection::item): Ditto. (WebCore::HTMLCollection::nextItem): Ditto. (WebCore::HTMLCollection::checkForNameMatch): Updated to take an Element instead of a Node pointer. (WebCore::HTMLCollection::namedItem): More of the same. (WebCore::HTMLCollection::updateNameCache): Ditto. (WebCore::HTMLCollection::namedItems): Ditto. (WebCore::HTMLCollection::nextNamedItem): Ditto. (WebCore::HTMLCollection::tags): Ditto.
  • html/HTMLCollection.h: Added a type FormElements, so that the HTMLFormCollection would not have a type of DocImages, which is what it previously did. Changed the base parameter to be a PassRefPtr to make it clear we take ownership of it. Added a comment explaining why we should change the name CollectionInfo. Made a lot more members private instead of protected. Renamed traverseNextItem to itemAfter. Changed most functions to take Element* instead of Node*.
  • html/HTMLFormCollection.cpp: (WebCore::HTMLFormCollection::formCollectionInfo): Added. (WebCore::HTMLFormCollection::HTMLFormCollection): Updated to pass collection info into the base class. (WebCore::HTMLFormCollection::calcLength): Updated to use base() so we don't need to get at m_base directly. (WebCore::HTMLFormCollection::item): Same, but for info(). (WebCore::HTMLFormCollection::getNamedItem): Removed unused first argument. (WebCore::HTMLFormCollection::getNamedFormItem): Got rid of unneeded checks that the base is still an element and still a form, since that's guaranteed. (WebCore::HTMLFormCollection::nextItem): Use info(). (WebCore::HTMLFormCollection::nextNamedItemInternal): Node instead of Element, some name changes. (WebCore::HTMLFormCollection::namedItem): Update for changes elsewhere. (WebCore::HTMLFormCollection::nextNamedItem): Ditto, also rewrote loop to be much simpler. (WebCore::HTMLFormCollection::updateNameCache): More of the same.
  • html/HTMLFormCollection.h: Changed constructor to take an HTMLFormElement, using a PassRefPtr to communicate transfer of ownership. Made everything private instead of protected. Removed unneeded override of firstItem. Made getNamedItem and nextNamedItemInternal non-virtual. Removed unused first argument of getNamedItem. Added declaration of formCollectionInfo.
  • html/HTMLNameCollection.cpp: (WebCore::HTMLNameCollection::HTMLNameCollection): Updated to pass collection info into the base class. (WebCore::HTMLNameCollection::itemAfter): Reformatted a bit and changed into a for loop.
  • html/HTMLNameCollection.h: Updated for name changes. Made function private instead of public. Used PassRefPtr in constructor.
  • html/HTMLOptionsCollection.cpp: (WebCore::HTMLOptionsCollection::HTMLOptionsCollection): Updated to pass collection info into the base class. (WebCore::HTMLOptionsCollection::add): Updated for public/private changes in the base class. (WebCore::HTMLOptionsCollection::selectedIndex): Ditto. (WebCore::HTMLOptionsCollection::setSelectedIndex): Ditto. (WebCore::HTMLOptionsCollection::setLength): Ditto.
  • html/HTMLOptionsCollection.h: Changed constructor parameter to be a PassRefPtr.
  • html/HTMLTableRowElement.cpp: (WebCore::HTMLTableRowElement::insertCell): Changed code to use RefPtr and PassRefPtr since this creates a new object. This alone fixed the crash. Also cleaned up logic a bit to be more readable.
  • html/HTMLTableRowElement.h: Changed insertCell to return a PassRefPtr. Also reordered functions a bit to make things a little more logical and removed the unused ncols data member.
  • html/HTMLTableSectionElement.cpp: (WebCore::HTMLTableSectionElement::rows): Pass TSectionRows, not TableRows. This mistake was harmless before because TableRows and TSectionRows were handled identically inside HTMLCollection, but that is no longer the case with this fix.
  • bindings/scripts/CodeGeneratorJS.pm: Add an include to cope with the fact that HTMLOptionsCollection no longer includes HTMLOptionElement. I don't think this really should be a special case -- might be worth returning later to see if this can be optimized.

LayoutTests:

Reviewed by Mitz.

  • fast/dom/HTMLTableElement/resources: Added.
  • fast/dom/HTMLTableElement/resources/TEMPLATE.html: Added.
  • fast/dom/HTMLTableElement/resources/rows.js: Added.
  • fast/dom/HTMLTableElement/resources/tBodies.js: Added.
  • fast/dom/HTMLTableElement/rows-expected.txt: Added.
  • fast/dom/HTMLTableElement/rows.html: Added.
  • fast/dom/HTMLTableElement/tBodies-expected.txt: Added.
  • fast/dom/HTMLTableElement/tBodies.html: Added.
  • fast/dom/HTMLTableRowElement: Added.
  • fast/dom/HTMLTableRowElement/cells-expected.txt: Added.
  • fast/dom/HTMLTableRowElement/cells.html: Added.
  • fast/dom/HTMLTableRowElement/insertCell-expected.txt: Added.
  • fast/dom/HTMLTableRowElement/insertCell.html: Added.
  • fast/dom/HTMLTableRowElement/resources: Added.
  • fast/dom/HTMLTableRowElement/resources/TEMPLATE.html: Added.
  • fast/dom/HTMLTableRowElement/resources/cells.js: Added.
  • fast/dom/HTMLTableSectionElement: Added.
  • fast/dom/HTMLTableSectionElement/resources: Added.
  • fast/dom/HTMLTableSectionElement/resources/TEMPLATE.html: Added.
  • fast/dom/HTMLTableSectionElement/resources/rows.js: Added.
  • fast/dom/HTMLTableSectionElement/rows-expected.txt: Added.
  • fast/dom/HTMLTableSectionElement/rows.html: Added.
Location:
trunk
Files:
22 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r28312 r28327  
     12007-12-02  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Mitz.
     4
     5        - tests for table-related HTMLCollection classes for misnested
     6          tables and for <rdar://problem/5601995> Hang/crash on http://ebay-uk.custhelp.com/
     7
     8        * fast/dom/HTMLTableElement/resources: Added.
     9        * fast/dom/HTMLTableElement/resources/TEMPLATE.html: Added.
     10        * fast/dom/HTMLTableElement/resources/rows.js: Added.
     11        * fast/dom/HTMLTableElement/resources/tBodies.js: Added.
     12        * fast/dom/HTMLTableElement/rows-expected.txt: Added.
     13        * fast/dom/HTMLTableElement/rows.html: Added.
     14        * fast/dom/HTMLTableElement/tBodies-expected.txt: Added.
     15        * fast/dom/HTMLTableElement/tBodies.html: Added.
     16        * fast/dom/HTMLTableRowElement: Added.
     17        * fast/dom/HTMLTableRowElement/cells-expected.txt: Added.
     18        * fast/dom/HTMLTableRowElement/cells.html: Added.
     19        * fast/dom/HTMLTableRowElement/insertCell-expected.txt: Added.
     20        * fast/dom/HTMLTableRowElement/insertCell.html: Added.
     21        * fast/dom/HTMLTableRowElement/resources: Added.
     22        * fast/dom/HTMLTableRowElement/resources/TEMPLATE.html: Added.
     23        * fast/dom/HTMLTableRowElement/resources/cells.js: Added.
     24        * fast/dom/HTMLTableSectionElement: Added.
     25        * fast/dom/HTMLTableSectionElement/resources: Added.
     26        * fast/dom/HTMLTableSectionElement/resources/TEMPLATE.html: Added.
     27        * fast/dom/HTMLTableSectionElement/resources/rows.js: Added.
     28        * fast/dom/HTMLTableSectionElement/rows-expected.txt: Added.
     29        * fast/dom/HTMLTableSectionElement/rows.html: Added.
     30
    1312007-12-01  Antti Koivisto  <antti@apple.com>
    232
  • trunk/WebCore/ChangeLog

    r28325 r28327  
     12007-12-02  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Mitz.
     4
     5        - fix <rdar://problem/5601995> Hang/crash on http://ebay-uk.custhelp.com/
     6
     7        There were two problems here:
     8
     9            1) Incorrect HTMLCollection behavior led to us trying to insert a
     10               new row inside an existing row instead of next to it. The fix for
     11               this is to make HTMLCollection work better for table-related
     12               collections.
     13
     14            2) HTMLTableRowElement::insertCell would return a bad pointer if
     15               the insertion failed. The code should have failed, but not crashed,
     16               so it's worth fixing that too.
     17
     18        While fixing the HTMLCollection issues, I did some clean-up of that
     19        class and its derived classes.
     20
     21        Test: fast/dom/HTMLTableElement/rows.html
     22        Test: fast/dom/HTMLTableElement/tBodies.html
     23        Test: fast/dom/HTMLTableRowElement/cells.html
     24        Test: fast/dom/HTMLTableRowElement/insertCell.html
     25        Test: fast/dom/HTMLTableSectionElement/rows.html
     26
     27        * bindings/js/JSHTMLCollectionCustom.cpp:
     28        (WebCore::toJS): Updated because collectionType() was renamed to type().
     29
     30        * html/HTMLCollection.cpp:
     31        (WebCore::HTMLCollection::HTMLCollection): Updated for data member name
     32        changes. Also added a protected constructor for use by derived classes
     33        that pass in a CollectionInfo.
     34        (WebCore::HTMLCollection::CollectionInfo::copyCacheMap): Moved out of
     35        the header.
     36        (WebCore::isTableSection): Added.
     37        (WebCore::HTMLCollection::itemAfter): Renamed from traverseNextItem,
     38        because the old name was grammatically incorrect and thus a bit confusing.
     39        Changed to operate on Element* instead of Node*, and use 0 to start
     40        rather than passing in the base node (required since the base node can be
     41        a document, which is not an element). Generalized the code that made
     42        NodeChildren not descend into deeper descendants so it can be used for
     43        TRCells, TSectionRows, TableTBodies, and TableRows. Reformatted the
     44        switch statement and got rid of the "found" boolean since we can just
     45        return when we find something. Got rid of the default case, and instead
     46        listed all the enum values. Also changed to use a for loop for clarity.
     47        (WebCore::HTMLCollection::calcLength): Updated for itemAfter changes.
     48        (WebCore::HTMLCollection::item): Ditto.
     49        (WebCore::HTMLCollection::nextItem): Ditto.
     50        (WebCore::HTMLCollection::checkForNameMatch): Updated to take an Element
     51        instead of a Node pointer.
     52        (WebCore::HTMLCollection::namedItem): More of the same.
     53        (WebCore::HTMLCollection::updateNameCache): Ditto.
     54        (WebCore::HTMLCollection::namedItems): Ditto.
     55        (WebCore::HTMLCollection::nextNamedItem): Ditto.
     56        (WebCore::HTMLCollection::tags): Ditto.
     57
     58        * html/HTMLCollection.h: Added a type FormElements, so that the
     59        HTMLFormCollection would not have a type of DocImages, which is what
     60        it previously did. Changed the base parameter to be a PassRefPtr to
     61        make it clear we take ownership of it. Added a comment explaining
     62        why we should change the name CollectionInfo. Made a lot more members
     63        private instead of protected. Renamed traverseNextItem to itemAfter.
     64        Changed most functions to take Element* instead of Node*.
     65
     66        * html/HTMLFormCollection.cpp:
     67        (WebCore::HTMLFormCollection::formCollectionInfo): Added.
     68        (WebCore::HTMLFormCollection::HTMLFormCollection): Updated to pass
     69        collection info into the base class.
     70        (WebCore::HTMLFormCollection::calcLength): Updated to use base() so we
     71        don't need to get at m_base directly.
     72        (WebCore::HTMLFormCollection::item): Same, but for info().
     73        (WebCore::HTMLFormCollection::getNamedItem): Removed unused first
     74        argument.
     75        (WebCore::HTMLFormCollection::getNamedFormItem): Got rid of unneeded
     76        checks that the base is still an element and still a form, since that's
     77        guaranteed.
     78        (WebCore::HTMLFormCollection::nextItem): Use info().
     79        (WebCore::HTMLFormCollection::nextNamedItemInternal): Node instead of
     80        Element, some name changes.
     81        (WebCore::HTMLFormCollection::namedItem): Update for changes elsewhere.
     82        (WebCore::HTMLFormCollection::nextNamedItem): Ditto, also rewrote loop
     83        to be much simpler.
     84        (WebCore::HTMLFormCollection::updateNameCache): More of the same.
     85
     86        * html/HTMLFormCollection.h: Changed constructor to take an
     87        HTMLFormElement, using a PassRefPtr to communicate transfer of
     88        ownership. Made everything private instead of protected. Removed
     89        unneeded override of firstItem. Made getNamedItem and
     90        nextNamedItemInternal non-virtual. Removed unused first argument of
     91        getNamedItem. Added declaration of formCollectionInfo.
     92
     93        * html/HTMLNameCollection.cpp:
     94        (WebCore::HTMLNameCollection::HTMLNameCollection): Updated to pass
     95        collection info into the base class.
     96        (WebCore::HTMLNameCollection::itemAfter): Reformatted a bit and
     97        changed into a for loop.
     98
     99        * html/HTMLNameCollection.h: Updated for name changes. Made function
     100        private instead of public. Used PassRefPtr in constructor.
     101
     102        * html/HTMLOptionsCollection.cpp:
     103        (WebCore::HTMLOptionsCollection::HTMLOptionsCollection): Updated to
     104        pass collection info into the base class.
     105        (WebCore::HTMLOptionsCollection::add): Updated for public/private
     106        changes in the base class.
     107        (WebCore::HTMLOptionsCollection::selectedIndex): Ditto.
     108        (WebCore::HTMLOptionsCollection::setSelectedIndex): Ditto.
     109        (WebCore::HTMLOptionsCollection::setLength): Ditto.
     110
     111        * html/HTMLOptionsCollection.h: Changed constructor parameter to be a
     112        PassRefPtr.
     113
     114        * html/HTMLTableRowElement.cpp:
     115        (WebCore::HTMLTableRowElement::insertCell): Changed code to use RefPtr
     116        and PassRefPtr since this creates a new object. This alone fixed the
     117        crash. Also cleaned up logic a bit to be more readable.
     118
     119        * html/HTMLTableRowElement.h: Changed insertCell to return a PassRefPtr.
     120        Also reordered functions a bit to make things a little more logical and
     121        removed the unused ncols data member.
     122
     123        * html/HTMLTableSectionElement.cpp:
     124        (WebCore::HTMLTableSectionElement::rows): Pass TSectionRows, not
     125        TableRows. This mistake was harmless before because TableRows and
     126        TSectionRows were handled identically inside HTMLCollection, but that is
     127        no longer the case with this fix.
     128
     129        * bindings/scripts/CodeGeneratorJS.pm: Add an include to cope with the
     130        fact that HTMLOptionsCollection no longer includes HTMLOptionElement.
     131        I don't think this really should be a special case -- might be worth
     132        returning later to see if this can be optimized.
     133
    11342007-12-02  Nikolas Zimmermann  <zimmermann@kde.org>
    2135
  • trunk/WebCore/bindings/js/JSHTMLCollectionCustom.cpp

    r25754 r28327  
    132132        return ret;
    133133
    134     switch (collection->collectionType()) {
     134    switch (collection->type()) {
    135135        case HTMLCollection::SelectOptions:
    136136            ret = new JSHTMLOptionsCollection(exec, static_cast<HTMLOptionsCollection*>(collection));
  • trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r28110 r28327  
    11461146                            push(@implContent, "    if (!${name}Ok) {\n");
    11471147                            push(@implContent, "        setDOMException(exec, TYPE_MISMATCH_ERR);\n");
    1148                             push(@implContent, "        return jsUndefined();\n        }\n");
     1148                            push(@implContent, "        return jsUndefined();\n");
     1149                            push(@implContent, "    }\n");
    11491150                        }
    11501151
     
    14001401    }
    14011402
    1402     if ($type eq "SVGRect") {
    1403         $implIncludes{"FloatRect.h"} = 1;
    1404     }
    1405 
    1406     if ($type eq "SVGPoint") {
    1407         $implIncludes{"FloatPoint.h"} = 1;
    1408     }
    1409 
    14101403    if ($type eq "VoidCallback") {
    14111404        $implIncludes{"JSCustomVoidCallback.h"} = 1;
    14121405        return "toVoidCallback(exec, $value${maybeOkParam})";
    14131406    }
     1407
     1408    $implIncludes{"FloatPoint.h"} = 1 if $type eq "SVGPoint";
     1409    $implIncludes{"FloatRect.h"} = 1 if $type eq "SVGRect";
     1410    $implIncludes{"HTMLOptionElement.h"} = 1 if $type eq "HTMLOptionElement";
    14141411
    14151412    # Default, assume autogenerated type conversion routines
  • trunk/WebCore/dom/Document.cpp

    r28071 r28327  
    35103510}
    35113511
    3512 HTMLCollection::CollectionInfo* Document::nameCollectionInfo(HTMLCollection::Type type, const String& name)
    3513 {
    3514     HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*>& map = m_nameCollectionInfo[type - HTMLCollection::UnnamedCollectionTypes];
    3515    
    3516     AtomicString atomicName(name);
    3517    
    3518     HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*>::iterator iter = map.find(atomicName.impl());
     3512HTMLCollection::CollectionInfo* Document::nameCollectionInfo(HTMLCollection::Type type, const AtomicString& name)
     3513{
     3514    ASSERT(type >= HTMLCollection::FirstNamedDocumentCachedType);
     3515    unsigned index = type - HTMLCollection::FirstNamedDocumentCachedType;
     3516    ASSERT(index < HTMLCollection::NumNamedDocumentCachedTypes);
     3517
     3518    NamedCollectionMap& map = m_nameCollectionInfo[index];
     3519    NamedCollectionMap::iterator iter = map.find(name.impl());
    35193520    if (iter == map.end())
    3520         iter = map.add(atomicName.impl(), new HTMLCollection::CollectionInfo).first;
    3521    
     3521        iter = map.add(name.impl(), new HTMLCollection::CollectionInfo).first;
    35223522    return iter->second;
    35233523}
  • trunk/WebCore/dom/Document.h

    r27690 r28327  
    231231    HTMLCollection::CollectionInfo* collectionInfo(HTMLCollection::Type type)
    232232    {
    233         if ((int)type < HTMLCollection::UnnamedCollectionTypes)
    234             return m_collectionInfo + type;
    235         return 0;
     233        ASSERT(type >= HTMLCollection::FirstUnnamedDocumentCachedType);
     234        unsigned index = type - HTMLCollection::FirstUnnamedDocumentCachedType;
     235        ASSERT(index < HTMLCollection::NumUnnamedDocumentCachedTypes);
     236        return &m_collectionInfo[index];
    236237    }
    237238
    238     HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type type, const String& name);
     239    HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type, const AtomicString& name);
    239240
    240241    // DOM methods overridden from  parent classes
     
    894895
    895896    HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons;
    896    
    897     HTMLCollection::CollectionInfo m_collectionInfo[HTMLCollection::UnnamedCollectionTypes];
    898     HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*> m_nameCollectionInfo[HTMLCollection::CollectionTypes - HTMLCollection::UnnamedCollectionTypes];
     897
     898    typedef HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*> NamedCollectionMap;
     899    HTMLCollection::CollectionInfo m_collectionInfo[HTMLCollection::NumUnnamedDocumentCachedTypes];
     900    NamedCollectionMap m_nameCollectionInfo[HTMLCollection::NumNamedDocumentCachedTypes];
    899901
    900902#if ENABLE(XPATH)
  • trunk/WebCore/html/HTMLCollection.cpp

    r25754 r28327  
    1 /**
    2  * This file is part of the DOM implementation for KDE.
    3  *
     1/*
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    6  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    75 *
    86 * This library is free software; you can redistribute it and/or
     
    3836using namespace HTMLNames;
    3937
    40 HTMLCollection::HTMLCollection(Node *_base, HTMLCollection::Type _type)
    41     : m_base(_base),
    42       type(_type),
    43       info(0),
    44       idsDone(false),
    45       m_ownsInfo(false)
    46 {
    47     if (_base->isDocumentNode())
    48         info = _base->document()->collectionInfo(type);
     38HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type)
     39    : m_idsDone(false)
     40    , m_base(base)
     41    , m_type(type)
     42    , m_info(m_base->isDocumentNode() ? static_cast<Document*>(m_base.get())->collectionInfo(type) : 0)
     43    , m_ownsInfo(false)
     44{
     45}
     46
     47HTMLCollection::HTMLCollection(PassRefPtr<Node> base, Type type, CollectionInfo* info)
     48    : m_idsDone(false)
     49    , m_base(base)
     50    , m_type(type)
     51    , m_info(info)
     52    , m_ownsInfo(false)
     53{
    4954}
    5055
     
    5257{
    5358    if (m_ownsInfo)
    54         delete info;
    55 }
    56 
    57 HTMLCollection::CollectionInfo::CollectionInfo() :
    58     version(0)
     59        delete m_info;
     60}
     61
     62HTMLCollection::CollectionInfo::CollectionInfo()
     63    : version(0)
    5964{
    6065    reset();
    6166}
    6267
     68inline void HTMLCollection::CollectionInfo::copyCacheMap(NodeCacheMap& dest, const NodeCacheMap& src)
     69{
     70    ASSERT(dest.isEmpty());
     71    NodeCacheMap::const_iterator end = src.end();
     72    for (NodeCacheMap::const_iterator it = src.begin(); it != end; ++it)
     73        dest.add(it->first, new Vector<Element*>(*it->second));
     74}
     75
    6376HTMLCollection::CollectionInfo::CollectionInfo(const CollectionInfo& other)
    64 {
    65     version = other.version;
    66     current = other.current;
    67     position = other.position;
    68     length = other.length;
    69     elementsArrayPosition = other.elementsArrayPosition;
    70    
     77    : version(other.version)
     78    , current(other.current)
     79    , position(other.position)
     80    , length(other.length)
     81    , elementsArrayPosition(other.elementsArrayPosition)
     82    , hasLength(other.hasLength)
     83    , hasNameCache(other.hasNameCache)
     84{
    7185    copyCacheMap(idCache, other.idCache);
    7286    copyCacheMap(nameCache, other.nameCache);
    73    
    74     haslength = other.haslength;
    75     hasNameCache = other.hasNameCache;
    7687}
    7788
     
    8798    nameCache.swap(other.nameCache);
    8899   
    89     std::swap(haslength, other.haslength);
     100    std::swap(hasLength, other.hasLength);
    90101    std::swap(hasNameCache, other.hasNameCache);
    91102}
     
    102113    position = 0;
    103114    length = 0;
    104     haslength = false;
     115    hasLength = false;
    105116    elementsArrayPosition = 0;
    106117    deleteAllValues(idCache);
     
    113124void HTMLCollection::resetCollectionInfo() const
    114125{
    115     unsigned int docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion();
    116 
    117     if (!info) {
    118         info = new CollectionInfo;
     126    unsigned docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion();
     127
     128    if (!m_info) {
     129        m_info = new CollectionInfo;
    119130        m_ownsInfo = true;
    120         info->version = docversion;
     131        m_info->version = docversion;
    121132        return;
    122133    }
    123134
    124     if (info->version != docversion) {
    125         info->reset();
    126         info->version = docversion;
    127     }
    128 }
    129 
    130 
    131 Node *HTMLCollection::traverseNextItem(Node *current) const
    132 {
    133     ASSERT(current);
    134 
    135     if (type == NodeChildren && m_base.get() != current)
    136         current = current->nextSibling();
     135    if (m_info->version != docversion) {
     136        m_info->reset();
     137        m_info->version = docversion;
     138    }
     139}
     140
     141static bool isTableSection(Element* element)
     142{
     143    return element->hasLocalName(tbodyTag) || element->hasLocalName(tfootTag) || element->hasLocalName(theadTag);
     144}
     145
     146static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
     147{
     148    return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
     149}
     150
     151Element* HTMLCollection::itemAfter(Element* previous) const
     152{
     153    bool deep = true;
     154
     155    switch (m_type) {
     156        case DocAll:
     157        case DocAnchors:
     158        case DocApplets:
     159        case DocEmbeds:
     160        case DocForms:
     161        case DocImages:
     162        case DocLinks:
     163        case DocObjects:
     164        case DocScripts:
     165        case DocumentNamedItems:
     166        case FormElements:
     167        case MapAreas:
     168        case SelectOptions:
     169        case WindowNamedItems:
     170            break;
     171        case NodeChildren:
     172        case TRCells:
     173        case TSectionRows:
     174        case TableTBodies:
     175            deep = false;
     176            break;
     177        case TableRows:
     178            // Look for table rows inside table sections that are immediately inside
     179            // the table, but not in nested table sections.
     180            deep = previous && previous->parent() == m_base && isTableSection(previous);
     181            break;
     182    }
     183
     184    Node* current;
     185    if (!previous)
     186        current = m_base->firstChild();
    137187    else
    138         current = current->traverseNextNode(m_base.get());
    139 
    140     while (current) {
    141         if (current->isElementNode()) {
    142             bool found = false;
    143             bool deep = true;
    144             HTMLElement *e = static_cast<HTMLElement *>(current);
    145             switch(type) {
     188        current = nextNodeOrSibling(m_base.get(), previous, deep);
     189
     190    for (; current; current = nextNodeOrSibling(m_base.get(), current, deep)) {
     191        if (!current->isElementNode())
     192            continue;
     193        Element* e = static_cast<Element*>(current);
     194        switch (m_type) {
    146195            case DocImages:
    147196                if (e->hasLocalName(imgTag))
    148                     found = true;
     197                    return e;
    149198                break;
    150199            case DocScripts:
    151200                if (e->hasLocalName(scriptTag))
    152                     found = true;
     201                    return e;
    153202                break;
    154203            case DocForms:
    155                 if(e->hasLocalName(formTag))
    156                     found = true;
     204                if (e->hasLocalName(formTag))
     205                    return e;
    157206                break;
    158207            case TableTBodies:
    159208                if (e->hasLocalName(tbodyTag))
    160                     found = true;
    161                 else if (e->hasLocalName(tableTag))
    162                     deep = false;
     209                    return e;
    163210                break;
    164211            case TRCells:
    165212                if (e->hasLocalName(tdTag) || e->hasLocalName(thTag))
    166                     found = true;
    167                 else if (e->hasLocalName(tableTag))
     213                    return e;
     214                break;
     215            case TableRows:
     216                // Look for table rows inside table sections that are immediately inside
     217                // the table, but not in nested table sections. Accept only rows that are
     218                // in those table sections.
     219                if (e->parent() == m_base)
     220                    deep = isTableSection(e);
     221                else {
     222                    if (e->hasLocalName(trTag))
     223                        return e;
    168224                    deep = false;
    169                 break;
    170             case TableRows:
     225                }
     226                break;
    171227            case TSectionRows:
    172228                if (e->hasLocalName(trTag))
    173                     found = true;
    174                 else if (e->hasLocalName(tableTag))
    175                     deep = false;
     229                    return e;
    176230                break;
    177231            case SelectOptions:
    178232                if (e->hasLocalName(optionTag))
    179                     found = true;
     233                    return e;
    180234                break;
    181235            case MapAreas:
    182236                if (e->hasLocalName(areaTag))
    183                     found = true;
    184                 break;
    185             case DocApplets:   // all APPLET elements and OBJECT elements that contain Java Applets
    186                 if (e->hasLocalName(appletTag) ||
    187                     (e->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet()))
    188                     found = true;
    189                 break;
    190             case DocEmbeds:   // all EMBED elements
     237                    return e;
     238                break;
     239            case DocApplets: // all <applet> elements and <object> elements that contain Java Applets
     240                if (e->hasLocalName(appletTag))
     241                    return e;
     242                if (e->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet())
     243                    return e;
     244                break;
     245            case DocEmbeds:
    191246                if (e->hasLocalName(embedTag))
    192                     found = true;
    193                 break;
    194             case DocObjects:   // all OBJECT elements
     247                    return e;
     248                break;
     249            case DocObjects:
    195250                if (e->hasLocalName(objectTag))
    196                     found = true;
    197                 break;
    198             case DocLinks:     // all A _and_ AREA elements with a value for href
    199                 if (e->hasLocalName(aTag) || e->hasLocalName(areaTag))
    200                     if (!e->getAttribute(hrefAttr).isNull())
    201                         found = true;
    202                 break;
    203             case DocAnchors:      // all A elements with a value for name or an id attribute
    204                 if (e->hasLocalName(aTag))
    205                     if (!e->getAttribute(nameAttr).isNull())
    206                         found = true;
     251                    return e;
     252                break;
     253            case DocLinks: // all <a> and <area> elements with a value for href
     254                if ((e->hasLocalName(aTag) || e->hasLocalName(areaTag)) && (!e->getAttribute(hrefAttr).isNull()))
     255                    return e;
     256                break;
     257            case DocAnchors: // all <a> elements with a value for name
     258                if (e->hasLocalName(aTag) && !e->getAttribute(nameAttr).isNull())
     259                    return e;
    207260                break;
    208261            case DocAll:
    209                 found = true;
    210                 break;
    211262            case NodeChildren:
    212                 found = true;
    213                 deep = false;
    214                 break;
    215             default:
    216                 break;
    217             }
    218 
    219             if (found)
    220                 return current;
    221             if (deep) {
    222                 current = current->traverseNextNode(m_base.get());
    223                 continue;
    224             }
    225         }
    226         current = current->traverseNextSibling(m_base.get());
    227     }
     263                return e;
     264            case DocumentNamedItems:
     265            case FormElements:
     266            case WindowNamedItems:
     267                ASSERT_NOT_REACHED();
     268                break;
     269        }
     270    }
     271
    228272    return 0;
    229273}
    230274
    231 
    232275unsigned HTMLCollection::calcLength() const
    233276{
    234277    unsigned len = 0;
    235 
    236     for (Node *current = traverseNextItem(m_base.get()); current; current = traverseNextItem(current)) {
    237         len++;
    238     }
    239 
     278    for (Element* current = itemAfter(0); current; current = itemAfter(current))
     279        ++len;
    240280    return len;
    241281}
     
    246286{
    247287    resetCollectionInfo();
    248     if (!info->haslength) {
    249         info->length = calcLength();
    250         info->haslength = true;
    251     }
    252     return info->length;
    253 }
    254 
    255 Node *HTMLCollection::item( unsigned index ) const
     288    if (!m_info->hasLength) {
     289        m_info->length = calcLength();
     290        m_info->hasLength = true;
     291    }
     292    return m_info->length;
     293}
     294
     295Node* HTMLCollection::item(unsigned index) const
    256296{
    257297     resetCollectionInfo();
    258      if (info->current && info->position == index) {
    259          return info->current;
    260      }
    261      if (info->haslength && info->length <= index) {
     298     if (m_info->current && m_info->position == index)
     299         return m_info->current;
     300     if (m_info->hasLength && m_info->length <= index)
    262301         return 0;
    263      }
    264      if (!info->current || info->position > index) {
    265          info->current = traverseNextItem(m_base.get());
    266          info->position = 0;
    267          if (!info->current)
     302     if (!m_info->current || m_info->position > index) {
     303         m_info->current = itemAfter(0);
     304         m_info->position = 0;
     305         if (!m_info->current)
    268306             return 0;
    269307     }
    270      Node *node = info->current;
    271      for (unsigned pos = info->position; node && pos < index; pos++) {
    272          node = traverseNextItem(node);
    273      }     
    274      info->current = node;
    275      info->position = index;
    276      return info->current;
    277 }
    278 
    279 Node *HTMLCollection::firstItem() const
     308     Element* e = m_info->current;
     309     for (unsigned pos = m_info->position; e && pos < index; pos++)
     310         e = itemAfter(e);
     311     m_info->current = e;
     312     m_info->position = index;
     313     return m_info->current;
     314}
     315
     316Node* HTMLCollection::firstItem() const
    280317{
    281318     return item(0);
    282319}
    283320
    284 Node *HTMLCollection::nextItem() const
     321Node* HTMLCollection::nextItem() const
    285322{
    286323     resetCollectionInfo();
    287324 
    288325     // Look for the 'second' item. The first one is currentItem, already given back.
    289      Node *retval = traverseNextItem(info->current);
    290      info->current = retval;
    291      info->position++;
     326     Element* retval = itemAfter(m_info->current);
     327     m_info->current = retval;
     328     m_info->position++;
    292329     return retval;
    293330}
    294331
    295 bool HTMLCollection::checkForNameMatch(Node *node, bool checkName, const String &name, bool caseSensitive) const
    296 {
    297     if (!node->isHTMLElement())
     332bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const String& name, bool caseSensitive) const
     333{
     334    if (!element->isHTMLElement())
    298335        return false;
    299336   
    300     HTMLElement *e = static_cast<HTMLElement*>(node);
     337    HTMLElement* e = static_cast<HTMLElement*>(element);
    301338    if (caseSensitive) {
    302339        if (checkName) {
    303340            // document.all returns only images, forms, applets, objects and embeds
    304341            // by name (though everything by id)
    305             if (type == DocAll &&
     342            if (m_type == DocAll &&
    306343                !(e->hasLocalName(imgTag) || e->hasLocalName(formTag) ||
    307344                  e->hasLocalName(appletTag) || e->hasLocalName(objectTag) ||
     
    317354            // document.all returns only images, forms, applets, objects and embeds
    318355            // by name (though everything by id)
    319             if (type == DocAll &&
     356            if (m_type == DocAll &&
    320357                !(e->hasLocalName(imgTag) || e->hasLocalName(formTag) ||
    321358                  e->hasLocalName(appletTag) || e->hasLocalName(objectTag) ||
     
    341378    // that are allowed a name attribute.
    342379    resetCollectionInfo();
    343     idsDone = false;
    344 
    345     Node *n;
    346     for (n = traverseNextItem(m_base.get()); n; n = traverseNextItem(n)) {
    347         if (checkForNameMatch(n, idsDone, name, caseSensitive))
    348             break;
     380    m_idsDone = false;
     381
     382    for (Element* e = itemAfter(0); e; e = itemAfter(e)) {
     383        if (checkForNameMatch(e, m_idsDone, name, caseSensitive)) {
     384            m_info->current = e;
     385            return e;
     386        }
    349387    }
    350388       
    351     info->current = n;
    352     if(info->current)
    353         return info->current;
    354     idsDone = true;
    355 
    356     for (n = traverseNextItem(m_base.get()); n; n = traverseNextItem(n)) {
    357         if (checkForNameMatch(n, idsDone, name, caseSensitive))
    358             break;
    359     }
    360 
    361     info->current = n;
    362     return info->current;
     389    m_idsDone = true;
     390
     391    for (Element* e = itemAfter(0); e; e = itemAfter(e)) {
     392        if (checkForNameMatch(e, m_idsDone, name, caseSensitive)) {
     393            m_info->current = e;
     394            return e;
     395        }
     396    }
     397
     398    m_info->current = 0;
     399    return 0;
    363400}
    364401
    365402void HTMLCollection::updateNameCache() const
    366403{
    367     if (info->hasNameCache)
     404    if (m_info->hasNameCache)
    368405        return;
    369406   
    370     for (Node *n = traverseNextItem(m_base.get()); n; n = traverseNextItem(n)) {
    371         if (!n->isHTMLElement())
     407    for (Element* element = itemAfter(0); element; element = itemAfter(element)) {
     408        if (!element->isHTMLElement())
    372409            continue;
    373         HTMLElement* e = static_cast<HTMLElement*>(n);
     410        HTMLElement* e = static_cast<HTMLElement*>(element);
    374411        const AtomicString& idAttrVal = e->getAttribute(idAttr);
    375412        const AtomicString& nameAttrVal = e->getAttribute(nameAttr);
    376413        if (!idAttrVal.isEmpty()) {
    377414            // add to id cache
    378             Vector<Node*>* idVector = info->idCache.get(idAttrVal.impl());
     415            Vector<Element*>* idVector = m_info->idCache.get(idAttrVal.impl());
    379416            if (!idVector) {
    380                 idVector = new Vector<Node*>;
    381                 info->idCache.add(idAttrVal.impl(), idVector);
     417                idVector = new Vector<Element*>;
     418                m_info->idCache.add(idAttrVal.impl(), idVector);
    382419            }
    383             idVector->append(n);
     420            idVector->append(e);
    384421        }
    385422        if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal
    386             && (type != DocAll ||
     423            && (m_type != DocAll ||
    387424                (e->hasLocalName(imgTag) || e->hasLocalName(formTag) ||
    388425                 e->hasLocalName(appletTag) || e->hasLocalName(objectTag) ||
     
    390427                 e->hasLocalName(selectTag)))) {
    391428            // add to name cache
    392             Vector<Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());
     429            Vector<Element*>* nameVector = m_info->nameCache.get(nameAttrVal.impl());
    393430            if (!nameVector) {
    394                 nameVector = new Vector<Node*>;
    395                 info->nameCache.add(nameAttrVal.impl(), nameVector);
     431                nameVector = new Vector<Element*>;
     432                m_info->nameCache.add(nameAttrVal.impl(), nameVector);
    396433            }
    397             nameVector->append(n);
    398         }
    399     }
    400 
    401     info->hasNameCache = true;
    402 }
    403 
    404 void HTMLCollection::namedItems(const AtomicString &name, Vector<RefPtr<Node> >& result) const
     434            nameVector->append(e);
     435        }
     436    }
     437
     438    m_info->hasNameCache = true;
     439}
     440
     441void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const
    405442{
    406443    ASSERT(result.isEmpty());
     
    412449    updateNameCache();
    413450   
    414     Vector<Node*>* idResults = info->idCache.get(name.impl());
    415     Vector<Node*>* nameResults = info->nameCache.get(name.impl());
     451    Vector<Element*>* idResults = m_info->idCache.get(name.impl());
     452    Vector<Element*>* nameResults = m_info->nameCache.get(name.impl());
    416453   
    417454    for (unsigned i = 0; idResults && i < idResults->size(); ++i)
     
    423460
    424461
    425 Node *HTMLCollection::nextNamedItem(const String &name) const
     462Node* HTMLCollection::nextNamedItem(const String& name) const
    426463{
    427464    resetCollectionInfo();
    428465
    429     for (Node *n = traverseNextItem(info->current ? info->current : m_base.get()); n; n = traverseNextItem(n)) {
    430         if (checkForNameMatch(n, idsDone, name, true)) {
    431             info->current = n;
    432             return n;
    433         }
    434     }
    435    
    436     if (idsDone) {
    437         info->current = 0;
     466    for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) {
     467        if (checkForNameMatch(e, m_idsDone, name, true)) {
     468            m_info->current = e;
     469            return e;
     470        }
     471    }
     472   
     473    if (m_idsDone) {
     474        m_info->current = 0;
    438475        return 0;
    439476    }
    440     idsDone = true;
    441 
    442     for (Node *n = traverseNextItem(info->current ? info->current : m_base.get()); n; n = traverseNextItem(n)) {
    443         if (checkForNameMatch(n, idsDone, name, true)) {
    444             info->current = n;
    445             return n;
     477    m_idsDone = true;
     478
     479    for (Element* e = itemAfter(m_info->current); e; e = itemAfter(e)) {
     480        if (checkForNameMatch(e, m_idsDone, name, true)) {
     481            m_info->current = e;
     482            return e;
    446483        }
    447484    }
     
    452489PassRefPtr<NodeList> HTMLCollection::tags(const String& name)
    453490{
    454     return base()->getElementsByTagName(name);
     491    return m_base->getElementsByTagName(name);
    455492}
    456493
  • trunk/WebCore/html/HTMLCollection.h

    r27776 r28327  
    11/*
    2  * This file is part of the DOM implementation for KDE.
    3  *
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    6  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    75 *
    86 * This library is free software; you can redistribute it and/or
     
    3533class AtomicString;
    3634class AtomicStringImpl;
     35class Element;
    3736class Node;
    3837class NodeList;
     
    4241public:
    4342    enum Type {
    44         // from JSHTMLDocument
    45         DocImages = 0, // all IMG elements in the document
    46         DocApplets,   // all OBJECT and APPLET elements
    47         DocEmbeds,    // all EMBED elements
    48         DocObjects,   // all OBJECT elements
    49         DocForms,     // all FORMS
    50         DocLinks,     // all A _and_ AREA elements with a value for href
    51         DocAnchors,      // all A elements with a value for name
    52         DocScripts,   // all SCRIPT element
    53         // from HTMLTable, HTMLTableSection, HTMLTableRow
    54         TableRows,    // all rows in this table or tablesection
    55         TableTBodies, // all TBODY elements in this table
    56         TSectionRows, // all rows elements in this table section
    57         TRCells,      // all CELLS in this row
    58         // from SELECT
     43        // unnamed collection types cached in the document
     44
     45        DocImages,    // all <img> elements in the document
     46        DocApplets,   // all <object> and <applet> elements
     47        DocEmbeds,    // all <embed> elements
     48        DocObjects,   // all <object> elements
     49        DocForms,     // all <form> elements
     50        DocLinks,     // all <a> _and_ <area> elements with a value for href
     51        DocAnchors,   // all <a> elements with a value for name
     52        DocScripts,   // all <script> elements
     53
     54        DocAll,       // "all" elements (IE)
     55        NodeChildren, // first-level children (IE)
     56
     57        // named collection types cached in the document
     58
     59        WindowNamedItems,
     60        DocumentNamedItems,
     61
     62        // types not cached in the document; these are types that can't be used on a document
     63
     64        TableRows,    // all rows in this table or table section
     65        TableTBodies, // all <tbody> elements in this table
     66        TSectionRows, // all row elements in this table section
     67        TRCells,      // all cells in this row
    5968        SelectOptions,
    60         // from HTMLMap
    6169        MapAreas,
    62         DocAll,        // "all" elements (IE)
    63         NodeChildren,   // first-level children (IE)
    64         WindowNamedItems,
    65         DocumentNamedItems
     70        FormElements
    6671    };
    6772
    68     enum {
    69         UnnamedCollectionTypes = NodeChildren + 1,
    70         CollectionTypes = DocumentNamedItems + 1
    71     };
     73    static const Type FirstUnnamedDocumentCachedType = DocImages;
     74    static const unsigned NumUnnamedDocumentCachedTypes = NodeChildren - DocImages + 1;
    7275
    73     HTMLCollection(Node *_base, HTMLCollection::Type _type);
     76    static const Type FirstNamedDocumentCachedType = WindowNamedItems;
     77    static const unsigned NumNamedDocumentCachedTypes = DocumentNamedItems - WindowNamedItems + 1;
     78
     79    HTMLCollection(PassRefPtr<Node> base, Type);
    7480    virtual ~HTMLCollection();
    7581   
    7682    unsigned length() const;
    7783   
    78     virtual Node *item(unsigned index) const;
    79     virtual Node *firstItem() const;
    80     virtual Node *nextItem() const;
     84    virtual Node* item(unsigned index) const;
     85    virtual Node* firstItem() const;
     86    virtual Node* nextItem() const;
    8187
    82     virtual Node *namedItem(const String &name, bool caseSensitive = true) const;
    83     // In case of multiple items named the same way
    84     virtual Node *nextNamedItem(const String &name) const;
     88    virtual Node* namedItem(const String& name, bool caseSensitive = true) const;
     89    virtual Node* nextNamedItem(const String& name) const; // In case of multiple items named the same way
    8590
    86     // Extension
     91    void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const;
     92
    8793    PassRefPtr<NodeList> tags(const String&);
    8894
    89     void namedItems(const AtomicString &name, Vector<RefPtr<Node> >&) const;
     95    Node* base() const { return m_base.get(); }
     96    Type type() const { return m_type; }
    9097
    91     Node *base() { return m_base.get(); }
    92 
     98    // FIXME: This class name is a bad in two ways. First, "info" is much too vague,
     99    // and doesn't convey the job of this class (caching collection state).
     100    // Second, since this is a member of HTMLCollection, it doesn't need "collection"
     101    // in its name.
    93102    struct CollectionInfo {
    94103        CollectionInfo();
     
    100109            return *this;
    101110        }
    102        
    103111        ~CollectionInfo();
     112
    104113        void reset();
    105114        void swap(CollectionInfo&);
    106115
    107         unsigned int version;
    108         Node *current;
    109         unsigned int position;
    110         unsigned int length;
     116        typedef HashMap<AtomicStringImpl*, Vector<Element*>*> NodeCacheMap;
     117
     118        unsigned version;
     119        Element* current;
     120        unsigned position;
     121        unsigned length;
    111122        int elementsArrayPosition;
    112         typedef HashMap<AtomicStringImpl*, Vector<Node*>*> NodeCacheMap;
    113123        NodeCacheMap idCache;
    114124        NodeCacheMap nameCache;
    115         bool haslength;
     125        bool hasLength;
    116126        bool hasNameCache;
     127
    117128    private:
    118         static void copyCacheMap(NodeCacheMap& dest, const NodeCacheMap& src)
    119         {
    120             ASSERT(dest.isEmpty());
    121             NodeCacheMap::const_iterator end = src.end();
    122             for (NodeCacheMap::const_iterator it = src.begin(); it != end; ++it)
    123                 dest.add(it->first, new Vector<Node*>(*it->second));
    124         }
     129        static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&);
    125130    };
    126131
    127     Type collectionType() const { return type; }
     132protected:
     133    HTMLCollection(PassRefPtr<Node> base, Type, CollectionInfo*);
    128134
    129 protected:
     135    CollectionInfo* info() const { return m_info; }
     136    virtual void resetCollectionInfo() const;
     137
     138    mutable bool m_idsDone; // for nextNamedItem()
     139
     140private:
     141    virtual Element* itemAfter(Element*) const;
     142    virtual unsigned calcLength() const;
    130143    virtual void updateNameCache() const;
    131144
    132     virtual Node *traverseNextItem(Node *start) const;
    133     bool checkForNameMatch(Node *node, bool checkName, const String &name, bool caseSensitive) const;
    134     virtual unsigned calcLength() const;
    135     virtual void resetCollectionInfo() const;
    136     // the base node, the collection refers to
     145    bool checkForNameMatch(Element*, bool checkName, const String &name, bool caseSensitive) const;
     146
    137147    RefPtr<Node> m_base;
    138     // The collection list the following elements
    139     Type type;
    140     mutable CollectionInfo *info;
     148    Type m_type;
    141149
    142     // For nextNamedItem()
    143     mutable bool idsDone;
    144 
     150    mutable CollectionInfo* m_info;
    145151    mutable bool m_ownsInfo;
    146152};
    147153
    148 } //namespace
     154} // namespace
    149155
    150156#endif
  • trunk/WebCore/html/HTMLFormCollection.cpp

    r25754 r28327  
    1 /**
    2  * This file is part of the DOM implementation for KDE.
    3  *
     1/*
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    6  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    75 *
    86 * This library is free software; you can redistribute it and/or
     
    3533using namespace HTMLNames;
    3634
    37 // since the collections are to be "live", we have to do the
    38 // calculation every time if anything has changed
    39 
    40 HTMLFormCollection::HTMLFormCollection(Node* _base)
    41     : HTMLCollection(_base, HTMLCollection::Type(0))
    42 {
    43     HTMLFormElement *formBase = static_cast<HTMLFormElement*>(m_base.get());
    44     if (!formBase->collectionInfo)
    45         formBase->collectionInfo = new CollectionInfo();
    46     info = formBase->collectionInfo;
     35// Since the collections are to be "live", we have to do the
     36// calculation every time if anything has changed.
     37
     38inline HTMLCollection::CollectionInfo* HTMLFormCollection::formCollectionInfo(HTMLFormElement* form)
     39{
     40    if (!form->collectionInfo)
     41        form->collectionInfo = new CollectionInfo;
     42    return form->collectionInfo;
     43}
     44
     45HTMLFormCollection::HTMLFormCollection(PassRefPtr<HTMLFormElement> form)
     46    : HTMLCollection(form.get(), FormElements, formCollectionInfo(form.get()))
     47{
    4748}
    4849
     
    5354unsigned HTMLFormCollection::calcLength() const
    5455{
    55     return static_cast<HTMLFormElement*>(m_base.get())->length();
    56 }
    57 
    58 Node *HTMLFormCollection::item(unsigned index) const
     56    return static_cast<HTMLFormElement*>(base())->length();
     57}
     58
     59Node* HTMLFormCollection::item(unsigned index) const
    5960{
    6061    resetCollectionInfo();
    6162
    62     if (info->current && info->position == index)
    63         return info->current;
    64 
    65     if (info->haslength && info->length <= index)
     63    if (info()->current && info()->position == index)
     64        return info()->current;
     65
     66    if (info()->hasLength && info()->length <= index)
    6667        return 0;
    6768
    68     if (!info->current || info->position > index) {
    69         info->current = 0;
    70         info->position = 0;
    71         info->elementsArrayPosition = 0;
    72     }
    73 
    74     Vector<HTMLGenericFormElement*>& l = static_cast<HTMLFormElement*>(m_base.get())->formElements;
    75     unsigned currentIndex = info->position;
     69    if (!info()->current || info()->position > index) {
     70        info()->current = 0;
     71        info()->position = 0;
     72        info()->elementsArrayPosition = 0;
     73    }
     74
     75    Vector<HTMLGenericFormElement*>& l = static_cast<HTMLFormElement*>(base())->formElements;
     76    unsigned currentIndex = info()->position;
    7677   
    77     for (unsigned i = info->elementsArrayPosition; i < l.size(); i++) {
     78    for (unsigned i = info()->elementsArrayPosition; i < l.size(); i++) {
    7879        if (l[i]->isEnumeratable() ) {
    7980            if (index == currentIndex) {
    80                 info->position = index;
    81                 info->current = l[i];
    82                 info->elementsArrayPosition = i;
     81                info()->position = index;
     82                info()->current = l[i];
     83                info()->elementsArrayPosition = i;
    8384                return l[i];
    8485            }
     
    9192}
    9293
    93 Node* HTMLFormCollection::getNamedItem(Node*, const QualifiedName& attrName, const String& name, bool caseSensitive) const
    94 {
    95     info->position = 0;
     94Element* HTMLFormCollection::getNamedItem(const QualifiedName& attrName, const String& name, bool caseSensitive) const
     95{
     96    info()->position = 0;
    9697    return getNamedFormItem(attrName, name, 0, caseSensitive);
    9798}
    9899
    99 Node* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber, bool caseSensitive) const
    100 {
    101     if (m_base->isElementNode()) {
    102         HTMLElement* baseElement = static_cast<HTMLElement*>(m_base.get());
    103         bool foundInputElements = false;
    104         if (baseElement->hasLocalName(formTag)) {
    105             HTMLFormElement* f = static_cast<HTMLFormElement*>(baseElement);
    106             for (unsigned i = 0; i < f->formElements.size(); ++i) {
    107                 HTMLGenericFormElement* e = f->formElements[i];
    108                 if (e->isEnumeratable()) {
    109                     bool found;
    110                     if (caseSensitive)
    111                         found = e->getAttribute(attrName) == name;
    112                     else
    113                         found = e->getAttribute(attrName).domString().lower() == name.lower();
    114                     if (found) {
    115                         foundInputElements = true;
    116                         if (!duplicateNumber)
    117                             return e;
    118                         --duplicateNumber;
    119                     }
    120                 }
    121             }
    122         }
    123 
    124         if (!foundInputElements) {
    125             HTMLFormElement* f = static_cast<HTMLFormElement*>(baseElement);
    126 
    127             for(unsigned i = 0; i < f->imgElements.size(); ++i)
    128             {
    129                 HTMLImageElement* e = f->imgElements[i];
    130                 bool found;
    131                 if (caseSensitive)
    132                     found = e->getAttribute(attrName) == name;
    133                 else
    134                     found = e->getAttribute(attrName).domString().lower() == name.lower();
    135                 if (found) {
    136                     if (!duplicateNumber)
    137                         return e;
    138                     --duplicateNumber;
    139                 }
    140             }
    141         }
    142     }
     100Element* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber, bool caseSensitive) const
     101{
     102    HTMLFormElement* form = static_cast<HTMLFormElement*>(base());
     103
     104    bool foundInputElements = false;
     105    for (unsigned i = 0; i < form->formElements.size(); ++i) {
     106        HTMLGenericFormElement* e = form->formElements[i];
     107        if (e->isEnumeratable()) {
     108            bool found;
     109            if (caseSensitive)
     110                found = e->getAttribute(attrName) == name;
     111            else
     112                found = e->getAttribute(attrName).domString().lower() == name.lower();
     113            if (found) {
     114                foundInputElements = true;
     115                if (!duplicateNumber)
     116                    return e;
     117                --duplicateNumber;
     118            }
     119        }
     120    }
     121
     122    if (!foundInputElements) {
     123        for (unsigned i = 0; i < form->imgElements.size(); ++i) {
     124            HTMLImageElement* e = form->imgElements[i];
     125            bool found;
     126            if (caseSensitive)
     127                found = e->getAttribute(attrName) == name;
     128            else
     129                found = e->getAttribute(attrName).domString().lower() == name.lower();
     130            if (found) {
     131                if (!duplicateNumber)
     132                    return e;
     133                --duplicateNumber;
     134            }
     135        }
     136    }
     137
    143138    return 0;
    144139}
    145140
    146 Node * HTMLFormCollection::firstItem() const
    147 {
    148     return item(0);
    149 }
    150 
    151 Node * HTMLFormCollection::nextItem() const
    152 {
    153     return item(info->position + 1);
    154 }
    155 
    156 Node * HTMLFormCollection::nextNamedItemInternal(const String &name) const
    157 {
    158     Node *retval = getNamedFormItem( idsDone ? nameAttr : idAttr, name, ++info->position, true );
     141Node* HTMLFormCollection::nextItem() const
     142{
     143    return item(info()->position + 1);
     144}
     145
     146Element* HTMLFormCollection::nextNamedItemInternal(const String &name) const
     147{
     148    Element* retval = getNamedFormItem(m_idsDone ? nameAttr : idAttr, name, ++info()->position, true);
    159149    if (retval)
    160150        return retval;
    161     if (idsDone) // we're done
     151    if (m_idsDone) // we're done
    162152        return 0;
    163153    // After doing id, do name
    164     idsDone = true;
    165     return getNamedItem(m_base->firstChild(), nameAttr, name, true);
    166 }
    167 
    168 Node *HTMLFormCollection::namedItem( const String &name, bool caseSensitive ) const
     154    m_idsDone = true;
     155    return getNamedItem(nameAttr, name, true);
     156}
     157
     158Node* HTMLFormCollection::namedItem(const String& name, bool caseSensitive) const
    169159{
    170160    // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
     
    174164    // that are allowed a name attribute.
    175165    resetCollectionInfo();
    176     idsDone = false;
    177     info->current = getNamedItem(m_base->firstChild(), idAttr, name, true);
    178     if(info->current)
    179         return info->current;
    180     idsDone = true;
    181     info->current = getNamedItem(m_base->firstChild(), nameAttr, name, true);
    182     return info->current;
    183 }
    184 
    185 Node *HTMLFormCollection::nextNamedItem( const String &name ) const
    186 {
    187     // nextNamedItemInternal can return an item that has both id=<name> and name=<name>
    188     // Here, we have to filter out such cases.
    189     Node *impl = nextNamedItemInternal( name );
    190     if (!idsDone) // looking for id=<name> -> no filtering
    191         return impl;
    192     // looking for name=<name> -> filter out if id=<name>
    193     bool ok = false;
    194     while (impl && !ok)
    195     {
    196         if(impl->isElementNode())
    197         {
    198             HTMLElement *e = static_cast<HTMLElement *>(impl);
    199             ok = (e->getAttribute(idAttr) != name);
    200             if (!ok)
    201                 impl = nextNamedItemInternal( name );
    202         } else // can't happen
    203             ok = true;
    204     }
     166    m_idsDone = false;
     167    info()->current = getNamedItem(idAttr, name, true);
     168    if (info()->current)
     169        return info()->current;
     170    m_idsDone = true;
     171    info()->current = getNamedItem(nameAttr, name, true);
     172    return info()->current;
     173}
     174
     175Node* HTMLFormCollection::nextNamedItem(const String& name) const
     176{
     177    // The nextNamedItemInternal function can return the same item twice if it has
     178    // both an id and name that are equal to the name parameter. So this function
     179    // checks if we are on the nameAttr half of the iteration and skips over any
     180    // that also have the same idAttr.
     181    Element* impl = nextNamedItemInternal(name);
     182    if (m_idsDone)
     183        while (impl && impl->getAttribute(idAttr) == name)
     184            impl = nextNamedItemInternal(name);
    205185    return impl;
    206186}
     
    208188void HTMLFormCollection::updateNameCache() const
    209189{
    210     if (info->hasNameCache)
     190    if (info()->hasNameCache)
    211191        return;
    212192
    213193    HashSet<AtomicStringImpl*> foundInputElements;
    214194
    215     if (!m_base->hasTagName(formTag)) {
    216         info->hasNameCache = true;
    217         return;
    218     }
    219 
    220     HTMLElement* baseElement = static_cast<HTMLElement*>(m_base.get());
    221 
    222     HTMLFormElement* f = static_cast<HTMLFormElement*>(baseElement);
     195    HTMLFormElement* f = static_cast<HTMLFormElement*>(base());
     196
    223197    for (unsigned i = 0; i < f->formElements.size(); ++i) {
    224198        HTMLGenericFormElement* e = f->formElements[i];
     
    228202            if (!idAttrVal.isEmpty()) {
    229203                // add to id cache
    230                 Vector<Node*>* idVector = info->idCache.get(idAttrVal.impl());
     204                Vector<Element*>* idVector = info()->idCache.get(idAttrVal.impl());
    231205                if (!idVector) {
    232                     idVector = new Vector<Node*>;
    233                     info->idCache.add(idAttrVal.impl(), idVector);
     206                    idVector = new Vector<Element*>;
     207                    info()->idCache.add(idAttrVal.impl(), idVector);
    234208                }
    235209                idVector->append(e);
     
    238212            if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
    239213                // add to name cache
    240                 Vector<Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());
     214                Vector<Element*>* nameVector = info()->nameCache.get(nameAttrVal.impl());
    241215                if (!nameVector) {
    242                     nameVector = new Vector<Node*>;
    243                     info->nameCache.add(nameAttrVal.impl(), nameVector);
     216                    nameVector = new Vector<Element*>;
     217                    info()->nameCache.add(nameAttrVal.impl(), nameVector);
    244218                }
    245219                nameVector->append(e);
     
    255229        if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl())) {
    256230            // add to id cache
    257             Vector<Node*>* idVector = info->idCache.get(idAttrVal.impl());
     231            Vector<Element*>* idVector = info()->idCache.get(idAttrVal.impl());
    258232            if (!idVector) {
    259                 idVector = new Vector<Node*>;
    260                 info->idCache.add(idAttrVal.impl(), idVector);
     233                idVector = new Vector<Element*>;
     234                info()->idCache.add(idAttrVal.impl(), idVector);
    261235            }
    262236            idVector->append(e);
     
    264238        if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl())) {
    265239            // add to name cache
    266             Vector<Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());
     240            Vector<Element*>* nameVector = info()->nameCache.get(nameAttrVal.impl());
    267241            if (!nameVector) {
    268                 nameVector = new Vector<Node*>;
    269                 info->nameCache.add(nameAttrVal.impl(), nameVector);
     242                nameVector = new Vector<Element*>;
     243                info()->nameCache.add(nameAttrVal.impl(), nameVector);
    270244            }
    271245            nameVector->append(e);
     
    273247    }
    274248
    275     info->hasNameCache = true;
    276 }
    277 
    278 }
     249    info()->hasNameCache = true;
     250}
     251
     252}
  • trunk/WebCore/html/HTMLFormCollection.h

    r25754 r28327  
    11/*
    2  * This file is part of the DOM implementation for KDE.
    3  *
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    6  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    75 *
    86 * This library is free software; you can redistribute it and/or
     
    2220 *
    2321 */
     22
    2423#ifndef HTMLFormCollection_h
    2524#define HTMLFormCollection_h
     
    2928namespace WebCore {
    3029
     30class HTMLFormElement;
    3131class QualifiedName;
    3232
    33 // this whole class is just a big hack to find form elements even in
    34 // malformed HTML elements
    35 // the famous <table><tr><form><td> problem
    36 class HTMLFormCollection : public HTMLCollection
    37 {
     33// This class is just a big hack to find form elements even in malformed HTML elements.
     34// The famous <table><tr><form><td> problem.
     35
     36class HTMLFormCollection : public HTMLCollection {
    3837public:
    39     // base must inherit HTMLGenericFormElement or this won't work
    40     HTMLFormCollection(Node* _base);
     38    HTMLFormCollection(PassRefPtr<HTMLFormElement>);
    4139    ~HTMLFormCollection();
    4240
    43     virtual Node *item ( unsigned index ) const;
    44     virtual Node *firstItem() const;
    45     virtual Node *nextItem() const;
     41    virtual Node* item(unsigned index) const;
     42    virtual Node* nextItem() const;
    4643
    47     virtual Node *namedItem ( const String &name, bool caseSensitive = true ) const;
    48     virtual Node *nextNamedItem( const String &name ) const;
     44    virtual Node* namedItem(const String& name, bool caseSensitive = true) const;
     45    virtual Node* nextNamedItem(const String& name) const;
    4946
    50 protected:
     47private:
    5148    virtual void updateNameCache() const;
    5249    virtual unsigned calcLength() const;
    53     virtual Node *getNamedItem(Node* current, const QualifiedName& attrName, const String& name, bool caseSensitive) const;
    54     virtual Node *nextNamedItemInternal( const String &name ) const;
    55 private:
    56     Node* getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber, bool caseSensitive) const;
     50
     51    static CollectionInfo* formCollectionInfo(HTMLFormElement*);
     52
     53    Element* getNamedItem(const QualifiedName& attrName, const String& name, bool caseSensitive) const;
     54    Element* nextNamedItemInternal(const String& name) const;
     55
     56    Element* getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber, bool caseSensitive) const;
     57
    5758    mutable int currentPos;
    5859};
  • trunk/WebCore/html/HTMLNameCollection.cpp

    r25754 r28327  
    1 /**
    2  * This file is part of the DOM implementation for KDE.
    3  *
     1/*
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    6  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    75 *
    86 * This library is free software; you can redistribute it and/or
     
    3533using namespace HTMLNames;
    3634
    37 HTMLNameCollection::HTMLNameCollection(Document* base, HTMLCollection::Type type, const String& name)
    38     : HTMLCollection(base, type)
     35HTMLNameCollection::HTMLNameCollection(PassRefPtr<Document> document, Type type, const String& name)
     36    : HTMLCollection(document.get(), type, document->nameCollectionInfo(type, name))
    3937    , m_name(name)
    4038{
    41     ASSERT(!info);
    42     info = base->nameCollectionInfo(type, name);
    4339}
    4440
    45 Node* HTMLNameCollection::traverseNextItem(Node* current) const
     41Element* HTMLNameCollection::itemAfter(Element* previous) const
    4642{
    47     ASSERT(current);
     43    ASSERT(previous != base());
    4844
    49     current = current->traverseNextNode(m_base.get());
     45    Node* current;
     46    if (!previous)
     47        current = base()->firstChild();
     48    else
     49        current = previous->traverseNextNode(base());
    5050
    51     while (current) {
    52         if (current->isElementNode()) {
    53             bool found = false;
    54             Element* e = static_cast<Element*>(current);
    55             switch(type) {
     51    for (; current; current = current->traverseNextNode(base())) {
     52        if (!current->isElementNode())
     53            continue;
     54        Element* e = static_cast<Element*>(current);
     55        switch (type()) {
    5656            case WindowNamedItems:
    5757                // find only images, forms, applets, embeds and objects by name,
     
    6262                    e->hasTagName(embedTag) ||
    6363                    e->hasTagName(objectTag))
    64                     found = e->getAttribute(nameAttr) == m_name;
    65                 found |= e->getAttribute(idAttr) == m_name;
     64                    if (e->getAttribute(nameAttr) == m_name)
     65                        return e;
     66                if (e->getAttribute(idAttr) == m_name)
     67                    return e;
    6668                break;
    6769            case DocumentNamedItems:
     
    6971                // applets and object by id, and images by id but only if they have
    7072                // a name attribute (this very strange rule matches IE)
    71                 if (e->hasTagName(formTag) ||
    72                     e->hasTagName(embedTag) ||
    73                     e->hasTagName(iframeTag))
    74                     found = e->getAttribute(nameAttr) == m_name;
    75                 else if (e->hasTagName(appletTag))
    76                     found = e->getAttribute(nameAttr) == m_name ||
    77                         e->getAttribute(idAttr) == m_name;
    78                 else if (e->hasTagName(objectTag))
    79                     found = (e->getAttribute(nameAttr) == m_name || e->getAttribute(idAttr) == m_name) &&
    80                         static_cast<HTMLObjectElement*>(e)->isDocNamedItem();
    81                 else if (e->hasTagName(imgTag))
    82                     found = e->getAttribute(nameAttr) == m_name || (e->getAttribute(idAttr) == m_name && e->hasAttribute(nameAttr));
     73                if (e->hasTagName(formTag) || e->hasTagName(embedTag) || e->hasTagName(iframeTag)) {
     74                    if (e->getAttribute(nameAttr) == m_name)
     75                        return e;
     76                } else if (e->hasTagName(appletTag)) {
     77                    if (e->getAttribute(nameAttr) == m_name || e->getAttribute(idAttr) == m_name)
     78                        return e;
     79                } else if (e->hasTagName(objectTag)) {
     80                    if ((e->getAttribute(nameAttr) == m_name || e->getAttribute(idAttr) == m_name)
     81                            && static_cast<HTMLObjectElement*>(e)->isDocNamedItem())
     82                        return e;
     83                } else if (e->hasTagName(imgTag)) {
     84                    if (e->getAttribute(nameAttr) == m_name || (e->getAttribute(idAttr) == m_name && e->hasAttribute(nameAttr)))
     85                        return e;
     86                }
    8387                break;
    84             default:
    85                 ASSERT(0);
    86             }
     88        default:
     89            ASSERT_NOT_REACHED();
     90        }
     91    }
    8792
    88             if (found)
    89                 return current;
    90         }
    91         current = current->traverseNextNode(m_base.get());
    92     }
    9393    return 0;
    9494}
  • trunk/WebCore/html/HTMLNameCollection.h

    r25754 r28327  
    11/*
    2  * This file is part of the DOM implementation for KDE.
    3  *
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    6  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    75 *
    86 * This library is free software; you can redistribute it and/or
     
    3331class Document;
    3432
    35 class HTMLNameCollection : public HTMLCollection
    36 {
     33class HTMLNameCollection : public HTMLCollection {
    3734public:
    38     HTMLNameCollection(Document*, HTMLCollection::Type type, const String &name);
     35    HTMLNameCollection(PassRefPtr<Document>, Type, const String& name);
    3936   
    40     virtual Node* traverseNextItem(Node*) const;
     37private:
     38    virtual Element* itemAfter(Element*) const;
    4139
    42 private:
    4340    String m_name;
    4441};
  • trunk/WebCore/html/HTMLOptionsCollection.cpp

    r25754 r28327  
    3030namespace WebCore {
    3131
    32 HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement* select)
    33     : HTMLCollection(select, SelectOptions)
     32HTMLOptionsCollection::HTMLOptionsCollection(PassRefPtr<HTMLSelectElement> select)
     33    : HTMLCollection(select.get(), SelectOptions, select->collectionInfo())
    3434{
    35     ASSERT(!info);
    36     info = select->collectionInfo();
    3735}
    3836
     
    5755
    5856    ec = 0;
    59     HTMLSelectElement* select = static_cast<HTMLSelectElement*>(m_base.get());
     57    HTMLSelectElement* select = static_cast<HTMLSelectElement*>(base());
    6058
    6159    if (index == -1 || unsigned(index) >= length())
     
    6967int HTMLOptionsCollection::selectedIndex() const
    7068{
    71     return static_cast<HTMLSelectElement*>(m_base.get())->selectedIndex();
     69    return static_cast<HTMLSelectElement*>(base())->selectedIndex();
    7270}
    7371
    7472void HTMLOptionsCollection::setSelectedIndex(int index)
    7573{
    76     static_cast<HTMLSelectElement*>(m_base.get())->setSelectedIndex(index);
     74    static_cast<HTMLSelectElement*>(base())->setSelectedIndex(index);
    7775}
    7876
    7977void HTMLOptionsCollection::setLength(unsigned length, ExceptionCode& ec)
    8078{
    81     static_cast<HTMLSelectElement*>(m_base.get())->setLength(length, ec);
     79    static_cast<HTMLSelectElement*>(base())->setLength(length, ec);
    8280}
    8381
  • trunk/WebCore/html/HTMLOptionsCollection.h

    r25754 r28327  
    11/*
    2  * This file is part of the DOM implementation for KDE.
    3  *
    42 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    53 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    64 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    7  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
     5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    86 *
    97 * This library is free software; you can redistribute it and/or
     
    2826
    2927#include "HTMLCollection.h"
    30 #include "HTMLOptionElement.h"
    3128
    3229namespace WebCore {
    3330
     31class HTMLOptionElement;
     32class HTMLSelectElement;
     33
    3434typedef int ExceptionCode;
    35 
    36 class HTMLSelectElement;
    3735
    3836class HTMLOptionsCollection : public HTMLCollection {
    3937public:
    40     HTMLOptionsCollection(HTMLSelectElement*);
     38    HTMLOptionsCollection(PassRefPtr<HTMLSelectElement>);
    4139
    4240    void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
  • trunk/WebCore/html/HTMLTableRowElement.cpp

    r25754 r28327  
    1 /**
    2  * This file is part of the DOM implementation for KDE.
    3  *
     1/*
    42 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
    53 *           (C) 1997 Torben Weis (weis@kde.org)
     
    75 *           (C) 1999 Lars Knoll (knoll@kde.org)
    86 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    9  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     7 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    108 *
    119 * This library is free software; you can redistribute it and/or
     
    2422 * Boston, MA 02110-1301, USA.
    2523 */
     24
    2625#include "config.h"
    2726#include "HTMLTableRowElement.h"
     
    131130}
    132131
    133 HTMLElement *HTMLTableRowElement::insertCell(int index, ExceptionCode& ec)
    134 {
    135     HTMLTableCellElement *c = 0L;
     132PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec)
     133{
    136134    RefPtr<HTMLCollection> children = cells();
    137135    int numCells = children ? children->length() : 0;
    138     if ( index < -1 || index > numCells )
    139         ec = INDEX_SIZE_ERR; // per the DOM
    140     else
    141     {
    142         c = new HTMLTableCellElement(tdTag, document());
    143         if(numCells == index || index == -1)
    144             appendChild(c, ec);
    145         else {
    146             Node *n;
    147             if(index < 1)
    148                 n = firstChild();
    149             else
    150                 n = children->item(index);
    151             insertBefore(c, n, ec);
    152         }
    153     }
    154     return c;
     136    if (index < -1 || index > numCells) {
     137        ec = INDEX_SIZE_ERR;
     138        return 0;
     139    }
     140
     141    RefPtr<HTMLTableCellElement> c = new HTMLTableCellElement(tdTag, document());
     142    if (index < 0 || index >= numCells)
     143        appendChild(c, ec);
     144    else {
     145        Node* n;
     146        if (index < 1)
     147            n = firstChild();
     148        else
     149            n = children->item(index);
     150        insertBefore(c, n, ec);
     151    }
     152    return c.release();
    155153}
    156154
  • trunk/WebCore/html/HTMLTableRowElement.h

    r25754 r28327  
    11/*
    2  * This file is part of the DOM implementation for KDE.
    3  *
    42 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
    53 *           (C) 1997 Torben Weis (weis@kde.org)
     
    75 *           (C) 1999 Lars Knoll (knoll@kde.org)
    86 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    9  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     7 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
    108 *
    119 * This library is free software; you can redistribute it and/or
     
    3331namespace WebCore {
    3432
    35 class HTMLTableRowElement : public HTMLTablePartElement
    36 {
     33class HTMLTableRowElement : public HTMLTablePartElement {
    3734public:
    38     HTMLTableRowElement(Document* doc);
     35    HTMLTableRowElement(Document*);
    3936
    4037    virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; }
     
    4441
    4542    int rowIndex() const;
    46     int sectionRowIndex() const;
    47 
    48     HTMLElement* insertCell(int index, ExceptionCode&);
    49     void deleteCell(int index, ExceptionCode&);
    50 
    5143    void setRowIndex(int);
    5244
     45    int sectionRowIndex() const;
    5346    void setSectionRowIndex(int);
     47
     48    PassRefPtr<HTMLElement> insertCell(int index, ExceptionCode&);
     49    void deleteCell(int index, ExceptionCode&);
    5450
    5551    PassRefPtr<HTMLCollection> cells();
     
    7066    String vAlign() const;
    7167    void setVAlign(const String&);
    72 
    73 protected:
    74     int ncols;
    7568};
    7669
    77 } //namespace
     70} // namespace
    7871
    7972#endif
  • trunk/WebCore/html/HTMLTableSectionElement.cpp

    r25754 r28327  
    169169PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
    170170{
    171     return new HTMLCollection(this, HTMLCollection::TableRows);
     171    return new HTMLCollection(this, HTMLCollection::TSectionRows);
    172172}
    173173
Note: See TracChangeset for help on using the changeset viewer.