inline void TreeScopeAdopter::moveNodeToNewDocument( Node& node, Document& oldDocument, Document& newDocument) const { DCHECK_NE(oldDocument, newDocument); if (node.hasRareData()) { NodeRareData* rareData = node.rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptDocument(oldDocument, newDocument); } oldDocument.moveNodeIteratorsToNewDocument(node, newDocument); if (node.getCustomElementState() == CustomElementState::Custom) { Element& element = toElement(node); CustomElement::enqueueAdoptedCallback(&element, &oldDocument, &newDocument); } if (node.isShadowRoot()) toShadowRoot(node).setDocument(newDocument); #if DCHECK_IS_ON() didMoveToNewDocumentWasCalled = false; oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument; #endif node.didMoveToNewDocument(oldDocument); #if DCHECK_IS_ON() DCHECK(didMoveToNewDocumentWasCalled); #endif }
inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDocument, Document* newDocument) const { ASSERT(!node->inDocument() || oldDocument != newDocument); newDocument->incrementReferencingNodeCount(); oldDocument->decrementReferencingNodeCount(); if (node->hasRareData()) { NodeRareData* rareData = node->rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptDocument(oldDocument, newDocument); } if (oldDocument) oldDocument->moveNodeIteratorsToNewDocument(node, newDocument); if (is<ShadowRoot>(*node)) downcast<ShadowRoot>(*node).setDocumentScope(newDocument); #ifndef NDEBUG didMoveToNewDocumentWasCalled = false; oldDocumentDidMoveToNewDocumentWasCalledWith = oldDocument; #endif node->didMoveToNewDocument(oldDocument); ASSERT(didMoveToNewDocumentWasCalled); }
void TreeScopeAdopter::moveTreeToNewScope(Node& root) const { ASSERT(needsScopeChange()); #if !ENABLE(OILPAN) oldScope().guardRef(); #endif // If an element is moved from a document and then eventually back again the collection cache for // that element may contain stale data as changes made to it will have updated the DOMTreeVersion // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here // we ensure that the collection cache will be invalidated as needed when the element is moved back. Document& oldDocument = oldScope().document(); Document& newDocument = newScope().document(); bool willMoveToNewDocument = oldDocument != newDocument; AXObjectCache* axObjectCache = oldDocument.existingAXObjectCache(); if (willMoveToNewDocument) oldDocument.incDOMTreeVersion(); for (Node& node : NodeTraversal::inclusiveDescendantsOf(root)) { updateTreeScope(node); if (willMoveToNewDocument) { if (axObjectCache) axObjectCache->remove(&node); moveNodeToNewDocument(node, oldDocument, newDocument); } else if (node.hasRareData()) { NodeRareData* rareData = node.rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptTreeScope(); } if (!node.isElementNode()) continue; if (node.hasSyntheticAttrChildNodes()) { WillBeHeapVector<RefPtrWillBeMember<Attr>>& attrs = *toElement(node).attrNodeList(); for (unsigned i = 0; i < attrs.size(); ++i) moveTreeToNewScope(*attrs[i]); } for (ShadowRoot* shadow = node.youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) { shadow->setParentTreeScope(newScope()); if (willMoveToNewDocument) moveTreeToNewDocument(*shadow, oldDocument, newDocument); } } #if !ENABLE(OILPAN) oldScope().guardDeref(); #endif }
void TreeScopeAdopter::moveTreeToNewScope(Node& root) const { DCHECK(needsScopeChange()); // If an element is moved from a document and then eventually back again the // collection cache for that element may contain stale data as changes made to // it will have updated the DOMTreeVersion of the document it was moved to. By // increasing the DOMTreeVersion of the donating document here we ensure that // the collection cache will be invalidated as needed when the element is // moved back. Document& oldDocument = oldScope().document(); Document& newDocument = newScope().document(); bool willMoveToNewDocument = oldDocument != newDocument; if (willMoveToNewDocument) oldDocument.incDOMTreeVersion(); for (Node& node : NodeTraversal::inclusiveDescendantsOf(root)) { updateTreeScope(node); if (willMoveToNewDocument) { moveNodeToNewDocument(node, oldDocument, newDocument); } else if (node.hasRareData()) { NodeRareData* rareData = node.rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptTreeScope(); } if (!node.isElementNode()) continue; Element& element = toElement(node); if (HeapVector<Member<Attr>>* attrs = element.attrNodeList()) { for (const auto& attr : *attrs) moveTreeToNewScope(*attr); } for (ShadowRoot* shadow = element.youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) { shadow->setParentTreeScope(newScope()); if (willMoveToNewDocument) moveTreeToNewDocument(*shadow, oldDocument, newDocument); } } if (!willMoveToNewDocument) return; oldDocument.didMoveTreeToNewDocument(root); }
// FIXME: Do we ever change tree scopes except between documents? void TreeScopeAdopter::moveTreeToNewScope(Node* root) const { ASSERT(needsScopeChange()); // If an element is moved from a document and then eventually back again the collection cache for // that element may contain stale data as changes made to it will have updated the DOMTreeVersion // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here // we ensure that the collection cache will be invalidated as needed when the element is moved back. Document& oldDocument = m_oldScope.documentScope(); Document& newDocument = m_newScope.documentScope(); bool willMoveToNewDocument = &oldDocument != &newDocument; if (willMoveToNewDocument) { oldDocument.incrementReferencingNodeCount(); oldDocument.incDOMTreeVersion(); } for (Node* node = root; node; node = NodeTraversal::next(node, root)) { updateTreeScope(node); if (willMoveToNewDocument) moveNodeToNewDocument(node, &oldDocument, &newDocument); else if (node->hasRareData()) { NodeRareData* rareData = node->rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptTreeScope(); } if (!is<Element>(*node)) continue; if (node->hasSyntheticAttrChildNodes()) { const Vector<RefPtr<Attr>>& attrs = downcast<Element>(*node).attrNodeList(); for (unsigned i = 0; i < attrs.size(); ++i) moveTreeToNewScope(attrs[i].get()); } if (ShadowRoot* shadow = node->shadowRoot()) { shadow->setParentTreeScope(&m_newScope); if (willMoveToNewDocument) moveShadowTreeToNewDocument(shadow, &oldDocument, &newDocument); } } if (willMoveToNewDocument) oldDocument.decrementReferencingNodeCount(); }
void TreeScopeAdopter::moveTreeToNewScope(Node* root) const { ASSERT(needsScopeChange()); m_oldScope->guardRef(); // If an element is moved from a document and then eventually back again the collection cache for // that element may contain stale data as changes made to it will have updated the DOMTreeVersion // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here // we ensure that the collection cache will be invalidated as needed when the element is moved back. Document* oldDocument = m_oldScope->documentScope(); Document* newDocument = m_newScope->documentScope(); bool willMoveToNewDocument = oldDocument != newDocument; if (oldDocument && willMoveToNewDocument) oldDocument->incDOMTreeVersion(); for (Node* node = root; node; node = NodeTraversal::next(node, root)) { updateTreeScope(node); if (willMoveToNewDocument) moveNodeToNewDocument(node, oldDocument, newDocument); else if (node->hasRareData()) { NodeRareData* rareData = node->rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptTreeScope(); } if (!node->isElementNode()) continue; if (node->hasSyntheticAttrChildNodes()) { const Vector<RefPtr<Attr> >& attrs = toElement(node)->attrNodeList(); for (unsigned i = 0; i < attrs.size(); ++i) moveTreeToNewScope(attrs[i].get()); } for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) { shadow->setParentTreeScope(m_newScope); if (willMoveToNewDocument) moveTreeToNewDocument(shadow, oldDocument, newDocument); } } m_oldScope->guardDeref(); }
inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument) const { ASSERT(oldDocument != newDocument); if (node.hasRareData()) { NodeRareData* rareData = node.rareData(); if (rareData->nodeLists()) rareData->nodeLists()->adoptDocument(oldDocument, newDocument); } oldDocument.moveNodeIteratorsToNewDocument(node, newDocument); if (node.isShadowRoot()) toShadowRoot(node).setDocument(newDocument); #ifndef NDEBUG didMoveToNewDocumentWasCalled = false; oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument; #endif node.didMoveToNewDocument(oldDocument); ASSERT(didMoveToNewDocumentWasCalled); }
PassRefPtr<NodeList> HTMLFormControlElement::labels() { if (!isLabelable()) return 0; if (!document()) return 0; NodeRareData* data = Node::ensureRareData(); if (!data->nodeLists()) { data->setNodeLists(NodeListsNodeData::create()); document()->addNodeListCache(); } return LabelsNodeList::create(this); }