void ChildFrameDisconnector::collectFrameOwners(Node& root) { if (!root.connectedSubframeCount()) return; if (root.isHTMLElement() && root.isFrameOwnerElement()) m_frameOwners.append(&toHTMLFrameOwnerElement(root)); for (Node* child = root.firstChild(); child; child = child->nextSibling()) collectFrameOwners(*child); ElementShadow* shadow = root.isElementNode() ? toElement(root).shadow() : 0; if (shadow) collectFrameOwners(*shadow); }
void disconnectSubframes(ContainerNode& root, SubframeDisconnectPolicy policy) { #ifndef NDEBUG assertConnectedSubrameCountIsConsistent(root); #endif ASSERT(root.connectedSubframeCount()); Vector<Ref<HTMLFrameOwnerElement>> frameOwners; if (policy == RootAndDescendants) { if (is<HTMLFrameOwnerElement>(root)) frameOwners.append(downcast<HTMLFrameOwnerElement>(root)); } collectFrameOwners(frameOwners, root); // Must disable frame loading in the subtree so an unload handler cannot // insert more frames and create loaded frames in detached subtrees. SubframeLoadingDisabler disabler(root); bool isFirst = true; for (auto& owner : frameOwners) { // Don't need to traverse up the tree for the first owner since no // script could have moved it. if (isFirst || root.containsIncludingShadowDOM(&owner.get())) owner.get().disconnectContentFrame(); isFirst = false; } }
void ChildFrameDisconnector::disconnect(DisconnectPolicy policy) { #if ENABLE(ASSERT) checkConnectedSubframeCountIsConsistent(root()); #endif if (!root().connectedSubframeCount()) return; if (policy == RootAndDescendants) { collectFrameOwners(root()); } else { for (Node* child = root().firstChild(); child; child = child->nextSibling()) collectFrameOwners(*child); } disconnectCollectedFrameOwners(); }
static void collectFrameOwners(Vector<Ref<HTMLFrameOwnerElement>>& frameOwners, ContainerNode& root) { auto elementDescendants = descendantsOfType<Element>(root); auto it = elementDescendants.begin(); auto end = elementDescendants.end(); while (it != end) { Element& element = *it; if (!element.connectedSubframeCount()) { it.traverseNextSkippingChildren(); continue; } if (is<HTMLFrameOwnerElement>(element)) frameOwners.append(downcast<HTMLFrameOwnerElement>(element)); if (ShadowRoot* shadowRoot = element.shadowRoot()) collectFrameOwners(frameOwners, *shadowRoot); ++it; } }
void ChildFrameDisconnector::collectFrameOwners(ElementShadow& shadow) { for (ShadowRoot* root = &shadow.youngestShadowRoot(); root; root = root->olderShadowRoot()) collectFrameOwners(*root); }