diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-20 13:01:08 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-20 13:01:08 +0200 |
| commit | 49233e234e5c787396cadb2cea33b31ae0cd65c1 (patch) | |
| tree | 5410cb9a8fd53168bb60d62c54b654d86f03c38d /Source/WebCore/dom/Node.cpp | |
| parent | b211c645d8ab690f713515dfdc84d80b11c27d2c (diff) | |
| download | qtwebkit-49233e234e5c787396cadb2cea33b31ae0cd65c1.tar.gz | |
Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813)
New snapshot with Windows build fixes
Diffstat (limited to 'Source/WebCore/dom/Node.cpp')
| -rw-r--r-- | Source/WebCore/dom/Node.cpp | 102 |
1 files changed, 40 insertions, 62 deletions
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index 79450c5b5..f35dc5b99 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -938,33 +938,6 @@ unsigned Node::nodeIndex() const return count; } -static void removeNodeListCacheIfPossible(Node* node, NodeRareData* data) -{ - if (!data->nodeLists()->isEmpty()) - return; - data->clearNodeLists(); - node->treeScope()->removeNodeListCache(); -} - -// FIXME: Move this function to Document -void Node::registerDynamicSubtreeNodeList(DynamicSubtreeNodeList* list) -{ - ASSERT(isDocumentNode()); - NodeRareData* data = ensureRareData(); - data->ensureNodeLists(this)->m_listsInvalidatedAtDocument.add(list); -} - -// FIXME: Move this function to Document -void Node::unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList* list) -{ - ASSERT(isDocumentNode()); - ASSERT(hasRareData()); - ASSERT(rareData()->nodeLists()); - NodeRareData* data = rareData(); - data->nodeLists()->m_listsInvalidatedAtDocument.remove(list); - removeNodeListCacheIfPossible(this, data); -} - void Node::invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName& attrName, Element* attributeOwnerElement) { if (hasRareData() && isAttributeNode()) { @@ -994,6 +967,11 @@ void Node::invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName& at && (attrName != idAttr || !attributeOwnerElement->isFormControlElement())) return; + if (document()->hasRareData()) { + if (NodeListsNodeData* nodeLists = document()->rareData()->nodeLists()) + nodeLists->invalidateCachesForDocument(); + } + if (!treeScope()->hasNodeListCaches()) return; @@ -1014,6 +992,11 @@ void Node::invalidateNodeListsCacheAfterChildrenChanged() if (hasRareData()) rareData()->clearChildNodeListCache(); + if (document()->hasRareData()) { + if (NodeListsNodeData* nodeLists = document()->rareData()->nodeLists()) + nodeLists->invalidateCachesForDocument(); + } + if (!treeScope()->hasNodeListCaches()) return; for (Node* node = this; node; node = node->parentNode()) { @@ -1672,54 +1655,30 @@ PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames) return list.release(); } -PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec) +PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, ExceptionCode& ec) { if (selectors.isEmpty()) { ec = SYNTAX_ERR; return 0; } - CSSParser parser(document()); - CSSSelectorList querySelectorList; - parser.parseSelector(selectors, querySelectorList); - - if (!querySelectorList.first() || querySelectorList.hasUnknownPseudoElements()) { - ec = SYNTAX_ERR; - return 0; - } - // throw a NAMESPACE_ERR if the selector includes any namespace prefixes. - if (querySelectorList.selectorsNeedNamespaceResolution()) { - ec = NAMESPACE_ERR; + SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selectors, document(), ec); + if (!selectorQuery) return 0; - } - - SelectorQuery selectorQuery(querySelectorList); - return selectorQuery.queryFirst(this); + return selectorQuery->queryFirst(this); } -PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCode& ec) +PassRefPtr<NodeList> Node::querySelectorAll(const AtomicString& selectors, ExceptionCode& ec) { if (selectors.isEmpty()) { ec = SYNTAX_ERR; return 0; } - CSSParser p(document()); - CSSSelectorList querySelectorList; - p.parseSelector(selectors, querySelectorList); - if (!querySelectorList.first() || querySelectorList.hasUnknownPseudoElements()) { - ec = SYNTAX_ERR; + SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selectors, document(), ec); + if (!selectorQuery) return 0; - } - - // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes. - if (querySelectorList.selectorsNeedNamespaceResolution()) { - ec = NAMESPACE_ERR; - return 0; - } - - SelectorQuery selectorQuery(querySelectorList); - return selectorQuery.queryAll(this); + return selectorQuery->queryAll(this); } Document *Node::ownerDocument() const @@ -2366,13 +2325,15 @@ void NodeListsNodeData::invalidateCaches() invalidateCachesThatDependOnAttributes(); } -void NodeListsNodeData::invalidateCachesThatDependOnAttributes() +void NodeListsNodeData::invalidateCachesForDocument() { - // Used by labels and region node lists on document. NodeListsNodeData::NodeListSet::iterator end = m_listsInvalidatedAtDocument.end(); for (NodeListsNodeData::NodeListSet::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it) (*it)->invalidateCache(); +} +void NodeListsNodeData::invalidateCachesThatDependOnAttributes() +{ ClassNodeListCache::iterator classCacheEnd = m_classNodeListCache.end(); for (ClassNodeListCache::iterator it = m_classNodeListCache.begin(); it != classCacheEnd; ++it) it->second->invalidateCache(); @@ -2939,7 +2900,7 @@ PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name) if (!result.isNewEntry) return PassRefPtr<RadioNodeList>(result.iterator->second); - RefPtr<RadioNodeList> list = RadioNodeList::create(name, toElement(this)); + RefPtr<RadioNodeList> list = RadioNodeList::create(toElement(this), name); result.iterator->second = list.get(); return list.release(); } @@ -2954,6 +2915,23 @@ void Node::removeCachedRadioNodeList(RadioNodeList* list, const AtomicString& na data->m_radioNodeListCache.remove(name); } +// It's important not to inline removedLastRef, because we don't want to inline the code to +// delete a Node at each deref call site. +void Node::removedLastRef() +{ + // An explicit check for Document here is better than a virtual function since it is + // faster for non-Document nodes, and because the call to removedLastRef that is inlined + // at all deref call sites is smaller if it's a non-virtual function. + if (isDocumentNode()) { + static_cast<Document*>(this)->removedLastRef(); + return; + } +#ifndef NDEBUG + m_deletionHasBegun = true; +#endif + delete this; +} + } // namespace WebCore #ifndef NDEBUG |
