Diff
Modified: branches/safari-536.28-branch/LayoutTests/ChangeLog (133089 => 133090)
--- branches/safari-536.28-branch/LayoutTests/ChangeLog 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/LayoutTests/ChangeLog 2012-10-31 22:50:32 UTC (rev 133090)
@@ -1,5 +1,19 @@
2012-10-31 Lucas Forschler <[email protected]>
+ Merge r121003
+
+ 2012-06-21 Ryosuke Niwa <[email protected]>
+
+ LabelsNostList isn't updated properly after its owner node is adopted into a new document
+ https://bugs.webkit.org/show_bug.cgi?id=89730
+
+ Reviewed by Darin Adler.
+
+ * fast/forms/label/labels-owner-node-adopted-expected.txt: Added.
+ * fast/forms/label/labels-owner-node-adopted.html: Added.
+
+2012-10-31 Lucas Forschler <[email protected]>
+
Merge r121001
2012-06-21 Abhishek Arya <[email protected]>
Added: branches/safari-536.28-branch/LayoutTests/fast/forms/label/labels-owner-node-adopted-expected.txt (0 => 133090)
--- branches/safari-536.28-branch/LayoutTests/fast/forms/label/labels-owner-node-adopted-expected.txt (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/forms/label/labels-owner-node-adopted-expected.txt 2012-10-31 22:50:32 UTC (rev 133090)
@@ -0,0 +1,13 @@
+This tests moving a node with labels property from one document to another. The labels node list should be updated when labels are modified in the new document.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+The input element initially have two label elements #label1 and #label2.
+PASS labels = input.labels; labels.length is 2
+PASS label0 = labels[0]; label1 = labels[1]; iframe.contentDocument.body.appendChild(form); labels.length; label1.parentNode.removeChild(label1); labels.length is 1
+PASS labels[0] is label0
+PASS label0.parentNode.appendChild(label1); labels.length is 2
+PASS labels[0] is label0
+PASS labels[1] is label1
+
Added: branches/safari-536.28-branch/LayoutTests/fast/forms/label/labels-owner-node-adopted.html (0 => 133090)
--- branches/safari-536.28-branch/LayoutTests/fast/forms/label/labels-owner-node-adopted.html (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/fast/forms/label/labels-owner-node-adopted.html 2012-10-31 22:50:32 UTC (rev 133090)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<body>
+<form>
+<label id="label1" for=""
+<label id="label2" for=""
+<input id="input" type="text">
+</form>
+<script src=""
+<script>
+
+var form = document.querySelector('form');
+var input = document.querySelector('input');
+
+var iframe = document.createElement('iframe');
+document.body.appendChild(iframe);
+var labels, label0, label1;
+
+description("This tests moving a node with labels property from one document to another.\n"
+ + "The labels node list should be updated when labels are modified in the new document.")
+
+debug('The input element initially have two label elements #label1 and #label2.');
+shouldBe("labels = input.labels; labels.length", "2");
+shouldBe("label0 = labels[0]; label1 = labels[1]; iframe.contentDocument.body.appendChild(form); labels.length; label1.parentNode.removeChild(label1); labels.length", "1");
+shouldBe("labels[0]", "label0");
+shouldBe("label0.parentNode.appendChild(label1); labels.length", "2");
+shouldBe("labels[0]", "label0");
+shouldBe("labels[1]", "label1");
+
+form.style.display = 'none';
+
+var successfullyParsed = true;
+
+</script>
+</body>
+</html>
Modified: branches/safari-536.28-branch/Source/WebCore/ChangeLog (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/ChangeLog 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/ChangeLog 2012-10-31 22:50:32 UTC (rev 133090)
@@ -1,5 +1,66 @@
2012-10-31 Lucas Forschler <[email protected]>
+ Merge r121003
+
+ 2012-06-21 Ryosuke Niwa <[email protected]>
+
+ LabelsNodeList isn't updated properly after its owner node is adopted into a new document
+ https://bugs.webkit.org/show_bug.cgi?id=89730
+
+ Reviewed by Darin Adler.
+
+ When a node is adopted, node lists that are invalidated at document level need to be unregistered
+ from old document and registered to new document so that DOM mutations in new document will invalidate
+ caches in the node lists. Done that in NodeListsNodeData::adoptTreeScope, which was extracted from
+ TreeScopeAdopter::moveTreeToNewScope.
+
+ Also renamed DynamicNodeList::node() and m_node to rootNode() and m_ownerNode to better express
+ their semantics and added ownerNode() to make m_ownerNode private to DynamicNodeList.
+
+ Test: fast/forms/label/labels-owner-node-adopted.html
+
+ * bindings/js/JSNodeListCustom.cpp:
+ (WebCore::JSNodeListOwner::isReachableFromOpaqueRoots):
+ * dom/ChildNodeList.cpp:
+ (WebCore::ChildNodeList::~ChildNodeList):
+ (WebCore::ChildNodeList::length):
+ (WebCore::ChildNodeList::item):
+ (WebCore::ChildNodeList::nodeMatches):
+ * dom/ClassNodeList.cpp:
+ (WebCore::ClassNodeList::ClassNodeList):
+ (WebCore::ClassNodeList::~ClassNodeList):
+ * dom/DynamicNodeList.cpp:
+ (WebCore::DynamicSubtreeNodeList::length):
+ (WebCore::DynamicSubtreeNodeList::itemForwardsFromCurrent):
+ (WebCore::DynamicSubtreeNodeList::itemBackwardsFromCurrent):
+ (WebCore::DynamicSubtreeNodeList::item):
+ (WebCore::DynamicNodeList::itemWithName):
+ * dom/DynamicNodeList.h:
+ (WebCore::DynamicNodeList::DynamicNodeList):
+ (WebCore::DynamicNodeList::ownerNode):
+ (WebCore::DynamicNodeList::rootedAtDocument):
+ (WebCore::DynamicNodeList::shouldInvalidateOnAttributeChange):
+ (WebCore::DynamicNodeList::rootNode):
+ (WebCore::DynamicNodeList::document):
+ (DynamicNodeList):
+ * dom/NameNodeList.cpp:
+ (WebCore::NameNodeList::~NameNodeList):
+ * dom/NodeRareData.h:
+ (WebCore::NodeListsNodeData::adoptTreeScope):
+ (NodeListsNodeData):
+ * dom/TagNodeList.cpp:
+ (WebCore::TagNodeList::~TagNodeList):
+ * dom/TreeScopeAdopter.cpp:
+ (WebCore::TreeScopeAdopter::moveTreeToNewScope):
+ * html/LabelsNodeList.cpp:
+ (WebCore::LabelsNodeList::~LabelsNodeList):
+ (WebCore::LabelsNodeList::nodeMatches):
+ * html/RadioNodeList.cpp:
+ (WebCore::RadioNodeList::~RadioNodeList):
+ (WebCore::RadioNodeList::checkElementMatchesRadioNodeListFilter):
+
+2012-10-31 Lucas Forschler <[email protected]>
+
Merge r121001
2012-06-21 Abhishek Arya <[email protected]>
Modified: branches/safari-536.28-branch/Source/WebCore/bindings/js/JSNodeListCustom.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/bindings/js/JSNodeListCustom.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/bindings/js/JSNodeListCustom.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -43,7 +43,7 @@
return false;
if (!jsNodeList->impl()->isDynamicNodeList())
return false;
- return visitor.containsOpaqueRoot(root(static_cast<DynamicNodeList*>(jsNodeList->impl())->node()));
+ return visitor.containsOpaqueRoot(root(static_cast<DynamicNodeList*>(jsNodeList->impl())->ownerNode()));
}
bool JSNodeList::canGetItemsForName(ExecState*, NodeList* impl, const Identifier& propertyName)
Modified: branches/safari-536.28-branch/Source/WebCore/dom/ChildNodeList.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/ChildNodeList.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/ChildNodeList.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -34,7 +34,7 @@
ChildNodeList::~ChildNodeList()
{
- node()->removeCachedChildNodeList();
+ ownerNode()->removeCachedChildNodeList();
}
unsigned ChildNodeList::length() const
@@ -43,7 +43,7 @@
return m_caches.cachedLength;
unsigned len = 0;
- for (Node* n = node()->firstChild(); n; n = n->nextSibling())
+ for (Node* n = rootNode()->firstChild(); n; n = n->nextSibling())
len++;
m_caches.cachedLength = len;
@@ -55,7 +55,7 @@
Node* ChildNodeList::item(unsigned index) const
{
unsigned int pos = 0;
- Node* n = node()->firstChild();
+ Node* n = rootNode()->firstChild();
if (m_caches.isItemCacheValid) {
if (index == m_caches.lastItemOffset)
@@ -76,7 +76,7 @@
int diff = index - pos;
unsigned dist = abs(diff);
if (dist > m_caches.cachedLength - 1 - index) {
- n = node()->lastChild();
+ n = rootNode()->lastChild();
pos = m_caches.cachedLength - 1;
}
}
@@ -108,7 +108,7 @@
// Note: Due to the overrides of the length and item functions above,
// this function will be called only by DynamicNodeList::itemWithName,
// for an element that was located with getElementById.
- return testNode->parentNode() == node();
+ return testNode->parentNode() == rootNode();
}
} // namespace WebCore
Modified: branches/safari-536.28-branch/Source/WebCore/dom/ClassNodeList.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/ClassNodeList.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/ClassNodeList.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -37,14 +37,14 @@
ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames)
: DynamicSubtreeNodeList(rootNode)
- , m_classNames(classNames, node()->document()->inQuirksMode())
+ , m_classNames(classNames, document()->inQuirksMode())
, m_originalClassNames(classNames)
{
}
ClassNodeList::~ClassNodeList()
{
- rootNode()->removeCachedClassNodeList(this, m_originalClassNames);
+ ownerNode()->removeCachedClassNodeList(this, m_originalClassNames);
}
bool ClassNodeList::nodeMatches(Element* testNode) const
Modified: branches/safari-536.28-branch/Source/WebCore/dom/Document.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/Document.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Document.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -113,6 +113,7 @@
#include "NewXMLDocumentParser.h"
#include "NodeFilter.h"
#include "NodeIterator.h"
+#include "NodeRareData.h"
#include "NodeWithIndex.h"
#include "Page.h"
#include "PageGroup.h"
@@ -3766,6 +3767,18 @@
n->setNeedsStyleRecalc();
}
+void Document::registerDynamicSubtreeNodeList(DynamicSubtreeNodeList* list)
+{
+ ensureRareData()->ensureNodeLists(this)->m_listsInvalidatedAtDocument.add(list);
+}
+
+void Document::unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList* list)
+{
+ ASSERT(hasRareData());
+ ASSERT(rareData()->nodeLists());
+ rareData()->nodeLists()->m_listsInvalidatedAtDocument.remove(list);
+}
+
void Document::attachNodeIterator(NodeIterator* ni)
{
m_nodeIterators.add(ni);
Modified: branches/safari-536.28-branch/Source/WebCore/dom/Document.h (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/Document.h 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Document.h 2012-10-31 22:50:32 UTC (rev 133090)
@@ -749,6 +749,9 @@
bool isPendingStyleRecalc() const;
void styleRecalcTimerFired(Timer<Document>*);
+ void registerDynamicSubtreeNodeList(DynamicSubtreeNodeList*);
+ void unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList*);
+
void attachNodeIterator(NodeIterator*);
void detachNodeIterator(NodeIterator*);
void moveNodeIteratorsToNewDocument(Node*, Document*);
Modified: branches/safari-536.28-branch/Source/WebCore/dom/DynamicNodeList.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/DynamicNodeList.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/DynamicNodeList.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -28,8 +28,8 @@
namespace WebCore {
-DynamicSubtreeNodeList::DynamicSubtreeNodeList(PassRefPtr<Node> node)
- : DynamicNodeList(node)
+DynamicSubtreeNodeList::DynamicSubtreeNodeList(PassRefPtr<Node> node, RootType rootType)
+ : DynamicNodeList(node, rootType)
{
}
@@ -43,8 +43,9 @@
return m_caches.cachedLength;
unsigned length = 0;
+ Node* rootNode = this->rootNode();
- for (Node* n = node()->firstChild(); n; n = n->traverseNextNode(rootNode()))
+ for (Node* n = rootNode->firstChild(); n; n = n->traverseNextNode(rootNode))
length += n->isElementNode() && nodeMatches(static_cast<Element*>(n));
m_caches.cachedLength = length;
@@ -56,7 +57,8 @@
Node* DynamicSubtreeNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
{
ASSERT(remainingOffset >= 0);
- for (Node* n = start; n; n = n->traverseNextNode(rootNode())) {
+ Node* rootNode = this->rootNode();
+ for (Node* n = start; n; n = n->traverseNextNode(rootNode)) {
if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) {
if (!remainingOffset) {
m_caches.lastItem = n;
@@ -74,7 +76,8 @@
Node* DynamicSubtreeNodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
{
ASSERT(remainingOffset < 0);
- for (Node* n = start; n; n = n->traversePreviousNode(rootNode())) {
+ Node* rootNode = this->rootNode();
+ for (Node* n = start; n; n = n->traversePreviousNode(rootNode)) {
if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) {
if (!remainingOffset) {
m_caches.lastItem = n;
@@ -92,7 +95,7 @@
Node* DynamicSubtreeNodeList::item(unsigned offset) const
{
int remainingOffset = offset;
- Node* start = node()->firstChild();
+ Node* start = rootNode()->firstChild();
if (m_caches.isItemCacheValid) {
if (offset == m_caches.lastItemOffset)
return m_caches.lastItem;
@@ -109,11 +112,13 @@
Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const
{
- if (node()->isDocumentNode() || node()->inDocument()) {
- Element* node = this->node()->treeScope()->getElementById(elementId);
- if (node && nodeMatches(node) && node->isDescendantOf(this->node()))
- return node;
- if (!node)
+ Node* rootNode = this->rootNode();
+
+ if (rootNode->inDocument()) {
+ Element* element = rootNode->treeScope()->getElementById(elementId);
+ if (element && nodeMatches(element) && element->isDescendantOf(rootNode))
+ return element;
+ if (!element)
return 0;
// In the case of multiple nodes with the same name, just fall through.
}
Modified: branches/safari-536.28-branch/Source/WebCore/dom/DynamicNodeList.h (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/DynamicNodeList.h 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/DynamicNodeList.h 2012-10-31 22:50:32 UTC (rev 133090)
@@ -24,6 +24,7 @@
#ifndef DynamicNodeList_h
#define DynamicNodeList_h
+#include "Document.h"
#include "NodeList.h"
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
@@ -35,8 +36,14 @@
class DynamicNodeList : public NodeList {
public:
- DynamicNodeList(PassRefPtr<Node> node)
- : m_node(node)
+ enum RootType {
+ RootedAtNode,
+ RootedAtDocument,
+ };
+
+ DynamicNodeList(PassRefPtr<Node> ownerNode, RootType rootType = RootedAtNode)
+ : m_ownerNode(ownerNode)
+ , m_caches(rootType)
{ }
virtual ~DynamicNodeList() { }
@@ -46,15 +53,28 @@
virtual Node* itemWithName(const AtomicString&) const;
// Other methods (not part of DOM)
- Node* node() const { return m_node.get(); }
+ Node* ownerNode() const { return m_ownerNode.get(); }
+ bool isRootedAtDocument() const { return m_caches.rootedAtDocument; }
void invalidateCache() { m_caches.reset(); }
protected:
+ Node* rootNode() const
+ {
+ if (m_caches.rootedAtDocument && m_ownerNode->inDocument())
+ return m_ownerNode->document();
+ return m_ownerNode.get();
+ }
+ Document* document() const { return m_ownerNode->document(); }
virtual bool nodeMatches(Element*) const = 0;
struct Caches {
- Caches() { reset(); }
+ Caches(RootType rootType)
+ : rootedAtDocument(rootType == RootedAtDocument)
+ {
+ reset();
+ }
+
void reset()
{
lastItem = 0;
@@ -64,13 +84,14 @@
Node* lastItem;
unsigned cachedLength;
- unsigned lastItemOffset;
- bool isLengthCacheValid : 1;
- bool isItemCacheValid : 1;
+ unsigned lastItemOffset : 29; // Borrow 3-bits for bit fields
+ unsigned isLengthCacheValid : 1;
+ unsigned isItemCacheValid : 1;
+ unsigned rootedAtDocument : 1;
};
+ RefPtr<Node> m_ownerNode;
mutable Caches m_caches;
- RefPtr<Node> m_node;
private:
virtual bool isDynamicNodeList() const OVERRIDE { return true; }
@@ -81,10 +102,9 @@
virtual ~DynamicSubtreeNodeList();
virtual unsigned length() const OVERRIDE;
virtual Node* item(unsigned index) const OVERRIDE;
- Node* rootNode() const { return node(); }
protected:
- DynamicSubtreeNodeList(PassRefPtr<Node> rootNode);
+ DynamicSubtreeNodeList(PassRefPtr<Node>, RootType = RootedAtNode);
private:
using DynamicNodeList::invalidateCache;
Modified: branches/safari-536.28-branch/Source/WebCore/dom/NameNodeList.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/NameNodeList.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/NameNodeList.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -39,7 +39,7 @@
NameNodeList::~NameNodeList()
{
- rootNode()->removeCachedNameNodeList(this, m_nodeName);
+ ownerNode()->removeCachedNameNodeList(this, m_nodeName);
}
bool NameNodeList::nodeMatches(Element* testNode) const
Modified: branches/safari-536.28-branch/Source/WebCore/dom/Node.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/Node.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Node.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -949,33 +949,6 @@
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 = ""
- 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 = ""
- data->nodeLists()->m_listsInvalidatedAtDocument.remove(list);
- removeNodeListCacheIfPossible(this, data);
-}
-
void Node::invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName& attrName)
{
if (hasRareData() && isAttributeNode()) {
@@ -995,6 +968,11 @@
&& attrName != forAttr)
return;
+ if (document()->hasRareData()) {
+ if (NodeListsNodeData* nodeLists = document()->rareData()->nodeLists())
+ nodeLists->invalidateCachesForDocument();
+ }
+
if (!treeScope()->hasNodeListCaches())
return;
@@ -1015,6 +993,11 @@
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()) {
@@ -2307,13 +2290,15 @@
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();
Modified: branches/safari-536.28-branch/Source/WebCore/dom/Node.h (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/Node.h 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Node.h 2012-10-31 22:50:32 UTC (rev 133090)
@@ -549,8 +549,6 @@
void showTreeForThisAcrossFrame() const;
#endif
- void registerDynamicSubtreeNodeList(DynamicSubtreeNodeList*);
- void unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList*);
void invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName&);
void invalidateNodeListsCacheAfterChildrenChanged();
void removeCachedClassNodeList(ClassNodeList*, const String&);
Modified: branches/safari-536.28-branch/Source/WebCore/dom/NodeRareData.h (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/NodeRareData.h 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/NodeRareData.h 2012-10-31 22:50:32 UTC (rev 133090)
@@ -26,6 +26,7 @@
#include "ClassNodeList.h"
#include "DOMSettableTokenList.h"
#include "DynamicNodeList.h"
+#include "LabelsNodeList.h"
#include "MutationObserverRegistration.h"
#include "NameNodeList.h"
#include "QualifiedName.h"
@@ -78,10 +79,25 @@
}
void invalidateCaches();
+ void invalidateCachesForDocument();
void invalidateCachesThatDependOnAttributes();
bool isEmpty() const;
+ void adoptTreeScope(TreeScope* oldTreeScope, TreeScope* newTreeScope, Document* oldDocument, Document* newDocument)
+ {
+ invalidateCaches();
+
+ if (oldDocument != newDocument) {
+ oldDocument->unregisterDynamicSubtreeNodeList(m_labelsNodeListCache);
+ newDocument->registerDynamicSubtreeNodeList(m_labelsNodeListCache);
+ }
+
+ if (oldTreeScope)
+ oldTreeScope->removeNodeListCache();
+ newTreeScope->addNodeListCache();
+ }
+
private:
NodeListsNodeData() : m_labelsNodeListCache(0) {}
};
Modified: branches/safari-536.28-branch/Source/WebCore/dom/TagNodeList.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/TagNodeList.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/TagNodeList.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -40,9 +40,9 @@
TagNodeList::~TagNodeList()
{
if (m_namespaceURI == starAtom)
- rootNode()->removeCachedTagNodeList(this, m_localName);
+ ownerNode()->removeCachedTagNodeList(this, m_localName);
else
- rootNode()->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI));
+ ownerNode()->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI));
}
bool TagNodeList::nodeMatches(Element* testNode) const
Modified: branches/safari-536.28-branch/Source/WebCore/dom/TreeScopeAdopter.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/dom/TreeScopeAdopter.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/dom/TreeScopeAdopter.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -53,12 +53,8 @@
for (Node* node = root; node; node = node->traverseNextNode(root)) {
NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope);
- if (rareData && rareData->nodeLists()) {
- rareData->nodeLists()->invalidateCaches();
- if (m_oldScope)
- m_oldScope->removeNodeListCache();
- m_newScope->addNodeListCache();
- }
+ if (rareData && rareData->nodeLists())
+ rareData->nodeLists()->adoptTreeScope(m_oldScope, m_newScope, oldDocument, newDocument);
if (willMoveToNewDocument)
moveNodeToNewDocument(node, oldDocument, newDocument);
Modified: branches/safari-536.28-branch/Source/WebCore/html/LabelsNodeList.cpp (133089 => 133090)
--- branches/safari-536.28-branch/Source/WebCore/html/LabelsNodeList.cpp 2012-10-31 22:40:43 UTC (rev 133089)
+++ branches/safari-536.28-branch/Source/WebCore/html/LabelsNodeList.cpp 2012-10-31 22:50:32 UTC (rev 133090)
@@ -32,21 +32,22 @@
using namespace HTMLNames;
-LabelsNodeList::LabelsNodeList(Node* forNode )
- : DynamicSubtreeNodeList(forNode->document()) , m_forNode(forNode)
+LabelsNodeList::LabelsNodeList(Node* forNode)
+ : DynamicSubtreeNodeList(forNode, RootedAtDocument)
+ , m_forNode(forNode)
{
m_forNode->document()->registerDynamicSubtreeNodeList(this);
}
LabelsNodeList::~LabelsNodeList()
{
- m_forNode->removeCachedLabelsNodeList(this);
- m_forNode->document()->unregisterDynamicSubtreeNodeList(this);
+ ownerNode()->removeCachedLabelsNodeList(this);
+ ownerNode()->document()->unregisterDynamicSubtreeNodeList(this);
}
bool LabelsNodeList::nodeMatches(Element* testNode) const
{
- return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == m_forNode;
+ return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == ownerNode();
}
} // namespace WebCore