Guest User

Untitled

a guest
Sep 25th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 68.37 KB | None | 0 0
  1. diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
  2. index 6d84249..25a47a4 100644
  3. --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
  4. +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
  5. @@ -4151,7 +4151,6 @@
  6. A8C4A80709D563270003AC8D /* Element.h in Headers */ = {isa = PBXBuildFile; fileRef = A8C4A7F509D563270003AC8D /* Element.h */; settings = {ATTRIBUTES = (Private, ); }; };
  7. A8C4A80809D563270003AC8D /* Element.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C4A7F609D563270003AC8D /* Element.cpp */; };
  8. A8C4A80B09D563270003AC8D /* Attribute.h in Headers */ = {isa = PBXBuildFile; fileRef = A8C4A7F909D563270003AC8D /* Attribute.h */; settings = {ATTRIBUTES = (Private, ); }; };
  9. - A8C4A80C09D563270003AC8D /* Attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C4A7FA09D563270003AC8D /* Attribute.cpp */; };
  10. A8C4A80D09D563270003AC8D /* Attr.h in Headers */ = {isa = PBXBuildFile; fileRef = A8C4A7FB09D563270003AC8D /* Attr.h */; settings = {ATTRIBUTES = (Private, ); }; };
  11. A8C4A80E09D563270003AC8D /* Attr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C4A7FC09D563270003AC8D /* Attr.cpp */; };
  12. A8CB413E0E8633FD0032C4F0 /* DashArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CB41020E85B8A50032C4F0 /* DashArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
  13. @@ -11048,7 +11047,6 @@
  14. A8C4A7F509D563270003AC8D /* Element.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Element.h; sourceTree = "<group>"; };
  15. A8C4A7F609D563270003AC8D /* Element.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Element.cpp; sourceTree = "<group>"; };
  16. A8C4A7F909D563270003AC8D /* Attribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Attribute.h; sourceTree = "<group>"; };
  17. - A8C4A7FA09D563270003AC8D /* Attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Attribute.cpp; sourceTree = "<group>"; };
  18. A8C4A7FB09D563270003AC8D /* Attr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Attr.h; sourceTree = "<group>"; };
  19. A8C4A7FC09D563270003AC8D /* Attr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Attr.cpp; sourceTree = "<group>"; };
  20. A8CB41020E85B8A50032C4F0 /* DashArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DashArray.h; sourceTree = "<group>"; };
  21. @@ -20887,7 +20885,6 @@
  22. A8C4A7FC09D563270003AC8D /* Attr.cpp */,
  23. A8C4A7FB09D563270003AC8D /* Attr.h */,
  24. 93EEC1E509C2877700C515D1 /* Attr.idl */,
  25. - A8C4A7FA09D563270003AC8D /* Attribute.cpp */,
  26. A8C4A7F909D563270003AC8D /* Attribute.h */,
  27. BC9462D7107A7B4C00857193 /* BeforeLoadEvent.h */,
  28. BC9462CB107A7A3900857193 /* BeforeLoadEvent.idl */,
  29. @@ -25126,7 +25123,6 @@
  30. E1CDE92015018ED000862CC5 /* AsyncFileStream.cpp in Sources */,
  31. 89D08D9F12228451001241DF /* AsyncFileSystem.cpp in Sources */,
  32. A8C4A80E09D563270003AC8D /* Attr.cpp in Sources */,
  33. - A8C4A80C09D563270003AC8D /* Attribute.cpp in Sources */,
  34. FD315FF612B0267600C1A359 /* AudioBasicProcessorNode.cpp in Sources */,
  35. FD315FF812B0267600C1A359 /* AudioBuffer.cpp in Sources */,
  36. FD315FFB12B0267600C1A359 /* AudioBufferSourceNode.cpp in Sources */,
  37. diff --git a/Source/WebCore/dom/Attr.cpp b/Source/WebCore/dom/Attr.cpp
  38. index 088fc2f..227862f 100644
  39. --- a/Source/WebCore/dom/Attr.cpp
  40. +++ b/Source/WebCore/dom/Attr.cpp
  41. @@ -3,7 +3,7 @@
  42. * (C) 1999 Antti Koivisto (koivisto@kde.org)
  43. * (C) 2001 Peter Kelly (pmk@post.com)
  44. * (C) 2001 Dirk Mueller (mueller@kde.org)
  45. - * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
  46. + * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights reserved.
  47. *
  48. * This library is free software; you can redistribute it and/or
  49. * modify it under the terms of the GNU Library General Public
  50. @@ -36,35 +36,48 @@ namespace WebCore {
  51.  
  52. using namespace HTMLNames;
  53.  
  54. -inline Attr::Attr(Element* element, Document* document, PassRefPtr<Attribute> attribute)
  55. - : ContainerNode(document)
  56. +Attr::Attr(Element* element, const QualifiedName& name)
  57. + : ContainerNode(element->document())
  58. , m_element(element)
  59. - , m_attribute(attribute)
  60. + , m_name(name)
  61. + , m_ignoreChildrenChanged(0)
  62. + , m_specified(true)
  63. +{
  64. +}
  65. +
  66. +Attr::Attr(Document* document, const QualifiedName& name, const AtomicString& value)
  67. + : ContainerNode(document)
  68. + , m_element(0)
  69. + , m_name(name)
  70. + , m_value(value)
  71. , m_ignoreChildrenChanged(0)
  72. , m_specified(true)
  73. {
  74. - ASSERT(!m_attribute->attr());
  75. - m_attribute->bindAttr(this);
  76. }
  77.  
  78. -PassRefPtr<Attr> Attr::create(Element* element, Document* document, PassRefPtr<Attribute> attribute)
  79. +PassRefPtr<Attr> Attr::create(Element* element, const QualifiedName& name)
  80. +{
  81. + RefPtr<Attr> attr = adoptRef(new Attr(element, name));
  82. + attr->createTextChild();
  83. + return attr.release();
  84. +}
  85. +
  86. +PassRefPtr<Attr> Attr::create(Document* document, const QualifiedName& name, const AtomicString& value)
  87. {
  88. - RefPtr<Attr> attr = adoptRef(new Attr(element, document, attribute));
  89. + RefPtr<Attr> attr = adoptRef(new Attr(document, name, value));
  90. attr->createTextChild();
  91. return attr.release();
  92. }
  93.  
  94. Attr::~Attr()
  95. {
  96. - ASSERT(m_attribute->attr() == this);
  97. - m_attribute->unbindAttr(this);
  98. }
  99.  
  100. void Attr::createTextChild()
  101. {
  102. ASSERT(refCount());
  103. - if (!m_attribute->value().isEmpty()) {
  104. - RefPtr<Text> textNode = document()->createTextNode(m_attribute->value().string());
  105. + if (!value().isEmpty()) {
  106. + RefPtr<Text> textNode = document()->createTextNode(value().string());
  107.  
  108. // This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
  109. // but much more efficiently.
  110. @@ -74,31 +87,6 @@ void Attr::createTextChild()
  111. }
  112. }
  113.  
  114. -String Attr::nodeName() const
  115. -{
  116. - return name();
  117. -}
  118. -
  119. -Node::NodeType Attr::nodeType() const
  120. -{
  121. - return ATTRIBUTE_NODE;
  122. -}
  123. -
  124. -const AtomicString& Attr::localName() const
  125. -{
  126. - return m_attribute->localName();
  127. -}
  128. -
  129. -const AtomicString& Attr::namespaceURI() const
  130. -{
  131. - return m_attribute->namespaceURI();
  132. -}
  133. -
  134. -const AtomicString& Attr::prefix() const
  135. -{
  136. - return m_attribute->prefix();
  137. -}
  138. -
  139. void Attr::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
  140. {
  141. ec = 0;
  142. @@ -112,12 +100,11 @@ void Attr::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
  143. return;
  144. }
  145.  
  146. - m_attribute->setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
  147. -}
  148. + const AtomicString& newPrefix = prefix.isEmpty() ? nullAtom : prefix;
  149.  
  150. -String Attr::nodeValue() const
  151. -{
  152. - return value();
  153. + if (Attribute* attribute = elementAttribute())
  154. + attribute->setPrefix(newPrefix);
  155. + m_name.setPrefix(newPrefix);
  156. }
  157.  
  158. void Attr::setValue(const AtomicString& value)
  159. @@ -125,22 +112,25 @@ void Attr::setValue(const AtomicString& value)
  160. EventQueueScope scope;
  161. m_ignoreChildrenChanged++;
  162. removeChildren();
  163. - m_attribute->setValue(value);
  164. + if (m_element)
  165. + elementAttribute()->setValue(value);
  166. + else
  167. + m_value = value;
  168. createTextChild();
  169. m_ignoreChildrenChanged--;
  170.  
  171. - invalidateNodeListsCacheAfterAttributeChanged(m_attribute->name());
  172. + invalidateNodeListsCacheAfterAttributeChanged(m_name);
  173. }
  174.  
  175. void Attr::setValue(const AtomicString& value, ExceptionCode&)
  176. {
  177. if (m_element)
  178. - m_element->willModifyAttribute(m_attribute->name(), m_attribute->value(), value);
  179. + m_element->willModifyAttribute(qualifiedName(), this->value(), value);
  180.  
  181. setValue(value);
  182.  
  183. if (m_element)
  184. - m_element->didModifyAttribute(m_attribute.get());
  185. + m_element->didModifyAttribute(elementAttribute());
  186. }
  187.  
  188. void Attr::setNodeValue(const String& v, ExceptionCode& ec)
  189. @@ -150,7 +140,7 @@ void Attr::setNodeValue(const String& v, ExceptionCode& ec)
  190.  
  191. PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
  192. {
  193. - RefPtr<Attr> clone = adoptRef(new Attr(0, document(), m_attribute->clone()));
  194. + RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
  195. cloneChildNodes(clone.get());
  196. return clone.release();
  197. }
  198. @@ -172,7 +162,7 @@ void Attr::childrenChanged(bool, Node*, Node*, int)
  199. if (m_ignoreChildrenChanged > 0)
  200. return;
  201.  
  202. - invalidateNodeListsCacheAfterAttributeChanged(m_attribute->name());
  203. + invalidateNodeListsCacheAfterAttributeChanged(qualifiedName());
  204.  
  205. // FIXME: We should include entity references in the value
  206.  
  207. @@ -184,11 +174,15 @@ void Attr::childrenChanged(bool, Node*, Node*, int)
  208.  
  209. AtomicString newValue = valueBuilder.toString();
  210. if (m_element)
  211. - m_element->willModifyAttribute(m_attribute->name(), m_attribute->value(), newValue);
  212. + m_element->willModifyAttribute(qualifiedName(), value(), newValue);
  213. +
  214. + if (m_element)
  215. + elementAttribute()->setValue(newValue);
  216. + else
  217. + m_value = newValue;
  218.  
  219. - m_attribute->setValue(newValue);
  220. if (m_element)
  221. - m_element->attributeChanged(m_attribute.get());
  222. + m_element->attributeChanged(elementAttribute());
  223. }
  224.  
  225. bool Attr::isId() const
  226. @@ -202,8 +196,37 @@ CSSStyleDeclaration* Attr::style()
  227. if (!m_element->isStyledElement())
  228. return 0;
  229. m_style = StylePropertySet::create();
  230. - static_cast<StyledElement*>(m_element)->collectStyleForAttribute(m_attribute.get(), m_style.get());
  231. + static_cast<StyledElement*>(m_element)->collectStyleForAttribute(elementAttribute(), m_style.get());
  232. return m_style->ensureCSSStyleDeclaration();
  233. }
  234.  
  235. +const AtomicString& Attr::value() const
  236. +{
  237. + if (m_element)
  238. + return m_element->getAttributeItem(qualifiedName())->value();
  239. + return m_value;
  240. +}
  241. +
  242. +Attribute* Attr::elementAttribute()
  243. +{
  244. + if (!m_element || !m_element->attributeData())
  245. + return 0;
  246. + return m_element->getAttributeItem(qualifiedName());
  247. +}
  248. +
  249. +void Attr::disconnectWithValue(const AtomicString& value)
  250. +{
  251. + ASSERT(m_element);
  252. + ASSERT(m_value.isNull());
  253. + m_value = value;
  254. + m_element = 0;
  255. +}
  256. +
  257. +void Attr::attachToElement(Element* element)
  258. +{
  259. + ASSERT(!m_element);
  260. + m_element = element;
  261. + m_value = nullAtom;
  262. +}
  263. +
  264. }
  265. diff --git a/Source/WebCore/dom/Attr.h b/Source/WebCore/dom/Attr.h
  266. index 7e1d293..c2d54b7 100644
  267. --- a/Source/WebCore/dom/Attr.h
  268. +++ b/Source/WebCore/dom/Attr.h
  269. @@ -26,7 +26,7 @@
  270. #define Attr_h
  271.  
  272. #include "ContainerNode.h"
  273. -#include "Attribute.h"
  274. +#include "QualifiedName.h"
  275.  
  276. namespace WebCore {
  277.  
  278. @@ -36,26 +36,24 @@ class StylePropertySet;
  279. // Attr can have Text and EntityReference children
  280. // therefore it has to be a fullblown Node. The plan
  281. // is to dynamically allocate a textchild and store the
  282. -// resulting nodevalue in the Attribute upon
  283. +// resulting nodevalue in the attribute upon
  284. // destruction. however, this is not yet implemented.
  285.  
  286. class Attr : public ContainerNode {
  287. - friend class AttributeVector;
  288. - friend class ElementAttributeData;
  289. public:
  290. - static PassRefPtr<Attr> create(Element*, Document*, PassRefPtr<Attribute>);
  291. + static PassRefPtr<Attr> create(Element*, const QualifiedName&);
  292. + static PassRefPtr<Attr> create(Document*, const QualifiedName&, const AtomicString& value);
  293. virtual ~Attr();
  294.  
  295. String name() const { return qualifiedName().toString(); }
  296. bool specified() const { return m_specified; }
  297. Element* ownerElement() const { return m_element; }
  298.  
  299. - const AtomicString& value() const { return m_attribute->value(); }
  300. + const AtomicString& value() const;
  301. void setValue(const AtomicString&, ExceptionCode&);
  302. void setValue(const AtomicString&);
  303.  
  304. - Attribute* attr() const { return m_attribute.get(); }
  305. - const QualifiedName& qualifiedName() const { return m_attribute->name(); }
  306. + const QualifiedName& qualifiedName() const { return m_name; }
  307.  
  308. bool isId() const;
  309.  
  310. @@ -63,21 +61,25 @@ public:
  311.  
  312. void setSpecified(bool specified) { m_specified = specified; }
  313.  
  314. + void attachToElement(Element*);
  315. + void disconnectWithValue(const AtomicString&);
  316. +
  317. private:
  318. - Attr(Element*, Document*, PassRefPtr<Attribute>);
  319. + Attr(Element*, const QualifiedName&);
  320. + Attr(Document*, const QualifiedName&, const AtomicString& value);
  321.  
  322. void createTextChild();
  323.  
  324. - virtual String nodeName() const;
  325. - virtual NodeType nodeType() const;
  326. + virtual String nodeName() const OVERRIDE { return name(); }
  327. + virtual NodeType nodeType() const OVERRIDE { return ATTRIBUTE_NODE; }
  328.  
  329. - const AtomicString& localName() const;
  330. - const AtomicString& namespaceURI() const;
  331. - const AtomicString& prefix() const;
  332. + const AtomicString& localName() const { return m_name.localName(); }
  333. + const AtomicString& namespaceURI() const { return m_name.namespaceURI(); }
  334. + const AtomicString& prefix() const { return m_name.prefix(); }
  335.  
  336. virtual void setPrefix(const AtomicString&, ExceptionCode&);
  337.  
  338. - virtual String nodeValue() const;
  339. + virtual String nodeValue() const OVERRIDE { return value(); }
  340. virtual void setNodeValue(const String&, ExceptionCode&);
  341. virtual PassRefPtr<Node> cloneNode(bool deep);
  342.  
  343. @@ -90,8 +92,14 @@ private:
  344. virtual const AtomicString& virtualLocalName() const { return localName(); }
  345. virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
  346.  
  347. + Attribute* elementAttribute();
  348. +
  349. + // Attr wraps either an element/name, or a name/value pair (when it's a standalone Node.)
  350. + // Note that m_name is always set, but m_element/m_value may be null.
  351. Element* m_element;
  352. - RefPtr<Attribute> m_attribute;
  353. + QualifiedName m_name;
  354. + AtomicString m_value;
  355. +
  356. RefPtr<StylePropertySet> m_style;
  357. unsigned m_ignoreChildrenChanged : 31;
  358. bool m_specified : 1;
  359. diff --git a/Source/WebCore/dom/Attribute.h b/Source/WebCore/dom/Attribute.h
  360. index 8c59d1c..9310c72 100644
  361. --- a/Source/WebCore/dom/Attribute.h
  362. +++ b/Source/WebCore/dom/Attribute.h
  363. @@ -3,7 +3,7 @@
  364. * (C) 1999 Antti Koivisto (koivisto@kde.org)
  365. * (C) 2001 Peter Kelly (pmk@post.com)
  366. * (C) 2001 Dirk Mueller (mueller@kde.org)
  367. - * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
  368. + * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved.
  369. *
  370. * This library is free software; you can redistribute it and/or
  371. * modify it under the terms of the GNU Library General Public
  372. @@ -29,38 +29,37 @@
  373.  
  374. namespace WebCore {
  375.  
  376. -class Attr;
  377. -class Element;
  378. -
  379. // This has no counterpart in DOM.
  380. // It is an internal representation of the node value of an Attr.
  381. // The actual Attr with its value as a Text child is allocated only if needed.
  382. -class Attribute : public RefCounted<Attribute> {
  383. - friend class Attr;
  384. +class Attribute {
  385. public:
  386. - static PassRefPtr<Attribute> create(const QualifiedName& name, const AtomicString& value)
  387. + Attribute()
  388. + : m_name(nullAtom, nullAtom, nullAtom)
  389. {
  390. - return adoptRef(new Attribute(name, value));
  391. }
  392. - static PassRefPtr<Attribute> create(const AtomicString& name, const AtomicString& value)
  393. +
  394. + Attribute(const QualifiedName& name, const AtomicString& value)
  395. + : m_name(name)
  396. + , m_value(value)
  397. + {
  398. + }
  399. +
  400. + Attribute(const AtomicString& name, const AtomicString& value)
  401. + : m_name(nullAtom, name, nullAtom)
  402. + , m_value(value)
  403. {
  404. - return adoptRef(new Attribute(name, value));
  405. }
  406.  
  407. const AtomicString& value() const { return m_value; }
  408. const AtomicString& prefix() const { return m_name.prefix(); }
  409. const AtomicString& localName() const { return m_name.localName(); }
  410. const AtomicString& namespaceURI() const { return m_name.namespaceURI(); }
  411. -
  412. +
  413. const QualifiedName& name() const { return m_name; }
  414. -
  415. - Attr* attr() const;
  416. - PassRefPtr<Attr> createAttrIfNeeded(Element*);
  417.  
  418. bool isNull() const { return m_value.isNull(); }
  419. bool isEmpty() const { return m_value.isEmpty(); }
  420. -
  421. - PassRefPtr<Attribute> clone() const;
  422.  
  423. void setValue(const AtomicString& value) { m_value = value; }
  424. void setPrefix(const AtomicString& prefix) { m_name.setPrefix(prefix); }
  425. @@ -71,26 +70,6 @@ public:
  426. void parserSetName(const QualifiedName& name) { m_name = name; }
  427.  
  428. private:
  429. - Attribute(const QualifiedName& name, const AtomicString& value)
  430. - : m_hasAttr(false)
  431. - , m_name(name)
  432. - , m_value(value)
  433. - {
  434. - }
  435. -
  436. - Attribute(const AtomicString& name, const AtomicString& value)
  437. - : m_hasAttr(false)
  438. - , m_name(nullAtom, name, nullAtom)
  439. - , m_value(value)
  440. - {
  441. - }
  442. -
  443. - void bindAttr(Attr*);
  444. - void unbindAttr(Attr*);
  445. -
  446. - // This boolean will go into the spare 32-bits of padding from RefCounted in 64-bit.
  447. - bool m_hasAttr;
  448. -
  449. QualifiedName m_name;
  450. AtomicString m_value;
  451. };
  452. diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
  453. index 8aad1a3..0e13cbb 100644
  454. --- a/Source/WebCore/dom/Document.cpp
  455. +++ b/Source/WebCore/dom/Document.cpp
  456. @@ -912,7 +912,7 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
  457. return newElement.release();
  458. }
  459. case ATTRIBUTE_NODE:
  460. - return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
  461. + return Attr::create(this, QualifiedName(nullAtom, static_cast<Attr*>(importedNode)->name(), nullAtom), static_cast<Attr*>(importedNode)->value());
  462. case DOCUMENT_FRAGMENT_NODE: {
  463. if (importedNode->isShadowRoot()) {
  464. // ShadowRoot nodes should not be explicitly importable.
  465. @@ -4459,7 +4459,7 @@ PassRefPtr<Attr> Document::createAttributeNS(const String& namespaceURI, const S
  466. return 0;
  467. }
  468.  
  469. - return Attr::create(0, this, Attribute::create(qName, StringImpl::empty()));
  470. + return Attr::create(this, qName, emptyString());
  471. }
  472.  
  473. #if ENABLE(SVG)
  474. diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
  475. index 9d66c01..e9b4b30 100644
  476. --- a/Source/WebCore/dom/Element.cpp
  477. +++ b/Source/WebCore/dom/Element.cpp
  478. @@ -127,7 +127,7 @@ Element::~Element()
  479. if (shadowTree())
  480. rareData()->m_shadowTree.clear();
  481. if (m_attributeData)
  482. - m_attributeData->clearAttributes();
  483. + m_attributeData->clearAttributes(this);
  484. }
  485.  
  486. inline ElementRareData* Element::rareData() const
  487. @@ -650,14 +650,14 @@ inline void Element::setAttributeInternal(size_t index, const QualifiedName& nam
  488. }
  489.  
  490. if (!old) {
  491. - m_attributeData->addAttribute(Attribute::create(name, value), this, inUpdateStyleAttribute);
  492. + m_attributeData->addAttribute(Attribute(name, value), this, inUpdateStyleAttribute);
  493. return;
  494. }
  495.  
  496. if (inUpdateStyleAttribute == NotInUpdateStyleAttribute)
  497. - willModifyAttribute(name, old ? old->value() : nullAtom, value);
  498. + willModifyAttribute(name, old->value(), value);
  499.  
  500. - if (Attr* attrNode = old->attr())
  501. + if (Attr* attrNode = getAttr(name))
  502. attrNode->setValue(value);
  503. else
  504. old->setValue(value);
  505. @@ -739,42 +739,41 @@ static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& v
  506. return (name.localName().endsWith(hrefAttr.localName()) || name == srcAttr || name == actionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));
  507. }
  508.  
  509. -void Element::parserSetAttributes(PassOwnPtr<AttributeVector> attributeVector, FragmentScriptingPermission scriptingPermission)
  510. +void Element::parserSetAttributes(const AttributeVector& attributeVector, FragmentScriptingPermission scriptingPermission)
  511. {
  512. ASSERT(!inDocument());
  513. ASSERT(!parentNode());
  514.  
  515. ASSERT(!m_attributeData);
  516.  
  517. - if (!attributeVector)
  518. + if (attributeVector.isEmpty())
  519. return;
  520.  
  521. createAttributeData();
  522. - m_attributeData->m_attributes.swap(*attributeVector);
  523. + m_attributeData->m_attributes = attributeVector;
  524.  
  525. // If the element is created as result of a paste or drag-n-drop operation
  526. // we want to remove all the script and event handlers.
  527. if (scriptingPermission == FragmentScriptingNotAllowed) {
  528. unsigned i = 0;
  529. while (i < m_attributeData->length()) {
  530. - const QualifiedName& attributeName = m_attributeData->m_attributes[i]->name();
  531. + const QualifiedName& attributeName = m_attributeData->m_attributes[i].name();
  532. if (isEventHandlerAttribute(attributeName)) {
  533. m_attributeData->m_attributes.remove(i);
  534. continue;
  535. }
  536.  
  537. - if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i]->value()))
  538. - m_attributeData->m_attributes[i]->setValue(nullAtom);
  539. + if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i].value()))
  540. + m_attributeData->m_attributes[i].setValue(nullAtom);
  541. i++;
  542. }
  543. }
  544.  
  545. // Store the set of attributes that changed on the stack in case
  546. // attributeChanged mutates m_attributeData.
  547. - Vector<RefPtr<Attribute> > attributes;
  548. - m_attributeData->copyAttributesToVector(attributes);
  549. - for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
  550. - attributeChanged(iter->get());
  551. + AttributeVector attributes = m_attributeData->attributeVector();
  552. + for (unsigned i = 0; i < attributes.size(); ++i)
  553. + attributeChanged(&attributes[i]);
  554. }
  555.  
  556. bool Element::hasAttributes() const
  557. @@ -1390,11 +1389,10 @@ PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
  558. }
  559.  
  560. ElementAttributeData* attributeData = ensureUpdatedAttributeData();
  561. - Attribute* attribute = attr->attr();
  562. - size_t index = attributeData->getAttributeItemIndex(attribute->name());
  563. - Attribute* oldAttribute = index != notFound ? attributeData->attributeItem(index) : 0;
  564. - if (oldAttribute == attribute)
  565. - return attr; // we know about it already
  566. +
  567. + RefPtr<Attr> oldAttr = getAttr(attr->qualifiedName());
  568. + if (oldAttr.get() == attr)
  569. + return attr; // This Attr is already attached to the element.
  570.  
  571. // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
  572. // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
  573. @@ -1403,13 +1401,22 @@ PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
  574. return 0;
  575. }
  576.  
  577. - RefPtr<Attr> oldAttr;
  578. - if (oldAttribute) {
  579. - oldAttr = oldAttribute->createAttrIfNeeded(this);
  580. - attributeData->replaceAttribute(index, attribute, this);
  581. - } else
  582. - attributeData->addAttribute(attribute, this);
  583. + size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName());
  584. + Attribute* oldAttribute = index != notFound ? attributeData->attributeItem(index) : 0;
  585. +
  586. + if (!oldAttribute) {
  587. + attributeData->addAttribute(Attribute(attr->qualifiedName(), attr->value()), this);
  588. + attributeData->setAttr(this, attr->qualifiedName(), attr);
  589. + return 0;
  590. + }
  591. +
  592. + if (oldAttr)
  593. + oldAttr->disconnectWithValue(oldAttribute->value());
  594. + else
  595. + oldAttr = Attr::create(document(), oldAttribute->name(), oldAttribute->value());
  596.  
  597. + attributeData->replaceAttribute(index, Attribute(attr->name(), attr->value()), this);
  598. + attributeData->setAttr(this, attr->qualifiedName(), attr);
  599. return oldAttr.release();
  600. }
  601.  
  602. @@ -1441,7 +1448,9 @@ PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
  603. return 0;
  604. }
  605.  
  606. - return attributeData->takeAttribute(index, this);
  607. + RefPtr<Attr> oldAttr = getOrCreateAttr(attr->qualifiedName());
  608. + attributeData->removeAttribute(index, this);
  609. + return oldAttr.release();
  610. }
  611.  
  612. void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
  613. @@ -1709,11 +1718,9 @@ void Element::normalizeAttributes()
  614. if (!attributeData || attributeData->isEmpty())
  615. return;
  616.  
  617. - Vector<RefPtr<Attribute> > attributeVector;
  618. - attributeData->copyAttributesToVector(attributeVector);
  619. - size_t numAttrs = attributeVector.size();
  620. - for (size_t i = 0; i < numAttrs; ++i) {
  621. - if (Attr* attr = attributeVector[i]->attr())
  622. + AttributeVector attributes = attributeData->attributeVector();
  623. + for (size_t i = 0; i < attributes.size(); ++i) {
  624. + if (Attr* attr = getAttr(attributes[i].name()))
  625. attr->normalize();
  626. }
  627. }
  628. @@ -2024,17 +2031,12 @@ void Element::didModifyAttribute(Attribute* attr)
  629. // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
  630. }
  631.  
  632. -void Element::didRemoveAttribute(Attribute* attr)
  633. +void Element::didRemoveAttribute(const QualifiedName& name)
  634. {
  635. - if (attr->isNull())
  636. - return;
  637. -
  638. - AtomicString savedValue = attr->value();
  639. - attr->setValue(nullAtom);
  640. - attributeChanged(attr);
  641. - attr->setValue(savedValue);
  642. + Attribute dummyAttribute(name, nullAtom);
  643. + attributeChanged(&dummyAttribute);
  644.  
  645. - InspectorInstrumentation::didRemoveDOMAttr(document(), this, attr->name().localName());
  646. + InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
  647. dispatchSubtreeModifiedEvent();
  648. }
  649.  
  650. @@ -2080,4 +2082,17 @@ void Element::setSavedLayerScrollOffset(const IntSize& size)
  651. ensureRareData()->m_savedLayerScrollOffset = size;
  652. }
  653.  
  654. +Attr* Element::getAttr(const QualifiedName& name)
  655. +{
  656. + if (!attributeData())
  657. + return 0;
  658. + return attributeData()->getAttr(this, name);
  659. +}
  660. +
  661. +Attr* Element::getOrCreateAttr(const QualifiedName& name)
  662. +{
  663. + ASSERT(attributeData());
  664. + return attributeData()->getOrCreateAttr(this, name);
  665. +}
  666. +
  667. } // namespace WebCore
  668. diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h
  669. index be26547..86b1235 100644
  670. --- a/Source/WebCore/dom/Element.h
  671. +++ b/Source/WebCore/dom/Element.h
  672. @@ -202,6 +202,9 @@ public:
  673. PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
  674. PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
  675. PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
  676. +
  677. + Attr* getAttr(const QualifiedName&);
  678. + Attr* getOrCreateAttr(const QualifiedName&);
  679.  
  680. virtual CSSStyleDeclaration* style();
  681.  
  682. @@ -236,7 +239,7 @@ public:
  683. virtual void attributeChanged(Attribute*);
  684.  
  685. // Only called by the parser immediately after element construction.
  686. - void parserSetAttributes(PassOwnPtr<AttributeVector>, FragmentScriptingPermission);
  687. + void parserSetAttributes(const AttributeVector&, FragmentScriptingPermission);
  688.  
  689. ElementAttributeData* attributeData() const { return m_attributeData.get(); }
  690. ElementAttributeData* ensureAttributeData() const;
  691. @@ -297,7 +300,7 @@ public:
  692. void willRemoveAttribute(const QualifiedName&, const AtomicString& value);
  693. void didAddAttribute(Attribute*);
  694. void didModifyAttribute(Attribute*);
  695. - void didRemoveAttribute(Attribute*);
  696. + void didRemoveAttribute(const QualifiedName&);
  697.  
  698. LayoutSize minimumSizeForResizing() const;
  699. void setMinimumSizeForResizing(const LayoutSize&);
  700. diff --git a/Source/WebCore/dom/ElementAttributeData.cpp b/Source/WebCore/dom/ElementAttributeData.cpp
  701. index d732b6e..320f137 100644
  702. --- a/Source/WebCore/dom/ElementAttributeData.cpp
  703. +++ b/Source/WebCore/dom/ElementAttributeData.cpp
  704. @@ -26,25 +26,63 @@
  705. #include "config.h"
  706. #include "ElementAttributeData.h"
  707.  
  708. +#include "Attr.h"
  709. #include "StyledElement.h"
  710.  
  711. namespace WebCore {
  712.  
  713. +typedef HashMap<pair<Element*, QualifiedName>, RefPtr<Attr> > AttrMap;
  714. +static AttrMap& attrMap()
  715. +{
  716. + DEFINE_STATIC_LOCAL(AttrMap, map, ());
  717. + return map;
  718. +}
  719. +
  720. +// FIXME: We are leaking these into the map.
  721. +
  722. +Attr* ElementAttributeData::getAttr(Element* element, const QualifiedName& name)
  723. +{
  724. + if (!m_attrCount)
  725. + return 0;
  726. + return attrMap().get(std::make_pair(element, name)).get();
  727. +}
  728. +
  729. +Attr* ElementAttributeData::getOrCreateAttr(Element* element, const QualifiedName& name)
  730. +{
  731. + AttrMap::AddResult result = attrMap().add(std::make_pair(element, name), 0);
  732. + if (result.isNewEntry) {
  733. + result.iterator->second = Attr::create(element, name);
  734. + setAttr(element, name, result.iterator->second.get());
  735. + }
  736. + return result.iterator->second.get();
  737. +}
  738. +
  739. +void ElementAttributeData::setAttr(Element* element, const QualifiedName& name, Attr* attr)
  740. +{
  741. + ASSERT(!attrMap().contains(std::make_pair(element, name)));
  742. + attrMap().add(std::make_pair(element, name), attr);
  743. + attr->attachToElement(element);
  744. + didAddAttr();
  745. +}
  746. +
  747. +void ElementAttributeData::removeAttr(Element* element, const QualifiedName& name)
  748. +{
  749. + ASSERT(attrMap().contains(std::make_pair(element, name)));
  750. + attrMap().remove(std::make_pair(element, name));
  751. + didRemoveAttr();
  752. +}
  753. +
  754. void AttributeVector::removeAttribute(const QualifiedName& name)
  755. {
  756. size_t index = getAttributeItemIndex(name);
  757. if (index == notFound)
  758. return;
  759.  
  760. - RefPtr<Attribute> attribute = at(index);
  761. - if (Attr* attr = attribute->attr())
  762. - attr->m_element = 0;
  763. remove(index);
  764. }
  765.  
  766. ElementAttributeData::~ElementAttributeData()
  767. {
  768. - detachAttributesFromElement();
  769. }
  770.  
  771. void ElementAttributeData::setClass(const String& className, bool shouldFoldCase)
  772. @@ -93,46 +131,36 @@ void ElementAttributeData::destroyInlineStyle(StyledElement* element)
  773. m_inlineStyleDecl = 0;
  774. }
  775.  
  776. -void ElementAttributeData::addAttribute(PassRefPtr<Attribute> prpAttribute, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute)
  777. +void ElementAttributeData::addAttribute(const Attribute& attribute, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute)
  778. {
  779. - RefPtr<Attribute> attribute = prpAttribute;
  780. -
  781. if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
  782. - element->willModifyAttribute(attribute->name(), nullAtom, attribute->value());
  783. + element->willModifyAttribute(attribute.name(), nullAtom, attribute.value());
  784.  
  785. m_attributes.append(attribute);
  786. - if (Attr* attr = attribute->attr())
  787. - attr->m_element = element;
  788.  
  789. if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
  790. - element->didAddAttribute(attribute.get());
  791. + element->didAddAttribute(const_cast<Attribute*>(&attribute));
  792. }
  793.  
  794. void ElementAttributeData::removeAttribute(size_t index, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute)
  795. {
  796. ASSERT(index < length());
  797.  
  798. - RefPtr<Attribute> attribute = m_attributes[index];
  799. + Attribute& attribute = m_attributes[index];
  800. + QualifiedName name = attribute.name();
  801.  
  802. if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
  803. - element->willRemoveAttribute(attribute->name(), attribute->value());
  804. + element->willRemoveAttribute(name, attribute.value());
  805. +
  806. + if (Attr* attr = getAttr(element, name)) {
  807. + attr->disconnectWithValue(attribute.value());
  808. + removeAttr(element, name);
  809. + }
  810.  
  811. - if (Attr* attr = attribute->attr())
  812. - attr->m_element = 0;
  813. m_attributes.remove(index);
  814.  
  815. if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute)
  816. - element->didRemoveAttribute(attribute.get());
  817. -}
  818. -
  819. -PassRefPtr<Attr> ElementAttributeData::takeAttribute(size_t index, Element* element)
  820. -{
  821. - ASSERT(index < length());
  822. - ASSERT(element);
  823. -
  824. - RefPtr<Attr> attr = m_attributes[index]->createAttrIfNeeded(element);
  825. - removeAttribute(index, element);
  826. - return attr.release();
  827. + element->didRemoveAttribute(name);
  828. }
  829.  
  830. bool ElementAttributeData::isEquivalent(const ElementAttributeData* other) const
  831. @@ -145,44 +173,39 @@ bool ElementAttributeData::isEquivalent(const ElementAttributeData* other) const
  832. return false;
  833.  
  834. for (unsigned i = 0; i < len; i++) {
  835. - Attribute* attr = attributeItem(i);
  836. - Attribute* otherAttr = other->getAttributeItem(attr->name());
  837. - if (!otherAttr || attr->value() != otherAttr->value())
  838. + Attribute* otherAttr = other->getAttributeItem(m_attributes[i].name());
  839. + if (!otherAttr || m_attributes[i].value() != otherAttr->value())
  840. return false;
  841. }
  842.  
  843. return true;
  844. }
  845.  
  846. -void ElementAttributeData::detachAttributesFromElement()
  847. +void ElementAttributeData::detachAttributesFromElement(Element* element)
  848. {
  849. - size_t size = m_attributes.size();
  850. - for (size_t i = 0; i < size; i++) {
  851. - if (Attr* attr = m_attributes[i]->attr())
  852. - attr->m_element = 0;
  853. - }
  854. -}
  855. + if (!m_attrCount)
  856. + return;
  857.  
  858. -void ElementAttributeData::copyAttributesToVector(Vector<RefPtr<Attribute> >& copy)
  859. -{
  860. - copy = m_attributes;
  861. + for (unsigned i = 0; i < m_attributes.size(); ++i) {
  862. + if (Attr* attr = getAttr(element, m_attributes[i].name()))
  863. + attr->disconnectWithValue(m_attributes[i].value()); {
  864. + removeAttr(element, m_attributes[i].name());
  865. + }
  866. + }
  867. }
  868.  
  869. size_t ElementAttributeData::getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const
  870. {
  871. - unsigned len = length();
  872. -
  873. // Continue to checking case-insensitively and/or full namespaced names if necessary:
  874. - for (unsigned i = 0; i < len; ++i) {
  875. - const QualifiedName& attrName = m_attributes[i]->name();
  876. - if (!attrName.hasPrefix()) {
  877. - if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attrName.localName()))
  878. + for (unsigned i = 0; i < m_attributes.size(); ++i) {
  879. + if (!m_attributes[i].name().hasPrefix()) {
  880. + if (shouldIgnoreAttributeCase && equalIgnoringCase(name, m_attributes[i].localName()))
  881. return i;
  882. } else {
  883. // FIXME: Would be faster to do this comparison without calling toString, which
  884. // generates a temporary string by concatenation. But this branch is only reached
  885. // if the attribute name has a prefix, which is rare in HTML.
  886. - if (equalPossiblyIgnoringCase(name, attrName.toString(), shouldIgnoreAttributeCase))
  887. + if (equalPossiblyIgnoringCase(name, m_attributes[i].name().toString(), shouldIgnoreAttributeCase))
  888. return i;
  889. }
  890. }
  891. @@ -207,41 +230,51 @@ void ElementAttributeData::setAttributes(const ElementAttributeData& other, Elem
  892. if (oldName || newName)
  893. element->updateName(oldName ? oldName->value() : nullAtom, newName ? newName->value() : nullAtom);
  894.  
  895. - clearAttributes();
  896. + clearAttributes(element);
  897. unsigned newLength = other.length();
  898. m_attributes.resize(newLength);
  899.  
  900. // FIXME: These loops can probably be combined.
  901. for (unsigned i = 0; i < newLength; i++)
  902. - m_attributes[i] = other.m_attributes[i]->clone();
  903. + m_attributes[i] = other.m_attributes[i];
  904. for (unsigned i = 0; i < newLength; i++)
  905. - element->attributeChanged(m_attributes[i].get());
  906. + element->attributeChanged(&m_attributes[i]);
  907. }
  908.  
  909. -void ElementAttributeData::clearAttributes()
  910. +void ElementAttributeData::clearAttributes(Element* element)
  911. {
  912. clearClass();
  913. - detachAttributesFromElement();
  914. + detachAttributesFromElement(element);
  915. m_attributes.clear();
  916. }
  917.  
  918. -void ElementAttributeData::replaceAttribute(size_t index, PassRefPtr<Attribute> prpAttribute, Element* element)
  919. +void ElementAttributeData::replaceAttribute(size_t index, const Attribute& attribute, Element* element)
  920. {
  921. ASSERT(element);
  922. ASSERT(index < length());
  923.  
  924. - RefPtr<Attribute> attribute = prpAttribute;
  925. - Attribute* old = m_attributes[index].get();
  926. -
  927. - element->willModifyAttribute(attribute->name(), old->value(), attribute->value());
  928. -
  929. - if (Attr* attr = old->attr())
  930. - attr->m_element = 0;
  931. + element->willModifyAttribute(attribute.name(), m_attributes[index].value(), attribute.value());
  932. m_attributes[index] = attribute;
  933. - if (Attr* attr = attribute->attr())
  934. - attr->m_element = element;
  935. + element->didModifyAttribute(const_cast<Attribute*>(&attribute));
  936. +}
  937.  
  938. - element->didModifyAttribute(attribute.get());
  939. +PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const String& name, bool shouldIgnoreAttributeCase, Element* element) const
  940. +{
  941. + ASSERT(element);
  942. + Attribute* attribute = getAttributeItem(name, shouldIgnoreAttributeCase);
  943. + if (!attribute)
  944. + return 0;
  945. + return const_cast<ElementAttributeData*>(this)->getOrCreateAttr(element, attribute->name());
  946. }
  947.  
  948. +PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const QualifiedName& name, Element* element) const
  949. +{
  950. + ASSERT(element);
  951. + Attribute* attribute = getAttributeItem(name);
  952. + if (!attribute)
  953. + return 0;
  954. + return const_cast<ElementAttributeData*>(this)->getOrCreateAttr(element, attribute->name());
  955. +}
  956. +
  957. +
  958. }
  959. diff --git a/Source/WebCore/dom/ElementAttributeData.h b/Source/WebCore/dom/ElementAttributeData.h
  960. index f854328..1882534 100644
  961. --- a/Source/WebCore/dom/ElementAttributeData.h
  962. +++ b/Source/WebCore/dom/ElementAttributeData.h
  963. @@ -26,7 +26,6 @@
  964. #ifndef ElementAttributeData_h
  965. #define ElementAttributeData_h
  966.  
  967. -#include "Attr.h"
  968. #include "Attribute.h"
  969. #include "SpaceSplitString.h"
  970. #include "StylePropertySet.h"
  971. @@ -34,49 +33,42 @@
  972.  
  973. namespace WebCore {
  974.  
  975. +class Attr;
  976. class Element;
  977.  
  978. -class AttributeVector : public Vector<RefPtr<Attribute>, 4> {
  979. - friend class ElementAttributeData;
  980. -
  981. +class AttributeVector : public Vector<Attribute, 4> {
  982. public:
  983. - static PassOwnPtr<AttributeVector> create()
  984. - {
  985. - return adoptPtr(new AttributeVector());
  986. - }
  987. + AttributeVector() { }
  988.  
  989. - Attribute* attributeItem(unsigned index) const { return at(index).get(); }
  990. + Attribute* attributeItem(unsigned index) const { return &const_cast<AttributeVector*>(this)->at(index); }
  991. Attribute* getAttributeItem(const QualifiedName&) const;
  992. size_t getAttributeItemIndex(const QualifiedName&) const;
  993.  
  994. // Used during parsing: only inserts if not already there.
  995. - void insertAttribute(PassRefPtr<Attribute> newAttribute);
  996. + void insertAttribute(const Attribute&);
  997. void removeAttribute(const QualifiedName&);
  998. -
  999. -private:
  1000. - AttributeVector() { }
  1001. };
  1002.  
  1003. inline Attribute* AttributeVector::getAttributeItem(const QualifiedName& name) const
  1004. {
  1005. size_t index = getAttributeItemIndex(name);
  1006. if (index != notFound)
  1007. - return at(index).get();
  1008. + return &const_cast<AttributeVector*>(this)->at(index);
  1009. return 0;
  1010. }
  1011.  
  1012. inline size_t AttributeVector::getAttributeItemIndex(const QualifiedName& name) const
  1013. {
  1014. for (unsigned i = 0; i < size(); ++i) {
  1015. - if (at(i)->name().matches(name))
  1016. + if (at(i).name().matches(name))
  1017. return i;
  1018. }
  1019. return notFound;
  1020. }
  1021.  
  1022. -inline void AttributeVector::insertAttribute(PassRefPtr<Attribute> newAttribute)
  1023. +inline void AttributeVector::insertAttribute(const Attribute& newAttribute)
  1024. {
  1025. - if (!getAttributeItem(newAttribute->name()))
  1026. + if (!getAttributeItem(newAttribute.name()))
  1027. append(newAttribute);
  1028. }
  1029.  
  1030. @@ -120,7 +112,7 @@ public:
  1031. size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const;
  1032.  
  1033. // These functions do no error checking.
  1034. - void addAttribute(PassRefPtr<Attribute>, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
  1035. + void addAttribute(const Attribute&, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
  1036. void removeAttribute(const QualifiedName&, Element*);
  1037. void removeAttribute(size_t index, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
  1038. PassRefPtr<Attr> takeAttribute(size_t index, Element*);
  1039. @@ -130,26 +122,40 @@ public:
  1040.  
  1041. bool isEquivalent(const ElementAttributeData* other) const;
  1042.  
  1043. + bool hasAttrs() const { return m_attrCount; }
  1044. + void didAddAttr() { m_attrCount++; }
  1045. + void didRemoveAttr() { m_attrCount--; }
  1046. +
  1047. + void setAttr(Element*, const QualifiedName&, Attr*);
  1048. + void removeAttr(Element*, const QualifiedName&);
  1049. + Attr* getAttr(Element*, const QualifiedName&);
  1050. + Attr* getOrCreateAttr(Element*, const QualifiedName&);
  1051. +
  1052. private:
  1053. friend class Element;
  1054. + friend class HTMLConstructionSite;
  1055.  
  1056. ElementAttributeData()
  1057. + : m_attrCount(0)
  1058. {
  1059. }
  1060.  
  1061. - void detachAttributesFromElement();
  1062. - void copyAttributesToVector(Vector<RefPtr<Attribute> >&);
  1063. + AttributeVector attributeVector() const { return m_attributes; }
  1064. +
  1065. + void detachAttributesFromElement(Element*);
  1066. Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
  1067. size_t getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const;
  1068. void setAttributes(const ElementAttributeData& other, Element*);
  1069. - void clearAttributes();
  1070. - void replaceAttribute(size_t index, PassRefPtr<Attribute>, Element*);
  1071. + void clearAttributes(Element*);
  1072. + void replaceAttribute(size_t index, const Attribute&, Element*);
  1073.  
  1074. RefPtr<StylePropertySet> m_inlineStyleDecl;
  1075. RefPtr<StylePropertySet> m_attributeStyle;
  1076. SpaceSplitString m_classNames;
  1077. AtomicString m_idForStyleResolution;
  1078. AttributeVector m_attributes;
  1079. +
  1080. + unsigned m_attrCount;
  1081. };
  1082.  
  1083. inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Element* element)
  1084. @@ -161,29 +167,11 @@ inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Ele
  1085. removeAttribute(index, element);
  1086. }
  1087.  
  1088. -inline PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const String& name, bool shouldIgnoreAttributeCase, Element* element) const
  1089. -{
  1090. - ASSERT(element);
  1091. - Attribute* attribute = getAttributeItem(name, shouldIgnoreAttributeCase);
  1092. - if (!attribute)
  1093. - return 0;
  1094. - return attribute->createAttrIfNeeded(element);
  1095. -}
  1096. -
  1097. -inline PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const QualifiedName& name, Element* element) const
  1098. -{
  1099. - ASSERT(element);
  1100. - Attribute* attribute = getAttributeItem(name);
  1101. - if (!attribute)
  1102. - return 0;
  1103. - return attribute->createAttrIfNeeded(element);
  1104. -}
  1105. -
  1106. inline Attribute* ElementAttributeData::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
  1107. {
  1108. size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
  1109. if (index != notFound)
  1110. - return m_attributes[index].get();
  1111. + return &const_cast<ElementAttributeData*>(this)->m_attributes[index];
  1112. return 0;
  1113. }
  1114.  
  1115. @@ -196,9 +184,8 @@ inline size_t ElementAttributeData::getAttributeItemIndex(const String& name, bo
  1116.  
  1117. // Optimize for the case where the attribute exists and its name exactly matches.
  1118. for (unsigned i = 0; i < len; ++i) {
  1119. - const QualifiedName& attrName = m_attributes[i]->name();
  1120. - if (!attrName.hasPrefix()) {
  1121. - if (name == attrName.localName())
  1122. + if (!m_attributes[i].name().hasPrefix()) {
  1123. + if (name == m_attributes[i].localName())
  1124. return i;
  1125. } else
  1126. doSlowCheck = true;
  1127. diff --git a/Source/WebCore/dom/NamedNodeMap.cpp b/Source/WebCore/dom/NamedNodeMap.cpp
  1128. index 942c40c..25b5a19 100644
  1129. --- a/Source/WebCore/dom/NamedNodeMap.cpp
  1130. +++ b/Source/WebCore/dom/NamedNodeMap.cpp
  1131. @@ -69,8 +69,10 @@ PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode
  1132. ec = NOT_FOUND_ERR;
  1133. return 0;
  1134. }
  1135. -
  1136. - return attributeData->takeAttribute(index, m_element);
  1137. +
  1138. + RefPtr<Attr> oldAttr = m_element->getOrCreateAttr(m_element->attributeItem(index)->name());
  1139. + attributeData->removeAttribute(index, m_element);
  1140. + return oldAttr.release();
  1141. }
  1142.  
  1143. PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
  1144. @@ -83,7 +85,9 @@ PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, con
  1145. return 0;
  1146. }
  1147.  
  1148. - return attributeData->takeAttribute(index, m_element);
  1149. + RefPtr<Attr> oldAttr = m_element->getOrCreateAttr(m_element->attributeItem(index)->name());
  1150. + attributeData->removeAttribute(index, m_element);
  1151. + return oldAttr.release();
  1152. }
  1153.  
  1154. PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionCode& ec)
  1155. @@ -111,7 +115,7 @@ PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
  1156. {
  1157. if (index >= length())
  1158. return 0;
  1159. - return m_element->attributeItem(index)->createAttrIfNeeded(m_element);
  1160. + return m_element->getOrCreateAttr(m_element->attributeItem(index)->name());
  1161. }
  1162.  
  1163. size_t NamedNodeMap::length() const
  1164. diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
  1165. index 0407527..1f45ef3 100644
  1166. --- a/Source/WebCore/dom/Node.cpp
  1167. +++ b/Source/WebCore/dom/Node.cpp
  1168. @@ -2094,10 +2094,10 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
  1169. // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
  1170. // when comparing two attributes of the same element, and inserting or removing additional attributes might change
  1171. // the order between existing attributes.
  1172. - Attribute* attr = owner1->attributeItem(i);
  1173. - if (attr1->attr() == attr)
  1174. + Attribute* attribute = owner1->attributeItem(i);
  1175. + if (attr1->qualifiedName() == attribute->name())
  1176. return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
  1177. - if (attr2->attr() == attr)
  1178. + if (attr2->qualifiedName() == attribute->name())
  1179. return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
  1180. }
  1181.  
  1182. diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
  1183. index 9fa5d37..02b1f36 100644
  1184. --- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp
  1185. +++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
  1186. @@ -194,7 +194,7 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
  1187. void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& token)
  1188. {
  1189. RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
  1190. - element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
  1191. + element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
  1192. attachLater(m_attachmentRoot, element);
  1193. m_openElements.pushHTMLHtmlElement(element);
  1194.  
  1195. @@ -205,12 +205,12 @@ void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& tok
  1196.  
  1197. void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken& token, Element* element)
  1198. {
  1199. - if (!token.attributes())
  1200. + if (token.attributes().isEmpty())
  1201. return;
  1202.  
  1203. ElementAttributeData* attributes = element->ensureAttributeData();
  1204. - for (unsigned i = 0; i < token.attributes()->size(); ++i) {
  1205. - Attribute* attribute = token.attributes()->attributeItem(i);
  1206. + for (unsigned i = 0; i < token.attributes().size(); ++i) {
  1207. + Attribute* attribute = token.attributes().attributeItem(i);
  1208. if (!attributes->getAttributeItem(attribute->name()))
  1209. element->setAttribute(attribute->name(), attribute->value());
  1210. }
  1211. @@ -336,7 +336,7 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken& token)
  1212. {
  1213. RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, currentNode()->document(), true);
  1214. if (m_fragmentScriptingPermission == FragmentScriptingAllowed)
  1215. - element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
  1216. + element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
  1217. attachLater(currentNode(), element);
  1218. m_openElements.push(element.release());
  1219. }
  1220. @@ -399,7 +399,7 @@ PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken& token,
  1221. {
  1222. QualifiedName tagName(nullAtom, token.name(), namespaceURI);
  1223. RefPtr<Element> element = currentNode()->document()->createElement(tagName, true);
  1224. - element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
  1225. + element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
  1226. return element.release();
  1227. }
  1228.  
  1229. @@ -410,7 +410,7 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken& tok
  1230. // have to pass the current form element. We should rework form association
  1231. // to occur after construction to allow better code sharing here.
  1232. RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, currentNode()->document(), form(), true);
  1233. - element->parserSetAttributes(token.takeAttributes(), m_fragmentScriptingPermission);
  1234. + element->parserSetAttributes(token.attributes(), m_fragmentScriptingPermission);
  1235. ASSERT(element->isHTMLElement());
  1236. return element.release();
  1237. }
  1238. @@ -420,26 +420,6 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromElementRecord(HTM
  1239. return createHTMLElementFromSavedElement(record->element());
  1240. }
  1241.  
  1242. -namespace {
  1243. -
  1244. -// FIXME: Move this function to the top of the file.
  1245. -inline PassOwnPtr<AttributeVector> cloneAttributes(Element* element)
  1246. -{
  1247. - ElementAttributeData* attributes = element->updatedAttributeData();
  1248. - if (!attributes)
  1249. - return nullptr;
  1250. -
  1251. - OwnPtr<AttributeVector> newAttributes = AttributeVector::create();
  1252. - for (size_t i = 0; i < attributes->length(); ++i) {
  1253. - Attribute* attribute = attributes->attributeItem(i);
  1254. - RefPtr<Attribute> clone = Attribute::create(attribute->name(), attribute->value());
  1255. - newAttributes->append(clone);
  1256. - }
  1257. - return newAttributes.release();
  1258. -}
  1259. -
  1260. -} // namespace
  1261. -
  1262. PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Element* element)
  1263. {
  1264. // FIXME: This method is wrong. We should be using the original token.
  1265. @@ -450,7 +430,12 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Elem
  1266. // spec implies it should be "1". Minefield matches the HTML5 spec here.
  1267.  
  1268. ASSERT(element->isHTMLElement()); // otherwise localName() might be wrong.
  1269. - AtomicHTMLToken fakeToken(HTMLTokenTypes::StartTag, element->localName(), cloneAttributes(element));
  1270. +
  1271. + AttributeVector attributes;
  1272. + if (ElementAttributeData* attributeData = element->updatedAttributeData())
  1273. + attributes = attributeData->attributeVector();
  1274. +
  1275. + AtomicHTMLToken fakeToken(HTMLTokenTypes::StartTag, element->localName(), attributes);
  1276. return createHTMLElement(fakeToken);
  1277. }
  1278.  
  1279. diff --git a/Source/WebCore/html/parser/HTMLToken.h b/Source/WebCore/html/parser/HTMLToken.h
  1280. index a391d34..686dd3a 100644
  1281. --- a/Source/WebCore/html/parser/HTMLToken.h
  1282. +++ b/Source/WebCore/html/parser/HTMLToken.h
  1283. @@ -86,7 +86,7 @@ class AtomicHTMLToken : public AtomicMarkupTokenBase<HTMLToken> {
  1284. public:
  1285. AtomicHTMLToken(HTMLToken& token) : AtomicMarkupTokenBase<HTMLToken>(&token) { }
  1286.  
  1287. - AtomicHTMLToken(HTMLTokenTypes::Type type, AtomicString name, PassOwnPtr<AttributeVector> attributes = nullptr)
  1288. + AtomicHTMLToken(HTMLTokenTypes::Type type, AtomicString name, const AttributeVector& attributes = AttributeVector())
  1289. : AtomicMarkupTokenBase<HTMLToken>(type, name, attributes)
  1290. {
  1291. }
  1292. diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
  1293. index 8062ebd..2412cd8 100644
  1294. --- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
  1295. +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
  1296. @@ -531,7 +531,7 @@ void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
  1297. parseError(token);
  1298. }
  1299.  
  1300. -void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, PassOwnPtr<AttributeVector> attributes)
  1301. +void HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, const AttributeVector& attributes)
  1302. {
  1303. // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
  1304. AtomicHTMLToken fakeToken(HTMLTokenTypes::StartTag, tagName.localName(), attributes);
  1305. @@ -560,20 +560,17 @@ void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
  1306. processEndTag(endP);
  1307. }
  1308.  
  1309. -PassOwnPtr<AttributeVector> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
  1310. +AttributeVector HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
  1311. {
  1312. - OwnPtr<AttributeVector> attributes = token.takeAttributes();
  1313. - if (!attributes)
  1314. - attributes = AttributeVector::create();
  1315. - else {
  1316. - attributes->removeAttribute(nameAttr);
  1317. - attributes->removeAttribute(actionAttr);
  1318. - attributes->removeAttribute(promptAttr);
  1319. + AttributeVector& attributes = token.attributes();
  1320. + if (!attributes.isEmpty()) {
  1321. + attributes.removeAttribute(nameAttr);
  1322. + attributes.removeAttribute(actionAttr);
  1323. + attributes.removeAttribute(promptAttr);
  1324. }
  1325.  
  1326. - RefPtr<Attribute> mappedAttribute = Attribute::create(nameAttr, isindexTag.localName());
  1327. - attributes->insertAttribute(mappedAttribute.release());
  1328. - return attributes.release();
  1329. + attributes.insertAttribute(Attribute(nameAttr, isindexTag.localName()));
  1330. + return attributes;
  1331. }
  1332.  
  1333. void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
  1334. @@ -585,12 +582,12 @@ void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
  1335. return;
  1336. notImplemented(); // Acknowledge self-closing flag
  1337. processFakeStartTag(formTag);
  1338. - RefPtr<Attribute> actionAttribute = token.getAttributeItem(actionAttr);
  1339. + Attribute* actionAttribute = token.getAttributeItem(actionAttr);
  1340. if (actionAttribute)
  1341. m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
  1342. processFakeStartTag(hrTag);
  1343. processFakeStartTag(labelTag);
  1344. - RefPtr<Attribute> promptAttribute = token.getAttributeItem(promptAttr);
  1345. + Attribute* promptAttribute = token.getAttributeItem(promptAttr);
  1346. if (promptAttribute)
  1347. processFakeCharacters(promptAttribute->value());
  1348. else
  1349. @@ -679,12 +676,8 @@ void adjustAttributes(AtomicHTMLToken& token)
  1350. mapLoweredLocalNameToName(caseMap, attrs, length);
  1351. }
  1352.  
  1353. - AttributeVector* attributes = token.attributes();
  1354. - if (!attributes)
  1355. - return;
  1356. -
  1357. - for (unsigned x = 0; x < attributes->size(); ++x) {
  1358. - Attribute* attribute = attributes->attributeItem(x);
  1359. + for (unsigned i = 0; i < token.attributes().size(); ++i) {
  1360. + Attribute* attribute = token.attributes().attributeItem(i);
  1361. const QualifiedName& casedName = caseMap->get(attribute->localName());
  1362. if (!casedName.localName().isNull())
  1363. attribute->parserSetName(casedName);
  1364. @@ -728,12 +721,8 @@ void adjustForeignAttributes(AtomicHTMLToken& token)
  1365. map->add("xmlns:xlink", QualifiedName("xmlns", "xlink", XMLNSNames::xmlnsNamespaceURI));
  1366. }
  1367.  
  1368. - AttributeVector* attributes = token.attributes();
  1369. - if (!attributes)
  1370. - return;
  1371. -
  1372. - for (unsigned x = 0; x < attributes->size(); ++x) {
  1373. - Attribute* attribute = attributes->attributeItem(x);
  1374. + for (unsigned i = 0; i < token.attributes().size(); ++i) {
  1375. + Attribute* attribute = token.attributes().attributeItem(i);
  1376. const QualifiedName& name = map->get(attribute->localName());
  1377. if (!name.localName().isNull())
  1378. attribute->parserSetName(name);
  1379. @@ -930,7 +919,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
  1380. return;
  1381. }
  1382. if (token.name() == inputTag) {
  1383. - RefPtr<Attribute> typeAttribute = token.getAttributeItem(typeAttr);
  1384. + Attribute* typeAttribute = token.getAttributeItem(typeAttr);
  1385. m_tree.reconstructTheActiveFormattingElements();
  1386. m_tree.insertSelfClosingHTMLElement(token);
  1387. if (!typeAttribute || !equalIgnoringCase(typeAttribute->value(), "hidden"))
  1388. diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h
  1389. index 35024f8..bc36a79 100644
  1390. --- a/Source/WebCore/html/parser/HTMLTreeBuilder.h
  1391. +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h
  1392. @@ -151,7 +151,7 @@ private:
  1393. void processCharacterBuffer(ExternalCharacterTokenBuffer&);
  1394. inline void processCharacterBufferForInBody(ExternalCharacterTokenBuffer&);
  1395.  
  1396. - void processFakeStartTag(const QualifiedName&, PassOwnPtr<AttributeVector> attributes = nullptr);
  1397. + void processFakeStartTag(const QualifiedName&, const AttributeVector& attributes = AttributeVector());
  1398. void processFakeEndTag(const QualifiedName&);
  1399. void processFakeCharacters(const String&);
  1400. void processFakePEndTagIfPInButtonScope();
  1401. @@ -172,7 +172,7 @@ private:
  1402. inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken&);
  1403. void processTokenInForeignContent(AtomicHTMLToken&);
  1404.  
  1405. - PassOwnPtr<AttributeVector> attributesForIsindexInput(AtomicHTMLToken&);
  1406. + AttributeVector attributesForIsindexInput(AtomicHTMLToken&);
  1407.  
  1408. HTMLElementStack::ElementRecord* furthestBlockForFormattingElement(Element*);
  1409. void callTheAdoptionAgency(AtomicHTMLToken&);
  1410. diff --git a/Source/WebCore/html/parser/TextDocumentParser.cpp b/Source/WebCore/html/parser/TextDocumentParser.cpp
  1411. index 3589c3f..742fbf7 100644
  1412. --- a/Source/WebCore/html/parser/TextDocumentParser.cpp
  1413. +++ b/Source/WebCore/html/parser/TextDocumentParser.cpp
  1414. @@ -60,10 +60,9 @@ void TextDocumentParser::insertFakePreElement()
  1415. // sending fake bytes through the front-end of the parser to avoid
  1416. // distrubing the line/column number calculations.
  1417.  
  1418. - RefPtr<Attribute> styleAttribute = Attribute::create("style", "word-wrap: break-word; white-space: pre-wrap;");
  1419. - OwnPtr<AttributeVector> attributes = AttributeVector::create();
  1420. - attributes->insertAttribute(styleAttribute.release());
  1421. - AtomicHTMLToken fakePre(HTMLTokenTypes::StartTag, preTag.localName(), attributes.release());
  1422. + AttributeVector attributes;
  1423. + attributes.insertAttribute(Attribute("style", "word-wrap: break-word; white-space: pre-wrap;"));
  1424. + AtomicHTMLToken fakePre(HTMLTokenTypes::StartTag, preTag.localName(), attributes);
  1425.  
  1426. treeBuilder()->constructTreeFromAtomicToken(fakePre);
  1427. // Normally we would skip the first \n after a <pre> element, but we don't
  1428. diff --git a/Source/WebCore/page/PageSerializer.cpp b/Source/WebCore/page/PageSerializer.cpp
  1429. index 9d50211..b7f38e0 100644
  1430. --- a/Source/WebCore/page/PageSerializer.cpp
  1431. +++ b/Source/WebCore/page/PageSerializer.cpp
  1432. @@ -159,8 +159,7 @@ void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, Ele
  1433.  
  1434. // We need to give a fake location to blank frames so they can be referenced by the serialized frame.
  1435. url = m_serializer->urlForBlankFrame(frame);
  1436. - RefPtr<Attribute> attribute = Attribute::create(frameOwnerURLAttributeName(*frameOwner), url.string());
  1437. - appendAttribute(out, element, *attribute, namespaces);
  1438. + appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwner), url.string()), namespaces);
  1439. }
  1440.  
  1441. void SerializerMarkupAccumulator::appendEndTag(Node* node)
  1442. diff --git a/Source/WebCore/svg/SVGFitToViewBox.cpp b/Source/WebCore/svg/SVGFitToViewBox.cpp
  1443. index 929167c..2c7b106 100644
  1444. --- a/Source/WebCore/svg/SVGFitToViewBox.cpp
  1445. +++ b/Source/WebCore/svg/SVGFitToViewBox.cpp
  1446. @@ -24,7 +24,7 @@
  1447. #include "SVGFitToViewBox.h"
  1448.  
  1449. #include "AffineTransform.h"
  1450. -#include "Attr.h"
  1451. +#include "Attribute.h"
  1452. #include "Document.h"
  1453. #include "FloatRect.h"
  1454. #include "SVGDocumentExtensions.h"
  1455. diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h b/Source/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h
  1456. index 6e4c487..887bc18 100644
  1457. --- a/Source/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h
  1458. +++ b/Source/WebCore/svg/properties/SVGAnimatedPropertySynchronizer.h
  1459. @@ -42,7 +42,7 @@ struct SVGAnimatedPropertySynchronizer<true> {
  1460. if (old && value.isNull())
  1461. attributeData->removeAttribute(old->name(), ownerElement);
  1462. else if (!old && !value.isNull())
  1463. - attributeData->addAttribute(Attribute::create(attrName, value), ownerElement);
  1464. + attributeData->addAttribute(Attribute(attrName, value), ownerElement);
  1465. else if (old && !value.isNull())
  1466. old->setValue(value);
  1467. }
  1468. diff --git a/Source/WebCore/xml/XMLErrors.cpp b/Source/WebCore/xml/XMLErrors.cpp
  1469. index 515772e..3851135 100644
  1470. --- a/Source/WebCore/xml/XMLErrors.cpp
  1471. +++ b/Source/WebCore/xml/XMLErrors.cpp
  1472. @@ -91,18 +91,18 @@ static inline PassRefPtr<Element> createXHTMLParserErrorHeader(Document* doc, co
  1473. {
  1474. RefPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), true);
  1475.  
  1476. - OwnPtr<AttributeVector> reportAttributes = AttributeVector::create();
  1477. - 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"));
  1478. - reportElement->parserSetAttributes(reportAttributes.release(), FragmentScriptingNotAllowed);
  1479. + AttributeVector reportAttributes;
  1480. + 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"));
  1481. + reportElement->parserSetAttributes(reportAttributes, FragmentScriptingNotAllowed);
  1482.  
  1483. RefPtr<Element> h3 = doc->createElement(h3Tag, true);
  1484. reportElement->parserAddChild(h3.get());
  1485. h3->parserAddChild(doc->createTextNode("This page contains the following errors:"));
  1486.  
  1487. RefPtr<Element> fixed = doc->createElement(divTag, true);
  1488. - OwnPtr<AttributeVector> fixedAttributes = AttributeVector::create();
  1489. - fixedAttributes->append(Attribute::create(styleAttr, "font-family:monospace;font-size:12px"));
  1490. - fixed->parserSetAttributes(fixedAttributes.release(), FragmentScriptingNotAllowed);
  1491. + AttributeVector fixedAttributes;
  1492. + fixedAttributes.append(Attribute(styleAttr, "font-family:monospace;font-size:12px"));
  1493. + fixed->parserSetAttributes(fixedAttributes, FragmentScriptingNotAllowed);
  1494. reportElement->parserAddChild(fixed.get());
  1495.  
  1496. fixed->parserAddChild(doc->createTextNode(errorMessages));
  1497. @@ -158,10 +158,10 @@ void XMLErrors::insertErrorMessageBlock()
  1498.  
  1499. #if ENABLE(XSLT)
  1500. if (m_document->transformSourceDocument()) {
  1501. - OwnPtr<AttributeVector> attributes = AttributeVector::create();
  1502. - attributes->append(Attribute::create(styleAttr, "white-space: normal"));
  1503. + AttributeVector attributes;
  1504. + attributes.append(Attribute(styleAttr, "white-space: normal"));
  1505. RefPtr<Element> paragraph = m_document->createElement(pTag, true);
  1506. - paragraph->parserSetAttributes(attributes.release(), FragmentScriptingNotAllowed);
  1507. + paragraph->parserSetAttributes(attributes, FragmentScriptingNotAllowed);
  1508. 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."));
  1509. reportElement->parserAddChild(paragraph.release());
  1510. }
  1511. diff --git a/Source/WebCore/xml/XPathNodeSet.cpp b/Source/WebCore/xml/XPathNodeSet.cpp
  1512. index f4e4d9a..a18b5df 100644
  1513. --- a/Source/WebCore/xml/XPathNodeSet.cpp
  1514. +++ b/Source/WebCore/xml/XPathNodeSet.cpp
  1515. @@ -219,9 +219,9 @@ void NodeSet::traversalSort() const
  1516.  
  1517. unsigned attributeCount = element->attributeCount();
  1518. for (unsigned i = 0; i < attributeCount; ++i) {
  1519. - Attr* attribute = element->attributeItem(i)->attr();
  1520. - if (attribute && nodes.contains(attribute))
  1521. - sortedNodes.append(attribute);
  1522. + Attr* attr = element->attributeData()->getAttr(element, element->attributeItem(i)->name());
  1523. + if (attr && nodes.contains(attr))
  1524. + sortedNodes.append(attr);
  1525. }
  1526. }
  1527.  
  1528. diff --git a/Source/WebCore/xml/XPathStep.cpp b/Source/WebCore/xml/XPathStep.cpp
  1529. index ff7e685..c7f736d 100644
  1530. --- a/Source/WebCore/xml/XPathStep.cpp
  1531. +++ b/Source/WebCore/xml/XPathStep.cpp
  1532. @@ -346,7 +346,7 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
  1533. return;
  1534.  
  1535. for (unsigned i = 0; i < contextElement->attributeCount(); ++i) {
  1536. - RefPtr<Attr> attr = contextElement->attributeItem(i)->createAttrIfNeeded(static_cast<Element*>(context));
  1537. + RefPtr<Attr> attr = contextElement->attributeData()->getOrCreateAttr(contextElement, contextElement->attributeItem(i)->name());
  1538. if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
  1539. nodes.append(attr.release());
  1540. }
  1541. diff --git a/Source/WebCore/xml/parser/MarkupTokenBase.h b/Source/WebCore/xml/parser/MarkupTokenBase.h
  1542. index 9644f40..1c96a4e 100644
  1543. --- a/Source/WebCore/xml/parser/MarkupTokenBase.h
  1544. +++ b/Source/WebCore/xml/parser/MarkupTokenBase.h
  1545. @@ -28,7 +28,6 @@
  1546. #define MarkupTokenBase_h
  1547.  
  1548. #include "ElementAttributeData.h"
  1549. -#include <wtf/PassOwnPtr.h>
  1550. #include <wtf/Vector.h>
  1551.  
  1552. #ifndef NDEBUG
  1553. @@ -410,7 +409,7 @@ public:
  1554. }
  1555. }
  1556.  
  1557. - AtomicMarkupTokenBase(typename Token::Type::Type type, AtomicString name, PassOwnPtr<AttributeVector> attributes = nullptr)
  1558. + AtomicMarkupTokenBase(typename Token::Type::Type type, AtomicString name, const AttributeVector& attributes = AttributeVector())
  1559. : m_type(type)
  1560. , m_name(name)
  1561. , m_externalCharacters(0)
  1562. @@ -442,21 +441,19 @@ public:
  1563. Attribute* getAttributeItem(const QualifiedName& attributeName)
  1564. {
  1565. ASSERT(usesAttributes());
  1566. - if (!m_attributes)
  1567. - return 0;
  1568. - return m_attributes->getAttributeItem(attributeName);
  1569. + return m_attributes.getAttributeItem(attributeName);
  1570. }
  1571.  
  1572. - AttributeVector* attributes() const
  1573. + AttributeVector& attributes()
  1574. {
  1575. ASSERT(usesAttributes());
  1576. - return m_attributes.get();
  1577. + return m_attributes;
  1578. }
  1579.  
  1580. - PassOwnPtr<AttributeVector> takeAttributes()
  1581. + const AttributeVector& attributes() const
  1582. {
  1583. ASSERT(usesAttributes());
  1584. - return m_attributes.release();
  1585. + return m_attributes;
  1586. }
  1587.  
  1588. const typename Token::DataVector& characters() const
  1589. @@ -517,7 +514,7 @@ protected:
  1590. // For StartTag and EndTag
  1591. bool m_selfClosing;
  1592.  
  1593. - OwnPtr<AttributeVector> m_attributes;
  1594. + AttributeVector m_attributes;
  1595. };
  1596.  
  1597. template<typename Token>
  1598. @@ -527,8 +524,8 @@ inline void AtomicMarkupTokenBase<Token>::initializeAttributes(const typename To
  1599. if (!size)
  1600. return;
  1601.  
  1602. - m_attributes = AttributeVector::create();
  1603. - m_attributes->reserveInitialCapacity(size);
  1604. + m_attributes.clear();
  1605. + m_attributes.reserveInitialCapacity(size);
  1606. for (size_t i = 0; i < size; ++i) {
  1607. const typename Token::Attribute& attribute = attributes[i];
  1608. if (attribute.m_name.isEmpty())
  1609. @@ -542,7 +539,7 @@ inline void AtomicMarkupTokenBase<Token>::initializeAttributes(const typename To
  1610. ASSERT(attribute.m_valueRange.m_end);
  1611.  
  1612. AtomicString value(attribute.m_value.data(), attribute.m_value.size());
  1613. - m_attributes->insertAttribute(Attribute::create(nameForAttribute(attribute), value));
  1614. + m_attributes.insertAttribute(Attribute(nameForAttribute(attribute), value));
  1615. }
  1616. }
  1617.  
  1618. diff --git a/Source/WebCore/xml/parser/XMLToken.h b/Source/WebCore/xml/parser/XMLToken.h
  1619. index 1ed16ca..6e14a11 100644
  1620. --- a/Source/WebCore/xml/parser/XMLToken.h
  1621. +++ b/Source/WebCore/xml/parser/XMLToken.h
  1622. @@ -431,7 +431,7 @@ public:
  1623. }
  1624. }
  1625.  
  1626. - AtomicXMLToken(XMLTokenTypes::Type type, AtomicString name, PassOwnPtr<AttributeVector> attributes = nullptr)
  1627. + AtomicXMLToken(XMLTokenTypes::Type type, AtomicString name, const AttributeVector& attributes = AttributeVector())
  1628. : AtomicMarkupTokenBase<XMLToken>(type, name, attributes)
  1629. {
  1630. }
  1631. diff --git a/Source/WebCore/xml/parser/XMLTreeBuilder.cpp b/Source/WebCore/xml/parser/XMLTreeBuilder.cpp
  1632. index 81793ed..e783bd2 100644
  1633. --- a/Source/WebCore/xml/parser/XMLTreeBuilder.cpp
  1634. +++ b/Source/WebCore/xml/parser/XMLTreeBuilder.cpp
  1635. @@ -298,11 +298,8 @@ void XMLTreeBuilder::processEntity(const AtomicXMLToken& token)
  1636.  
  1637. void XMLTreeBuilder::processNamespaces(const AtomicXMLToken& token, NodeStackItem& stackItem)
  1638. {
  1639. - if (!token.attributes())
  1640. - return;
  1641. -
  1642. - for (size_t i = 0; i < token.attributes()->size(); ++i) {
  1643. - Attribute* attribute = token.attributes()->attributeItem(i);
  1644. + for (unsigned i = 0; i < token.attributes().size(); ++i) {
  1645. + Attribute* attribute = token.attributes().attributeItem(i);
  1646. if (attribute->name().prefix() == xmlnsAtom)
  1647. stackItem.setNamespaceURI(attribute->name().localName(), attribute->value());
  1648. else if (attribute->name() == xmlnsAtom)
  1649. @@ -312,11 +309,8 @@ void XMLTreeBuilder::processNamespaces(const AtomicXMLToken& token, NodeStackIte
  1650.  
  1651. void XMLTreeBuilder::processAttributes(const AtomicXMLToken& token, NodeStackItem& stackItem, PassRefPtr<Element> newElement)
  1652. {
  1653. - if (!token.attributes())
  1654. - return;
  1655. -
  1656. - for (size_t i = 0; i < token.attributes()->size(); ++i) {
  1657. - Attribute* attribute = token.attributes()->attributeItem(i);
  1658. + for (unsigned i = 0; i < token.attributes().size(); ++i) {
  1659. + Attribute* attribute = token.attributes().attributeItem(i);
  1660. ExceptionCode ec = 0;
  1661. if (attribute->name().prefix() == xmlnsAtom)
  1662. newElement->setAttributeNS(XMLNSNames::xmlnsNamespaceURI, "xmlns:" + attribute->name().localName(), attribute->value(), ec);
Add Comment
Please, Sign In to add comment