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 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 #include "HTMLNames.h" | 31 #include "HTMLNames.h" |
| 32 #include "core/dom/Document.h" | 32 #include "core/dom/Document.h" |
| 33 #include "core/events/Event.h" | 33 #include "core/events/Event.h" |
| 34 #include "core/frame/Frame.h" | 34 #include "core/frame/Frame.h" |
| 35 #include "core/frame/FrameHost.h" | 35 #include "core/frame/FrameHost.h" |
| 36 #include "core/frame/Settings.h" | 36 #include "core/frame/Settings.h" |
| 37 #include "core/html/HTMLFrameOwnerElement.h" | 37 #include "core/html/HTMLFrameOwnerElement.h" |
| 38 #include "core/page/Chrome.h" | 38 #include "core/page/Chrome.h" |
| 39 #include "core/page/ChromeClient.h" | 39 #include "core/page/ChromeClient.h" |
| 40 #include "core/rendering/RenderFullScreen.h" | |
| 41 #include "platform/UserGestureIndicator.h" | 40 #include "platform/UserGestureIndicator.h" |
| 42 | 41 |
| 43 namespace WebCore { | 42 namespace WebCore { |
| 44 | 43 |
| 45 using namespace HTMLNames; | 44 using namespace HTMLNames; |
| 46 | 45 |
| 47 static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, cons t WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner) | 46 static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, cons t WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner) |
| 48 { | 47 { |
| 49 if (!owner) | 48 if (!owner) |
| 50 return true; | 49 return true; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 bool FullscreenElementStack::isFullScreen(Document* document) | 92 bool FullscreenElementStack::isFullScreen(Document* document) |
| 94 { | 93 { |
| 95 if (FullscreenElementStack* found = fromIfExists(document)) | 94 if (FullscreenElementStack* found = fromIfExists(document)) |
| 96 return found->webkitIsFullScreen(); | 95 return found->webkitIsFullScreen(); |
| 97 return false; | 96 return false; |
| 98 } | 97 } |
| 99 | 98 |
| 100 FullscreenElementStack::FullscreenElementStack(Document* document) | 99 FullscreenElementStack::FullscreenElementStack(Document* document) |
| 101 : DocumentLifecycleObserver(document) | 100 : DocumentLifecycleObserver(document) |
| 102 , m_areKeysEnabledInFullScreen(false) | 101 , m_areKeysEnabledInFullScreen(false) |
| 103 , m_fullScreenRenderer(0) | |
| 104 , m_fullScreenChangeDelayTimer(this, &FullscreenElementStack::fullScreenChan geDelayTimerFired) | 102 , m_fullScreenChangeDelayTimer(this, &FullscreenElementStack::fullScreenChan geDelayTimerFired) |
| 105 { | 103 { |
| 106 document->setHasFullscreenElementStack(); | 104 document->setHasFullscreenElementStack(); |
| 107 } | 105 } |
| 108 | 106 |
| 109 FullscreenElementStack::~FullscreenElementStack() | 107 FullscreenElementStack::~FullscreenElementStack() |
| 110 { | 108 { |
| 111 } | 109 } |
| 112 | 110 |
| 113 inline Document* FullscreenElementStack::document() | 111 inline Document* FullscreenElementStack::document() |
| 114 { | 112 { |
| 115 return lifecycleContext(); | 113 return lifecycleContext(); |
| 116 } | 114 } |
| 117 | 115 |
| 118 void FullscreenElementStack::documentWasDetached() | 116 void FullscreenElementStack::documentWasDetached() |
| 119 { | 117 { |
| 120 m_fullScreenChangeEventTargetQueue.clear(); | 118 m_fullScreenChangeEventTargetQueue.clear(); |
| 121 m_fullScreenErrorEventTargetQueue.clear(); | 119 m_fullScreenErrorEventTargetQueue.clear(); |
| 122 | |
| 123 if (m_fullScreenRenderer) | |
| 124 setFullScreenRenderer(0); | |
| 125 } | 120 } |
| 126 | 121 |
| 127 void FullscreenElementStack::documentWasDisposed() | 122 void FullscreenElementStack::documentWasDisposed() |
| 128 { | 123 { |
| 129 m_fullScreenElement = 0; | 124 m_fullScreenElement = 0; |
| 130 m_fullScreenElementStack.clear(); | 125 m_fullScreenElementStack.clear(); |
| 131 } | 126 } |
| 132 | 127 |
| 133 bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) con st | 128 bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) con st |
| 134 { | 129 { |
| (...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 | 252 // "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." | 253 // context's document and subsequently empty that document's fullscreen elem ent stack." |
| 259 if (!fullscreenElementFrom(document()->topDocument())) | 254 if (!fullscreenElementFrom(document()->topDocument())) |
| 260 return; | 255 return; |
| 261 | 256 |
| 262 // To achieve that aim, remove all the elements from the top document's stac k except for the first before | 257 // To achieve that aim, remove all the elements from the top document's stac k except for the first before |
| 263 // calling webkitExitFullscreen(): | 258 // calling webkitExitFullscreen(): |
| 264 Vector<RefPtr<Element> > replacementFullscreenElementStack; | 259 Vector<RefPtr<Element> > replacementFullscreenElementStack; |
| 265 replacementFullscreenElementStack.append(fullscreenElementFrom(document()->t opDocument())); | 260 replacementFullscreenElementStack.append(fullscreenElementFrom(document()->t opDocument())); |
| 266 FullscreenElementStack* topFullscreenElementStack = from(document()->topDocu ment()); | 261 FullscreenElementStack* topFullscreenElementStack = from(document()->topDocu ment()); |
| 262 // FIXME: This will remove a modal full screen dialog from the top layer. | |
| 263 // We shouldn't have separate vectors for full screen element stack and top | |
| 264 // layer. | |
|
esprehn
2014/01/21 18:59:05
file a bug and link here.
falken
2014/01/22 06:08:02
Done.
| |
| 265 Vector<RefPtr<Element> >::iterator end = topFullscreenElementStack->m_fullSc reenElementStack.end(); | |
| 266 for (Vector<RefPtr<Element> >::iterator iter = topFullscreenElementStack->m_ fullScreenElementStack.begin(); iter + 1 < end; ++iter) { | |
| 267 topFullscreenElementStack->document()->removeFromTopLayer(iter->get()); | |
| 268 } | |
| 267 topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscre enElementStack); | 269 topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscre enElementStack); |
| 268 topFullscreenElementStack->webkitExitFullscreen(); | 270 topFullscreenElementStack->webkitExitFullscreen(); |
| 269 } | 271 } |
| 270 | 272 |
| 271 void FullscreenElementStack::webkitExitFullscreen() | 273 void FullscreenElementStack::webkitExitFullscreen() |
| 272 { | 274 { |
| 273 // The exitFullscreen() method must run these steps: | 275 // The exitFullscreen() method must run these steps: |
| 274 | 276 |
| 275 // 1. Let doc be the context object. (i.e. "this") | 277 // 1. Let doc be the context object. (i.e. "this") |
| 276 Document* currentDoc = document(); | 278 Document* currentDoc = document(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 | 353 |
| 352 void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* elemen t) | 354 void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* elemen t) |
| 353 { | 355 { |
| 354 ASSERT(element); | 356 ASSERT(element); |
| 355 if (!document()->isActive()) | 357 if (!document()->isActive()) |
| 356 return; | 358 return; |
| 357 | 359 |
| 358 ASSERT(document()->settings()); // If we're active we must have settings. | 360 ASSERT(document()->settings()); // If we're active we must have settings. |
| 359 ASSERT(document()->settings()->fullScreenEnabled()); | 361 ASSERT(document()->settings()->fullScreenEnabled()); |
| 360 | 362 |
| 361 if (m_fullScreenRenderer) | |
| 362 m_fullScreenRenderer->unwrapRenderer(); | |
| 363 | |
| 364 m_fullScreenElement = element; | 363 m_fullScreenElement = element; |
| 365 | 364 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); | 365 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(true); |
| 381 | 366 |
| 382 document()->recalcStyle(Force); | 367 document()->recalcStyle(Force); |
| 383 } | 368 } |
| 384 | 369 |
| 385 void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*) | 370 void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*) |
| 386 { | 371 { |
| 387 if (!m_fullScreenElement) | 372 if (!m_fullScreenElement) |
| 388 return; | 373 return; |
| 389 | 374 |
| 390 if (!document()->isActive()) | 375 if (!document()->isActive()) |
| 391 return; | 376 return; |
| 392 | 377 |
| 393 m_fullScreenElement->didBecomeFullscreenElement(); | 378 m_fullScreenElement->didBecomeFullscreenElement(); |
| 394 | 379 |
| 395 m_fullScreenChangeDelayTimer.startOneShot(0); | 380 m_fullScreenChangeDelayTimer.startOneShot(0); |
| 396 } | 381 } |
| 397 | 382 |
| 398 void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*) | 383 void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*) |
| 399 { | 384 { |
| 400 if (!m_fullScreenElement) | 385 if (!m_fullScreenElement) |
| 401 return; | 386 return; |
| 402 | 387 |
| 403 if (!document()->isActive()) | 388 if (!document()->isActive()) |
| 404 return; | 389 return; |
| 405 | 390 |
| 391 document()->removeFromTopLayer(m_fullScreenElement.get()); | |
| 406 m_fullScreenElement->willStopBeingFullscreenElement(); | 392 m_fullScreenElement->willStopBeingFullscreenElement(); |
| 407 } | 393 } |
| 408 | 394 |
| 409 void FullscreenElementStack::webkitDidExitFullScreenForElement(Element*) | 395 void FullscreenElementStack::webkitDidExitFullScreenForElement(Element*) |
| 410 { | 396 { |
| 411 if (!m_fullScreenElement) | 397 if (!m_fullScreenElement) |
| 412 return; | 398 return; |
| 413 | 399 |
| 414 if (!document()->isActive()) | 400 if (!document()->isActive()) |
| 415 return; | 401 return; |
| 416 | 402 |
| 417 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(false); | 403 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(false); |
| 418 | 404 |
| 419 m_areKeysEnabledInFullScreen = false; | 405 m_areKeysEnabledInFullScreen = false; |
| 420 | 406 |
| 421 if (m_fullScreenRenderer) | |
| 422 m_fullScreenRenderer->unwrapRenderer(); | |
| 423 | |
| 424 m_fullScreenElement = 0; | 407 m_fullScreenElement = 0; |
| 425 document()->setNeedsStyleRecalc(); | 408 document()->setNeedsStyleRecalc(); |
| 426 | 409 |
| 427 // When webkitCancelFullScreen is called, we call webkitExitFullScreen on th e topDocument(). That | 410 // 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 | 411 // means that the events will be queued there. So if we have no events here, start the timer on |
| 429 // the exiting document. | 412 // the exiting document. |
| 430 Document* exitingDocument = document(); | 413 Document* exitingDocument = document(); |
| 431 if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTa rgetQueue.isEmpty()) | 414 if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTa rgetQueue.isEmpty()) |
| 432 exitingDocument = document()->topDocument(); | 415 exitingDocument = document()->topDocument(); |
| 433 from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0); | 416 from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0); |
| 434 } | 417 } |
| 435 | 418 |
| 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>*) | 419 void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle mentStack>*) |
| 461 { | 420 { |
| 462 // Since we dispatch events in this function, it's possible that the | 421 // 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 | 422 // document will be detached and GC'd. We protect it here to make sure we |
| 464 // can finish the function successfully. | 423 // can finish the function successfully. |
| 465 RefPtr<Document> protectDocument(document()); | 424 RefPtr<Document> protectDocument(document()); |
| 466 Deque<RefPtr<Node> > changeQueue; | 425 Deque<RefPtr<Node> > changeQueue; |
| 467 m_fullScreenChangeEventTargetQueue.swap(changeQueue); | 426 m_fullScreenChangeEventTargetQueue.swap(changeQueue); |
| 468 Deque<RefPtr<Node> > errorQueue; | 427 Deque<RefPtr<Node> > errorQueue; |
| 469 m_fullScreenErrorEventTargetQueue.swap(errorQueue); | 428 m_fullScreenErrorEventTargetQueue.swap(errorQueue); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 521 elementInSubtree = m_fullScreenElement->isDescendantOf(node); | 480 elementInSubtree = m_fullScreenElement->isDescendantOf(node); |
| 522 else | 481 else |
| 523 elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement- >isDescendantOf(node); | 482 elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement- >isDescendantOf(node); |
| 524 | 483 |
| 525 if (elementInSubtree) | 484 if (elementInSubtree) |
| 526 fullScreenElementRemoved(); | 485 fullScreenElementRemoved(); |
| 527 } | 486 } |
| 528 | 487 |
| 529 void FullscreenElementStack::clearFullscreenElementStack() | 488 void FullscreenElementStack::clearFullscreenElementStack() |
| 530 { | 489 { |
| 490 Vector<RefPtr<Element> >::iterator end = m_fullScreenElementStack.end(); | |
| 491 for (Vector<RefPtr<Element> >::iterator iter = m_fullScreenElementStack.begi n(); iter != end; ++iter) | |
| 492 document()->removeFromTopLayer(iter->get()); | |
| 531 m_fullScreenElementStack.clear(); | 493 m_fullScreenElementStack.clear(); |
| 532 } | 494 } |
| 533 | 495 |
| 534 void FullscreenElementStack::popFullscreenElementStack() | 496 void FullscreenElementStack::popFullscreenElementStack() |
| 535 { | 497 { |
| 536 if (m_fullScreenElementStack.isEmpty()) | 498 if (m_fullScreenElementStack.isEmpty()) |
| 537 return; | 499 return; |
| 538 | 500 |
| 501 RefPtr<Element> element = m_fullScreenElementStack.last(); | |
| 539 m_fullScreenElementStack.removeLast(); | 502 m_fullScreenElementStack.removeLast(); |
| 503 document()->removeFromTopLayer(element.get()); | |
| 540 } | 504 } |
| 541 | 505 |
| 542 void FullscreenElementStack::pushFullscreenElementStack(Element* element) | 506 void FullscreenElementStack::pushFullscreenElementStack(Element* element) |
| 543 { | 507 { |
| 508 document()->addToTopLayer(element); | |
| 544 m_fullScreenElementStack.append(element); | 509 m_fullScreenElementStack.append(element); |
| 545 } | 510 } |
| 546 | 511 |
| 547 void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d oc) | 512 void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d oc) |
| 548 { | 513 { |
| 549 ASSERT(doc); | 514 ASSERT(doc); |
| 550 | 515 |
| 551 Node* target = 0; | 516 Node* target = 0; |
| 552 if (FullscreenElementStack* fullscreen = fromIfExists(doc)) { | 517 if (FullscreenElementStack* fullscreen = fromIfExists(doc)) { |
| 553 target = fullscreen->webkitFullscreenElement(); | 518 target = fullscreen->webkitFullscreenElement(); |
| 554 if (!target) | 519 if (!target) |
| 555 target = fullscreen->webkitCurrentFullScreenElement(); | 520 target = fullscreen->webkitCurrentFullScreenElement(); |
| 556 } | 521 } |
| 557 | 522 |
| 558 if (!target) | 523 if (!target) |
| 559 target = doc; | 524 target = doc; |
| 560 m_fullScreenChangeEventTargetQueue.append(target); | 525 m_fullScreenChangeEventTargetQueue.append(target); |
| 561 } | 526 } |
| 562 | 527 |
| 563 } // namespace WebCore | 528 } // namespace WebCore |
| OLD | NEW |