Changeset 28327 in webkit
- Timestamp:
- Dec 2, 2007, 8:57:59 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 22 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r28312 r28327 1 2007-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 1 31 2007-12-01 Antti Koivisto <antti@apple.com> 2 32 -
trunk/WebCore/ChangeLog
r28325 r28327 1 2007-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 1 134 2007-12-02 Nikolas Zimmermann <zimmermann@kde.org> 2 135 -
trunk/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
r25754 r28327 132 132 return ret; 133 133 134 switch (collection-> collectionType()) {134 switch (collection->type()) { 135 135 case HTMLCollection::SelectOptions: 136 136 ret = new JSHTMLOptionsCollection(exec, static_cast<HTMLOptionsCollection*>(collection)); -
trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm
r28110 r28327 1146 1146 push(@implContent, " if (!${name}Ok) {\n"); 1147 1147 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"); 1149 1150 } 1150 1151 … … 1400 1401 } 1401 1402 1402 if ($type eq "SVGRect") {1403 $implIncludes{"FloatRect.h"} = 1;1404 }1405 1406 if ($type eq "SVGPoint") {1407 $implIncludes{"FloatPoint.h"} = 1;1408 }1409 1410 1403 if ($type eq "VoidCallback") { 1411 1404 $implIncludes{"JSCustomVoidCallback.h"} = 1; 1412 1405 return "toVoidCallback(exec, $value${maybeOkParam})"; 1413 1406 } 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"; 1414 1411 1415 1412 # Default, assume autogenerated type conversion routines -
trunk/WebCore/dom/Document.cpp
r28071 r28327 3510 3510 } 3511 3511 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()); 3512 HTMLCollection::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()); 3519 3520 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; 3522 3522 return iter->second; 3523 3523 } -
trunk/WebCore/dom/Document.h
r27690 r28327 231 231 HTMLCollection::CollectionInfo* collectionInfo(HTMLCollection::Type type) 232 232 { 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]; 236 237 } 237 238 238 HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type type, constString& name);239 HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type, const AtomicString& name); 239 240 240 241 // DOM methods overridden from parent classes … … 894 895 895 896 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]; 899 901 900 902 #if ENABLE(XPATH) -
trunk/WebCore/html/HTMLCollection.cpp
r25754 r28327 1 /** 2 * This file is part of the DOM implementation for KDE. 3 * 1 /* 4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (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. 7 5 * 8 6 * This library is free software; you can redistribute it and/or … … 38 36 using namespace HTMLNames; 39 37 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); 38 HTMLCollection::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 47 HTMLCollection::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 { 49 54 } 50 55 … … 52 57 { 53 58 if (m_ownsInfo) 54 delete info;55 } 56 57 HTMLCollection::CollectionInfo::CollectionInfo() :58 version(0)59 delete m_info; 60 } 61 62 HTMLCollection::CollectionInfo::CollectionInfo() 63 : version(0) 59 64 { 60 65 reset(); 61 66 } 62 67 68 inline 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 63 76 HTMLCollection::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 { 71 85 copyCacheMap(idCache, other.idCache); 72 86 copyCacheMap(nameCache, other.nameCache); 73 74 haslength = other.haslength;75 hasNameCache = other.hasNameCache;76 87 } 77 88 … … 87 98 nameCache.swap(other.nameCache); 88 99 89 std::swap(has length, other.haslength);100 std::swap(hasLength, other.hasLength); 90 101 std::swap(hasNameCache, other.hasNameCache); 91 102 } … … 102 113 position = 0; 103 114 length = 0; 104 has length = false;115 hasLength = false; 105 116 elementsArrayPosition = 0; 106 117 deleteAllValues(idCache); … … 113 124 void HTMLCollection::resetCollectionInfo() const 114 125 { 115 unsigned intdocversion = 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; 119 130 m_ownsInfo = true; 120 info->version = docversion;131 m_info->version = docversion; 121 132 return; 122 133 } 123 134 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 141 static bool isTableSection(Element* element) 142 { 143 return element->hasLocalName(tbodyTag) || element->hasLocalName(tfootTag) || element->hasLocalName(theadTag); 144 } 145 146 static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren) 147 { 148 return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base); 149 } 150 151 Element* 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(); 137 187 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) { 146 195 case DocImages: 147 196 if (e->hasLocalName(imgTag)) 148 found = true;197 return e; 149 198 break; 150 199 case DocScripts: 151 200 if (e->hasLocalName(scriptTag)) 152 found = true;201 return e; 153 202 break; 154 203 case DocForms: 155 if (e->hasLocalName(formTag))156 found = true;204 if (e->hasLocalName(formTag)) 205 return e; 157 206 break; 158 207 case TableTBodies: 159 208 if (e->hasLocalName(tbodyTag)) 160 found = true; 161 else if (e->hasLocalName(tableTag)) 162 deep = false; 209 return e; 163 210 break; 164 211 case TRCells: 165 212 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; 168 224 deep = false; 169 break;170 case TableRows:225 } 226 break; 171 227 case TSectionRows: 172 228 if (e->hasLocalName(trTag)) 173 found = true; 174 else if (e->hasLocalName(tableTag)) 175 deep = false; 229 return e; 176 230 break; 177 231 case SelectOptions: 178 232 if (e->hasLocalName(optionTag)) 179 found = true;233 return e; 180 234 break; 181 235 case MapAreas: 182 236 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: 191 246 if (e->hasLocalName(embedTag)) 192 found = true;193 break; 194 case DocObjects: // all OBJECT elements247 return e; 248 break; 249 case DocObjects: 195 250 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; 207 260 break; 208 261 case DocAll: 209 found = true;210 break;211 262 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 228 272 return 0; 229 273 } 230 274 231 232 275 unsigned HTMLCollection::calcLength() const 233 276 { 234 277 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; 240 280 return len; 241 281 } … … 246 286 { 247 287 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) const288 if (!m_info->hasLength) { 289 m_info->length = calcLength(); 290 m_info->hasLength = true; 291 } 292 return m_info->length; 293 } 294 295 Node* HTMLCollection::item(unsigned index) const 256 296 { 257 297 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) 262 301 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) 268 306 return 0; 269 307 } 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 316 Node* HTMLCollection::firstItem() const 280 317 { 281 318 return item(0); 282 319 } 283 320 284 Node *HTMLCollection::nextItem() const321 Node* HTMLCollection::nextItem() const 285 322 { 286 323 resetCollectionInfo(); 287 324 288 325 // 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++; 292 329 return retval; 293 330 } 294 331 295 bool HTMLCollection::checkForNameMatch( Node *node, bool checkName, const String &name, bool caseSensitive) const296 { 297 if (! node->isHTMLElement())332 bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const String& name, bool caseSensitive) const 333 { 334 if (!element->isHTMLElement()) 298 335 return false; 299 336 300 HTMLElement *e = static_cast<HTMLElement*>(node);337 HTMLElement* e = static_cast<HTMLElement*>(element); 301 338 if (caseSensitive) { 302 339 if (checkName) { 303 340 // document.all returns only images, forms, applets, objects and embeds 304 341 // by name (though everything by id) 305 if ( type == DocAll &&342 if (m_type == DocAll && 306 343 !(e->hasLocalName(imgTag) || e->hasLocalName(formTag) || 307 344 e->hasLocalName(appletTag) || e->hasLocalName(objectTag) || … … 317 354 // document.all returns only images, forms, applets, objects and embeds 318 355 // by name (though everything by id) 319 if ( type == DocAll &&356 if (m_type == DocAll && 320 357 !(e->hasLocalName(imgTag) || e->hasLocalName(formTag) || 321 358 e->hasLocalName(appletTag) || e->hasLocalName(objectTag) || … … 341 378 // that are allowed a name attribute. 342 379 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 } 349 387 } 350 388 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; 363 400 } 364 401 365 402 void HTMLCollection::updateNameCache() const 366 403 { 367 if ( info->hasNameCache)404 if (m_info->hasNameCache) 368 405 return; 369 406 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()) 372 409 continue; 373 HTMLElement* e = static_cast<HTMLElement*>( n);410 HTMLElement* e = static_cast<HTMLElement*>(element); 374 411 const AtomicString& idAttrVal = e->getAttribute(idAttr); 375 412 const AtomicString& nameAttrVal = e->getAttribute(nameAttr); 376 413 if (!idAttrVal.isEmpty()) { 377 414 // add to id cache 378 Vector< Node*>* idVector =info->idCache.get(idAttrVal.impl());415 Vector<Element*>* idVector = m_info->idCache.get(idAttrVal.impl()); 379 416 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); 382 419 } 383 idVector->append( n);420 idVector->append(e); 384 421 } 385 422 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal 386 && ( type != DocAll ||423 && (m_type != DocAll || 387 424 (e->hasLocalName(imgTag) || e->hasLocalName(formTag) || 388 425 e->hasLocalName(appletTag) || e->hasLocalName(objectTag) || … … 390 427 e->hasLocalName(selectTag)))) { 391 428 // add to name cache 392 Vector< Node*>* nameVector =info->nameCache.get(nameAttrVal.impl());429 Vector<Element*>* nameVector = m_info->nameCache.get(nameAttrVal.impl()); 393 430 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); 396 433 } 397 nameVector->append( n);398 } 399 } 400 401 info->hasNameCache = true;402 } 403 404 void HTMLCollection::namedItems(const AtomicString &name, Vector<RefPtr<Node> >& result) const434 nameVector->append(e); 435 } 436 } 437 438 m_info->hasNameCache = true; 439 } 440 441 void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const 405 442 { 406 443 ASSERT(result.isEmpty()); … … 412 449 updateNameCache(); 413 450 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()); 416 453 417 454 for (unsigned i = 0; idResults && i < idResults->size(); ++i) … … 423 460 424 461 425 Node *HTMLCollection::nextNamedItem(const String &name) const462 Node* HTMLCollection::nextNamedItem(const String& name) const 426 463 { 427 464 resetCollectionInfo(); 428 465 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; 438 475 return 0; 439 476 } 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; 446 483 } 447 484 } … … 452 489 PassRefPtr<NodeList> HTMLCollection::tags(const String& name) 453 490 { 454 return base()->getElementsByTagName(name);491 return m_base->getElementsByTagName(name); 455 492 } 456 493 -
trunk/WebCore/html/HTMLCollection.h
r27776 r28327 1 1 /* 2 * This file is part of the DOM implementation for KDE.3 *4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (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. 7 5 * 8 6 * This library is free software; you can redistribute it and/or … … 35 33 class AtomicString; 36 34 class AtomicStringImpl; 35 class Element; 37 36 class Node; 38 37 class NodeList; … … 42 41 public: 43 42 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 59 68 SelectOptions, 60 // from HTMLMap61 69 MapAreas, 62 DocAll, // "all" elements (IE) 63 NodeChildren, // first-level children (IE) 64 WindowNamedItems, 65 DocumentNamedItems 70 FormElements 66 71 }; 67 72 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; 72 75 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); 74 80 virtual ~HTMLCollection(); 75 81 76 82 unsigned length() const; 77 83 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; 81 87 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 85 90 86 // Extension 91 void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const; 92 87 93 PassRefPtr<NodeList> tags(const String&); 88 94 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; } 90 97 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. 93 102 struct CollectionInfo { 94 103 CollectionInfo(); … … 100 109 return *this; 101 110 } 102 103 111 ~CollectionInfo(); 112 104 113 void reset(); 105 114 void swap(CollectionInfo&); 106 115 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; 111 122 int elementsArrayPosition; 112 typedef HashMap<AtomicStringImpl*, Vector<Node*>*> NodeCacheMap;113 123 NodeCacheMap idCache; 114 124 NodeCacheMap nameCache; 115 bool has length;125 bool hasLength; 116 126 bool hasNameCache; 127 117 128 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&); 125 130 }; 126 131 127 Type collectionType() const { return type; } 132 protected: 133 HTMLCollection(PassRefPtr<Node> base, Type, CollectionInfo*); 128 134 129 protected: 135 CollectionInfo* info() const { return m_info; } 136 virtual void resetCollectionInfo() const; 137 138 mutable bool m_idsDone; // for nextNamedItem() 139 140 private: 141 virtual Element* itemAfter(Element*) const; 142 virtual unsigned calcLength() const; 130 143 virtual void updateNameCache() const; 131 144 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 137 147 RefPtr<Node> m_base; 138 // The collection list the following elements 139 Type type; 140 mutable CollectionInfo *info; 148 Type m_type; 141 149 142 // For nextNamedItem() 143 mutable bool idsDone; 144 150 mutable CollectionInfo* m_info; 145 151 mutable bool m_ownsInfo; 146 152 }; 147 153 148 } // namespace154 } // namespace 149 155 150 156 #endif -
trunk/WebCore/html/HTMLFormCollection.cpp
r25754 r28327 1 /** 2 * This file is part of the DOM implementation for KDE. 3 * 1 /* 4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (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. 7 5 * 8 6 * This library is free software; you can redistribute it and/or … … 35 33 using namespace HTMLNames; 36 34 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 38 inline HTMLCollection::CollectionInfo* HTMLFormCollection::formCollectionInfo(HTMLFormElement* form) 39 { 40 if (!form->collectionInfo) 41 form->collectionInfo = new CollectionInfo; 42 return form->collectionInfo; 43 } 44 45 HTMLFormCollection::HTMLFormCollection(PassRefPtr<HTMLFormElement> form) 46 : HTMLCollection(form.get(), FormElements, formCollectionInfo(form.get())) 47 { 47 48 } 48 49 … … 53 54 unsigned HTMLFormCollection::calcLength() const 54 55 { 55 return static_cast<HTMLFormElement*>( m_base.get())->length();56 } 57 58 Node *HTMLFormCollection::item(unsigned index) const56 return static_cast<HTMLFormElement*>(base())->length(); 57 } 58 59 Node* HTMLFormCollection::item(unsigned index) const 59 60 { 60 61 resetCollectionInfo(); 61 62 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) 66 67 return 0; 67 68 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; 76 77 77 for (unsigned i = info ->elementsArrayPosition; i < l.size(); i++) {78 for (unsigned i = info()->elementsArrayPosition; i < l.size(); i++) { 78 79 if (l[i]->isEnumeratable() ) { 79 80 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; 83 84 return l[i]; 84 85 } … … 91 92 } 92 93 93 Node* HTMLFormCollection::getNamedItem(Node*,const QualifiedName& attrName, const String& name, bool caseSensitive) const94 { 95 info ->position = 0;94 Element* HTMLFormCollection::getNamedItem(const QualifiedName& attrName, const String& name, bool caseSensitive) const 95 { 96 info()->position = 0; 96 97 return getNamedFormItem(attrName, name, 0, caseSensitive); 97 98 } 98 99 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 } 100 Element* 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 143 138 return 0; 144 139 } 145 140 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 ); 141 Node* HTMLFormCollection::nextItem() const 142 { 143 return item(info()->position + 1); 144 } 145 146 Element* HTMLFormCollection::nextNamedItemInternal(const String &name) const 147 { 148 Element* retval = getNamedFormItem(m_idsDone ? nameAttr : idAttr, name, ++info()->position, true); 159 149 if (retval) 160 150 return retval; 161 if ( idsDone) // we're done151 if (m_idsDone) // we're done 162 152 return 0; 163 153 // 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) const154 m_idsDone = true; 155 return getNamedItem(nameAttr, name, true); 156 } 157 158 Node* HTMLFormCollection::namedItem(const String& name, bool caseSensitive) const 169 159 { 170 160 // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp … … 174 164 // that are allowed a name attribute. 175 165 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 175 Node* 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); 205 185 return impl; 206 186 } … … 208 188 void HTMLFormCollection::updateNameCache() const 209 189 { 210 if (info ->hasNameCache)190 if (info()->hasNameCache) 211 191 return; 212 192 213 193 HashSet<AtomicStringImpl*> foundInputElements; 214 194 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 223 197 for (unsigned i = 0; i < f->formElements.size(); ++i) { 224 198 HTMLGenericFormElement* e = f->formElements[i]; … … 228 202 if (!idAttrVal.isEmpty()) { 229 203 // add to id cache 230 Vector< Node*>* idVector = info->idCache.get(idAttrVal.impl());204 Vector<Element*>* idVector = info()->idCache.get(idAttrVal.impl()); 231 205 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); 234 208 } 235 209 idVector->append(e); … … 238 212 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) { 239 213 // add to name cache 240 Vector< Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());214 Vector<Element*>* nameVector = info()->nameCache.get(nameAttrVal.impl()); 241 215 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); 244 218 } 245 219 nameVector->append(e); … … 255 229 if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl())) { 256 230 // add to id cache 257 Vector< Node*>* idVector = info->idCache.get(idAttrVal.impl());231 Vector<Element*>* idVector = info()->idCache.get(idAttrVal.impl()); 258 232 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); 261 235 } 262 236 idVector->append(e); … … 264 238 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl())) { 265 239 // add to name cache 266 Vector< Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());240 Vector<Element*>* nameVector = info()->nameCache.get(nameAttrVal.impl()); 267 241 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); 270 244 } 271 245 nameVector->append(e); … … 273 247 } 274 248 275 info ->hasNameCache = true;276 } 277 278 } 249 info()->hasNameCache = true; 250 } 251 252 } -
trunk/WebCore/html/HTMLFormCollection.h
r25754 r28327 1 1 /* 2 * This file is part of the DOM implementation for KDE.3 *4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (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. 7 5 * 8 6 * This library is free software; you can redistribute it and/or … … 22 20 * 23 21 */ 22 24 23 #ifndef HTMLFormCollection_h 25 24 #define HTMLFormCollection_h … … 29 28 namespace WebCore { 30 29 30 class HTMLFormElement; 31 31 class QualifiedName; 32 32 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 36 class HTMLFormCollection : public HTMLCollection { 38 37 public: 39 // base must inherit HTMLGenericFormElement or this won't work 40 HTMLFormCollection(Node* _base); 38 HTMLFormCollection(PassRefPtr<HTMLFormElement>); 41 39 ~HTMLFormCollection(); 42 40 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; 46 43 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; 49 46 50 pr otected:47 private: 51 48 virtual void updateNameCache() const; 52 49 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 57 58 mutable int currentPos; 58 59 }; -
trunk/WebCore/html/HTMLNameCollection.cpp
r25754 r28327 1 /** 2 * This file is part of the DOM implementation for KDE. 3 * 1 /* 4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (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. 7 5 * 8 6 * This library is free software; you can redistribute it and/or … … 35 33 using namespace HTMLNames; 36 34 37 HTMLNameCollection::HTMLNameCollection( Document* base, HTMLCollection::Type type, const String& name)38 : HTMLCollection( base, type)35 HTMLNameCollection::HTMLNameCollection(PassRefPtr<Document> document, Type type, const String& name) 36 : HTMLCollection(document.get(), type, document->nameCollectionInfo(type, name)) 39 37 , m_name(name) 40 38 { 41 ASSERT(!info);42 info = base->nameCollectionInfo(type, name);43 39 } 44 40 45 Node* HTMLNameCollection::traverseNextItem(Node* current) const41 Element* HTMLNameCollection::itemAfter(Element* previous) const 46 42 { 47 ASSERT( current);43 ASSERT(previous != base()); 48 44 49 current = current->traverseNextNode(m_base.get()); 45 Node* current; 46 if (!previous) 47 current = base()->firstChild(); 48 else 49 current = previous->traverseNextNode(base()); 50 50 51 while (current) {52 if ( current->isElementNode()) {53 bool found = false;54 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()) { 56 56 case WindowNamedItems: 57 57 // find only images, forms, applets, embeds and objects by name, … … 62 62 e->hasTagName(embedTag) || 63 63 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; 66 68 break; 67 69 case DocumentNamedItems: … … 69 71 // applets and object by id, and images by id but only if they have 70 72 // 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 } 83 87 break; 84 default: 85 ASSERT(0); 86 } 88 default: 89 ASSERT_NOT_REACHED(); 90 } 91 } 87 92 88 if (found)89 return current;90 }91 current = current->traverseNextNode(m_base.get());92 }93 93 return 0; 94 94 } -
trunk/WebCore/html/HTMLNameCollection.h
r25754 r28327 1 1 /* 2 * This file is part of the DOM implementation for KDE.3 *4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (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. 7 5 * 8 6 * This library is free software; you can redistribute it and/or … … 33 31 class Document; 34 32 35 class HTMLNameCollection : public HTMLCollection 36 { 33 class HTMLNameCollection : public HTMLCollection { 37 34 public: 38 HTMLNameCollection( Document*, HTMLCollection::Type type, const String &name);35 HTMLNameCollection(PassRefPtr<Document>, Type, const String& name); 39 36 40 virtual Node* traverseNextItem(Node*) const; 37 private: 38 virtual Element* itemAfter(Element*) const; 41 39 42 private:43 40 String m_name; 44 41 }; -
trunk/WebCore/html/HTMLOptionsCollection.cpp
r25754 r28327 30 30 namespace WebCore { 31 31 32 HTMLOptionsCollection::HTMLOptionsCollection( HTMLSelectElement*select)33 : HTMLCollection(select , SelectOptions)32 HTMLOptionsCollection::HTMLOptionsCollection(PassRefPtr<HTMLSelectElement> select) 33 : HTMLCollection(select.get(), SelectOptions, select->collectionInfo()) 34 34 { 35 ASSERT(!info);36 info = select->collectionInfo();37 35 } 38 36 … … 57 55 58 56 ec = 0; 59 HTMLSelectElement* select = static_cast<HTMLSelectElement*>( m_base.get());57 HTMLSelectElement* select = static_cast<HTMLSelectElement*>(base()); 60 58 61 59 if (index == -1 || unsigned(index) >= length()) … … 69 67 int HTMLOptionsCollection::selectedIndex() const 70 68 { 71 return static_cast<HTMLSelectElement*>( m_base.get())->selectedIndex();69 return static_cast<HTMLSelectElement*>(base())->selectedIndex(); 72 70 } 73 71 74 72 void HTMLOptionsCollection::setSelectedIndex(int index) 75 73 { 76 static_cast<HTMLSelectElement*>( m_base.get())->setSelectedIndex(index);74 static_cast<HTMLSelectElement*>(base())->setSelectedIndex(index); 77 75 } 78 76 79 77 void HTMLOptionsCollection::setLength(unsigned length, ExceptionCode& ec) 80 78 { 81 static_cast<HTMLSelectElement*>( m_base.get())->setLength(length, ec);79 static_cast<HTMLSelectElement*>(base())->setLength(length, ec); 82 80 } 83 81 -
trunk/WebCore/html/HTMLOptionsCollection.h
r25754 r28327 1 1 /* 2 * This file is part of the DOM implementation for KDE.3 *4 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 4 * (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. 8 6 * 9 7 * This library is free software; you can redistribute it and/or … … 28 26 29 27 #include "HTMLCollection.h" 30 #include "HTMLOptionElement.h"31 28 32 29 namespace WebCore { 33 30 31 class HTMLOptionElement; 32 class HTMLSelectElement; 33 34 34 typedef int ExceptionCode; 35 36 class HTMLSelectElement;37 35 38 36 class HTMLOptionsCollection : public HTMLCollection { 39 37 public: 40 HTMLOptionsCollection( HTMLSelectElement*);38 HTMLOptionsCollection(PassRefPtr<HTMLSelectElement>); 41 39 42 40 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 /* 4 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 5 3 * (C) 1997 Torben Weis (weis@kde.org) … … 7 5 * (C) 1999 Lars Knoll (knoll@kde.org) 8 6 * (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. 10 8 * 11 9 * This library is free software; you can redistribute it and/or … … 24 22 * Boston, MA 02110-1301, USA. 25 23 */ 24 26 25 #include "config.h" 27 26 #include "HTMLTableRowElement.h" … … 131 130 } 132 131 133 HTMLElement *HTMLTableRowElement::insertCell(int index, ExceptionCode& ec) 134 { 135 HTMLTableCellElement *c = 0L; 132 PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec) 133 { 136 134 RefPtr<HTMLCollection> children = cells(); 137 135 int numCells = children ? children->length() : 0; 138 if ( index < -1 || index > numCells )139 ec = INDEX_SIZE_ERR; // per the DOM140 else141 {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 else150 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(); 155 153 } 156 154 -
trunk/WebCore/html/HTMLTableRowElement.h
r25754 r28327 1 1 /* 2 * This file is part of the DOM implementation for KDE.3 *4 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 5 3 * (C) 1997 Torben Weis (weis@kde.org) … … 7 5 * (C) 1999 Lars Knoll (knoll@kde.org) 8 6 * (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. 10 8 * 11 9 * This library is free software; you can redistribute it and/or … … 33 31 namespace WebCore { 34 32 35 class HTMLTableRowElement : public HTMLTablePartElement 36 { 33 class HTMLTableRowElement : public HTMLTablePartElement { 37 34 public: 38 HTMLTableRowElement(Document* doc);35 HTMLTableRowElement(Document*); 39 36 40 37 virtual HTMLTagStatus endTagRequirement() const { return TagStatusOptional; } … … 44 41 45 42 int rowIndex() const; 46 int sectionRowIndex() const;47 48 HTMLElement* insertCell(int index, ExceptionCode&);49 void deleteCell(int index, ExceptionCode&);50 51 43 void setRowIndex(int); 52 44 45 int sectionRowIndex() const; 53 46 void setSectionRowIndex(int); 47 48 PassRefPtr<HTMLElement> insertCell(int index, ExceptionCode&); 49 void deleteCell(int index, ExceptionCode&); 54 50 55 51 PassRefPtr<HTMLCollection> cells(); … … 70 66 String vAlign() const; 71 67 void setVAlign(const String&); 72 73 protected:74 int ncols;75 68 }; 76 69 77 } // namespace70 } // namespace 78 71 79 72 #endif -
trunk/WebCore/html/HTMLTableSectionElement.cpp
r25754 r28327 169 169 PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows() 170 170 { 171 return new HTMLCollection(this, HTMLCollection::T ableRows);171 return new HTMLCollection(this, HTMLCollection::TSectionRows); 172 172 } 173 173
Note:
See TracChangeset
for help on using the changeset viewer.