diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/dom/DocumentOrderedMap.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/dom/DocumentOrderedMap.cpp')
-rw-r--r-- | Source/WebCore/dom/DocumentOrderedMap.cpp | 111 |
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); } |