| 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 158 |
| 159 bool Fullscreen::isFullScreen(Document& document) | 159 bool Fullscreen::isFullScreen(Document& document) |
| 160 { | 160 { |
| 161 return currentFullScreenElementFrom(document); | 161 return currentFullScreenElementFrom(document); |
| 162 } | 162 } |
| 163 | 163 |
| 164 Fullscreen::Fullscreen(Document& document) | 164 Fullscreen::Fullscreen(Document& document) |
| 165 : ContextLifecycleObserver(&document) | 165 : ContextLifecycleObserver(&document) |
| 166 , m_fullScreenLayoutObject(nullptr) | 166 , m_fullScreenLayoutObject(nullptr) |
| 167 , m_eventQueueTimer(this, &Fullscreen::eventQueueTimerFired) | 167 , m_eventQueueTimer(this, &Fullscreen::eventQueueTimerFired) |
| 168 , m_forCrossProcessAncestor(false) |
| 168 { | 169 { |
| 169 document.setHasFullscreenSupplement(); | 170 document.setHasFullscreenSupplement(); |
| 170 } | 171 } |
| 171 | 172 |
| 172 Fullscreen::~Fullscreen() | 173 Fullscreen::~Fullscreen() |
| 173 { | 174 { |
| 174 } | 175 } |
| 175 | 176 |
| 176 inline Document* Fullscreen::document() | 177 inline Document* Fullscreen::document() |
| 177 { | 178 { |
| 178 return toDocument(lifecycleContext()); | 179 return toDocument(lifecycleContext()); |
| 179 } | 180 } |
| 180 | 181 |
| 181 void Fullscreen::contextDestroyed() | 182 void Fullscreen::contextDestroyed() |
| 182 { | 183 { |
| 183 m_eventQueue.clear(); | 184 m_eventQueue.clear(); |
| 184 | 185 |
| 185 if (m_fullScreenLayoutObject) | 186 if (m_fullScreenLayoutObject) |
| 186 m_fullScreenLayoutObject->destroy(); | 187 m_fullScreenLayoutObject->destroy(); |
| 187 | 188 |
| 188 m_fullScreenElement = nullptr; | 189 m_fullScreenElement = nullptr; |
| 189 m_fullScreenElementStack.clear(); | 190 m_fullScreenElementStack.clear(); |
| 190 | 191 |
| 191 } | 192 } |
| 192 | 193 |
| 193 void Fullscreen::requestFullscreen(Element& element, RequestType requestType) | 194 void Fullscreen::requestFullscreen(Element& element, RequestType requestType, bo
ol forCrossProcessAncestor) |
| 194 { | 195 { |
| 195 if (document()->isSecureContext()) { | 196 // Use counters only need to be incremented in the process of the actual |
| 196 UseCounter::count(document(), UseCounter::FullscreenSecureOrigin); | 197 // fullscreen element. |
| 197 } else { | 198 if (!forCrossProcessAncestor) { |
| 198 UseCounter::count(document(), UseCounter::FullscreenInsecureOrigin); | 199 if (document()->isSecureContext()) { |
| 199 HostsUsingFeatures::countAnyWorld(*document(), HostsUsingFeatures::Featu
re::FullscreenInsecureHost); | 200 UseCounter::count(document(), UseCounter::FullscreenSecureOrigin); |
| 201 } else { |
| 202 UseCounter::count(document(), UseCounter::FullscreenInsecureOrigin); |
| 203 HostsUsingFeatures::countAnyWorld(*document(), HostsUsingFeatures::F
eature::FullscreenInsecureHost); |
| 204 } |
| 200 } | 205 } |
| 201 | 206 |
| 202 // Ignore this request if the document is not in a live frame. | 207 // Ignore this request if the document is not in a live frame. |
| 203 if (!document()->isActive()) | 208 if (!document()->isActive()) |
| 204 return; | 209 return; |
| 205 | 210 |
| 206 // If |element| is on top of |doc|'s fullscreen element stack, terminate the
se substeps. | 211 // If |element| is on top of |doc|'s fullscreen element stack, terminate the
se substeps. |
| 207 if (&element == fullscreenElement()) | 212 if (&element == fullscreenElement()) |
| 208 return; | 213 return; |
| 209 | 214 |
| 210 do { | 215 do { |
| 211 // 1. If any of the following conditions are true, terminate these steps
and queue a task to fire | 216 // 1. If any of the following conditions are true, terminate these steps
and queue a task to fire |
| 212 // an event named fullscreenerror with its bubbles attribute set to true
on the context object's | 217 // an event named fullscreenerror with its bubbles attribute set to true
on the context object's |
| 213 // node document: | 218 // node document: |
| 214 | 219 |
| 215 // The fullscreen element ready check returns false. | 220 // The fullscreen element ready check returns false. |
| 216 if (!fullscreenElementReady(element)) | 221 if (!fullscreenElementReady(element)) |
| 217 break; | 222 break; |
| 218 | 223 |
| 219 // This algorithm is not allowed to show a pop-up: | 224 // This algorithm is not allowed to show a pop-up: |
| 220 // An algorithm is allowed to show a pop-up if, in the task in which t
he algorithm is running, either: | 225 // An algorithm is allowed to show a pop-up if, in the task in which t
he algorithm is running, either: |
| 221 // - an activation behavior is currently being processed whose click e
vent was trusted, or | 226 // - an activation behavior is currently being processed whose click e
vent was trusted, or |
| 222 // - the event listener for a trusted click event is being handled. | 227 // - the event listener for a trusted click event is being handled. |
| 223 if (!UserGestureIndicator::utilizeUserGesture()) { | 228 // |
| 229 // If |forCrossProcessAncestor| is true, requestFullscreen was already |
| 230 // called on an element in another process, and getting here means that |
| 231 // it already passed the user gesture check. |
| 232 if (!UserGestureIndicator::utilizeUserGesture() && !forCrossProcessAnces
tor) { |
| 224 String message = ExceptionMessages::failedToExecute("requestFullScre
en", | 233 String message = ExceptionMessages::failedToExecute("requestFullScre
en", |
| 225 "Element", "API can only be initiated by a user gesture."); | 234 "Element", "API can only be initiated by a user gesture."); |
| 226 document()->addConsoleMessage( | 235 document()->addConsoleMessage( |
| 227 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, mes
sage)); | 236 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, mes
sage)); |
| 228 break; | 237 break; |
| 229 } | 238 } |
| 230 | 239 |
| 231 // Fullscreen is not supported. | 240 // Fullscreen is not supported. |
| 232 if (!fullscreenIsSupported(element.document())) | 241 if (!fullscreenIsSupported(element.document())) |
| 233 break; | 242 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 // stack, and queue a task to fire an event named fullscreenchan
ge with its bubbles attribute | 280 // stack, and queue a task to fire an event named fullscreenchan
ge with its bubbles attribute |
| 272 // set to true on document. | 281 // set to true on document. |
| 273 from(*currentDoc).pushFullscreenElementStack(*followingDoc->loca
lOwner(), requestType); | 282 from(*currentDoc).pushFullscreenElementStack(*followingDoc->loca
lOwner(), requestType); |
| 274 enqueueChangeEvent(*currentDoc, requestType); | 283 enqueueChangeEvent(*currentDoc, requestType); |
| 275 continue; | 284 continue; |
| 276 } | 285 } |
| 277 | 286 |
| 278 // 4. Otherwise, do nothing for this document. It stays the same. | 287 // 4. Otherwise, do nothing for this document. It stays the same. |
| 279 } while (++current != docs.end()); | 288 } while (++current != docs.end()); |
| 280 | 289 |
| 290 m_forCrossProcessAncestor = forCrossProcessAncestor; |
| 291 |
| 281 // 5. Return, and run the remaining steps asynchronously. | 292 // 5. Return, and run the remaining steps asynchronously. |
| 282 // 6. Optionally, perform some animation. | 293 // 6. Optionally, perform some animation. |
| 283 document()->frameHost()->chromeClient().enterFullScreenForElement(&eleme
nt); | 294 document()->frameHost()->chromeClient().enterFullScreenForElement(&eleme
nt); |
| 284 | 295 |
| 285 // 7. Optionally, display a message indicating how the user can exit dis
playing the context object fullscreen. | 296 // 7. Optionally, display a message indicating how the user can exit dis
playing the context object fullscreen. |
| 286 return; | 297 return; |
| 287 } while (false); | 298 } while (false); |
| 288 | 299 |
| 289 enqueueErrorEvent(element, requestType); | 300 enqueueErrorEvent(element, requestType); |
| 290 } | 301 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 414 |
| 404 bool Fullscreen::fullscreenEnabled(Document& document) | 415 bool Fullscreen::fullscreenEnabled(Document& document) |
| 405 { | 416 { |
| 406 // 4. The fullscreenEnabled attribute must return true if the context object
has its | 417 // 4. The fullscreenEnabled attribute must return true if the context object
has its |
| 407 // fullscreen enabled flag set and fullscreen is supported, and false oth
erwise. | 418 // fullscreen enabled flag set and fullscreen is supported, and false oth
erwise. |
| 408 | 419 |
| 409 // Top-level browsing contexts are implied to have their allowFullScreen att
ribute set. | 420 // Top-level browsing contexts are implied to have their allowFullScreen att
ribute set. |
| 410 return fullscreenIsAllowedForAllOwners(document) && fullscreenIsSupported(do
cument); | 421 return fullscreenIsAllowedForAllOwners(document) && fullscreenIsSupported(do
cument); |
| 411 } | 422 } |
| 412 | 423 |
| 413 void Fullscreen::didEnterFullScreenForElement(Element* element, bool isAncestorO
fFullscreenElement) | 424 void Fullscreen::didEnterFullScreenForElement(Element* element) |
| 414 { | 425 { |
| 415 DCHECK(element); | 426 DCHECK(element); |
| 416 if (!document()->isActive()) | 427 if (!document()->isActive()) |
| 417 return; | 428 return; |
| 418 | 429 |
| 419 if (m_fullScreenLayoutObject) | 430 if (m_fullScreenLayoutObject) |
| 420 m_fullScreenLayoutObject->unwrapLayoutObject(); | 431 m_fullScreenLayoutObject->unwrapLayoutObject(); |
| 421 | 432 |
| 422 m_fullScreenElement = element; | 433 m_fullScreenElement = element; |
| 423 | 434 |
| 424 // Create a placeholder block for a the full-screen element, to keep the pag
e from reflowing | 435 // Create a placeholder block for a the full-screen element, to keep the pag
e from reflowing |
| 425 // when the element is removed from the normal flow. Only do this for a Layo
utBox, as only | 436 // when the element is removed from the normal flow. Only do this for a Layo
utBox, as only |
| 426 // a box will have a frameRect. The placeholder will be created in setFullSc
reenLayoutObject() | 437 // a box will have a frameRect. The placeholder will be created in setFullSc
reenLayoutObject() |
| 427 // during layout. | 438 // during layout. |
| 428 LayoutObject* layoutObject = m_fullScreenElement->layoutObject(); | 439 LayoutObject* layoutObject = m_fullScreenElement->layoutObject(); |
| 429 bool shouldCreatePlaceholder = layoutObject && layoutObject->isBox(); | 440 bool shouldCreatePlaceholder = layoutObject && layoutObject->isBox(); |
| 430 if (shouldCreatePlaceholder) { | 441 if (shouldCreatePlaceholder) { |
| 431 m_savedPlaceholderFrameRect = toLayoutBox(layoutObject)->frameRect(); | 442 m_savedPlaceholderFrameRect = toLayoutBox(layoutObject)->frameRect(); |
| 432 m_savedPlaceholderComputedStyle = ComputedStyle::clone(layoutObject->sty
leRef()); | 443 m_savedPlaceholderComputedStyle = ComputedStyle::clone(layoutObject->sty
leRef()); |
| 433 } | 444 } |
| 434 | 445 |
| 435 // TODO(alexmos): When |isAncestorOfFullscreenElement| is true, some of | 446 // TODO(alexmos): When |m_forCrossProcessAncestor| is true, some of |
| 436 // this layout work has already been done in another process, so it should | 447 // this layout work has already been done in another process, so it should |
| 437 // not be necessary to repeat it here. | 448 // not be necessary to repeat it here. |
| 438 if (m_fullScreenElement != document()->documentElement()) | 449 if (m_fullScreenElement != document()->documentElement()) |
| 439 LayoutFullScreen::wrapLayoutObject(layoutObject, layoutObject ? layoutOb
ject->parent() : 0, document()); | 450 LayoutFullScreen::wrapLayoutObject(layoutObject, layoutObject ? layoutOb
ject->parent() : 0, document()); |
| 440 | 451 |
| 441 if (isAncestorOfFullscreenElement) { | 452 if (m_forCrossProcessAncestor) { |
| 442 DCHECK(m_fullScreenElement->isFrameOwnerElement()); | 453 DCHECK(m_fullScreenElement->isFrameOwnerElement()); |
| 443 DCHECK(toHTMLFrameOwnerElement(m_fullScreenElement)->contentFrame()->isR
emoteFrame()); | 454 DCHECK(toHTMLFrameOwnerElement(m_fullScreenElement)->contentFrame()->isR
emoteFrame()); |
| 444 m_fullScreenElement->setContainsFullScreenElement(true); | 455 m_fullScreenElement->setContainsFullScreenElement(true); |
| 445 } | 456 } |
| 446 | 457 |
| 447 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(true); | 458 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(true); |
| 448 | 459 |
| 449 document()->styleEngine().ensureFullscreenUAStyle(); | 460 document()->styleEngine().ensureFullscreenUAStyle(); |
| 450 m_fullScreenElement->pseudoStateChanged(CSSSelector::PseudoFullScreen); | 461 m_fullScreenElement->pseudoStateChanged(CSSSelector::PseudoFullScreen); |
| 451 | 462 |
| 452 // FIXME: This should not call updateStyleAndLayoutTree. | 463 // FIXME: This should not call updateStyleAndLayoutTree. |
| 453 document()->updateStyleAndLayoutTree(); | 464 document()->updateStyleAndLayoutTree(); |
| 454 | 465 |
| 455 m_fullScreenElement->didBecomeFullscreenElement(); | 466 m_fullScreenElement->didBecomeFullscreenElement(); |
| 456 | 467 |
| 457 if (document()->frame()) | 468 if (document()->frame()) |
| 458 document()->frame()->eventHandler().scheduleHoverStateUpdate(); | 469 document()->frame()->eventHandler().scheduleHoverStateUpdate(); |
| 459 | 470 |
| 460 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); | 471 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); |
| 461 } | 472 } |
| 462 | 473 |
| 463 void Fullscreen::didExitFullScreenForElement(bool isAncestorOfFullscreenElement) | 474 void Fullscreen::didExitFullScreenForElement() |
| 464 { | 475 { |
| 465 if (!m_fullScreenElement) | 476 if (!m_fullScreenElement) |
| 466 return; | 477 return; |
| 467 | 478 |
| 468 if (!document()->isActive()) | 479 if (!document()->isActive()) |
| 469 return; | 480 return; |
| 470 | 481 |
| 471 m_fullScreenElement->willStopBeingFullscreenElement(); | 482 m_fullScreenElement->willStopBeingFullscreenElement(); |
| 472 | 483 |
| 473 if (isAncestorOfFullscreenElement) | 484 if (m_forCrossProcessAncestor) |
| 474 m_fullScreenElement->setContainsFullScreenElement(false); | 485 m_fullScreenElement->setContainsFullScreenElement(false); |
| 475 | 486 |
| 476 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(false); | 487 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou
ndaries(false); |
| 477 | 488 |
| 478 if (m_fullScreenLayoutObject) | 489 if (m_fullScreenLayoutObject) |
| 479 LayoutFullScreenItem(m_fullScreenLayoutObject).unwrapLayoutObject(); | 490 LayoutFullScreenItem(m_fullScreenLayoutObject).unwrapLayoutObject(); |
| 480 | 491 |
| 481 document()->styleEngine().ensureFullscreenUAStyle(); | 492 document()->styleEngine().ensureFullscreenUAStyle(); |
| 482 m_fullScreenElement->pseudoStateChanged(CSSSelector::PseudoFullScreen); | 493 m_fullScreenElement->pseudoStateChanged(CSSSelector::PseudoFullScreen); |
| 483 m_fullScreenElement = nullptr; | 494 m_fullScreenElement = nullptr; |
| 484 | 495 |
| 485 if (document()->frame()) | 496 if (document()->frame()) |
| 486 document()->frame()->eventHandler().scheduleHoverStateUpdate(); | 497 document()->frame()->eventHandler().scheduleHoverStateUpdate(); |
| 487 | 498 |
| 488 // When fullyExitFullscreen is called, we call exitFullscreen on the topDocu
ment(). That means | 499 // When fullyExitFullscreen is called, we call exitFullscreen on the topDocu
ment(). That means |
| 489 // that the events will be queued there. So if we have no events here, start
the timer on the | 500 // that the events will be queued there. So if we have no events here, start
the timer on the |
| 490 // exiting document. | 501 // exiting document. |
| 491 Document* exitingDocument = document(); | 502 Document* exitingDocument = document(); |
| 492 if (m_eventQueue.isEmpty()) | 503 if (m_eventQueue.isEmpty()) |
| 493 exitingDocument = &document()->topDocument(); | 504 exitingDocument = &document()->topDocument(); |
| 494 DCHECK(exitingDocument); | 505 DCHECK(exitingDocument); |
| 495 from(*exitingDocument).m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); | 506 from(*exitingDocument).m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); |
| 507 |
| 508 m_forCrossProcessAncestor = false; |
| 496 } | 509 } |
| 497 | 510 |
| 498 void Fullscreen::setFullScreenLayoutObject(LayoutFullScreen* layoutObject) | 511 void Fullscreen::setFullScreenLayoutObject(LayoutFullScreen* layoutObject) |
| 499 { | 512 { |
| 500 if (layoutObject == m_fullScreenLayoutObject) | 513 if (layoutObject == m_fullScreenLayoutObject) |
| 501 return; | 514 return; |
| 502 | 515 |
| 503 if (layoutObject && m_savedPlaceholderComputedStyle) { | 516 if (layoutObject && m_savedPlaceholderComputedStyle) { |
| 504 layoutObject->createPlaceholder(m_savedPlaceholderComputedStyle.release(
), m_savedPlaceholderFrameRect); | 517 layoutObject->createPlaceholder(m_savedPlaceholderComputedStyle.release(
), m_savedPlaceholderFrameRect); |
| 505 } else if (layoutObject && m_fullScreenLayoutObject && m_fullScreenLayoutObj
ect->placeholder()) { | 518 } else if (layoutObject && m_fullScreenLayoutObject && m_fullScreenLayoutObj
ect->placeholder()) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 DEFINE_TRACE(Fullscreen) | 625 DEFINE_TRACE(Fullscreen) |
| 613 { | 626 { |
| 614 visitor->trace(m_fullScreenElement); | 627 visitor->trace(m_fullScreenElement); |
| 615 visitor->trace(m_fullScreenElementStack); | 628 visitor->trace(m_fullScreenElementStack); |
| 616 visitor->trace(m_eventQueue); | 629 visitor->trace(m_eventQueue); |
| 617 Supplement<Document>::trace(visitor); | 630 Supplement<Document>::trace(visitor); |
| 618 ContextLifecycleObserver::trace(visitor); | 631 ContextLifecycleObserver::trace(visitor); |
| 619 } | 632 } |
| 620 | 633 |
| 621 } // namespace blink | 634 } // namespace blink |
| OLD | NEW |