summaryrefslogtreecommitdiff
path: root/Source/WebCore/page/FrameTree.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/page/FrameTree.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/page/FrameTree.cpp')
-rw-r--r--Source/WebCore/page/FrameTree.cpp186
1 files changed, 128 insertions, 58 deletions
diff --git a/Source/WebCore/page/FrameTree.cpp b/Source/WebCore/page/FrameTree.cpp
index 2ef23b335..4e1bc29b7 100644
--- a/Source/WebCore/page/FrameTree.cpp
+++ b/Source/WebCore/page/FrameTree.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -38,7 +38,7 @@ namespace WebCore {
FrameTree::~FrameTree()
{
for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
- child->setView(0);
+ child->setView(nullptr);
}
void FrameTree::setName(const AtomicString& name)
@@ -48,14 +48,14 @@ void FrameTree::setName(const AtomicString& name)
m_uniqueName = name;
return;
}
- m_uniqueName = AtomicString(); // Remove our old frame name so it's not considered in uniqueChildName.
+ m_uniqueName = nullAtom; // Remove our old frame name so it's not considered in uniqueChildName.
m_uniqueName = parent()->tree().uniqueChildName(name);
}
void FrameTree::clearName()
{
- m_name = AtomicString();
- m_uniqueName = AtomicString();
+ m_name = nullAtom;
+ m_uniqueName = nullAtom;
}
Frame* FrameTree::parent() const
@@ -63,80 +63,61 @@ Frame* FrameTree::parent() const
return m_parent;
}
-bool FrameTree::transferChild(PassRefPtr<Frame> child)
+unsigned FrameTree::indexInParent() const
{
- Frame* oldParent = child->tree().parent();
- if (oldParent == &m_thisFrame)
- return false; // |child| is already a child of m_thisFrame.
-
- if (oldParent)
- oldParent->tree().removeChild(child.get());
-
- ASSERT(child->page() == m_thisFrame.page());
- child->tree().m_parent = &m_thisFrame;
-
- // We need to ensure that the child still has a unique frame name with respect to its new parent.
- child->tree().setName(child->tree().m_name);
-
- actuallyAppendChild(child); // Note, on return |child| is null.
- return true;
-}
-
-void FrameTree::appendChild(PassRefPtr<Frame> child)
-{
- ASSERT(child->page() == m_thisFrame.page());
- child->tree().m_parent = &m_thisFrame;
- actuallyAppendChild(child); // Note, on return |child| is null.
+ if (!m_parent)
+ return 0;
+ unsigned index = 0;
+ for (Frame* frame = m_parent->tree().firstChild(); frame; frame = frame->tree().nextSibling()) {
+ if (&frame->tree() == this)
+ return index;
+ ++index;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
}
-void FrameTree::actuallyAppendChild(PassRefPtr<Frame> child)
+void FrameTree::appendChild(Frame& child)
{
- ASSERT(child->tree().m_parent == &m_thisFrame);
+ ASSERT(child.page() == m_thisFrame.page());
+ child.tree().m_parent = &m_thisFrame;
Frame* oldLast = m_lastChild;
- m_lastChild = child.get();
+ m_lastChild = &child;
if (oldLast) {
- child->tree().m_previousSibling = oldLast;
- oldLast->tree().m_nextSibling = child;
+ child.tree().m_previousSibling = oldLast;
+ oldLast->tree().m_nextSibling = &child;
} else
- m_firstChild = child;
+ m_firstChild = &child;
m_scopedChildCount = invalidCount;
ASSERT(!m_lastChild->tree().m_nextSibling);
}
-void FrameTree::removeChild(Frame* child)
+void FrameTree::removeChild(Frame& child)
{
- child->tree().m_parent = 0;
-
- // Slightly tricky way to prevent deleting the child until we are done with it, w/o
- // extra refs. These swaps leave the child in a circular list by itself. Clearing its
- // previous and next will then finally deref it.
+ Frame*& newLocationForPrevious = m_lastChild == &child ? m_lastChild : child.tree().m_nextSibling->tree().m_previousSibling;
+ RefPtr<Frame>& newLocationForNext = m_firstChild == &child ? m_firstChild : child.tree().m_previousSibling->tree().m_nextSibling;
- RefPtr<Frame>& newLocationForNext = m_firstChild == child ? m_firstChild : child->tree().m_previousSibling->tree().m_nextSibling;
- Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->tree().m_nextSibling->tree().m_previousSibling;
- swap(newLocationForNext, child->tree().m_nextSibling);
- // For some inexplicable reason, the following line does not compile without the explicit std:: namespace
- std::swap(newLocationForPrevious, child->tree().m_previousSibling);
-
- child->tree().m_previousSibling = 0;
- child->tree().m_nextSibling = 0;
+ child.tree().m_parent = nullptr;
+ newLocationForPrevious = std::exchange(child.tree().m_previousSibling, nullptr);
+ newLocationForNext = WTFMove(child.tree().m_nextSibling);
m_scopedChildCount = invalidCount;
}
AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
{
+ // If the requested name (the frame's "name" attribute) is unique, just use that.
if (!requestedName.isEmpty() && !child(requestedName) && requestedName != "_blank")
return requestedName;
- // Create a repeatable name for a child about to be added to us. The name must be
- // unique within the frame tree. The string we generate includes a "path" of names
- // from the root frame down to us. For this path to be unique, each set of siblings must
- // contribute a unique name to the path, which can't collide with any HTML-assigned names.
- // We generate this path component by index in the child list along with an unlikely
- // frame name that can't be set in HTML because it collides with comment syntax.
+ // The "name" attribute was not unique or absent. Generate a name based on the
+ // new frame's location in the frame tree. The name uses HTML comment syntax to
+ // avoid collisions with author names.
+
+ // An example path for the third child of the second child of the root frame:
+ // <!--framePath //<!--frame1-->/<!--frame2-->-->
const char framePathPrefix[] = "<!--framePath ";
const int framePathPrefixLength = 14;
@@ -159,7 +140,11 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
for (int i = chain.size() - 1; i >= 0; --i) {
frame = chain[i];
name.append('/');
- name.append(frame->tree().uniqueName());
+ if (frame->tree().parent()) {
+ name.appendLiteral("<!--frame");
+ name.appendNumber(frame->tree().indexInParent());
+ name.appendLiteral("-->");
+ }
}
name.appendLiteral("/<!--frame");
@@ -356,6 +341,68 @@ Frame* FrameTree::traverseNext(const Frame* stayWithin) const
return nullptr;
}
+Frame* FrameTree::firstRenderedChild() const
+{
+ Frame* child = firstChild();
+ if (!child)
+ return nullptr;
+
+ if (child->ownerRenderer())
+ return child;
+
+ while ((child = child->tree().nextSibling())) {
+ if (child->ownerRenderer())
+ return child;
+ }
+
+ return nullptr;
+}
+
+Frame* FrameTree::nextRenderedSibling() const
+{
+ Frame* sibling = &m_thisFrame;
+
+ while ((sibling = sibling->tree().nextSibling())) {
+ if (sibling->ownerRenderer())
+ return sibling;
+ }
+
+ return nullptr;
+}
+
+Frame* FrameTree::traverseNextRendered(const Frame* stayWithin) const
+{
+ Frame* child = firstRenderedChild();
+ if (child) {
+ ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin));
+ return child;
+ }
+
+ if (&m_thisFrame == stayWithin)
+ return nullptr;
+
+ Frame* sibling = nextRenderedSibling();
+ if (sibling) {
+ ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin));
+ return sibling;
+ }
+
+ Frame* frame = &m_thisFrame;
+ while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) {
+ frame = frame->tree().parent();
+ if (!frame)
+ return nullptr;
+ sibling = frame->tree().nextRenderedSibling();
+ }
+
+ if (frame) {
+ ASSERT(!stayWithin || !sibling || sibling->tree().isDescendantOf(stayWithin));
+ return sibling;
+ }
+
+ return nullptr;
+}
+
Frame* FrameTree::traverseNextWithWrap(bool wrap) const
{
if (Frame* result = traverseNext())
@@ -384,6 +431,25 @@ Frame* FrameTree::traversePreviousWithWrap(bool wrap) const
return nullptr;
}
+Frame* FrameTree::traverseNextInPostOrderWithWrap(bool wrap) const
+{
+ if (m_nextSibling)
+ return m_nextSibling->tree().deepFirstChild();
+ if (m_parent)
+ return m_parent;
+ if (wrap)
+ return deepFirstChild();
+ return nullptr;
+}
+
+Frame* FrameTree::deepFirstChild() const
+{
+ Frame* result = &m_thisFrame;
+ while (auto* next = result->tree().firstChild())
+ result = next;
+ return result;
+}
+
Frame* FrameTree::deepLastChild() const
{
Frame* result = &m_thisFrame;
@@ -424,11 +490,15 @@ static void printFrames(const WebCore::Frame& frame, const WebCore::Frame* targe
printIndent(indent);
printf(" ownerElement=%p\n", frame.ownerElement());
printIndent(indent);
- printf(" frameView=%p\n", view);
+ printf(" frameView=%p (needs layout %d)\n", view, view ? view->needsLayout() : false);
+ printIndent(indent);
+ printf(" renderView=%p\n", view ? view->renderView() : nullptr);
+ printIndent(indent);
+ printf(" ownerRenderer=%p\n", frame.ownerRenderer());
printIndent(indent);
- printf(" document=%p\n", frame.document());
+ printf(" document=%p (needs style recalc %d)\n", frame.document(), frame.document() ? frame.document()->childNeedsStyleRecalc() : false);
printIndent(indent);
- printf(" uri=%s\n\n", frame.document()->documentURI().utf8().data());
+ printf(" uri=%s\n", frame.document()->documentURI().utf8().data());
for (WebCore::Frame* child = frame.tree().firstChild(); child; child = child->tree().nextSibling())
printFrames(*child, targetFrame, indent + 1);