Index: third_party/WebKit/Source/core/dom/Fullscreen.cpp |
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp |
index 9095f989c1615a6a6d51fe42a0be25c91ba58d0a..60a91662e467be9ae73c67779cbf7953b6b55943 100644 |
--- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp |
+++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp |
@@ -194,20 +194,38 @@ Event* createEvent(const AtomicString& type, EventTarget& target) { |
return event; |
} |
+// Walks the frame tree and returns the first local ancestor frame, if any. |
+LocalFrame* nextLocalAncestor(Frame& frame) { |
+ Frame* parent = frame.tree().parent(); |
+ if (!parent) |
+ return nullptr; |
+ if (parent->isLocalFrame()) |
+ return toLocalFrame(parent); |
+ return nextLocalAncestor(*parent); |
+} |
+ |
+// Walks the document's frame tree and returns the document of the first local |
+// ancestor frame, if any. |
+Document* nextLocalAncestor(Document& document) { |
+ LocalFrame* frame = document.frame(); |
+ if (!frame) |
+ return nullptr; |
+ LocalFrame* next = nextLocalAncestor(*document.frame()); |
+ if (!next) |
+ return nullptr; |
+ DCHECK(next->document()); |
+ return next->document(); |
+} |
+ |
// Helper to walk the ancestor chain and return the Document of the topmost |
// local ancestor frame. Note that this is not the same as the topmost frame's |
// Document, which might be unavailable in OOPIF scenarios. For example, with |
// OOPIFs, when called on the bottom frame's Document in a A-B-C-B hierarchy in |
// process B, this will skip remote frame C and return this frame: A-[B]-C-B. |
Document& topmostLocalAncestor(Document& document) { |
- Document* topmost = &document; |
- Frame* frame = document.frame(); |
- while (frame) { |
- frame = frame->tree().parent(); |
- if (frame && frame->isLocalFrame()) |
- topmost = toLocalFrame(frame)->document(); |
- } |
- return *topmost; |
+ if (Document* next = nextLocalAncestor(document)) |
+ return topmostLocalAncestor(*next); |
+ return document; |
} |
// Helper to find the browsing context container in |doc| that embeds the |
@@ -389,13 +407,8 @@ void Fullscreen::requestFullscreen(Element& element, |
// process, where the message should be queued up and processed after |
// the IPC that dispatches fullscreenchange. |
HeapDeque<Member<Document>> docs; |
- |
- docs.prepend(&document); |
- for (Frame* frame = document.frame()->tree().parent(); frame; |
- frame = frame->tree().parent()) { |
- if (frame->isLocalFrame()) |
- docs.prepend(toLocalFrame(frame)->document()); |
- } |
+ for (Document* doc = &document; doc; doc = nextLocalAncestor(*doc)) |
+ docs.prepend(doc); |
// 4. For each document in docs, run these substeps: |
HeapDeque<Member<Document>>::iterator current = docs.begin(), |
@@ -548,13 +561,8 @@ void Fullscreen::exitFullscreen(Document& document) { |
// TODO(alexmos): Deal with nested fullscreen cases, see |
// https://crbug.com/617369. |
if (!newTop) { |
- Frame* frame = currentDoc->frame()->tree().parent(); |
- while (frame && frame->isRemoteFrame()) |
- frame = frame->tree().parent(); |
- if (frame) { |
- currentDoc = toLocalFrame(frame)->document(); |
- continue; |
- } |
+ currentDoc = nextLocalAncestor(*currentDoc); |
+ continue; |
} |
// 4. Otherwise, set doc to null. |