Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: third_party/WebKit/Source/core/dom/Fullscreen.cpp

Issue 2040973003: OOPIF: Process all local ancestors when requesting and exiting fullscreen. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/site_per_process_interactive_browsertest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 r ights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r ights reserved.
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
9 * Copyright (C) 2013 Google Inc. All rights reserved. 9 * Copyright (C) 2013 Google Inc. All rights reserved.
10 * 10 *
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 114
115 static Event* createEvent(const AtomicString& type, EventTarget& target) 115 static Event* createEvent(const AtomicString& type, EventTarget& target)
116 { 116 {
117 EventInit initializer; 117 EventInit initializer;
118 initializer.setBubbles(isPrefixed(type)); 118 initializer.setBubbles(isPrefixed(type));
119 Event* event = Event::create(type, initializer); 119 Event* event = Event::create(type, initializer);
120 event->setTarget(&target); 120 event->setTarget(&target);
121 return event; 121 return event;
122 } 122 }
123 123
124 static Document& topmostDocument(Document& document)
foolip 2016/06/09 13:12:36 Can you name this so that it's clear that it's not
alexmos 2016/06/09 21:36:55 Renamed to topmostLocalAncestor and added a commen
foolip 2016/06/22 16:23:58 That's great, and the comments throughout this CL
125 {
126 Document* topmost = &document;
127 Frame* frame = document.frame();
128 while (frame) {
129 frame = frame->tree().parent();
130 if (frame && frame->isLocalFrame())
131 topmost = toLocalFrame(frame)->document();
132 }
133 return *topmost;
134 }
135
124 const char* Fullscreen::supplementName() 136 const char* Fullscreen::supplementName()
125 { 137 {
126 return "Fullscreen"; 138 return "Fullscreen";
127 } 139 }
128 140
129 Fullscreen& Fullscreen::from(Document& document) 141 Fullscreen& Fullscreen::from(Document& document)
130 { 142 {
131 Fullscreen* fullscreen = fromIfExists(document); 143 Fullscreen* fullscreen = fromIfExists(document);
132 if (!fullscreen) { 144 if (!fullscreen) {
133 fullscreen = new Fullscreen(document); 145 fullscreen = new Fullscreen(document);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 document()->addConsoleMessage( 247 document()->addConsoleMessage(
236 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, mes sage)); 248 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, mes sage));
237 break; 249 break;
238 } 250 }
239 251
240 // Fullscreen is not supported. 252 // Fullscreen is not supported.
241 if (!fullscreenIsSupported(element.document())) 253 if (!fullscreenIsSupported(element.document()))
242 break; 254 break;
243 255
244 // 2. Let doc be element's node document. (i.e. "this") 256 // 2. Let doc be element's node document. (i.e. "this")
245 Document* currentDoc = document(); 257 Frame* currentFrame = document()->frame();
foolip 2016/06/09 13:12:36 The spec quotes are a lot let useful when the name
alexmos 2016/06/09 21:36:55 The main reason I originally kept ancestors as Fra
foolip 2016/06/22 16:23:58 Looks great :)
246 258
247 // 3. Let docs be all doc's ancestor browsing context's documents (if an y) and doc. 259 // 3. Let docs be all doc's ancestor browsing context's documents (if an y) and doc.
248 HeapDeque<Member<Document>> docs; 260 HeapDeque<Member<Frame>> ancestors;
249 261
250 do { 262 do {
251 docs.prepend(currentDoc); 263 ancestors.prepend(currentFrame);
252 currentDoc = currentDoc->localOwner() ? &currentDoc->localOwner()->d ocument() : nullptr; 264 currentFrame = currentFrame->tree().parent();
253 } while (currentDoc); 265 } while (currentFrame);
254 266
255 // 4. For each document in docs, run these substeps: 267 // 4. For each document in docs, run these substeps:
256 HeapDeque<Member<Document>>::iterator current = docs.begin(), following = docs.begin(); 268 HeapDeque<Member<Frame>>::iterator current = ancestors.begin(), followin g = ancestors.begin();
257 269
258 do { 270 do {
259 ++following; 271 ++following;
260 272
261 // 1. Let following document be the document after document in docs, or null if there is no 273 // 1. Let following document be the document after document in docs, or null if there is no
262 // such document. 274 // such document.
263 Document* currentDoc = *current; 275 Frame* currentFrame = *current;
264 Document* followingDoc = following != docs.end() ? *following : null ptr; 276 Frame* followingFrame = following != ancestors.end() ? *following : nullptr;
265 277
266 // 2. If following document is null, push context object on document 's fullscreen element 278 // 2. If following document is null, push context object on document 's fullscreen element
267 // stack, and queue a task to fire an event named fullscreenchange w ith its bubbles attribute 279 // stack, and queue a task to fire an event named fullscreenchange w ith its bubbles attribute
268 // set to true on the document. 280 // set to true on the document.
269 if (!followingDoc) { 281 if (!followingFrame) {
270 from(*currentDoc).pushFullscreenElementStack(element, requestTyp e); 282 from(*toLocalFrame(currentFrame)->document()).pushFullscreenElem entStack(element, requestType);
271 enqueueChangeEvent(*currentDoc, requestType); 283 enqueueChangeEvent(*toLocalFrame(currentFrame)->document(), requ estType);
272 continue; 284 continue;
273 } 285 }
274 286
275 // 3. Otherwise, if document's fullscreen element stack is either em pty or its top element 287 // 3. Otherwise, if document's fullscreen element stack is either em pty or its top element
276 // is not following document's browsing context container, 288 // is not following document's browsing context container,
289 if (currentFrame->isRemoteFrame())
foolip 2016/06/09 13:12:36 Assuming that this isn't reverted to a list of onl
alexmos 2016/06/09 21:36:55 I did revert to a list of only local documents, so
290 continue;
291 Document* currentDoc = toLocalFrame(currentFrame)->document();
277 Element* topElement = fullscreenElementFrom(*currentDoc); 292 Element* topElement = fullscreenElementFrom(*currentDoc);
278 if (!topElement || topElement != followingDoc->localOwner()) { 293 if (!topElement || topElement != toHTMLFrameOwnerElement(followingFr ame->owner())) {
279 // ...push following document's browsing context container on do cument's fullscreen element 294 // ...push following document's browsing context container on do cument's fullscreen element
280 // stack, and queue a task to fire an event named fullscreenchan ge with its bubbles attribute 295 // stack, and queue a task to fire an event named fullscreenchan ge with its bubbles attribute
281 // set to true on document. 296 // set to true on document.
282 from(*currentDoc).pushFullscreenElementStack(*followingDoc->loca lOwner(), requestType); 297 from(*currentDoc).pushFullscreenElementStack(*toHTMLFrameOwnerEl ement(followingFrame->owner()), requestType);
283 enqueueChangeEvent(*currentDoc, requestType); 298 enqueueChangeEvent(*currentDoc, requestType);
284 continue; 299 continue;
285 } 300 }
286 301
287 // 4. Otherwise, do nothing for this document. It stays the same. 302 // 4. Otherwise, do nothing for this document. It stays the same.
288 } while (++current != docs.end()); 303 } while (++current != ancestors.end());
289 304
290 m_forCrossProcessAncestor = forCrossProcessAncestor; 305 m_forCrossProcessAncestor = forCrossProcessAncestor;
291 306
292 // 5. Return, and run the remaining steps asynchronously. 307 // 5. Return, and run the remaining steps asynchronously.
293 // 6. Optionally, perform some animation. 308 // 6. Optionally, perform some animation.
294 document()->frameHost()->chromeClient().enterFullScreenForElement(&eleme nt); 309 document()->frameHost()->chromeClient().enterFullScreenForElement(&eleme nt);
295 310
296 // 7. Optionally, display a message indicating how the user can exit dis playing the context object fullscreen. 311 // 7. Optionally, display a message indicating how the user can exit dis playing the context object fullscreen.
297 return; 312 return;
298 } while (false); 313 } while (false);
299 314
300 enqueueErrorEvent(element, requestType); 315 enqueueErrorEvent(element, requestType);
301 } 316 }
302 317
303 void Fullscreen::fullyExitFullscreen(Document& document) 318 void Fullscreen::fullyExitFullscreen(Document& document)
304 { 319 {
305 // To fully exit fullscreen, run these steps: 320 // To fully exit fullscreen, run these steps:
306 321
307 // 1. Let |doc| be the top-level browsing context's document. 322 // 1. Let |doc| be the top-level browsing context's document.
308 Document& doc = document.topDocument(); 323 //
324 // For OOPIF, use the Document of the topmost local ancestor frame. Each
foolip 2016/06/09 13:12:36 "Use the document... because OOPIF something somet
alexmos 2016/06/09 21:36:55 Rephrased the comment - let me know if it's better
325 // renderer process for the current page will separately call
326 // fullyExitFullscreen.
327 Document& doc = topmostDocument(document);
309 328
310 // 2. If |doc|'s fullscreen element stack is empty, terminate these steps. 329 // 2. If |doc|'s fullscreen element stack is empty, terminate these steps.
311 if (!fullscreenElementFrom(doc)) 330 if (!fullscreenElementFrom(doc))
312 return; 331 return;
313 332
314 // 3. Remove elements from |doc|'s fullscreen element stack until only the t op element is left. 333 // 3. Remove elements from |doc|'s fullscreen element stack until only the t op element is left.
315 size_t stackSize = from(doc).m_fullScreenElementStack.size(); 334 size_t stackSize = from(doc).m_fullScreenElementStack.size();
316 from(doc).m_fullScreenElementStack.remove(0, stackSize - 1); 335 from(doc).m_fullScreenElementStack.remove(0, stackSize - 1);
317 DCHECK_EQ(from(doc).m_fullScreenElementStack.size(), 1u); 336 DCHECK_EQ(from(doc).m_fullScreenElementStack.size(), 1u);
318 337
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 newTop = fullscreenElementFrom(*currentDoc); 386 newTop = fullscreenElementFrom(*currentDoc);
368 if (newTop && (!newTop->inShadowIncludingDocument() || newTop->document( ) != currentDoc)) 387 if (newTop && (!newTop->inShadowIncludingDocument() || newTop->document( ) != currentDoc))
369 continue; 388 continue;
370 389
371 // 2. Queue a task to fire an event named fullscreenchange with its bubb les attribute set to true 390 // 2. Queue a task to fire an event named fullscreenchange with its bubb les attribute set to true
372 // on doc. 391 // on doc.
373 enqueueChangeEvent(*currentDoc, requestType); 392 enqueueChangeEvent(*currentDoc, requestType);
374 393
375 // 3. If doc's fullscreen element stack is empty and doc's browsing cont ext has a browsing context 394 // 3. If doc's fullscreen element stack is empty and doc's browsing cont ext has a browsing context
376 // container, set doc to that browsing context container's node document . 395 // container, set doc to that browsing context container's node document .
377 if (!newTop && currentDoc->localOwner()) { 396 //
378 currentDoc = &currentDoc->localOwner()->document(); 397 // OOPIF: If browsing context container's document is in another
379 continue; 398 // process, keep moving up the ancestor chain and looking for a
399 // browsing context container with a local document.
400 // TODO(alexmos): Deal with nested fullscreen cases.
foolip 2016/06/09 13:12:36 What cases is that?
alexmos 2016/06/09 21:36:55 I described it in a comment on my original message
foolip 2016/06/22 16:23:58 Can you link to it here, unless it's too specific
alexmos 2016/06/22 18:04:22 Done.
401 if (!newTop) {
402 Frame* frame = currentDoc->frame()->tree().parent();
403 while (frame && frame->isRemoteFrame())
404 frame = frame->tree().parent();
405 if (frame) {
foolip 2016/06/09 13:12:36 OK, so this just skips over the remote frames and
alexmos 2016/06/09 21:36:55 Let me know if you feel this still needs improveme
foolip 2016/06/22 16:23:58 I think the symmetry is there now. What still feel
406 currentDoc = toLocalFrame(frame)->document();
407 continue;
408 }
380 } 409 }
381 410
382 // 4. Otherwise, set doc to null. 411 // 4. Otherwise, set doc to null.
383 currentDoc = 0; 412 currentDoc = 0;
384 } 413 }
385 414
386 // 6. Return, and run the remaining steps asynchronously. 415 // 6. Return, and run the remaining steps asynchronously.
387 // 7. Optionally, perform some animation. 416 // 7. Optionally, perform some animation.
388 417
389 FrameHost* host = document()->frameHost(); 418 FrameHost* host = document()->frameHost();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 m_fullScreenElement = nullptr; 523 m_fullScreenElement = nullptr;
495 524
496 if (document()->frame()) 525 if (document()->frame())
497 document()->frame()->eventHandler().scheduleHoverStateUpdate(); 526 document()->frame()->eventHandler().scheduleHoverStateUpdate();
498 527
499 // When fullyExitFullscreen is called, we call exitFullscreen on the topDocu ment(). That means 528 // When fullyExitFullscreen is called, we call exitFullscreen on the topDocu ment(). That means
500 // that the events will be queued there. So if we have no events here, start the timer on the 529 // that the events will be queued there. So if we have no events here, start the timer on the
501 // exiting document. 530 // exiting document.
502 Document* exitingDocument = document(); 531 Document* exitingDocument = document();
503 if (m_eventQueue.isEmpty()) 532 if (m_eventQueue.isEmpty())
504 exitingDocument = &document()->topDocument(); 533 exitingDocument = &topmostDocument(*document());
505 DCHECK(exitingDocument); 534 DCHECK(exitingDocument);
506 from(*exitingDocument).m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); 535 from(*exitingDocument).m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE);
507 536
508 m_forCrossProcessAncestor = false; 537 m_forCrossProcessAncestor = false;
509 } 538 }
510 539
511 void Fullscreen::setFullScreenLayoutObject(LayoutFullScreen* layoutObject) 540 void Fullscreen::setFullScreenLayoutObject(LayoutFullScreen* layoutObject)
512 { 541 {
513 if (layoutObject == m_fullScreenLayoutObject) 542 if (layoutObject == m_fullScreenLayoutObject)
514 return; 543 return;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 DEFINE_TRACE(Fullscreen) 654 DEFINE_TRACE(Fullscreen)
626 { 655 {
627 visitor->trace(m_fullScreenElement); 656 visitor->trace(m_fullScreenElement);
628 visitor->trace(m_fullScreenElementStack); 657 visitor->trace(m_fullScreenElementStack);
629 visitor->trace(m_eventQueue); 658 visitor->trace(m_eventQueue);
630 Supplement<Document>::trace(visitor); 659 Supplement<Document>::trace(visitor);
631 ContextLifecycleObserver::trace(visitor); 660 ContextLifecycleObserver::trace(visitor);
632 } 661 }
633 662
634 } // namespace blink 663 } // namespace blink
OLDNEW
« no previous file with comments | « chrome/browser/site_per_process_interactive_browsertest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698