Changeset 121003 in webkit
- Timestamp:
- Jun 21, 2012 10:33:58 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r121001 r121003 1 2012-06-21 Ryosuke Niwa <rniwa@webkit.org> 2 3 LabelsNostList isn't updated properly after its owner node is adopted into a new document 4 https://bugs.webkit.org/show_bug.cgi?id=89730 5 6 Reviewed by Darin Adler. 7 8 * fast/forms/label/labels-owner-node-adopted-expected.txt: Added. 9 * fast/forms/label/labels-owner-node-adopted.html: Added. 10 1 11 2012-06-21 Abhishek Arya <inferno@chromium.org> 2 12 -
trunk/Source/WebCore/ChangeLog
r121002 r121003 1 2012-06-21 Ryosuke Niwa <rniwa@webkit.org> 2 3 LabelsNodeList isn't updated properly after its owner node is adopted into a new document 4 https://bugs.webkit.org/show_bug.cgi?id=89730 5 6 Reviewed by Darin Adler. 7 8 When a node is adopted, node lists that are invalidated at document level need to be unregistered 9 from old document and registered to new document so that DOM mutations in new document will invalidate 10 caches in the node lists. Done that in NodeListsNodeData::adoptTreeScope, which was extracted from 11 TreeScopeAdopter::moveTreeToNewScope. 12 13 Also renamed DynamicNodeList::node() and m_node to rootNode() and m_ownerNode to better express 14 their semantics and added ownerNode() to make m_ownerNode private to DynamicNodeList. 15 16 Test: fast/forms/label/labels-owner-node-adopted.html 17 18 * bindings/js/JSNodeListCustom.cpp: 19 (WebCore::JSNodeListOwner::isReachableFromOpaqueRoots): 20 * dom/ChildNodeList.cpp: 21 (WebCore::ChildNodeList::~ChildNodeList): 22 (WebCore::ChildNodeList::length): 23 (WebCore::ChildNodeList::item): 24 (WebCore::ChildNodeList::nodeMatches): 25 * dom/ClassNodeList.cpp: 26 (WebCore::ClassNodeList::ClassNodeList): 27 (WebCore::ClassNodeList::~ClassNodeList): 28 * dom/DynamicNodeList.cpp: 29 (WebCore::DynamicSubtreeNodeList::length): 30 (WebCore::DynamicSubtreeNodeList::itemForwardsFromCurrent): 31 (WebCore::DynamicSubtreeNodeList::itemBackwardsFromCurrent): 32 (WebCore::DynamicSubtreeNodeList::item): 33 (WebCore::DynamicNodeList::itemWithName): 34 * dom/DynamicNodeList.h: 35 (WebCore::DynamicNodeList::DynamicNodeList): 36 (WebCore::DynamicNodeList::ownerNode): 37 (WebCore::DynamicNodeList::rootedAtDocument): 38 (WebCore::DynamicNodeList::shouldInvalidateOnAttributeChange): 39 (WebCore::DynamicNodeList::rootNode): 40 (WebCore::DynamicNodeList::document): 41 (DynamicNodeList): 42 * dom/NameNodeList.cpp: 43 (WebCore::NameNodeList::~NameNodeList): 44 * dom/NodeRareData.h: 45 (WebCore::NodeListsNodeData::adoptTreeScope): 46 (NodeListsNodeData): 47 * dom/TagNodeList.cpp: 48 (WebCore::TagNodeList::~TagNodeList): 49 * dom/TreeScopeAdopter.cpp: 50 (WebCore::TreeScopeAdopter::moveTreeToNewScope): 51 * html/LabelsNodeList.cpp: 52 (WebCore::LabelsNodeList::~LabelsNodeList): 53 (WebCore::LabelsNodeList::nodeMatches): 54 * html/RadioNodeList.cpp: 55 (WebCore::RadioNodeList::~RadioNodeList): 56 (WebCore::RadioNodeList::checkElementMatchesRadioNodeListFilter): 57 1 58 2012-06-21 Alexei Filippov <alexeif@chromium.org> 2 59 -
trunk/Source/WebCore/bindings/js/JSNodeListCustom.cpp
r116828 r121003 44 44 if (!jsNodeList->impl()->isDynamicNodeList()) 45 45 return false; 46 return visitor.containsOpaqueRoot(root(static_cast<DynamicNodeList*>(jsNodeList->impl())-> node()));46 return visitor.containsOpaqueRoot(root(static_cast<DynamicNodeList*>(jsNodeList->impl())->ownerNode())); 47 47 } 48 48 -
trunk/Source/WebCore/dom/ChildNodeList.cpp
r120979 r121003 35 35 ChildNodeList::~ChildNodeList() 36 36 { 37 node()->removeCachedChildNodeList();37 ownerNode()->removeCachedChildNodeList(); 38 38 } 39 39 … … 44 44 45 45 unsigned len = 0; 46 for (Node* n = node()->firstChild(); n; n = n->nextSibling())46 for (Node* n = rootNode()->firstChild(); n; n = n->nextSibling()) 47 47 len++; 48 48 … … 56 56 { 57 57 unsigned int pos = 0; 58 Node* n = node()->firstChild();58 Node* n = rootNode()->firstChild(); 59 59 60 60 if (m_caches.isItemCacheValid) { … … 77 77 unsigned dist = abs(diff); 78 78 if (dist > m_caches.cachedLength - 1 - index) { 79 n = node()->lastChild();79 n = rootNode()->lastChild(); 80 80 pos = m_caches.cachedLength - 1; 81 81 } … … 109 109 // this function will be called only by DynamicNodeList::itemWithName, 110 110 // for an element that was located with getElementById. 111 return testNode->parentNode() == node();111 return testNode->parentNode() == rootNode(); 112 112 } 113 113 -
trunk/Source/WebCore/dom/ClassNodeList.cpp
r120979 r121003 39 39 ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames) 40 40 : DynamicSubtreeNodeList(rootNode) 41 , m_classNames(classNames, node()->document()->inQuirksMode())41 , m_classNames(classNames, document()->inQuirksMode()) 42 42 , m_originalClassNames(classNames) 43 43 { … … 46 46 ClassNodeList::~ClassNodeList() 47 47 { 48 node()->nodeLists()->removeCacheWithName(this, DynamicNodeList::ClassNodeListType, m_originalClassNames);48 ownerNode()->nodeLists()->removeCacheWithName(this, DynamicNodeList::ClassNodeListType, m_originalClassNames); 49 49 } 50 50 -
trunk/Source/WebCore/dom/DynamicNodeList.cpp
r120979 r121003 39 39 40 40 unsigned length = 0; 41 Node* rootNode = node();41 Node* rootNode = this->rootNode(); 42 42 43 43 for (Node* n = rootNode->firstChild(); n; n = n->traverseNextNode(rootNode)) … … 53 53 { 54 54 ASSERT(remainingOffset >= 0); 55 Node* rootNode = node();55 Node* rootNode = this->rootNode(); 56 56 for (Node* n = start; n; n = n->traverseNextNode(rootNode)) { 57 57 if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) { … … 72 72 { 73 73 ASSERT(remainingOffset < 0); 74 Node* rootNode = node();74 Node* rootNode = this->rootNode(); 75 75 for (Node* n = start; n; n = n->traversePreviousNode(rootNode)) { 76 76 if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) { … … 91 91 { 92 92 int remainingOffset = offset; 93 Node* start = node()->firstChild();93 Node* start = rootNode()->firstChild(); 94 94 if (m_caches.isItemCacheValid) { 95 95 if (offset == m_caches.lastItemOffset) … … 108 108 Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const 109 109 { 110 Node* rootNode = node();110 Node* rootNode = this->rootNode(); 111 111 112 112 if (rootNode->inDocument()) { -
trunk/Source/WebCore/dom/DynamicNodeList.h
r120979 r121003 54 54 DoNotInvalidateOnAttributeChange, 55 55 }; 56 DynamicNodeList(PassRefPtr<Node> node, RootType rootType, InvalidationType invalidationType)57 : m_ node(node)56 DynamicNodeList(PassRefPtr<Node> ownerNode, RootType rootType, InvalidationType invalidationType) 57 : m_ownerNode(ownerNode) 58 58 , m_caches(rootType, invalidationType) 59 59 { } … … 66 66 67 67 // Other methods (not part of DOM) 68 Node* node() const 69 { 70 if (m_caches.rootedAtDocument && m_node->inDocument()) 71 return m_node->document(); 72 return m_node.get(); 73 } 74 Document* document() { return m_node->document(); } 75 68 Node* ownerNode() const { return m_ownerNode.get(); } 69 bool isRootedAtDocument() const { return m_caches.rootedAtDocument; } 76 70 bool shouldInvalidateOnAttributeChange() const { return m_caches.shouldInvalidateOnAttributeChange; } 77 78 71 void invalidateCache() { m_caches.reset(); } 79 72 80 73 protected: 74 Node* rootNode() const 75 { 76 if (m_caches.rootedAtDocument && m_ownerNode->inDocument()) 77 return m_ownerNode->document(); 78 return m_ownerNode.get(); 79 } 80 Document* document() const { return m_ownerNode->document(); } 81 81 virtual bool nodeMatches(Element*) const = 0; 82 82 … … 108 108 }; 109 109 110 RefPtr<Node> m_ node;110 RefPtr<Node> m_ownerNode; 111 111 mutable Caches m_caches; 112 112 -
trunk/Source/WebCore/dom/NameNodeList.cpp
r120979 r121003 41 41 NameNodeList::~NameNodeList() 42 42 { 43 m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::NameNodeListType, m_name);43 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::NameNodeListType, m_name); 44 44 } 45 45 -
trunk/Source/WebCore/dom/NodeRareData.h
r120983 r121003 120 120 } 121 121 122 void adoptTreeScope(TreeScope* oldTreeScope, TreeScope* newTreeScope, Document* oldDocument, Document* newDocument) 123 { 124 invalidateCaches(); 125 126 if (oldDocument != newDocument) { 127 NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end(); 128 for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) { 129 DynamicSubtreeNodeList* list = it->second; 130 if (list->isRootedAtDocument()) { 131 oldDocument->unregisterDynamicSubtreeNodeList(list); 132 newDocument->registerDynamicSubtreeNodeList(list); 133 } 134 } 135 136 NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end(); 137 for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) { 138 DynamicSubtreeNodeList* list = it->second; 139 if (list->isRootedAtDocument()) { 140 oldDocument->unregisterDynamicSubtreeNodeList(list); 141 newDocument->registerDynamicSubtreeNodeList(list); 142 } 143 } 144 } 145 146 if (oldTreeScope) 147 oldTreeScope->removeNodeListCache(); 148 newTreeScope->addNodeListCache(); 149 } 150 122 151 private: 123 152 NodeListsNodeData() { } -
trunk/Source/WebCore/dom/TagNodeList.cpp
r120979 r121003 42 42 { 43 43 if (m_namespaceURI == starAtom) 44 m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::TagNodeListType, m_localName);44 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::TagNodeListType, m_localName); 45 45 else 46 m_node->nodeLists()->removeCacheWithQualifiedName(this, m_namespaceURI, m_localName);46 ownerNode()->nodeLists()->removeCacheWithQualifiedName(this, m_namespaceURI, m_localName); 47 47 } 48 48 -
trunk/Source/WebCore/dom/TreeScopeAdopter.cpp
r117796 r121003 54 54 for (Node* node = root; node; node = node->traverseNextNode(root)) { 55 55 NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope); 56 if (rareData && rareData->nodeLists()) { 57 rareData->nodeLists()->invalidateCaches(); 58 if (m_oldScope) 59 m_oldScope->removeNodeListCache(); 60 m_newScope->addNodeListCache(); 61 } 56 if (rareData && rareData->nodeLists()) 57 rareData->nodeLists()->adoptTreeScope(m_oldScope, m_newScope, oldDocument, newDocument); 62 58 63 59 if (willMoveToNewDocument) -
trunk/Source/WebCore/html/LabelsNodeList.cpp
r120979 r121003 42 42 LabelsNodeList::~LabelsNodeList() 43 43 { 44 m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::LabelsNodeListType, starAtom);44 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::LabelsNodeListType, starAtom); 45 45 document()->unregisterDynamicSubtreeNodeList(this); 46 46 } … … 48 48 bool LabelsNodeList::nodeMatches(Element* testNode) const 49 49 { 50 return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == m_node;50 return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == ownerNode(); 51 51 } 52 52 -
trunk/Source/WebCore/html/RadioNodeList.cpp
r120979 r121003 47 47 RadioNodeList::~RadioNodeList() 48 48 { 49 m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::RadioNodeListType, m_name);49 ownerNode()->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::RadioNodeListType, m_name); 50 50 document()->unregisterDynamicSubtreeNodeList(this); 51 51 } … … 87 87 { 88 88 ASSERT(testElement->hasTagName(objectTag) || testElement->isFormControlElement()); 89 if ( m_node->hasTagName(formTag)) {89 if (ownerNode()->hasTagName(formTag)) { 90 90 HTMLFormElement* formElement = 0; 91 91 if (testElement->hasTagName(objectTag)) … … 93 93 else 94 94 formElement = static_cast<HTMLFormControlElement*>(testElement)->form(); 95 if (!formElement || formElement != m_node)95 if (!formElement || formElement != ownerNode()) 96 96 return false; 97 97 }
Note: See TracChangeset
for help on using the changeset viewer.