summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/DocumentOrderedMap.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/dom/DocumentOrderedMap.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/dom/DocumentOrderedMap.cpp')
-rw-r--r--Source/WebCore/dom/DocumentOrderedMap.cpp111
1 files changed, 47 insertions, 64 deletions
diff --git a/Source/WebCore/dom/DocumentOrderedMap.cpp b/Source/WebCore/dom/DocumentOrderedMap.cpp
index 1fab1d101..23c79406b 100644
--- a/Source/WebCore/dom/DocumentOrderedMap.cpp
+++ b/Source/WebCore/dom/DocumentOrderedMap.cpp
@@ -41,47 +41,6 @@ namespace WebCore {
using namespace HTMLNames;
-inline bool keyMatchesId(const AtomicStringImpl& key, const Element& element)
-{
- return element.getIdAttribute().impl() == &key;
-}
-
-inline bool keyMatchesName(const AtomicStringImpl& key, const Element& element)
-{
- return element.getNameAttribute().impl() == &key;
-}
-
-inline bool keyMatchesMapName(const AtomicStringImpl& key, const Element& element)
-{
- return isHTMLMapElement(element) && toHTMLMapElement(element).getName().impl() == &key;
-}
-
-inline bool keyMatchesLowercasedMapName(const AtomicStringImpl& key, const Element& element)
-{
- return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lower().impl() == &key;
-}
-
-inline bool keyMatchesLowercasedUsemap(const AtomicStringImpl& key, const Element& element)
-{
- // FIXME: HTML5 specification says we should match both image and object elements.
- return isHTMLImageElement(element) && toHTMLImageElement(element).matchesLowercasedUsemap(key);
-}
-
-inline bool keyMatchesLabelForAttribute(const AtomicStringImpl& key, const Element& element)
-{
- return isHTMLLabelElement(element) && element.getAttribute(forAttr).impl() == &key;
-}
-
-inline bool keyMatchesWindowNamedItem(const AtomicStringImpl& key, const Element& element)
-{
- return WindowNameCollection::nodeMatches(const_cast<Element*>(&element), &key);
-}
-
-inline bool keyMatchesDocumentNamedItem(const AtomicStringImpl& key, const Element& element)
-{
- return DocumentNameCollection::nodeMatches(const_cast<Element*>(&element), &key);
-}
-
void DocumentOrderedMap::clear()
{
m_map.clear();
@@ -89,15 +48,25 @@ void DocumentOrderedMap::clear()
void DocumentOrderedMap::add(const AtomicStringImpl& key, Element& element, const TreeScope& treeScope)
{
+ UNUSED_PARAM(treeScope);
ASSERT_WITH_SECURITY_IMPLICATION(element.isInTreeScope());
- ASSERT_WITH_SECURITY_IMPLICATION(treeScope.rootNode()->containsIncludingShadowDOM(&element));
- if (!element.isInTreeScope() || &element.document() != treeScope.documentScope())
+ ASSERT_WITH_SECURITY_IMPLICATION(treeScope.rootNode().containsIncludingShadowDOM(&element));
+
+ if (!element.isInTreeScope())
return;
- Map::AddResult addResult = m_map.add(&key, MapEntry(&element));
+ Map::AddResult addResult = m_map.ensure(&key, [&element] {
+ return MapEntry(&element);
+ });
+ MapEntry& entry = addResult.iterator->value;
+
+#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
+ ASSERT_WITH_SECURITY_IMPLICATION(!entry.registeredElements.contains(&element));
+ entry.registeredElements.add(&element);
+#endif
+
if (addResult.isNewEntry)
return;
- MapEntry& entry = addResult.iterator->value;
ASSERT_WITH_SECURITY_IMPLICATION(entry.count);
entry.element = nullptr;
entry.count++;
@@ -108,11 +77,13 @@ void DocumentOrderedMap::remove(const AtomicStringImpl& key, Element& element)
{
m_map.checkConsistency();
auto it = m_map.find(&key);
+
ASSERT_WITH_SECURITY_IMPLICATION(it != m_map.end());
if (it == m_map.end())
return;
- MapEntry& entry = it->value;
+ MapEntry& entry = it->value;
+ ASSERT_WITH_SECURITY_IMPLICATION(entry.registeredElements.remove(&element));
ASSERT_WITH_SECURITY_IMPLICATION(entry.count);
if (entry.count == 1) {
ASSERT_WITH_SECURITY_IMPLICATION(!entry.element || entry.element == &element);
@@ -125,8 +96,8 @@ void DocumentOrderedMap::remove(const AtomicStringImpl& key, Element& element)
}
}
-template<bool keyMatches(const AtomicStringImpl&, const Element&)>
-inline Element* DocumentOrderedMap::get(const AtomicStringImpl& key, const TreeScope& scope) const
+template <typename KeyMatchingFunction>
+inline Element* DocumentOrderedMap::get(const AtomicStringImpl& key, const TreeScope& scope, const KeyMatchingFunction& keyMatches) const
{
m_map.checkConsistency();
@@ -139,16 +110,18 @@ inline Element* DocumentOrderedMap::get(const AtomicStringImpl& key, const TreeS
if (entry.element) {
ASSERT_WITH_SECURITY_IMPLICATION(entry.element->isInTreeScope());
ASSERT_WITH_SECURITY_IMPLICATION(&entry.element->treeScope() == &scope);
+ ASSERT_WITH_SECURITY_IMPLICATION(entry.registeredElements.contains(entry.element));
return entry.element;
}
// We know there's at least one node that matches; iterate to find the first one.
- for (auto& element : descendantsOfType<Element>(*scope.rootNode())) {
+ for (auto& element : descendantsOfType<Element>(scope.rootNode())) {
if (!keyMatches(key, element))
continue;
entry.element = &element;
ASSERT_WITH_SECURITY_IMPLICATION(element.isInTreeScope());
ASSERT_WITH_SECURITY_IMPLICATION(&element.treeScope() == &scope);
+ ASSERT_WITH_SECURITY_IMPLICATION(entry.registeredElements.contains(entry.element));
return &element;
}
ASSERT_NOT_REACHED();
@@ -157,42 +130,52 @@ inline Element* DocumentOrderedMap::get(const AtomicStringImpl& key, const TreeS
Element* DocumentOrderedMap::getElementById(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return get<keyMatchesId>(key, scope);
+ return get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ return element.getIdAttribute().impl() == &key;
+ });
}
Element* DocumentOrderedMap::getElementByName(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return get<keyMatchesName>(key, scope);
+ return get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ return element.getNameAttribute().impl() == &key;
+ });
}
HTMLMapElement* DocumentOrderedMap::getElementByMapName(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return toHTMLMapElement(get<keyMatchesMapName>(key, scope));
-}
-
-HTMLMapElement* DocumentOrderedMap::getElementByLowercasedMapName(const AtomicStringImpl& key, const TreeScope& scope) const
-{
- return toHTMLMapElement(get<keyMatchesLowercasedMapName>(key, scope));
+ return downcast<HTMLMapElement>(get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ return is<HTMLMapElement>(element) && downcast<HTMLMapElement>(element).getName().impl() == &key;
+ }));
}
-HTMLImageElement* DocumentOrderedMap::getElementByLowercasedUsemap(const AtomicStringImpl& key, const TreeScope& scope) const
+HTMLImageElement* DocumentOrderedMap::getElementByUsemap(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return toHTMLImageElement(get<keyMatchesLowercasedUsemap>(key, scope));
+ return downcast<HTMLImageElement>(get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ // FIXME: HTML5 specification says we should match both image and object elements.
+ return is<HTMLImageElement>(element) && downcast<HTMLImageElement>(element).matchesUsemap(key);
+ }));
}
HTMLLabelElement* DocumentOrderedMap::getElementByLabelForAttribute(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return toHTMLLabelElement(get<keyMatchesLabelForAttribute>(key, scope));
+ return downcast<HTMLLabelElement>(get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ return is<HTMLLabelElement>(element) && element.attributeWithoutSynchronization(forAttr).impl() == &key;
+ }));
}
Element* DocumentOrderedMap::getElementByWindowNamedItem(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return get<keyMatchesWindowNamedItem>(key, scope);
+ return get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ return WindowNameCollection::elementMatches(element, &key);
+ });
}
Element* DocumentOrderedMap::getElementByDocumentNamedItem(const AtomicStringImpl& key, const TreeScope& scope) const
{
- return get<keyMatchesDocumentNamedItem>(key, scope);
+ return get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
+ return DocumentNameCollection::elementMatches(element, &key);
+ });
}
const Vector<Element*>* DocumentOrderedMap::getAllElementsById(const AtomicStringImpl& key, const TreeScope& scope) const
@@ -210,12 +193,12 @@ const Vector<Element*>* DocumentOrderedMap::getAllElementsById(const AtomicStrin
if (entry.orderedList.isEmpty()) {
entry.orderedList.reserveCapacity(entry.count);
- auto elementDescandents = descendantsOfType<Element>(*scope.rootNode());
+ auto elementDescandents = descendantsOfType<Element>(scope.rootNode());
auto it = entry.element ? elementDescandents.beginAt(*entry.element) : elementDescandents.begin();
auto end = elementDescandents.end();
for (; it != end; ++it) {
auto& element = *it;
- if (!keyMatchesId(key, element))
+ if (element.getIdAttribute().impl() != &key)
continue;
entry.orderedList.append(&element);
}