OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights
reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights
reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 , m_name(name) | 42 , m_name(name) |
43 , m_ignoreChildrenChanged(0) | 43 , m_ignoreChildrenChanged(0) |
44 { | 44 { |
45 ScriptWrappable::init(this); | 45 ScriptWrappable::init(this); |
46 } | 46 } |
47 | 47 |
48 Attr::Attr(Document& document, const QualifiedName& name, const AtomicString& st
andaloneValue) | 48 Attr::Attr(Document& document, const QualifiedName& name, const AtomicString& st
andaloneValue) |
49 : ContainerNode(&document) | 49 : ContainerNode(&document) |
50 , m_element(nullptr) | 50 , m_element(nullptr) |
51 , m_name(name) | 51 , m_name(name) |
52 , m_standaloneValue(standaloneValue) | 52 , m_standaloneValueOrAttachedLocalName(standaloneValue) |
53 , m_ignoreChildrenChanged(0) | 53 , m_ignoreChildrenChanged(0) |
54 { | 54 { |
55 ScriptWrappable::init(this); | 55 ScriptWrappable::init(this); |
56 } | 56 } |
57 | 57 |
58 PassRefPtrWillBeRawPtr<Attr> Attr::create(Element& element, const QualifiedName&
name) | 58 PassRefPtrWillBeRawPtr<Attr> Attr::create(Element& element, const QualifiedName&
name) |
59 { | 59 { |
60 RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeRefCountedGarbageCollected(new
Attr(element, name)); | 60 RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeRefCountedGarbageCollected(new
Attr(element, name)); |
61 attr->createTextChild(); | 61 attr->createTextChild(); |
62 return attr.release(); | 62 return attr.release(); |
63 } | 63 } |
64 | 64 |
65 PassRefPtrWillBeRawPtr<Attr> Attr::create(Document& document, const QualifiedNam
e& name, const AtomicString& value) | 65 PassRefPtrWillBeRawPtr<Attr> Attr::create(Document& document, const QualifiedNam
e& name, const AtomicString& value) |
66 { | 66 { |
67 RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeRefCountedGarbageCollected(new
Attr(document, name, value)); | 67 RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeRefCountedGarbageCollected(new
Attr(document, name, value)); |
68 attr->createTextChild(); | 68 attr->createTextChild(); |
69 return attr.release(); | 69 return attr.release(); |
70 } | 70 } |
71 | 71 |
72 Attr::~Attr() | 72 Attr::~Attr() |
73 { | 73 { |
74 } | 74 } |
75 | 75 |
| 76 const QualifiedName Attr::qualifiedName() const |
| 77 { |
| 78 if (m_element && !m_standaloneValueOrAttachedLocalName.isNull()) { |
| 79 // In the unlikely case the Element attribute has a local name |
| 80 // that differs by case, construct the qualified name based on |
| 81 // it. This is the qualified name that must be used when |
| 82 // looking up the attribute on the element. |
| 83 return QualifiedName(m_name.prefix(), m_standaloneValueOrAttachedLocalNa
me, m_name.namespaceURI()); |
| 84 } |
| 85 |
| 86 return m_name; |
| 87 } |
| 88 |
76 void Attr::createTextChild() | 89 void Attr::createTextChild() |
77 { | 90 { |
78 #if !ENABLE(OILPAN) | 91 #if !ENABLE(OILPAN) |
79 ASSERT(refCount()); | 92 ASSERT(refCount()); |
80 #endif | 93 #endif |
81 if (!value().isEmpty()) { | 94 if (!value().isEmpty()) { |
82 RefPtrWillBeRawPtr<Text> textNode = document().createTextNode(value().st
ring()); | 95 RefPtrWillBeRawPtr<Text> textNode = document().createTextNode(value().st
ring()); |
83 | 96 |
84 // This does everything appendChild() would do in this situation (assumi
ng m_ignoreChildrenChanged was set), | 97 // This does everything appendChild() would do in this situation (assumi
ng m_ignoreChildrenChanged was set), |
85 // but much more efficiently. | 98 // but much more efficiently. |
86 textNode->setParentOrShadowHostNode(this); | 99 textNode->setParentOrShadowHostNode(this); |
87 treeScope().adoptIfNeeded(*textNode); | 100 treeScope().adoptIfNeeded(*textNode); |
88 setFirstChild(textNode.get()); | 101 setFirstChild(textNode.get()); |
89 setLastChild(textNode.get()); | 102 setLastChild(textNode.get()); |
90 } | 103 } |
91 } | 104 } |
92 | 105 |
93 void Attr::setValue(const AtomicString& value) | 106 void Attr::setValue(const AtomicString& value) |
94 { | 107 { |
95 EventQueueScope scope; | 108 EventQueueScope scope; |
96 m_ignoreChildrenChanged++; | 109 m_ignoreChildrenChanged++; |
97 removeChildren(); | 110 removeChildren(); |
98 if (m_element) | 111 if (m_element) |
99 elementAttribute().setValue(value); | 112 elementAttribute().setValue(value); |
100 else | 113 else |
101 m_standaloneValue = value; | 114 m_standaloneValueOrAttachedLocalName = value; |
102 createTextChild(); | 115 createTextChild(); |
103 m_ignoreChildrenChanged--; | 116 m_ignoreChildrenChanged--; |
104 | 117 |
105 invalidateNodeListCachesInAncestors(&m_name, m_element); | 118 QualifiedName name = qualifiedName(); |
| 119 invalidateNodeListCachesInAncestors(&name, m_element); |
106 } | 120 } |
107 | 121 |
108 void Attr::setValueInternal(const AtomicString& value) | 122 void Attr::setValueInternal(const AtomicString& value) |
109 { | 123 { |
110 if (m_element) | 124 if (m_element) |
111 m_element->willModifyAttribute(qualifiedName(), this->value(), value); | 125 m_element->willModifyAttribute(qualifiedName(), this->value(), value); |
112 | 126 |
113 setValue(value); | 127 setValue(value); |
114 | 128 |
115 if (m_element) | 129 if (m_element) |
(...skipping 16 matching lines...) Expand all Loading... |
132 | 146 |
133 void Attr::setNodeValue(const String& v) | 147 void Attr::setNodeValue(const String& v) |
134 { | 148 { |
135 // Attr uses AtomicString type for its value to save memory as there | 149 // Attr uses AtomicString type for its value to save memory as there |
136 // is duplication among Elements' attributes values. | 150 // is duplication among Elements' attributes values. |
137 setValueInternal(AtomicString(v)); | 151 setValueInternal(AtomicString(v)); |
138 } | 152 } |
139 | 153 |
140 PassRefPtrWillBeRawPtr<Node> Attr::cloneNode(bool /*deep*/) | 154 PassRefPtrWillBeRawPtr<Node> Attr::cloneNode(bool /*deep*/) |
141 { | 155 { |
142 RefPtrWillBeRawPtr<Attr> clone = adoptRefWillBeRefCountedGarbageCollected(ne
w Attr(document(), qualifiedName(), value())); | 156 RefPtrWillBeRawPtr<Attr> clone = adoptRefWillBeRefCountedGarbageCollected(ne
w Attr(document(), m_name, value())); |
143 cloneChildNodes(clone.get()); | 157 cloneChildNodes(clone.get()); |
144 return clone.release(); | 158 return clone.release(); |
145 } | 159 } |
146 | 160 |
147 // DOM Section 1.1.1 | 161 // DOM Section 1.1.1 |
148 bool Attr::childTypeAllowed(NodeType type) const | 162 bool Attr::childTypeAllowed(NodeType type) const |
149 { | 163 { |
150 return TEXT_NODE == type; | 164 return TEXT_NODE == type; |
151 } | 165 } |
152 | 166 |
153 void Attr::childrenChanged(bool, Node*, Node*, int) | 167 void Attr::childrenChanged(bool, Node*, Node*, int) |
154 { | 168 { |
155 if (m_ignoreChildrenChanged > 0) | 169 if (m_ignoreChildrenChanged > 0) |
156 return; | 170 return; |
157 | 171 |
158 invalidateNodeListCachesInAncestors(&qualifiedName(), m_element); | 172 QualifiedName name = qualifiedName(); |
| 173 invalidateNodeListCachesInAncestors(&name, m_element); |
159 | 174 |
160 StringBuilder valueBuilder; | 175 StringBuilder valueBuilder; |
161 for (Node *n = firstChild(); n; n = n->nextSibling()) { | 176 for (Node *n = firstChild(); n; n = n->nextSibling()) { |
162 if (n->isTextNode()) | 177 if (n->isTextNode()) |
163 valueBuilder.append(toText(n)->data()); | 178 valueBuilder.append(toText(n)->data()); |
164 } | 179 } |
165 | 180 |
166 AtomicString newValue = valueBuilder.toAtomicString(); | 181 AtomicString newValue = valueBuilder.toAtomicString(); |
167 if (m_element) | 182 if (m_element) |
168 m_element->willModifyAttribute(qualifiedName(), value(), newValue); | 183 m_element->willModifyAttribute(qualifiedName(), value(), newValue); |
169 | 184 |
170 if (m_element) | 185 if (m_element) |
171 elementAttribute().setValue(newValue); | 186 elementAttribute().setValue(newValue); |
172 else | 187 else |
173 m_standaloneValue = newValue; | 188 m_standaloneValueOrAttachedLocalName = newValue; |
174 | 189 |
175 if (m_element) | 190 if (m_element) |
176 m_element->attributeChanged(qualifiedName(), newValue); | 191 m_element->attributeChanged(qualifiedName(), newValue); |
177 } | 192 } |
178 | 193 |
179 const AtomicString& Attr::value() const | 194 const AtomicString& Attr::value() const |
180 { | 195 { |
181 if (m_element) | 196 if (m_element) |
182 return m_element->getAttribute(qualifiedName()); | 197 return m_element->getAttribute(qualifiedName()); |
183 return m_standaloneValue; | 198 return m_standaloneValueOrAttachedLocalName; |
184 } | 199 } |
185 | 200 |
186 Attribute& Attr::elementAttribute() | 201 Attribute& Attr::elementAttribute() |
187 { | 202 { |
188 ASSERT(m_element); | 203 ASSERT(m_element); |
189 ASSERT(m_element->elementData()); | 204 ASSERT(m_element->elementData()); |
190 return *m_element->ensureUniqueElementData().getAttributeItem(qualifiedName(
)); | 205 return *m_element->ensureUniqueElementData().getAttributeItem(qualifiedName(
)); |
191 } | 206 } |
192 | 207 |
193 void Attr::detachFromElementWithValue(const AtomicString& value) | 208 void Attr::detachFromElementWithValue(const AtomicString& value) |
194 { | 209 { |
195 ASSERT(m_element); | 210 ASSERT(m_element); |
196 ASSERT(m_standaloneValue.isNull()); | 211 m_standaloneValueOrAttachedLocalName = value; |
197 m_standaloneValue = value; | |
198 m_element = nullptr; | 212 m_element = nullptr; |
199 } | 213 } |
200 | 214 |
201 void Attr::attachToElement(Element* element) | 215 void Attr::attachToElement(Element* element, const AtomicString& attachedLocalNa
me) |
202 { | 216 { |
203 ASSERT(!m_element); | 217 ASSERT(!m_element); |
204 m_element = element; | 218 m_element = element; |
205 m_standaloneValue = nullAtom; | 219 m_standaloneValueOrAttachedLocalName = attachedLocalName; |
206 } | 220 } |
207 | 221 |
208 void Attr::trace(Visitor* visitor) | 222 void Attr::trace(Visitor* visitor) |
209 { | 223 { |
210 visitor->trace(m_element); | 224 visitor->trace(m_element); |
211 ContainerNode::trace(visitor); | 225 ContainerNode::trace(visitor); |
212 } | 226 } |
213 | 227 |
214 } | 228 } |
OLD | NEW |