OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All r
ights reserved. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All r
ights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
11 * This library is distributed in the hope that it will be useful, | 11 * This library is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 * Library General Public License for more details. | 14 * Library General Public License for more details. |
15 * | 15 * |
16 * You should have received a copy of the GNU Library General Public License | 16 * You should have received a copy of the GNU Library General Public License |
17 * along with this library; see the file COPYING.LIB. If not, write to | 17 * along with this library; see the file COPYING.LIB. If not, write to |
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 * Boston, MA 02110-1301, USA. | 19 * Boston, MA 02110-1301, USA. |
20 * | 20 * |
21 */ | 21 */ |
22 | 22 |
23 #include "config.h" | 23 #include "config.h" |
24 #include "core/html/HTMLCollection.h" | 24 #include "core/html/HTMLCollection.h" |
25 | 25 |
26 #include "HTMLNames.h" | 26 #include "HTMLNames.h" |
27 #include "core/dom/ClassNodeList.h" | 27 #include "core/dom/ClassCollection.h" |
28 #include "core/dom/ElementTraversal.h" | 28 #include "core/dom/ElementTraversal.h" |
29 #include "core/dom/NodeList.h" | 29 #include "core/dom/NodeList.h" |
30 #include "core/dom/NodeRareData.h" | 30 #include "core/dom/NodeRareData.h" |
31 #include "core/dom/NodeTraversal.h" | 31 #include "core/dom/NodeTraversal.h" |
32 #include "core/html/HTMLElement.h" | 32 #include "core/html/HTMLElement.h" |
33 #include "core/html/HTMLObjectElement.h" | 33 #include "core/html/HTMLObjectElement.h" |
34 #include "core/html/HTMLOptionElement.h" | 34 #include "core/html/HTMLOptionElement.h" |
35 | 35 |
36 namespace WebCore { | 36 namespace WebCore { |
37 | 37 |
38 using namespace HTMLNames; | 38 using namespace HTMLNames; |
39 | 39 |
40 static bool shouldOnlyIncludeDirectChildren(CollectionType type) | 40 static bool shouldOnlyIncludeDirectChildren(CollectionType type) |
41 { | 41 { |
42 switch (type) { | 42 switch (type) { |
| 43 case ClassCollectionType: |
| 44 case TagCollectionType: |
| 45 case HTMLTagCollectionType: |
43 case DocAll: | 46 case DocAll: |
44 case DocAnchors: | 47 case DocAnchors: |
45 case DocApplets: | 48 case DocApplets: |
46 case DocEmbeds: | 49 case DocEmbeds: |
47 case DocForms: | 50 case DocForms: |
48 case DocImages: | 51 case DocImages: |
49 case DocLinks: | 52 case DocLinks: |
50 case DocScripts: | 53 case DocScripts: |
51 case DocumentNamedItems: | 54 case DocumentNamedItems: |
52 case MapAreas: | 55 case MapAreas: |
53 case TableRows: | 56 case TableRows: |
54 case SelectOptions: | 57 case SelectOptions: |
55 case SelectedOptions: | 58 case SelectedOptions: |
56 case DataListOptions: | 59 case DataListOptions: |
57 case WindowNamedItems: | 60 case WindowNamedItems: |
58 case FormControls: | 61 case FormControls: |
59 return false; | 62 return false; |
60 case NodeChildren: | 63 case NodeChildren: |
61 case TRCells: | 64 case TRCells: |
62 case TSectionRows: | 65 case TSectionRows: |
63 case TableTBodies: | 66 case TableTBodies: |
64 return true; | 67 return true; |
65 case ChildNodeListType: | 68 case ChildNodeListType: |
66 case ClassNodeListType: | |
67 case NameNodeListType: | 69 case NameNodeListType: |
68 case TagNodeListType: | |
69 case HTMLTagNodeListType: | |
70 case RadioNodeListType: | 70 case RadioNodeListType: |
71 case RadioImgNodeListType: | 71 case RadioImgNodeListType: |
72 case LabelsNodeListType: | 72 case LabelsNodeListType: |
73 break; | 73 break; |
74 } | 74 } |
75 ASSERT_NOT_REACHED(); | 75 ASSERT_NOT_REACHED(); |
76 return false; | 76 return false; |
77 } | 77 } |
78 | 78 |
79 static NodeListRootType rootTypeFromCollectionType(CollectionType type) | 79 static NodeListRootType rootTypeFromCollectionType(CollectionType type) |
80 { | 80 { |
81 switch (type) { | 81 switch (type) { |
82 case DocImages: | 82 case DocImages: |
83 case DocApplets: | 83 case DocApplets: |
84 case DocEmbeds: | 84 case DocEmbeds: |
85 case DocForms: | 85 case DocForms: |
86 case DocLinks: | 86 case DocLinks: |
87 case DocAnchors: | 87 case DocAnchors: |
88 case DocScripts: | 88 case DocScripts: |
89 case DocAll: | 89 case DocAll: |
90 case WindowNamedItems: | 90 case WindowNamedItems: |
91 case DocumentNamedItems: | 91 case DocumentNamedItems: |
92 case FormControls: | 92 case FormControls: |
93 return NodeListIsRootedAtDocument; | 93 return NodeListIsRootedAtDocument; |
| 94 case ClassCollectionType: |
| 95 case TagCollectionType: |
| 96 case HTMLTagCollectionType: |
94 case NodeChildren: | 97 case NodeChildren: |
95 case TableTBodies: | 98 case TableTBodies: |
96 case TSectionRows: | 99 case TSectionRows: |
97 case TableRows: | 100 case TableRows: |
98 case TRCells: | 101 case TRCells: |
99 case SelectOptions: | 102 case SelectOptions: |
100 case SelectedOptions: | 103 case SelectedOptions: |
101 case DataListOptions: | 104 case DataListOptions: |
102 case MapAreas: | 105 case MapAreas: |
103 return NodeListIsRootedAtNode; | 106 return NodeListIsRootedAtNode; |
104 case ChildNodeListType: | 107 case ChildNodeListType: |
105 case ClassNodeListType: | |
106 case NameNodeListType: | 108 case NameNodeListType: |
107 case TagNodeListType: | |
108 case HTMLTagNodeListType: | |
109 case RadioNodeListType: | 109 case RadioNodeListType: |
110 case RadioImgNodeListType: | 110 case RadioImgNodeListType: |
111 case LabelsNodeListType: | 111 case LabelsNodeListType: |
112 break; | 112 break; |
113 } | 113 } |
114 ASSERT_NOT_REACHED(); | 114 ASSERT_NOT_REACHED(); |
115 return NodeListIsRootedAtNode; | 115 return NodeListIsRootedAtNode; |
116 } | 116 } |
117 | 117 |
118 static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
lectionType type) | 118 static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
lectionType type) |
119 { | 119 { |
120 switch (type) { | 120 switch (type) { |
| 121 case TagCollectionType: |
| 122 case HTMLTagCollectionType: |
121 case DocImages: | 123 case DocImages: |
122 case DocEmbeds: | 124 case DocEmbeds: |
123 case DocForms: | 125 case DocForms: |
124 case DocScripts: | 126 case DocScripts: |
125 case DocAll: | 127 case DocAll: |
126 case NodeChildren: | 128 case NodeChildren: |
127 case TableTBodies: | 129 case TableTBodies: |
128 case TSectionRows: | 130 case TSectionRows: |
129 case TableRows: | 131 case TableRows: |
130 case TRCells: | 132 case TRCells: |
131 case SelectOptions: | 133 case SelectOptions: |
132 case MapAreas: | 134 case MapAreas: |
133 return DoNotInvalidateOnAttributeChanges; | 135 return DoNotInvalidateOnAttributeChanges; |
134 case DocApplets: | 136 case DocApplets: |
135 case SelectedOptions: | 137 case SelectedOptions: |
136 case DataListOptions: | 138 case DataListOptions: |
137 // FIXME: We can do better some day. | 139 // FIXME: We can do better some day. |
138 return InvalidateOnAnyAttrChange; | 140 return InvalidateOnAnyAttrChange; |
139 case DocAnchors: | 141 case DocAnchors: |
140 return InvalidateOnNameAttrChange; | 142 return InvalidateOnNameAttrChange; |
141 case DocLinks: | 143 case DocLinks: |
142 return InvalidateOnHRefAttrChange; | 144 return InvalidateOnHRefAttrChange; |
143 case WindowNamedItems: | 145 case WindowNamedItems: |
144 return InvalidateOnIdNameAttrChange; | 146 return InvalidateOnIdNameAttrChange; |
145 case DocumentNamedItems: | 147 case DocumentNamedItems: |
146 return InvalidateOnIdNameAttrChange; | 148 return InvalidateOnIdNameAttrChange; |
147 case FormControls: | 149 case FormControls: |
148 return InvalidateForFormControls; | 150 return InvalidateForFormControls; |
| 151 case ClassCollectionType: |
| 152 return InvalidateOnClassAttrChange; |
149 case ChildNodeListType: | 153 case ChildNodeListType: |
150 case ClassNodeListType: | |
151 case NameNodeListType: | 154 case NameNodeListType: |
152 case TagNodeListType: | |
153 case HTMLTagNodeListType: | |
154 case RadioNodeListType: | 155 case RadioNodeListType: |
155 case RadioImgNodeListType: | 156 case RadioImgNodeListType: |
156 case LabelsNodeListType: | 157 case LabelsNodeListType: |
157 break; | 158 break; |
158 } | 159 } |
159 ASSERT_NOT_REACHED(); | 160 ASSERT_NOT_REACHED(); |
160 return DoNotInvalidateOnAttributeChanges; | 161 return DoNotInvalidateOnAttributeChanges; |
161 } | 162 } |
162 | 163 |
163 HTMLCollection::HTMLCollection(ContainerNode* ownerNode, CollectionType type, It
emAfterOverrideType itemAfterOverrideType) | 164 HTMLCollection::HTMLCollection(ContainerNode* ownerNode, CollectionType type, It
emAfterOverrideType itemAfterOverrideType) |
164 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation
TypeExcludingIdAndNameAttributes(type), | 165 : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidation
TypeExcludingIdAndNameAttributes(type), |
165 WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideT
ype) | 166 WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideT
ype) |
166 , m_isNameCacheValid(false) | 167 , m_isNameCacheValid(false) |
167 { | 168 { |
168 ScriptWrappable::init(this); | 169 ScriptWrappable::init(this); |
169 } | 170 } |
170 | 171 |
171 PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, Collectio
nType type) | 172 PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, Collectio
nType type) |
172 { | 173 { |
173 return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); | 174 return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter)); |
174 } | 175 } |
175 | 176 |
176 HTMLCollection::~HTMLCollection() | 177 HTMLCollection::~HTMLCollection() |
177 { | 178 { |
178 // HTMLNameCollection removes cache by itself. | 179 // HTMLNameCollection, ClassCollection and TagCollection remove cache by the
mselves. |
179 if (type() != WindowNamedItems && type() != DocumentNamedItems) | 180 if (type() != WindowNamedItems && type() != DocumentNamedItems && type() !=
ClassCollectionType |
| 181 && type() != HTMLTagCollectionType && type() != TagCollectionType) { |
180 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); | 182 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type()); |
| 183 } |
181 } | 184 } |
182 | 185 |
183 void HTMLCollection::invalidateCache() const | 186 void HTMLCollection::invalidateCache() const |
184 { | 187 { |
185 LiveNodeListBase::invalidateCache(); | 188 LiveNodeListBase::invalidateCache(); |
186 invalidateIdNameCacheMaps(); | 189 invalidateIdNameCacheMaps(); |
187 } | 190 } |
188 | 191 |
189 template <class NodeListType> | 192 template <class NodeListType> |
190 inline bool isMatchingElement(const NodeListType&, const Element&); | 193 inline bool isMatchingElement(const NodeListType&, const Element&); |
191 | 194 |
192 template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection,
const Element& element) | 195 template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection,
const Element& element) |
193 { | 196 { |
194 CollectionType type = htmlCollection.type(); | 197 CollectionType type = htmlCollection.type(); |
195 if (!element.isHTMLElement() && !(type == DocAll || type == NodeChildren ||
type == WindowNamedItems)) | 198 |
| 199 // These collections apply to any kind of Elements, not just HTMLElements. |
| 200 switch (type) { |
| 201 case DocAll: |
| 202 case NodeChildren: |
| 203 return true; |
| 204 case ClassCollectionType: |
| 205 return static_cast<const ClassCollection&>(htmlCollection).elementMatche
s(element); |
| 206 case TagCollectionType: |
| 207 return static_cast<const TagCollection&>(htmlCollection).elementMatches(
element); |
| 208 case HTMLTagCollectionType: |
| 209 return static_cast<const HTMLTagCollection&>(htmlCollection).elementMatc
hes(element); |
| 210 default: |
| 211 break; |
| 212 } |
| 213 |
| 214 // The following only applies to HTMLElements. |
| 215 if (!element.isHTMLElement()) |
196 return false; | 216 return false; |
197 | 217 |
198 switch (type) { | 218 switch (type) { |
199 case DocImages: | 219 case DocImages: |
200 return element.hasLocalName(imgTag); | 220 return element.hasLocalName(imgTag); |
201 case DocScripts: | 221 case DocScripts: |
202 return element.hasLocalName(scriptTag); | 222 return element.hasLocalName(scriptTag); |
203 case DocForms: | 223 case DocForms: |
204 return element.hasLocalName(formTag); | 224 return element.hasLocalName(formTag); |
205 case TableTBodies: | 225 case TableTBodies: |
(...skipping 16 matching lines...) Expand all Loading... |
222 case MapAreas: | 242 case MapAreas: |
223 return element.hasLocalName(areaTag); | 243 return element.hasLocalName(areaTag); |
224 case DocApplets: | 244 case DocApplets: |
225 return element.hasLocalName(appletTag) || (element.hasLocalName(objectTa
g) && toHTMLObjectElement(element).containsJavaApplet()); | 245 return element.hasLocalName(appletTag) || (element.hasLocalName(objectTa
g) && toHTMLObjectElement(element).containsJavaApplet()); |
226 case DocEmbeds: | 246 case DocEmbeds: |
227 return element.hasLocalName(embedTag); | 247 return element.hasLocalName(embedTag); |
228 case DocLinks: | 248 case DocLinks: |
229 return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) &&
element.fastHasAttribute(hrefAttr); | 249 return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) &&
element.fastHasAttribute(hrefAttr); |
230 case DocAnchors: | 250 case DocAnchors: |
231 return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr); | 251 return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr); |
| 252 case ClassCollectionType: |
| 253 case TagCollectionType: |
| 254 case HTMLTagCollectionType: |
232 case DocAll: | 255 case DocAll: |
233 case NodeChildren: | 256 case NodeChildren: |
234 return true; | |
235 case FormControls: | 257 case FormControls: |
236 case DocumentNamedItems: | 258 case DocumentNamedItems: |
237 case TableRows: | 259 case TableRows: |
238 case WindowNamedItems: | 260 case WindowNamedItems: |
239 case ChildNodeListType: | 261 case ChildNodeListType: |
240 case ClassNodeListType: | |
241 case NameNodeListType: | 262 case NameNodeListType: |
242 case TagNodeListType: | |
243 case HTMLTagNodeListType: | |
244 case RadioNodeListType: | 263 case RadioNodeListType: |
245 case RadioImgNodeListType: | 264 case RadioImgNodeListType: |
246 case LabelsNodeListType: | 265 case LabelsNodeListType: |
247 ASSERT_NOT_REACHED(); | 266 ASSERT_NOT_REACHED(); |
248 } | 267 } |
249 return false; | 268 return false; |
250 } | 269 } |
251 | 270 |
252 template <> inline bool isMatchingElement(const LiveNodeList& nodeList, const El
ement& element) | 271 template <> inline bool isMatchingElement(const LiveNodeList& nodeList, const El
ement& element) |
253 { | 272 { |
254 return nodeList.nodeMatches(element); | 273 return nodeList.nodeMatches(element); |
255 } | 274 } |
256 | 275 |
257 template <> inline bool isMatchingElement(const HTMLTagNodeList& nodeList, const
Element& element) | |
258 { | |
259 return nodeList.nodeMatchesInlined(element); | |
260 } | |
261 | |
262 template <> inline bool isMatchingElement(const ClassNodeList& nodeList, const E
lement& element) | |
263 { | |
264 return nodeList.nodeMatchesInlined(element); | |
265 } | |
266 | |
267 static Node* previousNode(const Node& base, const Node& previous, bool onlyInclu
deDirectChildren) | 276 static Node* previousNode(const Node& base, const Node& previous, bool onlyInclu
deDirectChildren) |
268 { | 277 { |
269 return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversa
l::previous(previous, &base); | 278 return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversa
l::previous(previous, &base); |
270 } | 279 } |
271 | 280 |
272 static inline Node* lastDescendant(const Node& node) | 281 static inline Node* lastDescendant(const Node& node) |
273 { | 282 { |
274 Node* descendant = node.lastChild(); | 283 Node* descendant = node.lastChild(); |
275 for (Node* current = descendant; current; current = current->lastChild()) | 284 for (Node* current = descendant; current; current = current->lastChild()) |
276 descendant = current; | 285 descendant = current; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 } | 364 } |
356 | 365 |
357 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until fir
stMatchingElement() | 366 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until fir
stMatchingElement() |
358 // and others are moved to a separate header. | 367 // and others are moved to a separate header. |
359 inline Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) con
st | 368 inline Node* LiveNodeList::traverseToFirstElement(const ContainerNode& root) con
st |
360 { | 369 { |
361 ASSERT(isLiveNodeListType(type())); | 370 ASSERT(isLiveNodeListType(type())); |
362 switch (type()) { | 371 switch (type()) { |
363 case ChildNodeListType: | 372 case ChildNodeListType: |
364 return root.firstChild(); | 373 return root.firstChild(); |
365 case HTMLTagNodeListType: | |
366 return firstMatchingElement(static_cast<const HTMLTagNodeList&>(*this),
root); | |
367 case ClassNodeListType: | |
368 return firstMatchingElement(static_cast<const ClassNodeList&>(*this), ro
ot); | |
369 default: | 374 default: |
370 return firstMatchingElement(static_cast<const LiveNodeList&>(*this), roo
t); | 375 return firstMatchingElement(static_cast<const LiveNodeList&>(*this), roo
t); |
371 } | 376 } |
372 } | 377 } |
373 | 378 |
374 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra
verseMatchingElementsForwardToOffset() | 379 // FIXME: This should be in LiveNodeList.cpp but it needs to stay here until tra
verseMatchingElementsForwardToOffset() |
375 // and others are moved to a separate header. | 380 // and others are moved to a separate header. |
376 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
tNode, unsigned& currentOffset, const ContainerNode& root) const | 381 inline Node* LiveNodeList::traverseForwardToOffset(unsigned offset, Node& curren
tNode, unsigned& currentOffset, const ContainerNode& root) const |
377 { | 382 { |
378 switch (type()) { | 383 switch (type()) { |
379 case ChildNodeListType: | 384 case ChildNodeListType: |
380 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse
t); | 385 return traverseSiblingsForwardToOffset(offset, currentNode, currentOffse
t); |
381 case HTMLTagNodeListType: | |
382 return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTag
NodeList&>(*this), offset, toElement(currentNode), currentOffset, root); | |
383 case ClassNodeListType: | |
384 return traverseMatchingElementsForwardToOffset(static_cast<const ClassNo
deList&>(*this), offset, toElement(currentNode), currentOffset, root); | |
385 default: | 386 default: |
386 return traverseMatchingElementsForwardToOffset(*this, offset, toElement(
currentNode), currentOffset, root); | 387 return traverseMatchingElementsForwardToOffset(*this, offset, toElement(
currentNode), currentOffset, root); |
387 } | 388 } |
388 } | 389 } |
389 | 390 |
390 bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsign
ed offset) const | 391 bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsign
ed offset) const |
391 { | 392 { |
392 ASSERT(isLengthCacheValid()); | 393 ASSERT(isLengthCacheValid()); |
393 unsigned distanceFromLastItem = cachedLength() - offset; | 394 unsigned distanceFromLastItem = cachedLength() - offset; |
394 if (!cachedItem()) | 395 if (!cachedItem()) |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 | 649 |
649 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) | 650 void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element*
element) |
650 { | 651 { |
651 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; | 652 OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->v
alue; |
652 if (!vector) | 653 if (!vector) |
653 vector = adoptPtr(new Vector<Element*>); | 654 vector = adoptPtr(new Vector<Element*>); |
654 vector->append(element); | 655 vector->append(element); |
655 } | 656 } |
656 | 657 |
657 } // namespace WebCore | 658 } // namespace WebCore |
OLD | NEW |