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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 | 66 |
67 static bool fullscreenIsSupported(const Document& document, const Element& eleme nt) | 67 static bool fullscreenIsSupported(const Document& document, const Element& eleme nt) |
68 { | 68 { |
69 if (!document.settings() || (document.settings()->disallowFullscreenForNonMe diaElements() && !isHTMLMediaElement(element))) | 69 if (!document.settings() || (document.settings()->disallowFullscreenForNonMe diaElements() && !isHTMLMediaElement(element))) |
70 return false; | 70 return false; |
71 return fullscreenIsSupported(document); | 71 return fullscreenIsSupported(document); |
72 } | 72 } |
73 | 73 |
74 static PassRefPtrWillBeRawPtr<Event> createEvent(const AtomicString& type, Event Target& target) | 74 static PassRefPtrWillBeRawPtr<Event> createEvent(const AtomicString& type, Event Target& target) |
75 { | 75 { |
76 RefPtrWillBeRawPtr<Event> event = Event::createBubble(type); | 76 EventInit initializer; |
77 // The prefixed events bubble, the unprefixed ones do not. | |
78 initializer.bubbles = type == EventTypeNames::webkitfullscreenchange || type == EventTypeNames::webkitfullscreenerror; | |
falken
2014/08/12 03:26:08
This boolean expression appears again later. wdyt
philipj_slow
2014/08/12 08:09:53
Good idea, done!
| |
79 RefPtrWillBeRawPtr<Event> event = Event::create(type, initializer); | |
77 event->setTarget(&target); | 80 event->setTarget(&target); |
78 return event; | 81 return event; |
79 } | 82 } |
80 | 83 |
81 const char* FullscreenElementStack::supplementName() | 84 const char* FullscreenElementStack::supplementName() |
82 { | 85 { |
83 return "FullscreenElementStack"; | 86 return "FullscreenElementStack"; |
84 } | 87 } |
85 | 88 |
86 FullscreenElementStack& FullscreenElementStack::from(Document& document) | 89 FullscreenElementStack& FullscreenElementStack::from(Document& document) |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 | 253 |
251 // 1. Let following document be the document after document in docs, or null if there is no | 254 // 1. Let following document be the document after document in docs, or null if there is no |
252 // such document. | 255 // such document. |
253 Document* currentDoc = *current; | 256 Document* currentDoc = *current; |
254 Document* followingDoc = following != docs.end() ? *following : 0; | 257 Document* followingDoc = following != docs.end() ? *following : 0; |
255 | 258 |
256 // 2. If following document is null, push context object on document 's fullscreen element | 259 // 2. If following document is null, push context object on document 's fullscreen element |
257 // stack, and queue a task to fire an event named fullscreenchange w ith its bubbles attribute | 260 // stack, and queue a task to fire an event named fullscreenchange w ith its bubbles attribute |
258 // set to true on the document. | 261 // set to true on the document. |
259 if (!followingDoc) { | 262 if (!followingDoc) { |
260 from(*currentDoc).pushFullscreenElementStack(element); | 263 from(*currentDoc).pushFullscreenElementStack(element, requestTyp e); |
261 enqueueChangeEvent(*currentDoc); | 264 enqueueChangeEvent(*currentDoc, requestType); |
262 continue; | 265 continue; |
263 } | 266 } |
264 | 267 |
265 // 3. Otherwise, if document's fullscreen element stack is either em pty or its top element | 268 // 3. Otherwise, if document's fullscreen element stack is either em pty or its top element |
266 // is not following document's browsing context container, | 269 // is not following document's browsing context container, |
267 Element* topElement = fullscreenElementFrom(*currentDoc); | 270 Element* topElement = fullscreenElementFrom(*currentDoc); |
268 if (!topElement || topElement != followingDoc->ownerElement()) { | 271 if (!topElement || topElement != followingDoc->ownerElement()) { |
269 // ...push following document's browsing context container on do cument's fullscreen element | 272 // ...push following document's browsing context container on do cument's fullscreen element |
270 // stack, and queue a task to fire an event named fullscreenchan ge with its bubbles attribute | 273 // stack, and queue a task to fire an event named fullscreenchan ge with its bubbles attribute |
271 // set to true on document. | 274 // set to true on document. |
272 from(*currentDoc).pushFullscreenElementStack(*followingDoc->owne rElement()); | 275 from(*currentDoc).pushFullscreenElementStack(*followingDoc->owne rElement(), requestType); |
273 enqueueChangeEvent(*currentDoc); | 276 enqueueChangeEvent(*currentDoc, requestType); |
274 continue; | 277 continue; |
275 } | 278 } |
276 | 279 |
277 // 4. Otherwise, do nothing for this document. It stays the same. | 280 // 4. Otherwise, do nothing for this document. It stays the same. |
278 } while (++current != docs.end()); | 281 } while (++current != docs.end()); |
279 | 282 |
280 // 5. Return, and run the remaining steps asynchronously. | 283 // 5. Return, and run the remaining steps asynchronously. |
281 // 6. Optionally, perform some animation. | 284 // 6. Optionally, perform some animation. |
282 m_areKeysEnabledInFullScreen = requestType != PrefixedMozillaRequest && requestType != PrefixedVideoRequest; | 285 m_areKeysEnabledInFullScreen = requestType != PrefixedMozillaRequest && requestType != PrefixedVideoRequest; |
283 document()->frameHost()->chrome().client().enterFullScreenForElement(&el ement); | 286 document()->frameHost()->chrome().client().enterFullScreenForElement(&el ement); |
284 | 287 |
285 // 7. Optionally, display a message indicating how the user can exit dis playing the context object fullscreen. | 288 // 7. Optionally, display a message indicating how the user can exit dis playing the context object fullscreen. |
286 return; | 289 return; |
287 } while (0); | 290 } while (0); |
288 | 291 |
289 enqueueErrorEvent(element); | 292 enqueueErrorEvent(element, requestType); |
290 } | 293 } |
291 | 294 |
292 void FullscreenElementStack::fullyExitFullscreen() | 295 void FullscreenElementStack::fullyExitFullscreen() |
293 { | 296 { |
294 // "To fully exit fullscreen act as if the exitFullscreen() method was invok ed on the top-level browsing | 297 // "To fully exit fullscreen act as if the exitFullscreen() method was invok ed on the top-level browsing |
295 // context's document and subsequently empty that document's fullscreen elem ent stack." | 298 // context's document and subsequently empty that document's fullscreen elem ent stack." |
296 if (!fullscreenElementFrom(document()->topDocument())) | 299 if (!fullscreenElementFrom(document()->topDocument())) |
297 return; | 300 return; |
298 | 301 |
299 // To achieve that aim, remove all the elements from the top document's stac k except for the first before | 302 // To achieve that aim, remove all the elements from the top document's stac k except for the first before |
300 // calling exitFullscreen(): | 303 // calling exitFullscreen(): |
301 WillBeHeapVector<RefPtrWillBeMember<Element> > replacementFullscreenElementS tack; | 304 WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > repla cementFullscreenElementStack; |
302 replacementFullscreenElementStack.append(fullscreenElementFrom(document()->t opDocument())); | |
303 FullscreenElementStack& topFullscreenElementStack = from(document()->topDocu ment()); | 305 FullscreenElementStack& topFullscreenElementStack = from(document()->topDocu ment()); |
306 replacementFullscreenElementStack.append(topFullscreenElementStack.m_fullScr eenElementStack.last()); | |
304 topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscree nElementStack); | 307 topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscree nElementStack); |
305 topFullscreenElementStack.exitFullscreen(); | 308 topFullscreenElementStack.exitFullscreen(); |
306 } | 309 } |
307 | 310 |
308 void FullscreenElementStack::exitFullscreen() | 311 void FullscreenElementStack::exitFullscreen() |
309 { | 312 { |
310 // The exitFullscreen() method must run these steps: | 313 // The exitFullscreen() method must run these steps: |
311 | 314 |
312 // 1. Let doc be the context object. (i.e. "this") | 315 // 1. Let doc be the context object. (i.e. "this") |
313 Document* currentDoc = document(); | 316 Document* currentDoc = document(); |
(...skipping 13 matching lines...) Expand all Loading... | |
327 continue; | 330 continue; |
328 ASSERT(toLocalFrame(descendant)->document()); | 331 ASSERT(toLocalFrame(descendant)->document()); |
329 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) | 332 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) |
330 descendants.prepend(toLocalFrame(descendant)->document()); | 333 descendants.prepend(toLocalFrame(descendant)->document()); |
331 } | 334 } |
332 | 335 |
333 // 4. For each descendant in descendants, empty descendant's fullscreen elem ent stack, and queue a | 336 // 4. For each descendant in descendants, empty descendant's fullscreen elem ent stack, and queue a |
334 // task to fire an event named fullscreenchange with its bubbles attribute s et to true on descendant. | 337 // task to fire an event named fullscreenchange with its bubbles attribute s et to true on descendant. |
335 for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendant s.begin(); i != descendants.end(); ++i) { | 338 for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendant s.begin(); i != descendants.end(); ++i) { |
336 ASSERT(*i); | 339 ASSERT(*i); |
340 RequestType requestType = from(**i).m_fullScreenElementStack.last().seco nd; | |
337 from(**i).clearFullscreenElementStack(); | 341 from(**i).clearFullscreenElementStack(); |
338 enqueueChangeEvent(**i); | 342 enqueueChangeEvent(**i, requestType); |
339 } | 343 } |
340 | 344 |
341 // 5. While doc is not null, run these substeps: | 345 // 5. While doc is not null, run these substeps: |
342 Element* newTop = 0; | 346 Element* newTop = 0; |
343 while (currentDoc) { | 347 while (currentDoc) { |
348 RequestType requestType = from(*currentDoc).m_fullScreenElementStack.las t().second; | |
349 | |
344 // 1. Pop the top element of doc's fullscreen element stack. | 350 // 1. Pop the top element of doc's fullscreen element stack. |
345 from(*currentDoc).popFullscreenElementStack(); | 351 from(*currentDoc).popFullscreenElementStack(); |
346 | 352 |
347 // If doc's fullscreen element stack is non-empty and the element now at the top is either | 353 // If doc's fullscreen element stack is non-empty and the element now at the top is either |
348 // not in a document or its node document is not doc, repeat this sub step. | 354 // not in a document or its node document is not doc, repeat this sub step. |
349 newTop = fullscreenElementFrom(*currentDoc); | 355 newTop = fullscreenElementFrom(*currentDoc); |
350 if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc )) | 356 if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc )) |
351 continue; | 357 continue; |
352 | 358 |
353 // 2. Queue a task to fire an event named fullscreenchange with its bubb les attribute set to true | 359 // 2. Queue a task to fire an event named fullscreenchange with its bubb les attribute set to true |
354 // on doc. | 360 // on doc. |
355 enqueueChangeEvent(*currentDoc); | 361 enqueueChangeEvent(*currentDoc, requestType); |
356 | 362 |
357 // 3. If doc's fullscreen element stack is empty and doc's browsing cont ext has a browsing context | 363 // 3. If doc's fullscreen element stack is empty and doc's browsing cont ext has a browsing context |
358 // container, set doc to that browsing context container's node document . | 364 // container, set doc to that browsing context container's node document . |
359 if (!newTop && currentDoc->ownerElement()) { | 365 if (!newTop && currentDoc->ownerElement()) { |
360 currentDoc = ¤tDoc->ownerElement()->document(); | 366 currentDoc = ¤tDoc->ownerElement()->document(); |
361 continue; | 367 continue; |
362 } | 368 } |
363 | 369 |
364 // 4. Otherwise, set doc to null. | 370 // 4. Otherwise, set doc to null. |
365 currentDoc = 0; | 371 currentDoc = 0; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 ASSERT(!m_fullScreenRenderer); | 503 ASSERT(!m_fullScreenRenderer); |
498 | 504 |
499 m_fullScreenRenderer = renderer; | 505 m_fullScreenRenderer = renderer; |
500 } | 506 } |
501 | 507 |
502 void FullscreenElementStack::fullScreenRendererDestroyed() | 508 void FullscreenElementStack::fullScreenRendererDestroyed() |
503 { | 509 { |
504 m_fullScreenRenderer = nullptr; | 510 m_fullScreenRenderer = nullptr; |
505 } | 511 } |
506 | 512 |
507 void FullscreenElementStack::enqueueChangeEvent(Document& document) | 513 void FullscreenElementStack::enqueueChangeEvent(Document& document, RequestType requestType) |
508 { | 514 { |
509 ASSERT(document.hasFullscreenElementStack()); | 515 RefPtrWillBeRawPtr<Event> event; |
510 FullscreenElementStack& fullscreen = from(document); | 516 if (requestType == UnprefixedRequest) { |
511 | 517 event = createEvent(EventTypeNames::fullscreenchange, document); |
512 EventTarget* target = fullscreen.fullscreenElement(); | 518 } else { |
513 if (!target) | 519 ASSERT(document.hasFullscreenElementStack()); |
514 target = fullscreen.webkitCurrentFullScreenElement(); | 520 FullscreenElementStack& fullscreen = from(document); |
515 if (!target) | 521 EventTarget* target = fullscreen.fullscreenElement(); |
516 target = &document; | 522 if (!target) |
517 m_eventQueue.append(createEvent(EventTypeNames::webkitfullscreenchange, *tar get)); | 523 target = fullscreen.webkitCurrentFullScreenElement(); |
524 if (!target) | |
525 target = &document; | |
526 event = createEvent(EventTypeNames::webkitfullscreenchange, *target); | |
527 } | |
528 m_eventQueue.append(event); | |
518 // NOTE: The timer is started in didEnterFullScreenForElement/didExitFullScr eenForElement. | 529 // NOTE: The timer is started in didEnterFullScreenForElement/didExitFullScr eenForElement. |
519 } | 530 } |
520 | 531 |
521 void FullscreenElementStack::enqueueErrorEvent(Element& element) | 532 void FullscreenElementStack::enqueueErrorEvent(Element& element, RequestType req uestType) |
522 { | 533 { |
523 m_eventQueue.append(createEvent(EventTypeNames::webkitfullscreenerror, eleme nt)); | 534 RefPtrWillBeRawPtr<Event> event; |
535 if (requestType == UnprefixedRequest) | |
536 event = createEvent(EventTypeNames::fullscreenerror, element.document()) ; | |
537 else | |
538 event = createEvent(EventTypeNames::webkitfullscreenerror, element); | |
539 m_eventQueue.append(event); | |
524 m_eventQueueTimer.startOneShot(0, FROM_HERE); | 540 m_eventQueueTimer.startOneShot(0, FROM_HERE); |
525 } | 541 } |
526 | 542 |
527 void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>* ) | 543 void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>* ) |
528 { | 544 { |
529 // Since we dispatch events in this function, it's possible that the | 545 // Since we dispatch events in this function, it's possible that the |
530 // document will be detached and GC'd. We protect it here to make sure we | 546 // document will be detached and GC'd. We protect it here to make sure we |
531 // can finish the function successfully. | 547 // can finish the function successfully. |
532 RefPtrWillBeRawPtr<Document> protectDocument(document()); | 548 RefPtrWillBeRawPtr<Document> protectDocument(document()); |
533 WillBeHeapDeque<RefPtrWillBeMember<Event> > eventQueue; | 549 WillBeHeapDeque<RefPtrWillBeMember<Event> > eventQueue; |
534 m_eventQueue.swap(eventQueue); | 550 m_eventQueue.swap(eventQueue); |
535 | 551 |
536 while (!eventQueue.isEmpty()) { | 552 while (!eventQueue.isEmpty()) { |
537 RefPtrWillBeRawPtr<Event> event = eventQueue.takeFirst(); | 553 RefPtrWillBeRawPtr<Event> event = eventQueue.takeFirst(); |
538 Node* target = event->target()->toNode(); | 554 Node* target = event->target()->toNode(); |
539 | 555 |
540 // If the element was removed from our tree, also message the documentEl ement. | 556 // If the element was removed from our tree, also message the documentEl ement. |
541 if (!target->inDocument() && document()->documentElement()) | 557 if (!target->inDocument() && document()->documentElement()) { |
558 ASSERT(event->type() == EventTypeNames::webkitfullscreenchange || ev ent->type() == EventTypeNames::webkitfullscreenerror); | |
542 eventQueue.append(createEvent(event->type(), *document()->documentEl ement())); | 559 eventQueue.append(createEvent(event->type(), *document()->documentEl ement())); |
560 } | |
543 | 561 |
544 target->dispatchEvent(event); | 562 target->dispatchEvent(event); |
545 } | 563 } |
546 } | 564 } |
547 | 565 |
548 void FullscreenElementStack::fullScreenElementRemoved() | 566 void FullscreenElementStack::fullScreenElementRemoved() |
549 { | 567 { |
550 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(false); | 568 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(false); |
551 fullyExitFullscreen(); | 569 fullyExitFullscreen(); |
552 } | 570 } |
(...skipping 23 matching lines...) Expand all Loading... | |
576 } | 594 } |
577 | 595 |
578 void FullscreenElementStack::popFullscreenElementStack() | 596 void FullscreenElementStack::popFullscreenElementStack() |
579 { | 597 { |
580 if (m_fullScreenElementStack.isEmpty()) | 598 if (m_fullScreenElementStack.isEmpty()) |
581 return; | 599 return; |
582 | 600 |
583 m_fullScreenElementStack.removeLast(); | 601 m_fullScreenElementStack.removeLast(); |
584 } | 602 } |
585 | 603 |
586 void FullscreenElementStack::pushFullscreenElementStack(Element& element) | 604 void FullscreenElementStack::pushFullscreenElementStack(Element& element, Reques tType requestType) |
587 { | 605 { |
588 m_fullScreenElementStack.append(&element); | 606 m_fullScreenElementStack.append(std::make_pair(&element, requestType)); |
589 } | 607 } |
590 | 608 |
591 void FullscreenElementStack::trace(Visitor* visitor) | 609 void FullscreenElementStack::trace(Visitor* visitor) |
592 { | 610 { |
593 visitor->trace(m_fullScreenElement); | 611 visitor->trace(m_fullScreenElement); |
594 visitor->trace(m_fullScreenElementStack); | 612 visitor->trace(m_fullScreenElementStack); |
595 visitor->trace(m_fullScreenRenderer); | 613 visitor->trace(m_fullScreenRenderer); |
596 visitor->trace(m_eventQueue); | 614 visitor->trace(m_eventQueue); |
597 DocumentSupplement::trace(visitor); | 615 DocumentSupplement::trace(visitor); |
598 } | 616 } |
599 | 617 |
600 } // namespace blink | 618 } // namespace blink |
OLD | NEW |