Source/WebCore/CMakeLists.txt

@@SET(WebCore_SOURCES
522522
523523 dom/ActiveDOMObject.cpp
524524 dom/Attr.cpp
525  dom/Attribute.cpp
526525 dom/BeforeTextInsertedEvent.cpp
527526 dom/BeforeUnloadEvent.cpp
528527 dom/CDATASection.cpp

Source/WebCore/ChangeLog

 12012-04-13 Andreas Kling <kling@webkit.org>
 2
 3 Optimize Element attribute storage for the common case (no Attr objects.)
 4 <http://webkit.org/b/83440>
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Reduce Attribute to its smallest possible size; a qname/value pair.
 9 They are no-longer ref-counted, which allows us to store them in Vectors.
 10
 11 Refactored the Attr object to go with the new Attribute:
 12 Attr now wraps either {element, qname} or {qname, value}. The latter is for
 13 the case where a standalone Attr object is instantiated via DOM APIs.
 14
 15 ElementAttributeData.cpp manages a map of pair<element, qname> => Attr.
 16 Each Element (well, ElementAttributeData) keeps track of how many Attr
 17 objects are pointing to it. This is so we can avoid hash lookups during
 18 common operations in the typical case where you have zero Attrs.
 19
 20 * CMakeLists.txt:
 21 * GNUmakefile.list.am:
 22 * Target.pri:
 23 * WebCore.gypi:
 24 * WebCore.vcproj/WebCore.vcproj:
 25 * WebCore.xcodeproj/project.pbxproj:
 26 * dom/Attr.cpp:
 27 (WebCore::Attr::Attr):
 28 (WebCore):
 29 (WebCore::Attr::create):
 30 (WebCore::Attr::~Attr):
 31 (WebCore::Attr::createTextChild):
 32 (WebCore::Attr::setPrefix):
 33 (WebCore::Attr::setValue):
 34 (WebCore::Attr::cloneNode):
 35 (WebCore::Attr::childrenChanged):
 36 (WebCore::Attr::style):
 37 (WebCore::Attr::value):
 38 (WebCore::Attr::elementAttribute):
 39 (WebCore::Attr::detachFromElementWithValue):
 40 (WebCore::Attr::attachToElement):
 41 * dom/Attr.h:
 42 (WebCore):
 43 (Attr):
 44 (WebCore::Attr::qualifiedName):
 45 (WebCore::Attr::localName):
 46 (WebCore::Attr::namespaceURI):
 47 (WebCore::Attr::prefix):
 48 * dom/Attribute.cpp: Removed.
 49 * dom/Attribute.h:
 50 (WebCore::Attribute::Attribute):
 51 (Attribute):
 52 * dom/Document.cpp:
 53 (WebCore::Document::importNode):
 54 (WebCore::Document::createAttributeNS):
 55 * dom/Element.cpp:
 56 (WebCore::Element::~Element):
 57 (WebCore::Element::takeAttribute):
 58 (WebCore):
 59 (WebCore::Element::removeAttribute):
 60 (WebCore::Element::setAttributeInternal):
 61 (WebCore::Element::parserSetAttributes):
 62 (WebCore::Element::setAttributeNode):
 63 (WebCore::Element::removeAttributeNode):
 64 (WebCore::Element::normalizeAttributes):
 65 (WebCore::Element::didRemoveAttribute):
 66 (WebCore::Element::getAttr):
 67 (WebCore::Element::getOrCreateAttr):
 68 * dom/Element.h:
 69 (Element):
 70 (WebCore::Element::getAttributeItemIndex):
 71 * dom/ElementAttributeData.cpp:
 72 (WebCore):
 73 (WebCore::attrMap):
 74 (WebCore::ElementAttributeData::getAttr):
 75 (WebCore::ElementAttributeData::getOrCreateAttr):
 76 (WebCore::ElementAttributeData::setAttr):
 77 (WebCore::ElementAttributeData::removeAttr):
 78 (WebCore::AttributeVector::removeAttribute):
 79 (WebCore::ElementAttributeData::~ElementAttributeData):
 80 (WebCore::ElementAttributeData::addAttribute):
 81 (WebCore::ElementAttributeData::removeAttribute):
 82 (WebCore::ElementAttributeData::isEquivalent):
 83 (WebCore::ElementAttributeData::detachAttributesFromElement):
 84 (WebCore::ElementAttributeData::getAttributeItemIndexSlowCase):
 85 (WebCore::ElementAttributeData::setAttributes):
 86 (WebCore::ElementAttributeData::clearAttributes):
 87 (WebCore::ElementAttributeData::replaceAttribute):
 88 (WebCore::ElementAttributeData::getAttributeNode):
 89 * dom/ElementAttributeData.h:
 90 (WebCore):
 91 (WebCore::AttributeVector::AttributeVector):
 92 (WebCore::AttributeVector::attributeItem):
 93 (AttributeVector):
 94 (WebCore::AttributeVector::getAttributeItem):
 95 (WebCore::AttributeVector::getAttributeItemIndex):
 96 (WebCore::AttributeVector::insertAttribute):
 97 (ElementAttributeData):
 98 (WebCore::ElementAttributeData::hasAttrs):
 99 (WebCore::ElementAttributeData::didAddAttr):
 100 (WebCore::ElementAttributeData::didRemoveAttr):
 101 (WebCore::ElementAttributeData::ElementAttributeData):
 102 (WebCore::ElementAttributeData::attributeVector):
 103 (WebCore::ElementAttributeData::removeAttribute):
 104 (WebCore::ElementAttributeData::getAttributeItem):
 105 (WebCore::ElementAttributeData::getAttributeItemIndex):
 106 * dom/NamedNodeMap.cpp:
 107 (WebCore::NamedNodeMap::getNamedItem):
 108 (WebCore::NamedNodeMap::getNamedItemNS):
 109 (WebCore::NamedNodeMap::removeNamedItem):
 110 (WebCore::NamedNodeMap::removeNamedItemNS):
 111 (WebCore::NamedNodeMap::item):
 112 * dom/Node.cpp:
 113 (WebCore::Node::compareDocumentPosition):
 114 * html/parser/HTMLConstructionSite.cpp:
 115 (WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML):
 116 (WebCore::HTMLConstructionSite::mergeAttributesFromTokenIntoElement):
 117 (WebCore::HTMLConstructionSite::insertScriptElement):
 118 (WebCore::HTMLConstructionSite::createElement):
 119 (WebCore::HTMLConstructionSite::createHTMLElement):
 120 (WebCore::HTMLConstructionSite::createHTMLElementFromSavedElement):
 121 * html/parser/HTMLToken.h:
 122 (WebCore::AtomicHTMLToken::AtomicHTMLToken):
 123 * html/parser/HTMLTreeBuilder.cpp:
 124 (WebCore::HTMLTreeBuilder::processFakeStartTag):
 125 (WebCore::HTMLTreeBuilder::attributesForIsindexInput):
 126 (WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody):
 127 (WebCore):
 128 (WebCore::HTMLTreeBuilder::processStartTagForInBody):
 129 * html/parser/HTMLTreeBuilder.h:
 130 * html/parser/TextDocumentParser.cpp:
 131 (WebCore::TextDocumentParser::insertFakePreElement):
 132 * page/PageSerializer.cpp:
 133 (WebCore::SerializerMarkupAccumulator::appendCustomAttributes):
 134 * svg/SVGFitToViewBox.cpp:
 135 * svg/properties/SVGAnimatedPropertySynchronizer.h:
 136 * xml/XMLErrors.cpp:
 137 (WebCore::createXHTMLParserErrorHeader):
 138 (WebCore::XMLErrors::insertErrorMessageBlock):
 139 * xml/XPathNodeSet.cpp:
 140 (WebCore::XPath::NodeSet::traversalSort):
 141 * xml/XPathStep.cpp:
 142 (WebCore::XPath::Step::nodesInAxis):
 143 * xml/parser/MarkupTokenBase.h:
 144 (WebCore::AtomicMarkupTokenBase::AtomicMarkupTokenBase):
 145 (WebCore::AtomicMarkupTokenBase::getAttributeItem):
 146 (WebCore::AtomicMarkupTokenBase::attributes):
 147 (AtomicMarkupTokenBase):
 148 (WebCore::::initializeAttributes):
 149 * xml/parser/XMLToken.h:
 150 (WebCore::AtomicXMLToken::AtomicXMLToken):
 151 * xml/parser/XMLTreeBuilder.cpp:
 152 (WebCore::XMLTreeBuilder::processNamespaces):
 153 (WebCore::XMLTreeBuilder::processAttributes):
 154
 1552012-04-13 Andreas Kling <kling@webkit.org>
 156
 157 Optimize Element attribute storage for the common case (no Attr objects.)
 158 <http://webkit.org/b/83440>
 159
 160 Reviewed by NOBODY (OOPS!).
 161
 162 Reduce Attribute to its smallest possible size; a qname/value pair.
 163 They are no-longer ref-counted, which allows us to store them in Vectors.
 164
 165 Refactored the Attr object to go with the new Attribute:
 166 Attr now wraps either {element, qname} or {qname, value}. The latter is for
 167 the case where a standalone Attr object is instantiated via DOM APIs.
 168
 169 ElementAttributeData.cpp manages a map of pair<element, qname> => Attr.
 170 Each Element (well, ElementAttributeData) keeps track of how many Attr
 171 objects are pointing to it. This is so we can avoid hash lookups during
 172 common operations in the typical case where you have zero Attrs.
 173
 174 * CMakeLists.txt:
 175 * GNUmakefile.list.am:
 176 * Target.pri:
 177 * WebCore.gypi:
 178 * WebCore.vcproj/WebCore.vcproj:
 179 * WebCore.xcodeproj/project.pbxproj:
 180 * dom/Attr.cpp:
 181 (WebCore::Attr::Attr):
 182 (WebCore):
 183 (WebCore::Attr::create):
 184 (WebCore::Attr::~Attr):
 185 (WebCore::Attr::createTextChild):
 186 (WebCore::Attr::setPrefix):
 187 (WebCore::Attr::setValue):
 188 (WebCore::Attr::cloneNode):
 189 (WebCore::Attr::childrenChanged):
 190 (WebCore::Attr::style):
 191 (WebCore::Attr::value):
 192 (WebCore::Attr::elementAttribute):
 193 (WebCore::Attr::detachWithValue):
 194 (WebCore::Attr::attachToElement):
 195 * dom/Attr.h:
 196 (WebCore):
 197 (Attr):
 198 (WebCore::Attr::qualifiedName):
 199 (WebCore::Attr::localName):
 200 (WebCore::Attr::namespaceURI):
 201 (WebCore::Attr::prefix):
 202 * dom/Attribute.cpp: Removed.
 203 * dom/Attribute.h:
 204 (WebCore::Attribute::Attribute):
 205 (Attribute):
 206 * dom/Document.cpp:
 207 (WebCore::Document::importNode):
 208 (WebCore::Document::createAttributeNS):
 209 * dom/Element.cpp:
 210 (WebCore::Element::~Element):
 211 (WebCore::Element::takeAttribute):
 212 (WebCore):
 213 (WebCore::Element::removeAttribute):
 214 (WebCore::Element::setAttributeInternal):
 215 (WebCore::Element::parserSetAttributes):
 216 (WebCore::Element::setAttributeNode):
 217 (WebCore::Element::removeAttributeNode):
 218 (WebCore::Element::normalizeAttributes):
 219 (WebCore::Element::didRemoveAttribute):
 220 (WebCore::Element::getAttr):
 221 (WebCore::Element::getOrCreateAttr):
 222 * dom/Element.h:
 223 (Element):
 224 (WebCore::Element::getAttributeItemIndex):
 225 * dom/ElementAttributeData.cpp:
 226 (WebCore):
 227 (WebCore::attrMap):
 228 (WebCore::ElementAttributeData::getAttr):
 229 (WebCore::ElementAttributeData::getOrCreateAttr):
 230 (WebCore::ElementAttributeData::setAttr):
 231 (WebCore::ElementAttributeData::removeAttr):
 232 (WebCore::AttributeVector::removeAttribute):
 233 (WebCore::ElementAttributeData::~ElementAttributeData):
 234 (WebCore::ElementAttributeData::addAttribute):
 235 (WebCore::ElementAttributeData::removeAttribute):
 236 (WebCore::ElementAttributeData::isEquivalent):
 237 (WebCore::ElementAttributeData::detachAttributesFromElement):
 238 (WebCore::ElementAttributeData::getAttributeItemIndexSlowCase):
 239 (WebCore::ElementAttributeData::setAttributes):
 240 (WebCore::ElementAttributeData::clearAttributes):
 241 (WebCore::ElementAttributeData::replaceAttribute):
 242 (WebCore::ElementAttributeData::getAttributeNode):
 243 * dom/ElementAttributeData.h:
 244 (WebCore):
 245 (WebCore::AttributeVector::AttributeVector):
 246 (WebCore::AttributeVector::attributeItem):
 247 (AttributeVector):
 248 (WebCore::AttributeVector::getAttributeItem):
 249 (WebCore::AttributeVector::getAttributeItemIndex):
 250 (WebCore::AttributeVector::insertAttribute):
 251 (ElementAttributeData):
 252 (WebCore::ElementAttributeData::hasAttrs):
 253 (WebCore::ElementAttributeData::didAddAttr):
 254 (WebCore::ElementAttributeData::didRemoveAttr):
 255 (WebCore::ElementAttributeData::ElementAttributeData):
 256 (WebCore::ElementAttributeData::attributeVector):
 257 (WebCore::ElementAttributeData::removeAttribute):
 258 (WebCore::ElementAttributeData::getAttributeItem):
 259 (WebCore::ElementAttributeData::getAttributeItemIndex):
 260 * dom/NamedNodeMap.cpp:
 261 (WebCore::NamedNodeMap::getNamedItem):
 262 (WebCore::NamedNodeMap::getNamedItemNS):
 263 (WebCore::NamedNodeMap::removeNamedItem):
 264 (WebCore::NamedNodeMap::removeNamedItemNS):
 265 (WebCore::NamedNodeMap::item):
 266 * dom/Node.cpp:
 267 (WebCore::Node::compareDocumentPosition):
 268 * html/parser/HTMLConstructionSite.cpp:
 269 (WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML):
 270 (WebCore::HTMLConstructionSite::mergeAttributesFromTokenIntoElement):
 271 (WebCore::HTMLConstructionSite::insertScriptElement):
 272 (WebCore::HTMLConstructionSite::createElement):
 273 (WebCore::HTMLConstructionSite::createHTMLElement):
 274 (WebCore::HTMLConstructionSite::createHTMLElementFromSavedElement):
 275 * html/parser/HTMLToken.h:
 276 (WebCore::AtomicHTMLToken::AtomicHTMLToken):
 277 * html/parser/HTMLTreeBuilder.cpp:
 278 (WebCore::HTMLTreeBuilder::processFakeStartTag):
 279 (WebCore::HTMLTreeBuilder::attributesForIsindexInput):
 280 (WebCore::HTMLTreeBuilder::processIsindexStartTagForInBody):
 281 (WebCore):
 282 (WebCore::HTMLTreeBuilder::processStartTagForInBody):
 283 * html/parser/HTMLTreeBuilder.h:
 284 * html/parser/TextDocumentParser.cpp:
 285 (WebCore::TextDocumentParser::insertFakePreElement):
 286 * page/PageSerializer.cpp:
 287 (WebCore::SerializerMarkupAccumulator::appendCustomAttributes):
 288 * svg/SVGFitToViewBox.cpp:
 289 * svg/properties/SVGAnimatedPropertySynchronizer.h:
 290 * xml/XMLErrors.cpp:
 291 (WebCore::createXHTMLParserErrorHeader):
 292 (WebCore::XMLErrors::insertErrorMessageBlock):
 293 * xml/XPathNodeSet.cpp:
 294 (WebCore::XPath::NodeSet::traversalSort):
 295 * xml/XPathStep.cpp:
 296 (WebCore::XPath::Step::nodesInAxis):
 297 * xml/parser/MarkupTokenBase.h:
 298 (WebCore::AtomicMarkupTokenBase::AtomicMarkupTokenBase):
 299 (WebCore::AtomicMarkupTokenBase::getAttributeItem):
 300 (WebCore::AtomicMarkupTokenBase::attributes):
 301 (AtomicMarkupTokenBase):
 302 (WebCore::::initializeAttributes):
 303 * xml/parser/XMLToken.h:
 304 (WebCore::AtomicXMLToken::AtomicXMLToken):
 305 * xml/parser/XMLTreeBuilder.cpp:
 306 (WebCore::XMLTreeBuilder::processNamespaces):
 307 (WebCore::XMLTreeBuilder::processAttributes):
 308
13092012-04-12 Alec Flett <alecflett@chromium.org>
2310
3311 IndexedDB: Attributes for a cursor "run past the end" should be undefined.

Source/WebCore/GNUmakefile.list.am

@@webcore_sources += \
17241724 Source/WebCore/dom/ActiveDOMObject.h \
17251725 Source/WebCore/dom/Attr.cpp \
17261726 Source/WebCore/dom/Attr.h \
1727  Source/WebCore/dom/Attribute.cpp \
17281727 Source/WebCore/dom/Attribute.h \
17291728 Source/WebCore/dom/BeforeLoadEvent.h \
17301729 Source/WebCore/dom/BeforeTextInsertedEvent.cpp \

Source/WebCore/Target.pri

@@SOURCES += \
499499 css/WebKitCSSTransformValue.cpp \
500500 dom/ActiveDOMObject.cpp \
501501 dom/Attr.cpp \
502  dom/Attribute.cpp \
503502 dom/BeforeTextInsertedEvent.cpp \
504503 dom/BeforeUnloadEvent.cpp \
505504 dom/CDATASection.cpp \

Source/WebCore/WebCore.gypi

51125112 'webcore_dom_files': [
51135113 'dom/ActiveDOMObject.cpp',
51145114 'dom/Attr.cpp',
5115  'dom/Attribute.cpp',
51165115 'dom/BeforeLoadEvent.h',
51175116 'dom/BeforeTextInsertedEvent.cpp',
51185117 'dom/BeforeTextInsertedEvent.h',

Source/WebCore/WebCore.vcproj/WebCore.vcproj

4718247182 >
4718347183 </File>
4718447184 <File
47185  RelativePath="..\dom\Attribute.cpp"
47186  >
47187  <FileConfiguration
47188  Name="Debug|Win32"
47189  ExcludedFromBuild="true"
47190  >
47191  <Tool
47192  Name="VCCLCompilerTool"
47193  />
47194  </FileConfiguration>
47195  <FileConfiguration
47196  Name="Release|Win32"
47197  ExcludedFromBuild="true"
47198  >
47199  <Tool
47200  Name="VCCLCompilerTool"
47201  />
47202  </FileConfiguration>
47203  <FileConfiguration
47204  Name="Debug_Cairo_CFLite|Win32"
47205  ExcludedFromBuild="true"
47206  >
47207  <Tool
47208  Name="VCCLCompilerTool"
47209  />
47210  </FileConfiguration>
47211  <FileConfiguration
47212  Name="Release_Cairo_CFLite|Win32"
47213  ExcludedFromBuild="true"
47214  >
47215  <Tool
47216  Name="VCCLCompilerTool"
47217  />
47218  </FileConfiguration>
47219  <FileConfiguration
47220  Name="Debug_All|Win32"
47221  ExcludedFromBuild="true"
47222  >
47223  <Tool
47224  Name="VCCLCompilerTool"
47225  />
47226  </FileConfiguration>
47227  <FileConfiguration
47228  Name="Production|Win32"
47229  ExcludedFromBuild="true"
47230  >
47231  <Tool
47232  Name="VCCLCompilerTool"
47233  />
47234  </FileConfiguration>
47235  </File>
47236  <File
4723747185 RelativePath="..\dom\Attribute.h"
4723847186 >
4723947187 </File>

Source/WebCore/WebCore.xcodeproj/project.pbxproj

41554155 A8C4A80709D563270003AC8D /* Element.h in Headers */ = {isa = PBXBuildFile; fileRef = A8C4A7F509D563270003AC8D /* Element.h */; settings = {ATTRIBUTES = (Private, ); }; };
41564156 A8C4A80809D563270003AC8D /* Element.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C4A7F609D563270003AC8D /* Element.cpp */; };
41574157 A8C4A80B09D563270003AC8D /* Attribute.h in Headers */ = {isa = PBXBuildFile; fileRef = A8C4A7F909D563270003AC8D /* Attribute.h */; settings = {ATTRIBUTES = (Private, ); }; };
4158  A8C4A80C09D563270003AC8D /* Attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C4A7FA09D563270003AC8D /* Attribute.cpp */; };
41594158 A8C4A80D09D563270003AC8D /* Attr.h in Headers */ = {isa = PBXBuildFile; fileRef = A8C4A7FB09D563270003AC8D /* Attr.h */; settings = {ATTRIBUTES = (Private, ); }; };
41604159 A8C4A80E09D563270003AC8D /* Attr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C4A7FC09D563270003AC8D /* Attr.cpp */; };
41614160 A8CB413E0E8633FD0032C4F0 /* DashArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CB41020E85B8A50032C4F0 /* DashArray.h */; settings = {ATTRIBUTES = (Private, ); }; };

1106111060 A8C4A7F509D563270003AC8D /* Element.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Element.h; sourceTree = "<group>"; };
1106211061 A8C4A7F609D563270003AC8D /* Element.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Element.cpp; sourceTree = "<group>"; };
1106311062 A8C4A7F909D563270003AC8D /* Attribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Attribute.h; sourceTree = "<group>"; };
11064  A8C4A7FA09D563270003AC8D /* Attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Attribute.cpp; sourceTree = "<group>"; };
1106511063 A8C4A7FB09D563270003AC8D /* Attr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Attr.h; sourceTree = "<group>"; };
1106611064 A8C4A7FC09D563270003AC8D /* Attr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Attr.cpp; sourceTree = "<group>"; };
1106711065 A8CB41020E85B8A50032C4F0 /* DashArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DashArray.h; sourceTree = "<group>"; };

2091420912 A8C4A7FC09D563270003AC8D /* Attr.cpp */,
2091520913 A8C4A7FB09D563270003AC8D /* Attr.h */,
2091620914 93EEC1E509C2877700C515D1 /* Attr.idl */,
20917  A8C4A7FA09D563270003AC8D /* Attribute.cpp */,
2091820915 A8C4A7F909D563270003AC8D /* Attribute.h */,
2091920916 BC9462D7107A7B4C00857193 /* BeforeLoadEvent.h */,
2092020917 BC9462CB107A7A3900857193 /* BeforeLoadEvent.idl */,

2515925156 E1CDE92015018ED000862CC5 /* AsyncFileStream.cpp in Sources */,
2516025157 89D08D9F12228451001241DF /* AsyncFileSystem.cpp in Sources */,
2516125158 A8C4A80E09D563270003AC8D /* Attr.cpp in Sources */,
25162  A8C4A80C09D563270003AC8D /* Attribute.cpp in Sources */,
2516325159 FD315FF612B0267600C1A359 /* AudioBasicProcessorNode.cpp in Sources */,
2516425160 FD315FF812B0267600C1A359 /* AudioBuffer.cpp in Sources */,
2516525161 FD315FFB12B0267600C1A359 /* AudioBufferSourceNode.cpp in Sources */,

Source/WebCore/dom/Attr.cpp

33 * (C) 1999 Antti Koivisto (koivisto@kde.org)
44 * (C) 2001 Peter Kelly (pmk@post.com)
55 * (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights reserved.
77 *
88 * This library is free software; you can redistribute it and/or
99 * modify it under the terms of the GNU Library General Public

@@namespace WebCore {
3636
3737using namespace HTMLNames;
3838
39 inline Attr::Attr(Element* element, Document* document, PassRefPtr<Attribute> attribute)
40  : ContainerNode(document)
 39Attr::Attr(Element* element, const QualifiedName& name)
 40 : ContainerNode(element->document())
4141 , m_element(element)
42  , m_attribute(attribute)
 42 , m_name(name)
 43 , m_ignoreChildrenChanged(0)
 44 , m_specified(true)
 45{
 46}
 47
 48Attr::Attr(Document* document, const QualifiedName& name, const AtomicString& value)
 49 : ContainerNode(document)
 50 , m_element(0)
 51 , m_name(name)
 52 , m_value(value)
4353 , m_ignoreChildrenChanged(0)
4454 , m_specified(true)
4555{
46  ASSERT(!m_attribute->attr());
47  m_attribute->bindAttr(this);
4856}
4957
50 PassRefPtr<Attr> Attr::create(Element* element, Document* document, PassRefPtr<Attribute> attribute)
 58PassRefPtr<Attr> Attr::create(Element* element, const QualifiedName& name)
 59{
 60 RefPtr<Attr> attr = adoptRef(new Attr(element, name));
 61 attr->createTextChild();
 62 return attr.release();
 63}
 64
 65PassRefPtr<Attr> Attr::create(Document* document, const QualifiedName& name, const AtomicString& value)
5166{
52  RefPtr<Attr> attr = adoptRef(new Attr(element, document, attribute));
 67 RefPtr<Attr> attr = adoptRef(new Attr(document, name, value));
5368 attr->createTextChild();
5469 return attr.release();
5570}
5671
5772Attr::~Attr()
5873{
59  ASSERT(m_attribute->attr() == this);
60  m_attribute->unbindAttr(this);
6174}
6275
6376void Attr::createTextChild()
6477{
6578 ASSERT(refCount());
66  if (!m_attribute->value().isEmpty()) {
67  RefPtr<Text> textNode = document()->createTextNode(m_attribute->value().string());
 79 if (!value().isEmpty()) {
 80 RefPtr<Text> textNode = document()->createTextNode(value().string());
6881
6982 // This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
7083 // but much more efficiently.

@@void Attr::createTextChild()
7487 }
7588}
7689
77 String Attr::nodeName() const
78 {
79  return name();
80 }
81 
82 Node::NodeType Attr::nodeType() const
83 {
84  return ATTRIBUTE_NODE;
85 }
86 
87 const AtomicString& Attr::localName() const
88 {
89  return m_attribute->localName();
90 }
91 
92 const AtomicString& Attr::namespaceURI() const
93 {
94  return m_attribute->namespaceURI();
95 }
96 
97 const AtomicString& Attr::prefix() const
98 {
99  return m_attribute->prefix();
100 }
101 
10290void Attr::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
10391{
10492 ec = 0;

@@void Attr::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
112100 return;
113101 }
114102
115  m_attribute->setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
116 }
 103 const AtomicString& newPrefix = prefix.isEmpty() ? nullAtom : prefix;
117104
118 String Attr::nodeValue() const
119 {
120  return value();
 105 if (Attribute* attribute = elementAttribute())
 106 attribute->setPrefix(newPrefix);
 107 m_name.setPrefix(newPrefix);
121108}
122109
123110void Attr::setValue(const AtomicString& value)

@@void Attr::setValue(const AtomicString& value)
125112 EventQueueScope scope;
126113 m_ignoreChildrenChanged++;
127114 removeChildren();
128  m_attribute->setValue(value);
 115 if (m_element)
 116 elementAttribute()->setValue(value);
 117 else
 118 m_value = value;
129119 createTextChild();
130120 m_ignoreChildrenChanged--;
131121
132  invalidateNodeListsCacheAfterAttributeChanged(m_attribute->name());
 122 invalidateNodeListsCacheAfterAttributeChanged(m_name);
133123}
134124
135125void Attr::setValue(const AtomicString& value, ExceptionCode&)
136126{
137127 if (m_element)
138  m_element->willModifyAttribute(m_attribute->name(), m_attribute->value(), value);
 128 m_element->willModifyAttribute(qualifiedName(), this->value(), value);
139129
140130 setValue(value);
141131
142132 if (m_element)
143  m_element->didModifyAttribute(m_attribute.get());
 133 m_element->didModifyAttribute(elementAttribute());
144134}
145135
146136void Attr::setNodeValue(const String& v, ExceptionCode& ec)

@@void Attr::setNodeValue(const String& v, ExceptionCode& ec)
150140
151141PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
152142{
153  RefPtr<Attr> clone = adoptRef(new Attr(0, document(), m_attribute->clone()));
 143 RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
154144 cloneChildNodes(clone.get());
155145 return clone.release();
156146}

@@void Attr::childrenChanged(bool, Node*, Node*, int)
172162 if (m_ignoreChildrenChanged > 0)
173163 return;
174164
175  invalidateNodeListsCacheAfterAttributeChanged(m_attribute->name());
 165 invalidateNodeListsCacheAfterAttributeChanged(qualifiedName());
176166
177167 // FIXME: We should include entity references in the value
178168

@@void Attr::childrenChanged(bool, Node*, Node*, int)
184174
185175 AtomicString newValue = valueBuilder.toString();
186176 if (m_element)
187  m_element->willModifyAttribute(m_attribute->name(), m_attribute->value(), newValue);
 177 m_element->willModifyAttribute(qualifiedName(), value(), newValue);
 178
 179 if (m_element)
 180 elementAttribute()->setValue(newValue);
 181 else
 182 m_value = newValue;
188183
189  m_attribute->setValue(newValue);
190184 if (m_element)
191  m_element->attributeChanged(m_attribute.get());
 185 m_element->attributeChanged(elementAttribute());
192186}
193187
194188bool Attr::isId() const

@@CSSStyleDeclaration* Attr::style()
202196 if (!m_element->isStyledElement())
203197 return 0;
204198 m_style = StylePropertySet::create();
205  static_cast<StyledElement*>(m_element)->collectStyleForAttribute(m_attribute.get(), m_style.get());
 199 static_cast<StyledElement*>(m_element)->collectStyleForAttribute(elementAttribute(), m_style.get());
206200 return m_style->ensureCSSStyleDeclaration();
207201}
208202
 203const AtomicString& Attr::value() const
 204{
 205 if (m_element)
 206 return m_element->getAttributeItem(qualifiedName())->value();
 207 return m_value;
 208}
 209
 210Attribute* Attr::elementAttribute()
 211{
 212 if (!m_element || !m_element->attributeData())
 213 return 0;
 214 return m_element->getAttributeItem(qualifiedName());
 215}
 216
 217void Attr::detachFromElementWithValue(const AtomicString& value)
 218{
 219 ASSERT(m_element);
 220 ASSERT(m_value.isNull());
 221 m_element->attributeData()->removeAttr(m_element, qualifiedName());
 222 m_value = value;
 223 m_element = 0;
 224}
 225
 226void Attr::attachToElement(Element* element)
 227{
 228 ASSERT(!m_element);
 229 m_element = element;
 230 m_value = nullAtom;
 231}
 232
209233}

Source/WebCore/dom/Attr.h

 1
12/*
23 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
34 * (C) 1999 Antti Koivisto (koivisto@kde.org)

2627#define Attr_h
2728
2829#include "ContainerNode.h"
29 #include "Attribute.h"
 30#include "QualifiedName.h"
3031
3132namespace WebCore {
3233

@@class StylePropertySet;
3637// Attr can have Text and EntityReference children
3738// therefore it has to be a fullblown Node. The plan
3839// is to dynamically allocate a textchild and store the
39 // resulting nodevalue in the Attribute upon
 40// resulting nodevalue in the attribute upon
4041// destruction. however, this is not yet implemented.
4142
4243class Attr : public ContainerNode {
43  friend class AttributeVector;
44  friend class ElementAttributeData;
4544public:
46  static PassRefPtr<Attr> create(Element*, Document*, PassRefPtr<Attribute>);
 45 static PassRefPtr<Attr> create(Element*, const QualifiedName&);
 46 static PassRefPtr<Attr> create(Document*, const QualifiedName&, const AtomicString& value);
4747 virtual ~Attr();
4848
4949 String name() const { return qualifiedName().toString(); }
5050 bool specified() const { return m_specified; }
5151 Element* ownerElement() const { return m_element; }
5252
53  const AtomicString& value() const { return m_attribute->value(); }
 53 const AtomicString& value() const;
5454 void setValue(const AtomicString&, ExceptionCode&);
5555 void setValue(const AtomicString&);
5656
57  Attribute* attr() const { return m_attribute.get(); }
58  const QualifiedName& qualifiedName() const { return m_attribute->name(); }
 57 const QualifiedName& qualifiedName() const { return m_name; }
5958
6059 bool isId() const;
6160

@@public:
6362
6463 void setSpecified(bool specified) { m_specified = specified; }
6564
 65 void attachToElement(Element*);
 66 void detachFromElementWithValue(const AtomicString&);
 67
6668private:
67  Attr(Element*, Document*, PassRefPtr<Attribute>);
 69 Attr(Element*, const QualifiedName&);
 70 Attr(Document*, const QualifiedName&, const AtomicString& value);
6871
6972 void createTextChild();
7073
71  virtual String nodeName() const;
72  virtual NodeType nodeType() const;
 74 virtual String nodeName() const OVERRIDE { return name(); }
 75 virtual NodeType nodeType() const OVERRIDE { return ATTRIBUTE_NODE; }
7376
74  const AtomicString& localName() const;
75  const AtomicString& namespaceURI() const;
76  const AtomicString& prefix() const;
 77 const AtomicString& localName() const { return m_name.localName(); }
 78 const AtomicString& namespaceURI() const { return m_name.namespaceURI(); }
 79 const AtomicString& prefix() const { return m_name.prefix(); }
7780
7881 virtual void setPrefix(const AtomicString&, ExceptionCode&);
7982
80  virtual String nodeValue() const;
 83 virtual String nodeValue() const OVERRIDE { return value(); }
8184 virtual void setNodeValue(const String&, ExceptionCode&);
8285 virtual PassRefPtr<Node> cloneNode(bool deep);
8386

@@private:
9093 virtual const AtomicString& virtualLocalName() const { return localName(); }
9194 virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
9295
 96 Attribute* elementAttribute();
 97
 98 // Attr wraps either an element/name, or a name/value pair (when it's a standalone Node.)
 99 // Note that m_name is always set, but m_element/m_value may be null.
93100 Element* m_element;
94  RefPtr<Attribute> m_attribute;
 101 QualifiedName m_name;
 102 AtomicString m_value;
 103
95104 RefPtr<StylePropertySet> m_style;
96105 unsigned m_ignoreChildrenChanged : 31;
97106 bool m_specified : 1;

Source/WebCore/dom/Attribute.cpp

1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * (C) 1999 Antti Koivisto (koivisto@kde.org)
4  * (C) 2001 Peter Kelly (pmk@post.com)
5  * (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #include "config.h"
25 #include "Attribute.h"
26 
27 #include "Attr.h"
28 #include "Element.h"
29 #include <wtf/HashMap.h>
30 #include <wtf/UnusedParam.h>
31 
32 namespace WebCore {
33 
34 typedef HashMap<Attribute*, Attr*> AttributeAttrMap;
35 static AttributeAttrMap& attributeAttrMap()
36 {
37  DEFINE_STATIC_LOCAL(AttributeAttrMap, map, ());
38  return map;
39 }
40 
41 PassRefPtr<Attribute> Attribute::clone() const
42 {
43  return adoptRef(new Attribute(m_name, m_value));
44 }
45 
46 Attr* Attribute::attr() const
47 {
48  if (m_hasAttr) {
49  ASSERT(attributeAttrMap().contains(const_cast<Attribute*>(this)));
50  return attributeAttrMap().get(const_cast<Attribute*>(this));
51  }
52 
53  ASSERT(!attributeAttrMap().contains(const_cast<Attribute*>(this)));
54  return 0;
55 }
56 
57 PassRefPtr<Attr> Attribute::createAttrIfNeeded(Element* e)
58 {
59  RefPtr<Attr> r;
60  if (m_hasAttr) {
61  ASSERT(attributeAttrMap().contains(this));
62  r = attributeAttrMap().get(this);
63  } else {
64  ASSERT(!attributeAttrMap().contains(this));
65  r = Attr::create(e, e->document(), this); // This will end up calling Attribute::bindAttr.
66  ASSERT(attributeAttrMap().contains(this));
67  }
68 
69  return r.release();
70 }
71 
72 void Attribute::bindAttr(Attr* attr)
73 {
74  ASSERT(!m_hasAttr);
75  ASSERT(!attributeAttrMap().contains(this));
76  attributeAttrMap().set(this, attr);
77  m_hasAttr = true;
78 }
79 
80 void Attribute::unbindAttr(Attr* attr)
81 {
82  ASSERT(m_hasAttr);
83  ASSERT(attributeAttrMap().contains(this));
84  ASSERT_UNUSED(attr, attributeAttrMap().get(this) == attr);
85  attributeAttrMap().remove(this);
86  m_hasAttr = false;
87 }
88 
89 } // namespace WebCore

Source/WebCore/dom/Attribute.h

33 * (C) 1999 Antti Koivisto (koivisto@kde.org)
44 * (C) 2001 Peter Kelly (pmk@post.com)
55 * (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
 6 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved.
77 *
88 * This library is free software; you can redistribute it and/or
99 * modify it under the terms of the GNU Library General Public

2929
3030namespace WebCore {
3131
32 class Attr;
33 class Element;
34 
3532// This has no counterpart in DOM.
3633// It is an internal representation of the node value of an Attr.
3734// The actual Attr with its value as a Text child is allocated only if needed.
38 class Attribute : public RefCounted<Attribute> {
39  friend class Attr;
 35class Attribute {
4036public:
41  static PassRefPtr<Attribute> create(const QualifiedName& name, const AtomicString& value)
 37 Attribute()
 38 : m_name(nullAtom, nullAtom, nullAtom)
4239 {
43  return adoptRef(new Attribute(name, value));
4440 }
45  static PassRefPtr<Attribute> create(const AtomicString& name, const AtomicString& value)
 41
 42 Attribute(const QualifiedName& name, const AtomicString& value)
 43 : m_name(name)
 44 , m_value(value)
 45 {
 46 }
 47
 48 Attribute(const AtomicString& name, const AtomicString& value)
 49 : m_name(nullAtom, name, nullAtom)
 50 , m_value(value)
4651 {
47  return adoptRef(new Attribute(name, value));
4852 }
4953
5054 const AtomicString& value() const { return m_value; }
5155 const AtomicString& prefix() const { return m_name.prefix(); }
5256 const AtomicString& localName() const { return m_name.localName(); }
5357 const AtomicString& namespaceURI() const { return m_name.namespaceURI(); }
54 
 58
5559 const QualifiedName& name() const { return m_name; }
56 
57  Attr* attr() const;
58  PassRefPtr<Attr> createAttrIfNeeded(Element*);
5960
6061 bool isNull() const { return m_value.isNull(); }
6162 bool isEmpty() const { return m_value.isEmpty(); }
62 
63  PassRefPtr<Attribute> clone() const;
6463
6564 void setValue(const AtomicString& value) { m_value = value; }
6665 void setPrefix(const AtomicString& prefix) { m_name.setPrefix(prefix); }

@@public:
7170 void parserSetName(const QualifiedName& name) { m_name = name; }
7271
7372private:
74  Attribute(const QualifiedName& name, const AtomicString& value)
75  : m_hasAttr(false)
76  , m_name(name)
77  , m_value(value)
78  {
79  }
80 
81  Attribute(const AtomicString& name, const AtomicString& value)
82  : m_hasAttr(false)
83  , m_name(nullAtom, name, nullAtom)
84  , m_value(value)
85  {
86  }
87 
88  void bindAttr(Attr*);
89  void unbindAttr(Attr*);
90 
91  // This boolean will go into the spare 32-bits of padding from RefCounted in 64-bit.
92  bool m_hasAttr;
93 
9473 QualifiedName m_name;
9574 AtomicString m_value;
9675};

Source/WebCore/dom/Document.cpp

@@PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
910910 return newElement.release();
911911 }
912912 case ATTRIBUTE_NODE:
913  return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
 913 return Attr::create(this, QualifiedName(nullAtom, static_cast<Attr*>(importedNode)->name(), nullAtom), static_cast<Attr*>(importedNode)->value());
914914 case DOCUMENT_FRAGMENT_NODE: {
915915 if (importedNode->isShadowRoot()) {
916916 // ShadowRoot nodes should not be explicitly importable.

@@PassRefPtr<Attr> Document::createAttributeNS(const String& namespaceURI, const S
44504450 return 0;
44514451 }
44524452
4453  return Attr::create(0, this, Attribute::create(qName, StringImpl::empty()));
 4453 return Attr::create(this, qName, emptyString());
44544454}
44554455
44564456#if ENABLE(SVG)

Source/WebCore/dom/Element.cpp

@@Element::~Element()
127127 if (shadowTree())
128128 rareData()->m_shadowTree.clear();
129129 if (m_attributeData)
130  m_attributeData->clearAttributes();
 130 m_attributeData->clearAttributes(this);
131131}
132132
133133inline ElementRareData* Element::rareData() const

@@void Element::copyNonAttributeProperties(const Element*)
185185{
186186}
187187
 188PassRefPtr<Attr> Element::takeAttribute(size_t index)
 189{
 190 if (!attributeData())
 191 return 0;
 192
 193 Attribute* attribute = attributeData()->attributeItem(index);
 194
 195 RefPtr<Attr> attr = getAttr(attribute->name());
 196 if (attr)
 197 attr->detachFromElementWithValue(attribute->value());
 198 else
 199 attr = Attr::create(document(), attribute->name(), attribute->value());
 200
 201 attributeData()->removeAttribute(index, this);
 202 return attr.release();
 203}
 204
188205void Element::removeAttribute(const QualifiedName& name)
189206{
190207 if (!attributeData())
191208 return;
 209
 210 if (RefPtr<Attr> attr = getAttr(name))
 211 attr->detachFromElementWithValue(attr->value());
 212
192213 attributeData()->removeAttribute(name, this);
193214}
194215

@@inline void Element::setAttributeInternal(size_t index, const QualifiedName& nam
651672 }
652673
653674 if (!old) {
654  m_attributeData->addAttribute(Attribute::create(name, value), this, inUpdateStyleAttribute);
 675 m_attributeData->addAttribute(Attribute(name, value), this, inUpdateStyleAttribute);
655676 return;
656677 }
657678
658679 if (inUpdateStyleAttribute == NotInUpdateStyleAttribute)
659  willModifyAttribute(name, old ? old->value() : nullAtom, value);
 680 willModifyAttribute(name, old->value(), value);
660681
661  if (Attr* attrNode = old->attr())
 682 if (RefPtr<Attr> attrNode = getAttr(name))
662683 attrNode->setValue(value);
663684 else
664685 old->setValue(value);

@@static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& v
740761 return (name.localName().endsWith(hrefAttr.localName()) || name == srcAttr || name == actionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));
741762}
742763
743 void Element::parserSetAttributes(PassOwnPtr<AttributeVector> attributeVector, FragmentScriptingPermission scriptingPermission)
 764void Element::parserSetAttributes(const AttributeVector& attributeVector, FragmentScriptingPermission scriptingPermission)
744765{
745766 ASSERT(!inDocument());
746767 ASSERT(!parentNode());
747768
748769 ASSERT(!m_attributeData);
749770
750  if (!attributeVector)
 771 if (attributeVector.isEmpty())
751772 return;
752773
753774 createAttributeData();
754  m_attributeData->m_attributes.swap(*attributeVector);
 775 m_attributeData->m_attributes = attributeVector;
755776
756777 // If the element is created as result of a paste or drag-n-drop operation
757778 // we want to remove all the script and event handlers.
758779 if (scriptingPermission == FragmentScriptingNotAllowed) {
759780 unsigned i = 0;
760781 while (i < m_attributeData->length()) {
761  const QualifiedName& attributeName = m_attributeData->m_attributes[i]->name();
 782 const QualifiedName& attributeName = m_attributeData->m_attributes[i].name();
762783 if (isEventHandlerAttribute(attributeName)) {
763784 m_attributeData->m_attributes.remove(i);
764785 continue;
765786 }
766787
767  if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i]->value()))
768  m_attributeData->m_attributes[i]->setValue(nullAtom);
 788 if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i].value()))
 789 m_attributeData->m_attributes[i].setValue(nullAtom);
769790 i++;
770791 }
771792 }
772793
773794 // Store the set of attributes that changed on the stack in case
774795 // attributeChanged mutates m_attributeData.
775  Vector<RefPtr<Attribute> > attributes;
776  m_attributeData->copyAttributesToVector(attributes);
777  for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
778  attributeChanged(iter->get());
 796 AttributeVector attributes = m_attributeData->attributeVector();
 797 for (unsigned i = 0; i < attributes.size(); ++i)
 798 attributeChanged(&attributes[i]);
779799}
780800
781801bool Element::hasAttributes() const

@@PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
13911411 }
13921412
13931413 ElementAttributeData* attributeData = ensureUpdatedAttributeData();
1394  Attribute* attribute = attr->attr();
1395  size_t index = attributeData->getAttributeItemIndex(attribute->name());
1396  Attribute* oldAttribute = index != notFound ? attributeData->attributeItem(index) : 0;
1397  if (oldAttribute == attribute)
1398  return attr; // we know about it already
 1414
 1415 RefPtr<Attr> oldAttr = getAttr(attr->qualifiedName());
 1416 if (oldAttr.get() == attr)
 1417 return attr; // This Attr is already attached to the element.
13991418
14001419 // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
14011420 // The DOM user must explicitly clone Attr nodes to re-use them in other elements.

@@PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
14041423 return 0;
14051424 }
14061425
1407  RefPtr<Attr> oldAttr;
1408  if (oldAttribute) {
1409  oldAttr = oldAttribute->createAttrIfNeeded(this);
1410  attributeData->replaceAttribute(index, attribute, this);
1411  } else
1412  attributeData->addAttribute(attribute, this);
 1426 size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName());
 1427 Attribute* oldAttribute = index != notFound ? attributeData->attributeItem(index) : 0;
14131428
 1429 if (!oldAttribute) {
 1430 attributeData->addAttribute(Attribute(attr->qualifiedName(), attr->value()), this);
 1431 attributeData->setAttr(this, attr->qualifiedName(), attr);
 1432 return 0;
 1433 }
 1434
 1435 if (oldAttr)
 1436 oldAttr->detachFromElementWithValue(oldAttribute->value());
 1437 else
 1438 oldAttr = Attr::create(document(), oldAttribute->name(), oldAttribute->value());
 1439
 1440 attributeData->replaceAttribute(index, Attribute(attr->name(), attr->value()), this);
 1441 attributeData->setAttr(this, attr->qualifiedName(), attr);
14141442 return oldAttr.release();
14151443}
14161444

@@PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
14421470 return 0;
14431471 }
14441472
1445  return attributeData->takeAttribute(index, this);
 1473 RefPtr<Attr> oldAttr = getOrCreateAttr(attr->qualifiedName());
 1474 attributeData->removeAttribute(index, this);
 1475 return oldAttr.release();
14461476}
14471477
14481478void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)

@@void Element::removeAttribute(const String& name)
14731503 String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
14741504 size_t index = attributeData->getAttributeItemIndex(localName, false);
14751505 if (index == notFound)
1476  return;
 1506 return;
14771507
14781508 attributeData->removeAttribute(index, this);
14791509}

@@void Element::normalizeAttributes()
17101740 if (!attributeData || attributeData->isEmpty())
17111741 return;
17121742
1713  Vector<RefPtr<Attribute> > attributeVector;
1714  attributeData->copyAttributesToVector(attributeVector);
1715  size_t numAttrs = attributeVector.size();
1716  for (size_t i = 0; i < numAttrs; ++i) {
1717  if (Attr* attr = attributeVector[i]->attr())
 1743 AttributeVector attributes = attributeData->attributeVector();
 1744 for (size_t i = 0; i < attributes.size(); ++i) {
 1745 if (RefPtr<Attr> attr = getAttr(attributes[i].name()))
17181746 attr->normalize();
17191747 }
17201748}

@@void Element::didModifyAttribute(Attribute* attr)
20252053 // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
20262054}
20272055
2028 void Element::didRemoveAttribute(Attribute* attr)
 2056void Element::didRemoveAttribute(const QualifiedName& name)
20292057{
2030  if (attr->isNull())
2031  return;
2032 
2033  AtomicString savedValue = attr->value();
2034  attr->setValue(nullAtom);
2035  attributeChanged(attr);
2036  attr->setValue(savedValue);
 2058 Attribute dummyAttribute(name, nullAtom);
 2059 attributeChanged(&dummyAttribute);
20372060
2038  InspectorInstrumentation::didRemoveDOMAttr(document(), this, attr->name().localName());
 2061 InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
20392062 dispatchSubtreeModifiedEvent();
20402063}
20412064

@@void Element::setSavedLayerScrollOffset(const IntSize& size)
20812104 ensureRareData()->m_savedLayerScrollOffset = size;
20822105}
20832106
 2107PassRefPtr<Attr> Element::getAttr(const QualifiedName& name)
 2108{
 2109 if (!attributeData())
 2110 return 0;
 2111 return attributeData()->getAttr(this, name);
 2112}
 2113
 2114PassRefPtr<Attr> Element::getOrCreateAttr(const QualifiedName& name)
 2115{
 2116 ASSERT(attributeData());
 2117 return attributeData()->getOrCreateAttr(this, name);
 2118}
 2119
20842120} // namespace WebCore

Source/WebCore/dom/Element.h

@@public:
115115 const AtomicString& getAttribute(const QualifiedName&) const;
116116 void setAttribute(const QualifiedName&, const AtomicString& value, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
117117 void removeAttribute(const QualifiedName&);
 118 void removeAttribute(size_t index);
118119
119120 // Typed getters and setters for language bindings.
120121 int getIntegralAttribute(const QualifiedName& attributeName) const;

@@public:
163164 size_t attributeCount() const;
164165 Attribute* attributeItem(unsigned index) const;
165166 Attribute* getAttributeItem(const QualifiedName&) const;
 167 size_t getAttributeItemIndex(const QualifiedName& name) const { return attributeData()->getAttributeItemIndex(name); }
 168 size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const { return attributeData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
166169
167170 void scrollIntoView(bool alignToTop = true);
168171 void scrollIntoViewIfNeeded(bool centerIfNeeded = true);

@@public:
196199
197200 void removeAttribute(const String& name);
198201 void removeAttributeNS(const String& namespaceURI, const String& localName);
 202
 203 PassRefPtr<Attr> takeAttribute(size_t index);
199204
200205 PassRefPtr<Attr> getAttributeNode(const String& name);
201206 PassRefPtr<Attr> getAttributeNodeNS(const String& namespaceURI, const String& localName);
202207 PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
203208 PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
204209 PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
 210
 211 PassRefPtr<Attr> getAttr(const QualifiedName&);
 212 PassRefPtr<Attr> getOrCreateAttr(const QualifiedName&);
205213
206214 virtual CSSStyleDeclaration* style();
207215

@@public:
236244 virtual void attributeChanged(Attribute*);
237245
238246 // Only called by the parser immediately after element construction.
239  void parserSetAttributes(PassOwnPtr<AttributeVector>, FragmentScriptingPermission);
 247 void parserSetAttributes(const AttributeVector&, FragmentScriptingPermission);
240248
241249 ElementAttributeData* attributeData() const { return m_attributeData.get(); }
242250 ElementAttributeData* ensureAttributeData() const;

@@public:
297305 void willRemoveAttribute(const QualifiedName&, const AtomicString& value);
298306 void didAddAttribute(Attribute*);
299307 void didModifyAttribute(Attribute*);
300  void didRemoveAttribute(Attribute*);
 308 void didRemoveAttribute(const QualifiedName&);
301309
302310 LayoutSize minimumSizeForResizing() const;
303311 void setMinimumSizeForResizing(const LayoutSize&);

Source/WebCore/dom/ElementAttributeData.cpp

2727#include "ElementAttributeData.h"
2828
2929#include "CSSStyleSheet.h"
 30#include "Attr.h"
3031#include "StyledElement.h"
3132
3233namespace WebCore {
3334
 35typedef HashMap<pair<Element*, QualifiedName>, RefPtr<Attr> > AttrMap;
 36static AttrMap& attrMap()
 37{
 38 DEFINE_STATIC_LOCAL(AttrMap, map, ());
 39 return map;
 40}
 41
 42PassRefPtr<Attr> ElementAttributeData::getAttr(Element* element, const QualifiedName& name)
 43{
 44 if (!m_attrCount)
 45 return 0;
 46 return attrMap().get(std::make_pair(element, name)).get();
 47}
 48
 49PassRefPtr<Attr> ElementAttributeData::getOrCreateAttr(Element* element, const QualifiedName& name)
 50{
 51 AttrMap::AddResult result = attrMap().add(std::make_pair(element, name), 0);
 52 if (result.isNewEntry) {
 53 result.iterator->second = Attr::create(element, name);
 54 setAttr(element, name, result.iterator->second.get());
 55 }
 56 return result.iterator->second.get();
 57}
 58
 59void ElementAttributeData::setAttr(Element* element, const QualifiedName& name, Attr* attr)
 60{
 61 ASSERT(!attrMap().contains(std::make_pair(element, name)));
 62 attrMap().add(std::make_pair(element, name), attr);
 63 attr->attachToElement(element);
 64 didAddAttr();
 65}
 66
 67void ElementAttributeData::removeAttr(Element* element, const QualifiedName& name)
 68{
 69 ASSERT(attrMap().contains(std::make_pair(element, name)));
 70 attrMap().remove(std::make_pair(element, name));
 71 didRemoveAttr();
 72}
 73
3474void AttributeVector::removeAttribute(const QualifiedName& name)
3575{
3676 size_t index = getAttributeItemIndex(name);
3777 if (index == notFound)
3878 return;
3979
40  RefPtr<Attribute> attribute = at(index);
41  if (Attr* attr = attribute->attr())
42  attr->m_element = 0;
4380 remove(index);
4481}
4582
4683ElementAttributeData::~ElementAttributeData()
4784{
48  detachAttributesFromElement();
4985}
5086
5187void ElementAttributeData::setClass(const String& className, bool shouldFoldCase)

@@void ElementAttributeData::destroyInlineStyle(StyledElement* element)
94130 m_inlineStyleDecl = 0;
95131}
96132
97 void ElementAttributeData::addAttribute(PassRefPtr<Attribute> prpAttribute, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute)
 133void ElementAttributeData::addAttribute(const Attribute& attribute, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute)
98134{
99  RefPtr<Attribute> attribute = prpAttribute;
100 
101135 if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
102  element->willModifyAttribute(attribute->name(), nullAtom, attribute->value());
 136 element->willModifyAttribute(attribute.name(), nullAtom, attribute.value());
103137
104138 m_attributes.append(attribute);
105  if (Attr* attr = attribute->attr())
106  attr->m_element = element;
107139
108140 if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
109  element->didAddAttribute(attribute.get());
 141 element->didAddAttribute(const_cast<Attribute*>(&attribute));
110142}
111143
112144void ElementAttributeData::removeAttribute(size_t index, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute)
113145{
114146 ASSERT(index < length());
115147
116  RefPtr<Attribute> attribute = m_attributes[index];
 148 Attribute& attribute = m_attributes[index];
 149 QualifiedName name = attribute.name();
117150
118151 if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
119  element->willRemoveAttribute(attribute->name(), attribute->value());
 152 element->willRemoveAttribute(name, attribute.value());
 153
 154 if (RefPtr<Attr> attr = getAttr(element, name))
 155 attr->detachFromElementWithValue(attribute.value());
120156
121  if (Attr* attr = attribute->attr())
122  attr->m_element = 0;
123157 m_attributes.remove(index);
124158
125159 if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
126  element->didRemoveAttribute(attribute.get());
127 }
128 
129 PassRefPtr<Attr> ElementAttributeData::takeAttribute(size_t index, Element* element)
130 {
131  ASSERT(index < length());
132  ASSERT(element);
133 
134  RefPtr<Attr> attr = m_attributes[index]->createAttrIfNeeded(element);
135  removeAttribute(index, element);
136  return attr.release();
 160 element->didRemoveAttribute(name);
137161}
138162
139163bool ElementAttributeData::isEquivalent(const ElementAttributeData* other) const

@@bool ElementAttributeData::isEquivalent(const ElementAttributeData* other) const
146170 return false;
147171
148172 for (unsigned i = 0; i < len; i++) {
149  Attribute* attr = attributeItem(i);
150  Attribute* otherAttr = other->getAttributeItem(attr->name());
151  if (!otherAttr || attr->value() != otherAttr->value())
 173 Attribute* otherAttr = other->getAttributeItem(m_attributes[i].name());
 174 if (!otherAttr || m_attributes[i].value() != otherAttr->value())
152175 return false;
153176 }
154177
155178 return true;
156179}
157180
158 void ElementAttributeData::detachAttributesFromElement()
 181void ElementAttributeData::detachAttributesFromElement(Element* element)
159182{
160  size_t size = m_attributes.size();
161  for (size_t i = 0; i < size; i++) {
162  if (Attr* attr = m_attributes[i]->attr())
163  attr->m_element = 0;
164  }
165 }
 183 if (!m_attrCount)
 184 return;
166185
167 void ElementAttributeData::copyAttributesToVector(Vector<RefPtr<Attribute> >& copy)
168 {
169  copy = m_attributes;
 186 for (unsigned i = 0; i < m_attributes.size(); ++i) {
 187 if (RefPtr<Attr> attr = getAttr(element, m_attributes[i].name()))
 188 attr->detachFromElementWithValue(m_attributes[i].value());
 189 }
170190}
171191
172192size_t ElementAttributeData::getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const
173193{
174  unsigned len = length();
175 
176194 // Continue to checking case-insensitively and/or full namespaced names if necessary:
177  for (unsigned i = 0; i < len; ++i) {
178  const QualifiedName& attrName = m_attributes[i]->name();
179  if (!attrName.hasPrefix()) {
180  if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attrName.localName()))
 195 for (unsigned i = 0; i < m_attributes.size(); ++i) {
 196 if (!m_attributes[i].name().hasPrefix()) {
 197 if (shouldIgnoreAttributeCase && equalIgnoringCase(name, m_attributes[i].localName()))
181198 return i;
182199 } else {
183200 // FIXME: Would be faster to do this comparison without calling toString, which
184201 // generates a temporary string by concatenation. But this branch is only reached
185202 // if the attribute name has a prefix, which is rare in HTML.
186  if (equalPossiblyIgnoringCase(name, attrName.toString(), shouldIgnoreAttributeCase))
 203 if (equalPossiblyIgnoringCase(name, m_attributes[i].name().toString(), shouldIgnoreAttributeCase))
187204 return i;
188205 }
189206 }

@@void ElementAttributeData::setAttributes(const ElementAttributeData& other, Elem
208225 if (oldName || newName)
209226 element->updateName(oldName ? oldName->value() : nullAtom, newName ? newName->value() : nullAtom);
210227
211  clearAttributes();
 228 clearAttributes(element);
212229 unsigned newLength = other.length();
213230 m_attributes.resize(newLength);
214231
215232 // FIXME: These loops can probably be combined.
216233 for (unsigned i = 0; i < newLength; i++)
217  m_attributes[i] = other.m_attributes[i]->clone();
 234 m_attributes[i] = other.m_attributes[i];
218235 for (unsigned i = 0; i < newLength; i++)
219  element->attributeChanged(m_attributes[i].get());
 236 element->attributeChanged(&m_attributes[i]);
220237}
221238
222 void ElementAttributeData::clearAttributes()
 239void ElementAttributeData::clearAttributes(Element* element)
223240{
224241 clearClass();
225  detachAttributesFromElement();
 242 detachAttributesFromElement(element);
226243 m_attributes.clear();
227244}
228245
229 void ElementAttributeData::replaceAttribute(size_t index, PassRefPtr<Attribute> prpAttribute, Element* element)
 246void ElementAttributeData::replaceAttribute(size_t index, const Attribute& attribute, Element* element)
230247{
231248 ASSERT(element);
232249 ASSERT(index < length());
233250
234  RefPtr<Attribute> attribute = prpAttribute;
235  Attribute* old = m_attributes[index].get();
236 
237  element->willModifyAttribute(attribute->name(), old->value(), attribute->value());
238 
239  if (Attr* attr = old->attr())
240  attr->m_element = 0;
 251 element->willModifyAttribute(attribute.name(), m_attributes[index].value(), attribute.value());
241252 m_attributes[index] = attribute;
242  if (Attr* attr = attribute->attr())
243  attr->m_element = element;
 253 element->didModifyAttribute(const_cast<Attribute*>(&attribute));
 254}
 255
 256PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const String& name, bool shouldIgnoreAttributeCase, Element* element) const
 257{
 258 ASSERT(element);
 259 Attribute* attribute = getAttributeItem(name, shouldIgnoreAttributeCase);
 260 if (!attribute)
 261 return 0;
 262 return const_cast<ElementAttributeData*>(this)->getOrCreateAttr(element, attribute->name());
 263}
244264
245  element->didModifyAttribute(attribute.get());
 265PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const QualifiedName& name, Element* element) const
 266{
 267 ASSERT(element);
 268 Attribute* attribute = getAttributeItem(name);
 269 if (!attribute)
 270 return 0;
 271 return const_cast<ElementAttributeData*>(this)->getOrCreateAttr(element, attribute->name());
246272}
247273
 274
248275}

Source/WebCore/dom/ElementAttributeData.h

2626#ifndef ElementAttributeData_h
2727#define ElementAttributeData_h
2828
29 #include "Attr.h"
3029#include "Attribute.h"
3130#include "SpaceSplitString.h"
3231#include "StylePropertySet.h"

3433
3534namespace WebCore {
3635
 36class Attr;
3737class Element;
3838
39 class AttributeVector : public Vector<RefPtr<Attribute>, 4> {
40  friend class ElementAttributeData;
41 
 39class AttributeVector : public Vector<Attribute, 4> {
4240public:
43  static PassOwnPtr<AttributeVector> create()
44  {
45  return adoptPtr(new AttributeVector());
46  }
 41 AttributeVector() { }
4742
48  Attribute* attributeItem(unsigned index) const { return at(index).get(); }
 43 Attribute* attributeItem(unsigned index) const { return &const_cast<AttributeVector*>(this)->at(index); }
4944 Attribute* getAttributeItem(const QualifiedName&) const;
5045 size_t getAttributeItemIndex(const QualifiedName&) const;
5146
5247 // Used during parsing: only inserts if not already there.
53  void insertAttribute(PassRefPtr<Attribute> newAttribute);
 48 void insertAttribute(const Attribute&);
5449 void removeAttribute(const QualifiedName&);
55 
56 private:
57  AttributeVector() { }
5850};
5951
6052inline Attribute* AttributeVector::getAttributeItem(const QualifiedName& name) const
6153{
6254 size_t index = getAttributeItemIndex(name);
6355 if (index != notFound)
64  return at(index).get();
 56 return &const_cast<AttributeVector*>(this)->at(index);
6557 return 0;
6658}
6759
6860inline size_t AttributeVector::getAttributeItemIndex(const QualifiedName& name) const
6961{
7062 for (unsigned i = 0; i < size(); ++i) {
71  if (at(i)->name().matches(name))
 63 if (at(i).name().matches(name))
7264 return i;
7365 }
7466 return notFound;
7567}
7668
77 inline void AttributeVector::insertAttribute(PassRefPtr<Attribute> newAttribute)
 69inline void AttributeVector::insertAttribute(const Attribute& newAttribute)
7870{
79  if (!getAttributeItem(newAttribute->name()))
 71 if (!getAttributeItem(newAttribute.name()))
8072 append(newAttribute);
8173}
8274

@@public:
120112 size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const;
121113
122114 // These functions do no error checking.
123  void addAttribute(PassRefPtr<Attribute>, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
 115 void addAttribute(const Attribute&, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
124116 void removeAttribute(const QualifiedName&, Element*);
125117 void removeAttribute(size_t index, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
126118 PassRefPtr<Attr> takeAttribute(size_t index, Element*);

@@public:
130122
131123 bool isEquivalent(const ElementAttributeData* other) const;
132124
 125 bool hasAttrs() const { return m_attrCount; }
 126 void didAddAttr() { m_attrCount++; }
 127 void didRemoveAttr() { m_attrCount--; }
 128
 129 void setAttr(Element*, const QualifiedName&, Attr*);
 130 void removeAttr(Element*, const QualifiedName&);
 131 PassRefPtr<Attr> getAttr(Element*, const QualifiedName&);
 132 PassRefPtr<Attr> getOrCreateAttr(Element*, const QualifiedName&);
 133
133134private:
134135 friend class Element;
 136 friend class HTMLConstructionSite;
135137
136138 ElementAttributeData()
 139 : m_attrCount(0)
137140 {
138141 }
139142
140  void detachAttributesFromElement();
141  void copyAttributesToVector(Vector<RefPtr<Attribute> >&);
 143 AttributeVector attributeVector() const { return m_attributes; }
 144
 145 void detachAttributesFromElement(Element*);
142146 Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
143147 size_t getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const;
144148 void setAttributes(const ElementAttributeData& other, Element*);
145  void clearAttributes();
146  void replaceAttribute(size_t index, PassRefPtr<Attribute>, Element*);
 149 void clearAttributes(Element*);
 150 void replaceAttribute(size_t index, const Attribute&, Element*);
147151
148152 RefPtr<StylePropertySet> m_inlineStyleDecl;
149153 RefPtr<StylePropertySet> m_attributeStyle;
150154 SpaceSplitString m_classNames;
151155 AtomicString m_idForStyleResolution;
152156 AttributeVector m_attributes;
 157
 158 unsigned m_attrCount;
153159};
154160
155161inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Element* element)

@@inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Ele
159165 return;
160166
161167 removeAttribute(index, element);
162 }
163 
164 inline PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const String& name, bool shouldIgnoreAttributeCase, Element* element) const
165 {
166  ASSERT(element);
167  Attribute* attribute = getAttributeItem(name, shouldIgnoreAttributeCase);
168  if (!attribute)
169  return 0;
170  return attribute->createAttrIfNeeded(element);
171 }
172 
173 inline PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const QualifiedName& name, Element* element) const
174 {
175  ASSERT(element);
176  Attribute* attribute = getAttributeItem(name);
177  if (!attribute)
178  return 0;
179  return attribute->createAttrIfNeeded(element);
 168 return;
180169}
181170
182171inline Attribute* ElementAttributeData::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
183172{
184173 size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
185174 if (index != notFound)
186  return m_attributes[index].get();
 175 return &const_cast<ElementAttributeData*>(this)->m_attributes[index];
187176 return 0;
188177}
189178

@@inline size_t ElementAttributeData::getAttributeItemIndex(const String& name, bo
196185
197186 // Optimize for the case where the attribute exists and its name exactly matches.
198187 for (unsigned i = 0; i < len; ++i) {
199  const QualifiedName& attrName = m_attributes[i]->name();
200  if (!attrName.hasPrefix()) {
201  if (name == attrName.localName())
 188 if (!m_attributes[i].name().hasPrefix()) {
 189 if (name == m_attributes[i].localName())
202190 return i;
203191 } else
204192 doSlowCheck = true;

Source/WebCore/dom/NamedNodeMap.cpp

@@void NamedNodeMap::deref()
5252
5353PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const
5454{
55  return m_element->attributeData()->getAttributeNode(name, shouldIgnoreAttributeCase(m_element), m_element);
 55 return m_element->getAttributeNode(name);
5656}
5757
5858PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const String& namespaceURI, const String& localName) const
5959{
60  return m_element->attributeData()->getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), m_element);
 60 return m_element->getAttributeNodeNS(namespaceURI, localName);
6161}
6262
6363PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode& ec)
6464{
65  ElementAttributeData* attributeData = m_element->attributeData();
66 
67  size_t index = attributeData->getAttributeItemIndex(name, shouldIgnoreAttributeCase(m_element));
 65 size_t index = m_element->getAttributeItemIndex(name, shouldIgnoreAttributeCase(m_element));
6866 if (index == notFound) {
6967 ec = NOT_FOUND_ERR;
7068 return 0;
7169 }
72 
73  return attributeData->takeAttribute(index, m_element);
 70 return m_element->takeAttribute(index);
7471}
7572
7673PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
7774{
78  ElementAttributeData* attributeData = m_element->attributeData();
79 
80  size_t index = attributeData->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI));
 75 size_t index = m_element->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI));
8176 if (index == notFound) {
8277 ec = NOT_FOUND_ERR;
8378 return 0;
8479 }
85 
86  return attributeData->takeAttribute(index, m_element);
 80 return m_element->takeAttribute(index);
8781}
8882
8983PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionCode& ec)

@@PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
111105{
112106 if (index >= length())
113107 return 0;
114  return m_element->attributeItem(index)->createAttrIfNeeded(m_element);
 108 return m_element->getOrCreateAttr(m_element->attributeItem(index)->name());
115109}
116110
117111size_t NamedNodeMap::length() const

Source/WebCore/dom/Node.cpp

@@unsigned short Node::compareDocumentPosition(Node* otherNode)
20902090 // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
20912091 // when comparing two attributes of the same element, and inserting or removing additional attributes might change
20922092 // the order between existing attributes.
2093  Attribute* attr = owner1->attributeItem(i);
2094  if (attr1->attr() == attr)
 2093 Attribute* attribute = owner1->attributeItem(i);
 2094 if (attr1->qualifiedName() == attribute->name())
20952095 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
2096  if (attr2->attr() == attr)
 2096 if (attr2->qualifiedName() == attribute->name())
20972097 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
20982098 }
20992099

Source/WebCore/html/parser/HTMLConstructionSite.cpp

@@void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
194194void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& token)
195195{
196196 RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
197  element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
 197 element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
198198 attachLater(m_attachmentRoot, element);
199199 m_openElements.pushHTMLHtmlElement(element);
200200

@@void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& tok
205205
206206void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken& token, Element* element)
207207{
208  if (!token.attributes())
 208 if (token.attributes().isEmpty())
209209 return;
210210
211211 ElementAttributeData* attributes = element->ensureAttributeData();
212  for (unsigned i = 0; i < token.attributes()->size(); ++i) {
213  Attribute* attribute = token.attributes()->attributeItem(i);
 212 for (unsigned i = 0; i < token.attributes().size(); ++i) {
 213 Attribute* attribute = token.attributes().attributeItem(i);
214214 if (!attributes->getAttributeItem(attribute->name()))
215215 element->setAttribute(attribute->name(), attribute->value());
216216 }

@@void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken& token)
336336{
337337 RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, currentNode()->document(), true);
338338 if (m_fragmentScriptingPermission == FragmentScriptingAllowed)
339  element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
 339 element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
340340 attachLater(currentNode(), element);
341341 m_openElements.push(element.release());
342342}

@@PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken& token,
399399{
400400 QualifiedName tagName(nullAtom, token.name(), namespaceURI);
401401 RefPtr<Element> element = currentNode()->document()->createElement(tagName, true);
402  element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
 402 element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
403403 return element.release();
404404}
405405

@@PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken& tok
410410 // have to pass the current form element. We should rework form association
411411 // to occur after construction to allow better code sharing here.
412412 RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, currentNode()->document(), form(), true);
413  element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
 413 element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
414414 ASSERT(element->isHTMLElement());
415415 return element.release();
416416}

@@PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromElementRecord(HTM
420420 return createHTMLElementFromSavedElement(record->element());
421421}
422422
423 namespace {
424 
425 // FIXME: Move this function to the top of the file.
426 inline PassOwnPtr<AttributeVector> cloneAttributes(Element* element)
427 {
428  ElementAttributeData* attributes = element->updatedAttributeData();
429  if (!attributes)
430  return nullptr;
431 
432  OwnPtr<AttributeVector> newAttributes = AttributeVector::create();
433  for (size_t i = 0; i < attributes->length(); ++i) {
434  Attribute* attribute = attributes->attributeItem(i);
435  RefPtr<Attribute> clone = Attribute::create(attribute->name(), attribute->value());
436  newAttributes->append(clone);
437  }
438  return newAttributes.release();
439 }
440 
441 } // namespace
442 
443423PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Element* element)
444424{
445425 // FIXME: This method is wrong. We should be using the original token.

@@PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Elem
450430 // spec implies it should be "1". Minefield matches the HTML5 spec here.
451431
452432 ASSERT(element->isHTMLElement()); // otherwise localName() might be wrong.
453  AtomicHTMLToken fakeToken(HTMLTokenTypes::StartTag, element->localName(), cloneAttributes(element));
 433
 434 AttributeVector attributes;
 435 if (ElementAttributeData* attributeData = element->updatedAttributeData())
 436 attributes = attributeData->attributeVector();
 437
 438 AtomicHTMLToken fakeToken(HTMLTokenTypes::StartTag, element->localName(), attributes);
454439 return createHTMLElement(fakeToken);
455440}
456441

Source/WebCore/html/parser/HTMLToken.h

@@class AtomicHTMLToken : public AtomicMarkupTokenBase<HTMLToken> {
8686public:
8787 AtomicHTMLToken(HTMLToken& token) : AtomicMarkupTokenBase<HTMLToken>(&token) { }
8888
89  AtomicHTMLToken(HTMLTokenTypes::Type type, AtomicString name, PassOwnPtr<AttributeVector> attributes = nullptr)
 89 AtomicHTMLToken(HTMLTokenTypes::Type type, AtomicString name, const AttributeVector& attributes = AttributeVector())
9090 : AtomicMarkupTokenBase<HTMLToken>(type, name, attributes)
9191 {
9292 }

Source/WebCore/html/parser/HTMLTreeBuilder.cpp

@@void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
531531 parseError(token);
532532}
533533
534 void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, PassOwnPtr<AttributeVector> attributes)
 534void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, const AttributeVector& attributes)
535535{
536536 // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
537537 AtomicHTMLToken fakeToken(HTMLTokenTypes::StartTag, tagName.localName(), attributes);

@@void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
560560 processEndTag(endP);
561561}
562562
563 PassOwnPtr<AttributeVector> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
 563AttributeVector HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
564564{
565  OwnPtr<AttributeVector> attributes = token.takeAttributes();
566  if (!attributes)
567  attributes = AttributeVector::create();
568  else {
569  attributes->removeAttribute(nameAttr);
570  attributes->removeAttribute(actionAttr);
571  attributes->removeAttribute(promptAttr);
 565 AttributeVector& attributes = token.attributes();
 566 if (!attributes.isEmpty()) {
 567 attributes.removeAttribute(nameAttr);
 568 attributes.removeAttribute(actionAttr);
 569 attributes.removeAttribute(promptAttr);
572570 }
573571
574  RefPtr<Attribute> mappedAttribute = Attribute::create(nameAttr, isindexTag.localName());
575  attributes->insertAttribute(mappedAttribute.release());
576  return attributes.release();
 572 attributes.insertAttribute(Attribute(nameAttr, isindexTag.localName()));
 573 return attributes;
577574}
578575
579576void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)

@@void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
585582 return;
586583 notImplemented(); // Acknowledge self-closing flag
587584 processFakeStartTag(formTag);
588  RefPtr<Attribute> actionAttribute = token.getAttributeItem(actionAttr);
 585 Attribute* actionAttribute = token.getAttributeItem(actionAttr);
589586 if (actionAttribute)
590587 m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
591588 processFakeStartTag(hrTag);
592589 processFakeStartTag(labelTag);
593  RefPtr<Attribute> promptAttribute = token.getAttributeItem(promptAttr);
 590 Attribute* promptAttribute = token.getAttributeItem(promptAttr);
594591 if (promptAttribute)
595592 processFakeCharacters(promptAttribute->value());
596593 else

@@void adjustAttributes(AtomicHTMLToken& token)
679676 mapLoweredLocalNameToName(caseMap, attrs, length);
680677 }
681678
682  AttributeVector* attributes = token.attributes();
683  if (!attributes)
684  return;
685 
686  for (unsigned x = 0; x < attributes->size(); ++x) {
687  Attribute* attribute = attributes->attributeItem(x);
 679 for (unsigned i = 0; i < token.attributes().size(); ++i) {
 680 Attribute* attribute = token.attributes().attributeItem(i);
688681 const QualifiedName& casedName = caseMap->get(attribute->localName());
689682 if (!casedName.localName().isNull())
690683 attribute->parserSetName(casedName);

@@void adjustForeignAttributes(AtomicHTMLToken& token)
728721 map->add("xmlns:xlink", QualifiedName("xmlns", "xlink", XMLNSNames::xmlnsNamespaceURI));
729722 }
730723
731  AttributeVector* attributes = token.attributes();
732  if (!attributes)
733  return;
734 
735  for (unsigned x = 0; x < attributes->size(); ++x) {
736  Attribute* attribute = attributes->attributeItem(x);
 724 for (unsigned i = 0; i < token.attributes().size(); ++i) {
 725 Attribute* attribute = token.attributes().attributeItem(i);
737726 const QualifiedName& name = map->get(attribute->localName());
738727 if (!name.localName().isNull())
739728 attribute->parserSetName(name);

@@void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
930919 return;
931920 }
932921 if (token.name() == inputTag) {
933  RefPtr<Attribute> typeAttribute = token.getAttributeItem(typeAttr);
 922 Attribute* typeAttribute = token.getAttributeItem(typeAttr);
934923 m_tree.reconstructTheActiveFormattingElements();
935924 m_tree.insertSelfClosingHTMLElement(token);
936925 if (!typeAttribute || !equalIgnoringCase(typeAttribute->value(), "hidden"))

Source/WebCore/html/parser/HTMLTreeBuilder.h

@@private:
151151 void processCharacterBuffer(ExternalCharacterTokenBuffer&);
152152 inline void processCharacterBufferForInBody(ExternalCharacterTokenBuffer&);
153153
154  void processFakeStartTag(const QualifiedName&, PassOwnPtr<AttributeVector> attributes = nullptr);
 154 void processFakeStartTag(const QualifiedName&, const AttributeVector& attributes = AttributeVector());
155155 void processFakeEndTag(const QualifiedName&);
156156 void processFakeCharacters(const String&);
157157 void processFakePEndTagIfPInButtonScope();

@@private:
172172 inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken&);
173173 void processTokenInForeignContent(AtomicHTMLToken&);
174174
175  PassOwnPtr<AttributeVector> attributesForIsindexInput(AtomicHTMLToken&);
 175 AttributeVector attributesForIsindexInput(AtomicHTMLToken&);
176176
177177 HTMLElementStack::ElementRecord* furthestBlockForFormattingElement(Element*);
178178 void callTheAdoptionAgency(AtomicHTMLToken&);

Source/WebCore/html/parser/TextDocumentParser.cpp

@@void TextDocumentParser::insertFakePreElement()
6060 // sending fake bytes through the front-end of the parser to avoid
6161 // distrubing the line/column number calculations.
6262
63  RefPtr<Attribute> styleAttribute = Attribute::create("style", "word-wrap: break-word; white-space: pre-wrap;");
64  OwnPtr<AttributeVector> attributes = AttributeVector::create();
65  attributes->insertAttribute(styleAttribute.release());
66  AtomicHTMLToken fakePre(HTMLTokenTypes::StartTag, preTag.localName(), attributes.release());
 63 AttributeVector attributes;
 64 attributes.insertAttribute(Attribute("style", "word-wrap: break-word; white-space: pre-wrap;"));
 65 AtomicHTMLToken fakePre(HTMLTokenTypes::StartTag, preTag.localName(), attributes);
6766
6867 treeBuilder()->constructTreeFromAtomicToken(fakePre);
6968 // Normally we would skip the first \n after a <pre> element, but we don't

Source/WebCore/page/PageSerializer.cpp

@@void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, Ele
159159
160160 // We need to give a fake location to blank frames so they can be referenced by the serialized frame.
161161 url = m_serializer->urlForBlankFrame(frame);
162  RefPtr<Attribute> attribute = Attribute::create(frameOwnerURLAttributeName(*frameOwner), url.string());
163  appendAttribute(out, element, *attribute, namespaces);
 162 appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwner), url.string()), namespaces);
164163}
165164
166165void SerializerMarkupAccumulator::appendEndTag(Node* node)

Source/WebCore/svg/SVGFitToViewBox.cpp

2424#include "SVGFitToViewBox.h"
2525
2626#include "AffineTransform.h"
27 #include "Attr.h"
 27#include "Attribute.h"
2828#include "Document.h"
2929#include "FloatRect.h"
3030#include "SVGDocumentExtensions.h"

Source/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h

@@struct SVGAnimatedPropertySynchronizer<true> {
4242 if (old && value.isNull())
4343 attributeData->removeAttribute(old->name(), ownerElement);
4444 else if (!old && !value.isNull())
45  attributeData->addAttribute(Attribute::create(attrName, value), ownerElement);
 45 attributeData->addAttribute(Attribute(attrName, value), ownerElement);
4646 else if (old && !value.isNull())
4747 old->setValue(value);
4848 }

Source/WebCore/xml/XMLErrors.cpp

@@static inline PassRefPtr<Element> createXHTMLParserErrorHeader(Document* doc, co
9191{
9292 RefPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), true);
9393
94  OwnPtr<AttributeVector> reportAttributes = AttributeVector::create();
95  reportAttributes->append(Attribute::create(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"));
96  reportElement->parserSetAttributes(reportAttributes.release(), FragmentScriptingNotAllowed);
 94 AttributeVector reportAttributes;
 95 reportAttributes.append(Attribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"));
 96 reportElement->parserSetAttributes(reportAttributes, FragmentScriptingNotAllowed);
9797
9898 RefPtr<Element> h3 = doc->createElement(h3Tag, true);
9999 reportElement->parserAddChild(h3.get());
100100 h3->parserAddChild(doc->createTextNode("This page contains the following errors:"));
101101
102102 RefPtr<Element> fixed = doc->createElement(divTag, true);
103  OwnPtr<AttributeVector> fixedAttributes = AttributeVector::create();
104  fixedAttributes->append(Attribute::create(styleAttr, "font-family:monospace;font-size:12px"));
105  fixed->parserSetAttributes(fixedAttributes.release(), FragmentScriptingNotAllowed);
 103 AttributeVector fixedAttributes;
 104 fixedAttributes.append(Attribute(styleAttr, "font-family:monospace;font-size:12px"));
 105 fixed->parserSetAttributes(fixedAttributes, FragmentScriptingNotAllowed);
106106 reportElement->parserAddChild(fixed.get());
107107
108108 fixed->parserAddChild(doc->createTextNode(errorMessages));

@@void XMLErrors::insertErrorMessageBlock()
158158
159159#if ENABLE(XSLT)
160160 if (m_document->transformSourceDocument()) {
161  OwnPtr<AttributeVector> attributes = AttributeVector::create();
162  attributes->append(Attribute::create(styleAttr, "white-space: normal"));
 161 AttributeVector attributes;
 162 attributes.append(Attribute(styleAttr, "white-space: normal"));
163163 RefPtr<Element> paragraph = m_document->createElement(pTag, true);
164  paragraph->parserSetAttributes(attributes.release(), FragmentScriptingNotAllowed);
 164 paragraph->parserSetAttributes(attributes, FragmentScriptingNotAllowed);
165165 paragraph->parserAddChild(m_document->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."));
166166 reportElement->parserAddChild(paragraph.release());
167167 }

Source/WebCore/xml/XPathNodeSet.cpp

@@void NodeSet::traversalSort() const
219219
220220 unsigned attributeCount = element->attributeCount();
221221 for (unsigned i = 0; i < attributeCount; ++i) {
222  Attr* attribute = element->attributeItem(i)->attr();
223  if (attribute && nodes.contains(attribute))
224  sortedNodes.append(attribute);
 222 RefPtr<Attr> attr = element->attributeData()->getAttr(element, element->attributeItem(i)->name());
 223 if (attr && nodes.contains(attr.get()))
 224 sortedNodes.append(attr);
225225 }
226226 }
227227

Source/WebCore/xml/XPathStep.cpp

@@void Step::nodesInAxis(Node* context, NodeSet& nodes) const
346346 return;
347347
348348 for (unsigned i = 0; i < contextElement->attributeCount(); ++i) {
349  RefPtr<Attr> attr = contextElement->attributeItem(i)->createAttrIfNeeded(static_cast<Element*>(context));
 349 RefPtr<Attr> attr = contextElement->attributeData()->getOrCreateAttr(contextElement, contextElement->attributeItem(i)->name());
350350 if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
351351 nodes.append(attr.release());
352352 }

Source/WebCore/xml/parser/MarkupTokenBase.h

2828#define MarkupTokenBase_h
2929
3030#include "ElementAttributeData.h"
31 #include <wtf/PassOwnPtr.h>
3231#include <wtf/Vector.h>
3332
3433#ifndef NDEBUG

@@public:
410409 }
411410 }
412411
413  AtomicMarkupTokenBase(typename Token::Type::Type type, AtomicString name, PassOwnPtr<AttributeVector> attributes = nullptr)
 412 AtomicMarkupTokenBase(typename Token::Type::Type type, AtomicString name, const AttributeVector& attributes = AttributeVector())
414413 : m_type(type)
415414 , m_name(name)
416415 , m_externalCharacters(0)

@@public:
442441 Attribute* getAttributeItem(const QualifiedName& attributeName)
443442 {
444443 ASSERT(usesAttributes());
445  if (!m_attributes)
446  return 0;
447  return m_attributes->getAttributeItem(attributeName);
 444 return m_attributes.getAttributeItem(attributeName);
448445 }
449446
450  AttributeVector* attributes() const
 447 AttributeVector& attributes()
451448 {
452449 ASSERT(usesAttributes());
453  return m_attributes.get();
 450 return m_attributes;
454451 }
455452
456  PassOwnPtr<AttributeVector> takeAttributes()
 453 const AttributeVector& attributes() const
457454 {
458455 ASSERT(usesAttributes());
459  return m_attributes.release();
 456 return m_attributes;
460457 }
461458
462459 const typename Token::DataVector& characters() const

@@protected:
517514 // For StartTag and EndTag
518515 bool m_selfClosing;
519516
520  OwnPtr<AttributeVector> m_attributes;
 517 AttributeVector m_attributes;
521518};
522519
523520template<typename Token>

@@inline void AtomicMarkupTokenBase<Token>::initializeAttributes(const typename To
527524 if (!size)
528525 return;
529526
530  m_attributes = AttributeVector::create();
531  m_attributes->reserveInitialCapacity(size);
 527 m_attributes.clear();
 528 m_attributes.reserveInitialCapacity(size);
532529 for (size_t i = 0; i < size; ++i) {
533530 const typename Token::Attribute& attribute = attributes[i];
534531 if (attribute.m_name.isEmpty())

@@inline void AtomicMarkupTokenBase<Token>::initializeAttributes(const typename To
542539 ASSERT(attribute.m_valueRange.m_end);
543540
544541 AtomicString value(attribute.m_value.data(), attribute.m_value.size());
545  m_attributes->insertAttribute(Attribute::create(nameForAttribute(attribute), value));
 542 m_attributes.insertAttribute(Attribute(nameForAttribute(attribute), value));
546543 }
547544}
548545

Source/WebCore/xml/parser/XMLToken.h

@@public:
431431 }
432432 }
433433
434  AtomicXMLToken(XMLTokenTypes::Type type, AtomicString name, PassOwnPtr<AttributeVector> attributes = nullptr)
 434 AtomicXMLToken(XMLTokenTypes::Type type, AtomicString name, const AttributeVector& attributes = AttributeVector())
435435 : AtomicMarkupTokenBase<XMLToken>(type, name, attributes)
436436 {
437437 }

Source/WebCore/xml/parser/XMLTreeBuilder.cpp

@@void XMLTreeBuilder::processEntity(const AtomicXMLToken& token)
298298
299299void XMLTreeBuilder::processNamespaces(const AtomicXMLToken& token, NodeStackItem& stackItem)
300300{
301  if (!token.attributes())
302  return;
303 
304  for (size_t i = 0; i < token.attributes()->size(); ++i) {
305  Attribute* attribute = token.attributes()->attributeItem(i);
 301 for (unsigned i = 0; i < token.attributes().size(); ++i) {
 302 Attribute* attribute = token.attributes().attributeItem(i);
306303 if (attribute->name().prefix() == xmlnsAtom)
307304 stackItem.setNamespaceURI(attribute->name().localName(), attribute->value());
308305 else if (attribute->name() == xmlnsAtom)

@@void XMLTreeBuilder::processNamespaces(const AtomicXMLToken& token, NodeStackIte
312309
313310void XMLTreeBuilder::processAttributes(const AtomicXMLToken& token, NodeStackItem& stackItem, PassRefPtr<Element> newElement)
314311{
315  if (!token.attributes())
316  return;
317 
318  for (size_t i = 0; i < token.attributes()->size(); ++i) {
319  Attribute* attribute = token.attributes()->attributeItem(i);
 312 for (unsigned i = 0; i < token.attributes().size(); ++i) {
 313 Attribute* attribute = token.attributes().attributeItem(i);
320314 ExceptionCode ec = 0;
321315 if (attribute->name().prefix() == xmlnsAtom)
322316 newElement->setAttributeNS(XMLNSNames::xmlnsNamespaceURI, "xmlns:" + attribute->name().localName(), attribute->value(), ec);

Source/WebKit/chromium/ChangeLog

 12012-04-13 Andreas Kling <kling@webkit.org>
 2
 3 Optimize Element attribute storage for the common case (no Attr objects.)
 4 <http://webkit.org/b/83440>
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Neuter the WebKit/chromium API wrapper for WebCore::Attribute in an attempt
 9 to get cr-ews results. This is not the final patch, obviously.
 10
 11 * public/WebAttribute.h:
 12 (WebAttribute):
 13 * src/WebAttribute.cpp:
 14 (WebKit::WebAttribute::reset):
 15 (WebKit::WebAttribute::assign):
 16 (WebKit::WebAttribute::localName):
 17 (WebKit::WebAttribute::value):
 18
1192012-04-12 Kent Tamura <tkent@chromium.org>
220
321 [Chromium] Enable INPUT_TYPE_DATE

Source/WebKit/chromium/public/WebAttribute.h

3535#include "platform/WebPrivatePtr.h"
3636
3737namespace WebCore { class Attribute; }
38 #if WEBKIT_IMPLEMENTATION
39 namespace WTF { template <typename T> class PassRefPtr; }
40 #endif
4138
4239namespace WebKit {
4340class WebString;

@@public:
6057
6158 WEBKIT_EXPORT WebString localName() const;
6259 WEBKIT_EXPORT WebString value() const;
63 
64 #if WEBKIT_IMPLEMENTATION
65  WebAttribute(const WTF::PassRefPtr<WebCore::Attribute>&);
66 #endif
67 
68 private:
69  WebPrivatePtr<WebCore::Attribute> m_private;
7060};
7161
7262} // namespace WebKit

Source/WebKit/chromium/src/WebAttribute.cpp

@@namespace WebKit {
4141
4242void WebAttribute::reset()
4343{
44  m_private.reset();
4544}
4645
4746void WebAttribute::assign(const WebAttribute& other)
4847{
49  m_private = other.m_private;
50 }
51 
52 WebAttribute::WebAttribute(const PassRefPtr<Attribute>& other)
53  : m_private(other)
54 {
5548}
5649
5750WebString WebAttribute::localName() const
5851{
59  return WebString(m_private->localName());
 52 return WebString();
6053}
6154
6255WebString WebAttribute::value() const
6356{
64  return WebString(m_private->value());
 57 return WebString();
6558}
6659
6760} // namespace WebKit