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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 112 |
113 inline Document* FullscreenElementStack::document() | 113 inline Document* FullscreenElementStack::document() |
114 { | 114 { |
115 return lifecycleContext(); | 115 return lifecycleContext(); |
116 } | 116 } |
117 | 117 |
118 void FullscreenElementStack::documentWasDetached() | 118 void FullscreenElementStack::documentWasDetached() |
119 { | 119 { |
120 m_fullScreenChangeEventTargetQueue.clear(); | 120 m_fullScreenChangeEventTargetQueue.clear(); |
121 m_fullScreenErrorEventTargetQueue.clear(); | 121 m_fullScreenErrorEventTargetQueue.clear(); |
122 | |
123 if (m_fullScreenRenderer) | |
124 setFullScreenRenderer(0); | |
125 } | 122 } |
126 | 123 |
127 void FullscreenElementStack::documentWasDisposed() | 124 void FullscreenElementStack::documentWasDisposed() |
128 { | 125 { |
129 m_fullScreenElement = 0; | 126 m_fullScreenElement = 0; |
130 m_fullScreenElementStack.clear(); | 127 m_fullScreenElementStack.clear(); |
131 } | 128 } |
132 | 129 |
133 bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) con
st | 130 bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) con
st |
134 { | 131 { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 // "To fully exit fullscreen act as if the exitFullscreen() method was invok
ed on the top-level browsing | 254 // "To fully exit fullscreen act as if the exitFullscreen() method was invok
ed on the top-level browsing |
258 // context's document and subsequently empty that document's fullscreen elem
ent stack." | 255 // context's document and subsequently empty that document's fullscreen elem
ent stack." |
259 if (!fullscreenElementFrom(document()->topDocument())) | 256 if (!fullscreenElementFrom(document()->topDocument())) |
260 return; | 257 return; |
261 | 258 |
262 // To achieve that aim, remove all the elements from the top document's stac
k except for the first before | 259 // To achieve that aim, remove all the elements from the top document's stac
k except for the first before |
263 // calling webkitExitFullscreen(): | 260 // calling webkitExitFullscreen(): |
264 Vector<RefPtr<Element> > replacementFullscreenElementStack; | 261 Vector<RefPtr<Element> > replacementFullscreenElementStack; |
265 replacementFullscreenElementStack.append(fullscreenElementFrom(document()->t
opDocument())); | 262 replacementFullscreenElementStack.append(fullscreenElementFrom(document()->t
opDocument())); |
266 FullscreenElementStack* topFullscreenElementStack = from(document()->topDocu
ment()); | 263 FullscreenElementStack* topFullscreenElementStack = from(document()->topDocu
ment()); |
| 264 Vector<RefPtr<Element> >::iterator end = topFullscreenElementStack->m_fullSc
reenElementStack.end(); |
| 265 // FIXME: This will remove a modal full screen dialog from the top layer. Do |
| 266 // we care about this case? Really we shouldn't have separate vectors for |
| 267 // full screen element stack and top layer. |
| 268 for (Vector<RefPtr<Element> >::iterator iter = topFullscreenElementStack->m_
fullScreenElementStack.begin(); iter + 1 < end; ++iter) { |
| 269 topFullscreenElementStack->document()->removeFromTopLayer(iter->get()); |
| 270 } |
267 topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscre
enElementStack); | 271 topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscre
enElementStack); |
268 topFullscreenElementStack->webkitExitFullscreen(); | 272 topFullscreenElementStack->webkitExitFullscreen(); |
269 } | 273 } |
270 | 274 |
271 void FullscreenElementStack::webkitExitFullscreen() | 275 void FullscreenElementStack::webkitExitFullscreen() |
272 { | 276 { |
273 // The exitFullscreen() method must run these steps: | 277 // The exitFullscreen() method must run these steps: |
274 | 278 |
275 // 1. Let doc be the context object. (i.e. "this") | 279 // 1. Let doc be the context object. (i.e. "this") |
276 Document* currentDoc = document(); | 280 Document* currentDoc = document(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 355 |
352 void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* elemen
t) | 356 void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* elemen
t) |
353 { | 357 { |
354 ASSERT(element); | 358 ASSERT(element); |
355 if (!document()->isActive()) | 359 if (!document()->isActive()) |
356 return; | 360 return; |
357 | 361 |
358 ASSERT(document()->settings()); // If we're active we must have settings. | 362 ASSERT(document()->settings()); // If we're active we must have settings. |
359 ASSERT(document()->settings()->fullScreenEnabled()); | 363 ASSERT(document()->settings()->fullScreenEnabled()); |
360 | 364 |
361 if (m_fullScreenRenderer) | |
362 m_fullScreenRenderer->unwrapRenderer(); | |
363 | |
364 m_fullScreenElement = element; | 365 m_fullScreenElement = element; |
365 | 366 document()->addToTopLayer(element); |
366 // Create a placeholder block for a the full-screen element, to keep the pag
e from reflowing | |
367 // when the element is removed from the normal flow. Only do this for a Rend
erBox, as only | |
368 // a box will have a frameRect. The placeholder will be created in setFullSc
reenRenderer() | |
369 // during layout. | |
370 RenderObject* renderer = m_fullScreenElement->renderer(); | |
371 bool shouldCreatePlaceholder = renderer && renderer->isBox(); | |
372 if (shouldCreatePlaceholder) { | |
373 m_savedPlaceholderFrameRect = toRenderBox(renderer)->frameRect(); | |
374 m_savedPlaceholderRenderStyle = RenderStyle::clone(renderer->style()); | |
375 } | |
376 | |
377 if (m_fullScreenElement != document()->documentElement()) | |
378 RenderFullScreen::wrapRenderer(renderer, renderer ? renderer->parent() :
0, document()); | |
379 | |
380 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(true); | 367 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(true); |
381 | 368 |
382 document()->recalcStyle(Force); | 369 document()->recalcStyle(Force); |
383 } | 370 } |
384 | 371 |
385 void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*) | 372 void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*) |
386 { | 373 { |
387 if (!m_fullScreenElement) | 374 if (!m_fullScreenElement) |
388 return; | 375 return; |
389 | 376 |
390 if (!document()->isActive()) | 377 if (!document()->isActive()) |
391 return; | 378 return; |
392 | 379 |
393 m_fullScreenElement->didBecomeFullscreenElement(); | 380 m_fullScreenElement->didBecomeFullscreenElement(); |
394 | 381 |
395 m_fullScreenChangeDelayTimer.startOneShot(0); | 382 m_fullScreenChangeDelayTimer.startOneShot(0); |
396 } | 383 } |
397 | 384 |
398 void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*) | 385 void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*) |
399 { | 386 { |
400 if (!m_fullScreenElement) | 387 if (!m_fullScreenElement) |
401 return; | 388 return; |
402 | 389 |
403 if (!document()->isActive()) | 390 if (!document()->isActive()) |
404 return; | 391 return; |
405 | 392 |
| 393 document()->removeFromTopLayer(m_fullScreenElement.get()); |
406 m_fullScreenElement->willStopBeingFullscreenElement(); | 394 m_fullScreenElement->willStopBeingFullscreenElement(); |
407 } | 395 } |
408 | 396 |
409 void FullscreenElementStack::webkitDidExitFullScreenForElement(Element*) | 397 void FullscreenElementStack::webkitDidExitFullScreenForElement(Element*) |
410 { | 398 { |
411 if (!m_fullScreenElement) | 399 if (!m_fullScreenElement) |
412 return; | 400 return; |
413 | 401 |
414 if (!document()->isActive()) | 402 if (!document()->isActive()) |
415 return; | 403 return; |
416 | 404 |
417 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(false); | 405 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(false); |
418 | 406 |
419 m_areKeysEnabledInFullScreen = false; | 407 m_areKeysEnabledInFullScreen = false; |
420 | 408 |
421 if (m_fullScreenRenderer) | |
422 m_fullScreenRenderer->unwrapRenderer(); | |
423 | |
424 m_fullScreenElement = 0; | 409 m_fullScreenElement = 0; |
425 document()->setNeedsStyleRecalc(); | 410 document()->setNeedsStyleRecalc(); |
426 | 411 |
427 // When webkitCancelFullScreen is called, we call webkitExitFullScreen on th
e topDocument(). That | 412 // When webkitCancelFullScreen is called, we call webkitExitFullScreen on th
e topDocument(). That |
428 // means that the events will be queued there. So if we have no events here,
start the timer on | 413 // means that the events will be queued there. So if we have no events here,
start the timer on |
429 // the exiting document. | 414 // the exiting document. |
430 Document* exitingDocument = document(); | 415 Document* exitingDocument = document(); |
431 if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTa
rgetQueue.isEmpty()) | 416 if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTa
rgetQueue.isEmpty()) |
432 exitingDocument = document()->topDocument(); | 417 exitingDocument = document()->topDocument(); |
433 from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0); | 418 from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0); |
434 } | 419 } |
435 | 420 |
436 void FullscreenElementStack::setFullScreenRenderer(RenderFullScreen* renderer) | |
437 { | |
438 if (renderer == m_fullScreenRenderer) | |
439 return; | |
440 | |
441 if (renderer && m_savedPlaceholderRenderStyle) { | |
442 renderer->createPlaceholder(m_savedPlaceholderRenderStyle.release(), m_s
avedPlaceholderFrameRect); | |
443 } else if (renderer && m_fullScreenRenderer && m_fullScreenRenderer->placeho
lder()) { | |
444 RenderBlock* placeholder = m_fullScreenRenderer->placeholder(); | |
445 renderer->createPlaceholder(RenderStyle::clone(placeholder->style()), pl
aceholder->frameRect()); | |
446 } | |
447 | |
448 if (m_fullScreenRenderer) | |
449 m_fullScreenRenderer->destroy(); | |
450 ASSERT(!m_fullScreenRenderer); | |
451 | |
452 m_fullScreenRenderer = renderer; | |
453 } | |
454 | |
455 void FullscreenElementStack::fullScreenRendererDestroyed() | |
456 { | |
457 m_fullScreenRenderer = 0; | |
458 } | |
459 | |
460 void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle
mentStack>*) | 421 void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle
mentStack>*) |
461 { | 422 { |
462 // Since we dispatch events in this function, it's possible that the | 423 // Since we dispatch events in this function, it's possible that the |
463 // document will be detached and GC'd. We protect it here to make sure we | 424 // document will be detached and GC'd. We protect it here to make sure we |
464 // can finish the function successfully. | 425 // can finish the function successfully. |
465 RefPtr<Document> protectDocument(document()); | 426 RefPtr<Document> protectDocument(document()); |
466 Deque<RefPtr<Node> > changeQueue; | 427 Deque<RefPtr<Node> > changeQueue; |
467 m_fullScreenChangeEventTargetQueue.swap(changeQueue); | 428 m_fullScreenChangeEventTargetQueue.swap(changeQueue); |
468 Deque<RefPtr<Node> > errorQueue; | 429 Deque<RefPtr<Node> > errorQueue; |
469 m_fullScreenErrorEventTargetQueue.swap(errorQueue); | 430 m_fullScreenErrorEventTargetQueue.swap(errorQueue); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 elementInSubtree = m_fullScreenElement->isDescendantOf(node); | 482 elementInSubtree = m_fullScreenElement->isDescendantOf(node); |
522 else | 483 else |
523 elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement-
>isDescendantOf(node); | 484 elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement-
>isDescendantOf(node); |
524 | 485 |
525 if (elementInSubtree) | 486 if (elementInSubtree) |
526 fullScreenElementRemoved(); | 487 fullScreenElementRemoved(); |
527 } | 488 } |
528 | 489 |
529 void FullscreenElementStack::clearFullscreenElementStack() | 490 void FullscreenElementStack::clearFullscreenElementStack() |
530 { | 491 { |
| 492 Vector<RefPtr<Element> >::iterator end = m_fullScreenElementStack.end(); |
| 493 for (Vector<RefPtr<Element> >::iterator iter = m_fullScreenElementStack.begi
n(); iter != end; ++iter) |
| 494 document()->removeFromTopLayer(iter->get()); |
531 m_fullScreenElementStack.clear(); | 495 m_fullScreenElementStack.clear(); |
532 } | 496 } |
533 | 497 |
534 void FullscreenElementStack::popFullscreenElementStack() | 498 void FullscreenElementStack::popFullscreenElementStack() |
535 { | 499 { |
536 if (m_fullScreenElementStack.isEmpty()) | 500 if (m_fullScreenElementStack.isEmpty()) |
537 return; | 501 return; |
538 | 502 |
| 503 RefPtr<Element> element = m_fullScreenElementStack.last(); |
539 m_fullScreenElementStack.removeLast(); | 504 m_fullScreenElementStack.removeLast(); |
| 505 document()->removeFromTopLayer(element.get()); |
540 } | 506 } |
541 | 507 |
542 void FullscreenElementStack::pushFullscreenElementStack(Element* element) | 508 void FullscreenElementStack::pushFullscreenElementStack(Element* element) |
543 { | 509 { |
| 510 document()->addToTopLayer(element); |
544 m_fullScreenElementStack.append(element); | 511 m_fullScreenElementStack.append(element); |
545 } | 512 } |
546 | 513 |
547 void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
oc) | 514 void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
oc) |
548 { | 515 { |
549 ASSERT(doc); | 516 ASSERT(doc); |
550 | 517 |
551 Node* target = 0; | 518 Node* target = 0; |
552 if (FullscreenElementStack* fullscreen = fromIfExists(doc)) { | 519 if (FullscreenElementStack* fullscreen = fromIfExists(doc)) { |
553 target = fullscreen->webkitFullscreenElement(); | 520 target = fullscreen->webkitFullscreenElement(); |
554 if (!target) | 521 if (!target) |
555 target = fullscreen->webkitCurrentFullScreenElement(); | 522 target = fullscreen->webkitCurrentFullScreenElement(); |
556 } | 523 } |
557 | 524 |
558 if (!target) | 525 if (!target) |
559 target = doc; | 526 target = doc; |
560 m_fullScreenChangeEventTargetQueue.append(target); | 527 m_fullScreenChangeEventTargetQueue.append(target); |
561 } | 528 } |
562 | 529 |
563 } // namespace WebCore | 530 } // namespace WebCore |
OLD | NEW |