OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All |
7 * rights reserved. | 7 * rights reserved. |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 10 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 } | 187 } |
188 | 188 |
189 Event* createEvent(const AtomicString& type, EventTarget& target) { | 189 Event* createEvent(const AtomicString& type, EventTarget& target) { |
190 EventInit initializer; | 190 EventInit initializer; |
191 initializer.setBubbles(isPrefixed(type)); | 191 initializer.setBubbles(isPrefixed(type)); |
192 Event* event = Event::create(type, initializer); | 192 Event* event = Event::create(type, initializer); |
193 event->setTarget(&target); | 193 event->setTarget(&target); |
194 return event; | 194 return event; |
195 } | 195 } |
196 | 196 |
197 // Walks the frame tree and returns the first local ancestor frame, if any. | |
198 LocalFrame* nextLocalAncestor(Frame& frame) { | |
199 Frame* parent = frame.tree().parent(); | |
200 if (!parent) | |
201 return nullptr; | |
202 if (parent->isLocalFrame()) | |
203 return toLocalFrame(parent); | |
204 return nextLocalAncestor(*parent); | |
205 } | |
206 | |
207 // Walks the document's frame tree and returns the document of the first local | |
208 // ancestor frame, if any. | |
209 Document* nextLocalAncestor(Document& document) { | |
210 if (LocalFrame* frame = document.frame()) { | |
211 if (LocalFrame* next = nextLocalAncestor(*frame)) { | |
212 DCHECK(next->document()); | |
213 return next->document(); | |
214 } | |
215 } | |
216 return nullptr; | |
mlamouri (slow - plz ping)
2016/12/12 13:36:56
Feel free to ignore but I think it would read bett
foolip
2016/12/12 16:56:31
The ternary part of that was how I started out, bu
| |
217 } | |
218 | |
197 // Helper to walk the ancestor chain and return the Document of the topmost | 219 // Helper to walk the ancestor chain and return the Document of the topmost |
198 // local ancestor frame. Note that this is not the same as the topmost frame's | 220 // local ancestor frame. Note that this is not the same as the topmost frame's |
199 // Document, which might be unavailable in OOPIF scenarios. For example, with | 221 // Document, which might be unavailable in OOPIF scenarios. For example, with |
200 // OOPIFs, when called on the bottom frame's Document in a A-B-C-B hierarchy in | 222 // OOPIFs, when called on the bottom frame's Document in a A-B-C-B hierarchy in |
201 // process B, this will skip remote frame C and return this frame: A-[B]-C-B. | 223 // process B, this will skip remote frame C and return this frame: A-[B]-C-B. |
202 Document& topmostLocalAncestor(Document& document) { | 224 Document& topmostLocalAncestor(Document& document) { |
203 Document* topmost = &document; | 225 if (Document* next = nextLocalAncestor(document)) |
204 Frame* frame = document.frame(); | 226 return topmostLocalAncestor(*next); |
205 while (frame) { | 227 return document; |
206 frame = frame->tree().parent(); | |
207 if (frame && frame->isLocalFrame()) | |
208 topmost = toLocalFrame(frame)->document(); | |
209 } | |
210 return *topmost; | |
211 } | 228 } |
212 | 229 |
213 // Helper to find the browsing context container in |doc| that embeds the | 230 // Helper to find the browsing context container in |doc| that embeds the |
214 // |descendant| Document, possibly through multiple levels of nesting. This | 231 // |descendant| Document, possibly through multiple levels of nesting. This |
215 // works even in OOPIF scenarios like A-B-A, where there may be remote frames | 232 // works even in OOPIF scenarios like A-B-A, where there may be remote frames |
216 // in between |doc| and |descendant|. | 233 // in between |doc| and |descendant|. |
217 HTMLFrameOwnerElement* findContainerForDescendant(const Document& doc, | 234 HTMLFrameOwnerElement* findContainerForDescendant(const Document& doc, |
218 const Document& descendant) { | 235 const Document& descendant) { |
219 Frame* frame = descendant.frame(); | 236 Frame* frame = descendant.frame(); |
220 while (frame->tree().parent() != doc.frame()) | 237 while (frame->tree().parent() != doc.frame()) |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 // | 393 // |
377 // For OOPIF scenarios, |docs| will only contain documents for local | 394 // For OOPIF scenarios, |docs| will only contain documents for local |
378 // ancestors, and remote ancestors will be processed in their | 395 // ancestors, and remote ancestors will be processed in their |
379 // respective processes. This preserves the spec's event firing order | 396 // respective processes. This preserves the spec's event firing order |
380 // for local ancestors, but not for remote ancestors. However, that | 397 // for local ancestors, but not for remote ancestors. However, that |
381 // difference shouldn't be observable in practice: a fullscreenchange | 398 // difference shouldn't be observable in practice: a fullscreenchange |
382 // event handler would need to postMessage a frame in another renderer | 399 // event handler would need to postMessage a frame in another renderer |
383 // process, where the message should be queued up and processed after | 400 // process, where the message should be queued up and processed after |
384 // the IPC that dispatches fullscreenchange. | 401 // the IPC that dispatches fullscreenchange. |
385 HeapDeque<Member<Document>> docs; | 402 HeapDeque<Member<Document>> docs; |
386 | 403 for (Document* doc = &document; doc; doc = nextLocalAncestor(*doc)) |
387 docs.prepend(&document); | 404 docs.prepend(doc); |
388 for (Frame* frame = document.frame()->tree().parent(); frame; | |
389 frame = frame->tree().parent()) { | |
390 if (frame->isLocalFrame()) | |
391 docs.prepend(toLocalFrame(frame)->document()); | |
392 } | |
393 | 405 |
394 // 4. For each document in docs, run these substeps: | 406 // 4. For each document in docs, run these substeps: |
395 HeapDeque<Member<Document>>::iterator current = docs.begin(), | 407 HeapDeque<Member<Document>>::iterator current = docs.begin(), |
396 following = docs.begin(); | 408 following = docs.begin(); |
397 | 409 |
398 do { | 410 do { |
399 ++following; | 411 ++following; |
400 | 412 |
401 // 1. Let following document be the document after document in docs, or | 413 // 1. Let following document be the document after document in docs, or |
402 // null if there is no such document. | 414 // null if there is no such document. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 | 546 |
535 // 3. If doc's fullscreen element stack is empty and doc's browsing context | 547 // 3. If doc's fullscreen element stack is empty and doc's browsing context |
536 // has a browsing context container, set doc to that browsing context | 548 // has a browsing context container, set doc to that browsing context |
537 // container's node document. | 549 // container's node document. |
538 // | 550 // |
539 // OOPIF: If browsing context container's document is in another | 551 // OOPIF: If browsing context container's document is in another |
540 // process, keep moving up the ancestor chain and looking for a | 552 // process, keep moving up the ancestor chain and looking for a |
541 // browsing context container with a local document. | 553 // browsing context container with a local document. |
542 // TODO(alexmos): Deal with nested fullscreen cases, see | 554 // TODO(alexmos): Deal with nested fullscreen cases, see |
543 // https://crbug.com/617369. | 555 // https://crbug.com/617369. |
544 if (!newTop) { | 556 if (!newTop) |
545 Frame* frame = currentDoc->frame()->tree().parent(); | 557 currentDoc = nextLocalAncestor(*currentDoc); |
546 while (frame && frame->isRemoteFrame()) | |
547 frame = frame->tree().parent(); | |
548 if (frame) { | |
549 currentDoc = toLocalFrame(frame)->document(); | |
550 continue; | |
551 } | |
552 } | |
553 | 558 |
554 // 4. Otherwise, set doc to null. | 559 // 4. Otherwise, set doc to null. |
555 currentDoc = nullptr; | 560 currentDoc = nullptr; |
556 } | 561 } |
557 | 562 |
558 // 6. Return, and run the remaining steps asynchronously. | 563 // 6. Return, and run the remaining steps asynchronously. |
559 // 7. Optionally, perform some animation. | 564 // 7. Optionally, perform some animation. |
560 | 565 |
561 // Only exit fullscreen mode if the fullscreen element stack is empty. | 566 // Only exit fullscreen mode if the fullscreen element stack is empty. |
562 if (!newTop) { | 567 if (!newTop) { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
812 DEFINE_TRACE(Fullscreen) { | 817 DEFINE_TRACE(Fullscreen) { |
813 visitor->trace(m_pendingFullscreenElement); | 818 visitor->trace(m_pendingFullscreenElement); |
814 visitor->trace(m_fullscreenElementStack); | 819 visitor->trace(m_fullscreenElementStack); |
815 visitor->trace(m_currentFullScreenElement); | 820 visitor->trace(m_currentFullScreenElement); |
816 visitor->trace(m_eventQueue); | 821 visitor->trace(m_eventQueue); |
817 Supplement<Document>::trace(visitor); | 822 Supplement<Document>::trace(visitor); |
818 ContextLifecycleObserver::trace(visitor); | 823 ContextLifecycleObserver::trace(visitor); |
819 } | 824 } |
820 | 825 |
821 } // namespace blink | 826 } // namespace blink |
OLD | NEW |