Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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() ? ¤tDoc->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 Loading... | |
| 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 = ¤tDoc->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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |