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 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. |
8 * (C) 2007 Eric Seidel (eric@webkit.org) | 8 * (C) 2007 Eric Seidel (eric@webkit.org) |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "core/css/resolver/StyleResolver.h" | 42 #include "core/css/resolver/StyleResolver.h" |
43 #include "core/dom/Attr.h" | 43 #include "core/dom/Attr.h" |
44 #include "core/dom/ClientRect.h" | 44 #include "core/dom/ClientRect.h" |
45 #include "core/dom/ClientRectList.h" | 45 #include "core/dom/ClientRectList.h" |
46 #include "core/dom/ElementDataCache.h" | 46 #include "core/dom/ElementDataCache.h" |
47 #include "core/dom/ElementRareData.h" | 47 #include "core/dom/ElementRareData.h" |
48 #include "core/dom/ElementTraversal.h" | 48 #include "core/dom/ElementTraversal.h" |
49 #include "core/dom/ExceptionCode.h" | 49 #include "core/dom/ExceptionCode.h" |
50 #include "core/dom/MutationObserverInterestGroup.h" | 50 #include "core/dom/MutationObserverInterestGroup.h" |
51 #include "core/dom/MutationRecord.h" | 51 #include "core/dom/MutationRecord.h" |
52 #include "core/dom/NamedNodeMap.h" | |
53 #include "core/dom/NodeRenderStyle.h" | 52 #include "core/dom/NodeRenderStyle.h" |
54 #include "core/dom/RenderTreeBuilder.h" | 53 #include "core/dom/RenderTreeBuilder.h" |
55 #include "core/dom/SelectorQuery.h" | 54 #include "core/dom/SelectorQuery.h" |
56 #include "core/dom/StyleEngine.h" | 55 #include "core/dom/StyleEngine.h" |
57 #include "core/dom/Text.h" | 56 #include "core/dom/Text.h" |
58 #include "core/dom/custom/CustomElement.h" | 57 #include "core/dom/custom/CustomElement.h" |
59 #include "core/dom/custom/CustomElementRegistrationContext.h" | 58 #include "core/dom/custom/CustomElementRegistrationContext.h" |
60 #include "core/dom/shadow/InsertionPoint.h" | 59 #include "core/dom/shadow/InsertionPoint.h" |
61 #include "core/dom/shadow/ShadowRoot.h" | 60 #include "core/dom/shadow/ShadowRoot.h" |
62 #include "core/editing/FrameSelection.h" | 61 #include "core/editing/FrameSelection.h" |
(...skipping 25 matching lines...) Expand all Loading... |
88 #include "platform/UserGestureIndicator.h" | 87 #include "platform/UserGestureIndicator.h" |
89 #include "platform/scroll/ScrollableArea.h" | 88 #include "platform/scroll/ScrollableArea.h" |
90 #include "wtf/BitVector.h" | 89 #include "wtf/BitVector.h" |
91 #include "wtf/HashFunctions.h" | 90 #include "wtf/HashFunctions.h" |
92 #include "wtf/text/CString.h" | 91 #include "wtf/text/CString.h" |
93 #include "wtf/text/StringBuilder.h" | 92 #include "wtf/text/StringBuilder.h" |
94 #include "wtf/text/TextPosition.h" | 93 #include "wtf/text/TextPosition.h" |
95 | 94 |
96 namespace blink { | 95 namespace blink { |
97 | 96 |
98 typedef Vector<RefPtr<Attr> > AttrNodeList; | |
99 | |
100 static Attr* findAttrNodeInList(const AttrNodeList& attrNodeList, const Qualifie
dName& name) | |
101 { | |
102 AttrNodeList::const_iterator end = attrNodeList.end(); | |
103 for (AttrNodeList::const_iterator it = attrNodeList.begin(); it != end; ++it
) { | |
104 if ((*it)->name() == name.localName()) | |
105 return it->get(); | |
106 } | |
107 return 0; | |
108 } | |
109 | |
110 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* docu
ment) | 97 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* docu
ment) |
111 { | 98 { |
112 return adoptRef(new Element(tagName, document, CreateElement)); | 99 return adoptRef(new Element(tagName, document, CreateElement)); |
113 } | 100 } |
114 | 101 |
115 Element::Element(const QualifiedName& tagName, Document* document, ConstructionT
ype type) | 102 Element::Element(const QualifiedName& tagName, Document* document, ConstructionT
ype type) |
116 : ContainerNode(document, type) | 103 : ContainerNode(document, type) |
117 , m_tagName(tagName) | 104 , m_tagName(tagName) |
118 { | 105 { |
119 ScriptWrappable::init(this); | 106 ScriptWrappable::init(this); |
120 } | 107 } |
121 | 108 |
122 Element::~Element() | 109 Element::~Element() |
123 { | 110 { |
124 ASSERT(needsAttach()); | 111 ASSERT(needsAttach()); |
125 | 112 |
126 #if !ENABLE(OILPAN) | 113 #if !ENABLE(OILPAN) |
127 if (hasRareData()) | 114 if (hasRareData()) |
128 elementRareData()->clearShadow(); | 115 elementRareData()->clearShadow(); |
129 | 116 |
130 if (isCustomElement()) | 117 if (isCustomElement()) |
131 CustomElement::wasDestroyed(this); | 118 CustomElement::wasDestroyed(this); |
132 | |
133 if (hasSyntheticAttrChildNodes()) | |
134 detachAllAttrNodesFromElement(); | |
135 #endif | 119 #endif |
136 } | 120 } |
137 | 121 |
138 inline ElementRareData* Element::elementRareData() const | 122 inline ElementRareData* Element::elementRareData() const |
139 { | 123 { |
140 ASSERT(hasRareData()); | 124 ASSERT(hasRareData()); |
141 return static_cast<ElementRareData*>(rareData()); | 125 return static_cast<ElementRareData*>(rareData()); |
142 } | 126 } |
143 | 127 |
144 inline ElementRareData& Element::ensureElementRareData() | 128 inline ElementRareData& Element::ensureElementRareData() |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 } | 235 } |
252 | 236 |
253 void Element::setBooleanAttribute(const QualifiedName& name, bool value) | 237 void Element::setBooleanAttribute(const QualifiedName& name, bool value) |
254 { | 238 { |
255 if (value) | 239 if (value) |
256 setAttribute(name, emptyAtom); | 240 setAttribute(name, emptyAtom); |
257 else | 241 else |
258 removeAttribute(name); | 242 removeAttribute(name); |
259 } | 243 } |
260 | 244 |
261 NamedNodeMap* Element::attributesForBindings() const | |
262 { | |
263 ElementRareData& rareData = const_cast<Element*>(this)->ensureElementRareDat
a(); | |
264 if (NamedNodeMap* attributeMap = rareData.attributeMap()) | |
265 return attributeMap; | |
266 | |
267 rareData.setAttributeMap(NamedNodeMap::create(const_cast<Element*>(this))); | |
268 return rareData.attributeMap(); | |
269 } | |
270 | |
271 ActiveAnimations* Element::activeAnimations() const | 245 ActiveAnimations* Element::activeAnimations() const |
272 { | 246 { |
273 if (hasRareData()) | 247 if (hasRareData()) |
274 return elementRareData()->activeAnimations(); | 248 return elementRareData()->activeAnimations(); |
275 return 0; | 249 return 0; |
276 } | 250 } |
277 | 251 |
278 ActiveAnimations& Element::ensureActiveAnimations() | 252 ActiveAnimations& Element::ensureActiveAnimations() |
279 { | 253 { |
280 ElementRareData& rareData = ensureElementRareData(); | 254 ElementRareData& rareData = ensureElementRareData(); |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 if (result.length() > 0) | 1198 if (result.length() > 0) |
1225 result.appendLiteral("; "); | 1199 result.appendLiteral("; "); |
1226 result.appendLiteral("class="); | 1200 result.appendLiteral("class="); |
1227 result.append(s); | 1201 result.append(s); |
1228 } | 1202 } |
1229 | 1203 |
1230 strncpy(buffer, result.toString().utf8().data(), length - 1); | 1204 strncpy(buffer, result.toString().utf8().data(), length - 1); |
1231 } | 1205 } |
1232 #endif | 1206 #endif |
1233 | 1207 |
1234 Vector<RefPtr<Attr> >* Element::attrNodeList() | |
1235 { | |
1236 return hasRareData() ? elementRareData()->attrNodeList() : 0; | |
1237 } | |
1238 | |
1239 Vector<RefPtr<Attr> >& Element::ensureAttrNodeList() | |
1240 { | |
1241 setHasSyntheticAttrChildNodes(true); | |
1242 return ensureElementRareData().ensureAttrNodeList(); | |
1243 } | |
1244 | |
1245 void Element::removeAttrNodeList() | |
1246 { | |
1247 ASSERT(hasSyntheticAttrChildNodes()); | |
1248 if (hasRareData()) | |
1249 elementRareData()->removeAttrNodeList(); | |
1250 setHasSyntheticAttrChildNodes(false); | |
1251 } | |
1252 | |
1253 void Element::parseAttribute(const QualifiedName& name, const AtomicString& valu
e) | 1208 void Element::parseAttribute(const QualifiedName& name, const AtomicString& valu
e) |
1254 { | 1209 { |
1255 if (name == HTMLNames::tabindexAttr) { | 1210 if (name == HTMLNames::tabindexAttr) { |
1256 int tabindex = 0; | 1211 int tabindex = 0; |
1257 if (value.isEmpty()) { | 1212 if (value.isEmpty()) { |
1258 clearTabIndexExplicitlyIfNeeded(); | 1213 clearTabIndexExplicitlyIfNeeded(); |
1259 if (treeScope().adjustedFocusedElement() == this) { | 1214 if (treeScope().adjustedFocusedElement() == this) { |
1260 // We might want to call blur(), but it's dangerous to dispatch | 1215 // We might want to call blur(), but it's dangerous to dispatch |
1261 // events here. | 1216 // events here. |
1262 document().setNeedsFocusedElementCheck(); | 1217 document().setNeedsFocusedElementCheck(); |
(...skipping 23 matching lines...) Expand all Loading... |
1286 ASSERT_WITH_SECURITY_IMPLICATION(index < attributes.size()); | 1241 ASSERT_WITH_SECURITY_IMPLICATION(index < attributes.size()); |
1287 | 1242 |
1288 QualifiedName name = attributes[index].name(); | 1243 QualifiedName name = attributes[index].name(); |
1289 AtomicString valueBeingRemoved = attributes[index].value(); | 1244 AtomicString valueBeingRemoved = attributes[index].value(); |
1290 | 1245 |
1291 if (!inSynchronizationOfLazyAttribute) { | 1246 if (!inSynchronizationOfLazyAttribute) { |
1292 if (!valueBeingRemoved.isNull()) | 1247 if (!valueBeingRemoved.isNull()) |
1293 willModifyAttribute(name, valueBeingRemoved, nullAtom); | 1248 willModifyAttribute(name, valueBeingRemoved, nullAtom); |
1294 } | 1249 } |
1295 | 1250 |
1296 if (RefPtr<Attr> attrNode = attrIfExists(name)) | |
1297 attrNode->detachFromElement(); | |
1298 | |
1299 attributes.remove(index); | 1251 attributes.remove(index); |
1300 | 1252 |
1301 if (!inSynchronizationOfLazyAttribute) | 1253 if (!inSynchronizationOfLazyAttribute) |
1302 attributeChanged(name, nullAtom); | 1254 attributeChanged(name, nullAtom); |
1303 } | 1255 } |
1304 | 1256 |
1305 void Element::appendAttributeInternal(const QualifiedName& name, const AtomicStr
ing& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute) | 1257 void Element::appendAttributeInternal(const QualifiedName& name, const AtomicStr
ing& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute) |
1306 { | 1258 { |
1307 if (!inSynchronizationOfLazyAttribute) | 1259 if (!inSynchronizationOfLazyAttribute) |
1308 willModifyAttribute(name, nullAtom, value); | 1260 willModifyAttribute(name, nullAtom, value); |
(...skipping 17 matching lines...) Expand all Loading... |
1326 removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute); | 1278 removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute); |
1327 } | 1279 } |
1328 | 1280 |
1329 Vector<RefPtr<Attr>> Element::getAttributes() | 1281 Vector<RefPtr<Attr>> Element::getAttributes() |
1330 { | 1282 { |
1331 if (!elementData()) | 1283 if (!elementData()) |
1332 return Vector<RefPtr<Attr>>(); | 1284 return Vector<RefPtr<Attr>>(); |
1333 synchronizeAllAttributes(); | 1285 synchronizeAllAttributes(); |
1334 Vector<RefPtr<Attr>> attributes; | 1286 Vector<RefPtr<Attr>> attributes; |
1335 for (const Attribute& attribute : elementData()->attributes()) | 1287 for (const Attribute& attribute : elementData()->attributes()) |
1336 attributes.append(ensureAttr(attribute.name())); | 1288 attributes.append(Attr::create(attribute.name(), attribute.value())); |
1337 return attributes; | 1289 return attributes; |
1338 } | 1290 } |
1339 | 1291 |
1340 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName) | |
1341 { | |
1342 if (!elementData()) | |
1343 return nullptr; | |
1344 synchronizeAttribute(localName); | |
1345 const Attribute* attribute = elementData()->attributes().find(localName); | |
1346 if (!attribute) | |
1347 return nullptr; | |
1348 return ensureAttr(attribute->name()); | |
1349 } | |
1350 | |
1351 void Element::focus(bool restorePreviousSelection, FocusType type) | 1292 void Element::focus(bool restorePreviousSelection, FocusType type) |
1352 { | 1293 { |
1353 if (!inDocument()) | 1294 if (!inDocument()) |
1354 return; | 1295 return; |
1355 | 1296 |
1356 if (document().focusedElement() == this) | 1297 if (document().focusedElement() == this) |
1357 return; | 1298 return; |
1358 | 1299 |
1359 if (!document().isActive()) | 1300 if (!document().isActive()) |
1360 return; | 1301 return; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 } while (n && value.isNull()); | 1550 } while (n && value.isNull()); |
1610 | 1551 |
1611 return value; | 1552 return value; |
1612 } | 1553 } |
1613 | 1554 |
1614 Locale& Element::locale() const | 1555 Locale& Element::locale() const |
1615 { | 1556 { |
1616 return document().getCachedLocale(computeInheritedLanguage()); | 1557 return document().getCachedLocale(computeInheritedLanguage()); |
1617 } | 1558 } |
1618 | 1559 |
1619 void Element::normalizeAttributes() | |
1620 { | |
1621 if (!hasAttributes()) | |
1622 return; | |
1623 Vector<RefPtr<Attr> >* attrNodes = attrNodeList(); | |
1624 if (!attrNodes) | |
1625 return; | |
1626 // Copy the Attr Vector because Node::normalize() can fire synchronous JS | |
1627 // events (e.g. DOMSubtreeModified) and a JS listener could add / remove | |
1628 // attributes while we are iterating. | |
1629 Vector<RefPtr<Attr> > attrNodesCopy(*attrNodes); | |
1630 for (size_t i = 0; i < attrNodesCopy.size(); ++i) | |
1631 attrNodesCopy[i]->normalize(); | |
1632 } | |
1633 | |
1634 bool Element::matches(const String& selectors, ExceptionState& exceptionState) | 1560 bool Element::matches(const String& selectors, ExceptionState& exceptionState) |
1635 { | 1561 { |
1636 SelectorQuery* selectorQuery = document().selectorQueryCache().add(AtomicStr
ing(selectors), document(), exceptionState); | 1562 SelectorQuery* selectorQuery = document().selectorQueryCache().add(AtomicStr
ing(selectors), document(), exceptionState); |
1637 if (!selectorQuery) | 1563 if (!selectorQuery) |
1638 return false; | 1564 return false; |
1639 return selectorQuery->matches(*this); | 1565 return selectorQuery->matches(*this); |
1640 } | 1566 } |
1641 | 1567 |
1642 DOMTokenList& Element::classList() | 1568 DOMTokenList& Element::classList() |
1643 { | 1569 { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 case SpellcheckAttributeFalse: | 1664 case SpellcheckAttributeFalse: |
1739 return false; | 1665 return false; |
1740 case SpellcheckAttributeDefault: | 1666 case SpellcheckAttributeDefault: |
1741 break; | 1667 break; |
1742 } | 1668 } |
1743 } | 1669 } |
1744 | 1670 |
1745 return true; | 1671 return true; |
1746 } | 1672 } |
1747 | 1673 |
1748 #ifdef DUMP_NODE_STATISTICS | |
1749 bool Element::hasNamedNodeMap() const | |
1750 { | |
1751 return hasRareData() && elementRareData()->attributeMap(); | |
1752 } | |
1753 #endif | |
1754 | |
1755 inline void Element::updateId(const AtomicString& oldId, const AtomicString& new
Id) | 1674 inline void Element::updateId(const AtomicString& oldId, const AtomicString& new
Id) |
1756 { | 1675 { |
1757 if (!isInTreeScope()) | 1676 if (!isInTreeScope()) |
1758 return; | 1677 return; |
1759 | 1678 |
1760 if (oldId == newId) | 1679 if (oldId == newId) |
1761 return; | 1680 return; |
1762 | 1681 |
1763 updateId(treeScope(), oldId, newId); | 1682 updateId(treeScope(), oldId, newId); |
1764 } | 1683 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize
(); | 1751 return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize
(); |
1833 } | 1752 } |
1834 | 1753 |
1835 void Element::setSavedLayerScrollOffset(const IntSize& size) | 1754 void Element::setSavedLayerScrollOffset(const IntSize& size) |
1836 { | 1755 { |
1837 if (size.isZero() && !hasRareData()) | 1756 if (size.isZero() && !hasRareData()) |
1838 return; | 1757 return; |
1839 ensureElementRareData().setSavedLayerScrollOffset(size); | 1758 ensureElementRareData().setSavedLayerScrollOffset(size); |
1840 } | 1759 } |
1841 | 1760 |
1842 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name) | |
1843 { | |
1844 if (AttrNodeList* attrNodeList = this->attrNodeList()) | |
1845 return findAttrNodeInList(*attrNodeList, name); | |
1846 return nullptr; | |
1847 } | |
1848 | |
1849 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name) | |
1850 { | |
1851 AttrNodeList& attrNodeList = ensureAttrNodeList(); | |
1852 RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name); | |
1853 if (!attrNode) { | |
1854 attrNode = Attr::create(*this, name); | |
1855 treeScope().adoptIfNeeded(*attrNode); | |
1856 attrNodeList.append(attrNode); | |
1857 } | |
1858 return attrNode.release(); | |
1859 } | |
1860 | |
1861 void Element::detachAllAttrNodesFromElement() | |
1862 { | |
1863 AttrNodeList* list = this->attrNodeList(); | |
1864 ASSERT(list); | |
1865 | |
1866 for (unsigned i = 0; i < list->size(); ++i) | |
1867 list->at(i)->detachFromElement(); | |
1868 removeAttrNodeList(); | |
1869 } | |
1870 | |
1871 void Element::willRecalcStyle(StyleRecalcChange) | 1761 void Element::willRecalcStyle(StyleRecalcChange) |
1872 { | 1762 { |
1873 ASSERT(hasCustomStyleCallbacks()); | 1763 ASSERT(hasCustomStyleCallbacks()); |
1874 } | 1764 } |
1875 | 1765 |
1876 void Element::didRecalcStyle(StyleRecalcChange) | 1766 void Element::didRecalcStyle(StyleRecalcChange) |
1877 { | 1767 { |
1878 ASSERT(hasCustomStyleCallbacks()); | 1768 ASSERT(hasCustomStyleCallbacks()); |
1879 } | 1769 } |
1880 | 1770 |
1881 | 1771 |
1882 PassRefPtr<RenderStyle> Element::customStyleForRenderer() | 1772 PassRefPtr<RenderStyle> Element::customStyleForRenderer() |
1883 { | 1773 { |
1884 ASSERT(hasCustomStyleCallbacks()); | 1774 ASSERT(hasCustomStyleCallbacks()); |
1885 return nullptr; | 1775 return nullptr; |
1886 } | 1776 } |
1887 | 1777 |
1888 void Element::cloneAttributesFromElement(const Element& other) | 1778 void Element::cloneAttributesFromElement(const Element& other) |
1889 { | 1779 { |
1890 if (hasSyntheticAttrChildNodes()) | |
1891 detachAllAttrNodesFromElement(); | |
1892 | |
1893 other.synchronizeAllAttributes(); | 1780 other.synchronizeAllAttributes(); |
1894 if (!other.m_elementData) { | 1781 if (!other.m_elementData) { |
1895 m_elementData.clear(); | 1782 m_elementData.clear(); |
1896 return; | 1783 return; |
1897 } | 1784 } |
1898 | 1785 |
1899 const AtomicString& oldID = getIdAttribute(); | 1786 const AtomicString& oldID = getIdAttribute(); |
1900 const AtomicString& newID = other.getIdAttribute(); | 1787 const AtomicString& newID = other.getIdAttribute(); |
1901 | 1788 |
1902 if (!oldID.isNull() || !newID.isNull()) | 1789 if (!oldID.isNull() || !newID.isNull()) |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 { | 1990 { |
2104 #if ENABLE(OILPAN) | 1991 #if ENABLE(OILPAN) |
2105 if (hasRareData()) | 1992 if (hasRareData()) |
2106 visitor->trace(elementRareData()); | 1993 visitor->trace(elementRareData()); |
2107 visitor->trace(m_elementData); | 1994 visitor->trace(m_elementData); |
2108 #endif | 1995 #endif |
2109 ContainerNode::trace(visitor); | 1996 ContainerNode::trace(visitor); |
2110 } | 1997 } |
2111 | 1998 |
2112 } // namespace blink | 1999 } // namespace blink |
OLD | NEW |