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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 #if !ENABLE(OILPAN) | 138 #if !ENABLE(OILPAN) |
139 void FullscreenElementStack::documentWasDisposed() | 139 void FullscreenElementStack::documentWasDisposed() |
140 { | 140 { |
141 // NOTE: the context dispose phase is not supported in oilpan. Please | 141 // NOTE: the context dispose phase is not supported in oilpan. Please |
142 // consider using the detach phase instead. | 142 // consider using the detach phase instead. |
143 m_fullScreenElement = nullptr; | 143 m_fullScreenElement = nullptr; |
144 m_fullScreenElementStack.clear(); | 144 m_fullScreenElementStack.clear(); |
145 } | 145 } |
146 #endif | 146 #endif |
147 | 147 |
148 bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) con
st | 148 void FullscreenElementStack::requestFullScreenForElement(Element& element, unsig
ned short flags, FullScreenCheckType checkType) |
149 { | |
150 ASSERT(element); | |
151 return fullscreenIsAllowedForAllOwners(element->document()); | |
152 } | |
153 | |
154 void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
ned short flags, FullScreenCheckType checkType) | |
155 { | 149 { |
156 // Ignore this request if the document is not in a live frame. | 150 // Ignore this request if the document is not in a live frame. |
157 if (!document()->isActive()) | 151 if (!document()->isActive()) |
158 return; | 152 return; |
159 | 153 |
160 // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI
> has different requirements | 154 // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI
> has different requirements |
161 // for full screen mode, and do not have the concept of a full screen elemen
t stack. | 155 // for full screen mode, and do not have the concept of a full screen elemen
t stack. |
162 bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST); | 156 bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST); |
163 | 157 |
164 do { | 158 do { |
165 if (!element) | |
166 element = document()->documentElement(); | |
167 | |
168 // 1. If any of the following conditions are true, terminate these steps
and queue a task to fire | 159 // 1. If any of the following conditions are true, terminate these steps
and queue a task to fire |
169 // an event named fullscreenerror with its bubbles attribute set to true
on the context object's | 160 // an event named fullscreenerror with its bubbles attribute set to true
on the context object's |
170 // node document: | 161 // node document: |
171 | 162 |
172 // The context object is not in a document. | 163 // The context object is not in a document. |
173 if (!element->inDocument()) | 164 if (!element.inDocument()) |
174 break; | 165 break; |
175 | 166 |
176 // The context object's node document, or an ancestor browsing context's
document does not have | 167 // The context object's node document, or an ancestor browsing context's
document does not have |
177 // the fullscreen enabled flag set. | 168 // the fullscreen enabled flag set. |
178 if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullScreenI
sAllowedForElement(element)) | 169 if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullscreenI
sAllowedForAllOwners(element.document())) |
179 break; | 170 break; |
180 | 171 |
181 // The context object's node document fullscreen element stack is not em
pty and its top element | 172 // The context object's node document fullscreen element stack is not em
pty and its top element |
182 // is not an ancestor of the context object. (NOTE: Ignore this requirem
ent if the request was | 173 // is not an ancestor of the context object. (NOTE: Ignore this requirem
ent if the request was |
183 // made via the legacy Mozilla-style API.) | 174 // made via the legacy Mozilla-style API.) |
184 if (!m_fullScreenElementStack.isEmpty() && !inLegacyMozillaMode) { | 175 if (!m_fullScreenElementStack.isEmpty() && !inLegacyMozillaMode) { |
185 Element* lastElementOnStack = m_fullScreenElementStack.last().get(); | 176 Element* lastElementOnStack = m_fullScreenElementStack.last().get(); |
186 if (lastElementOnStack == element || !lastElementOnStack->contains(e
lement)) | 177 if (lastElementOnStack == &element || !lastElementOnStack->contains(
&element)) |
187 break; | 178 break; |
188 } | 179 } |
189 | 180 |
190 // A descendant browsing context's document has a non-empty fullscreen e
lement stack. | 181 // A descendant browsing context's document has a non-empty fullscreen e
lement stack. |
191 bool descendentHasNonEmptyStack = false; | 182 bool descendentHasNonEmptyStack = false; |
192 for (Frame* descendant = document()->frame() ? document()->frame()->tree
().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext(
)) { | 183 for (Frame* descendant = document()->frame() ? document()->frame()->tree
().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext(
)) { |
193 if (!descendant->isLocalFrame()) | 184 if (!descendant->isLocalFrame()) |
194 continue; | 185 continue; |
195 ASSERT(toLocalFrame(descendant)->document()); | 186 ASSERT(toLocalFrame(descendant)->document()); |
196 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) { | 187 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 // 1. Let following document be the document after document in docs,
or null if there is no | 221 // 1. Let following document be the document after document in docs,
or null if there is no |
231 // such document. | 222 // such document. |
232 Document* currentDoc = *current; | 223 Document* currentDoc = *current; |
233 Document* followingDoc = following != docs.end() ? *following : 0; | 224 Document* followingDoc = following != docs.end() ? *following : 0; |
234 | 225 |
235 // 2. If following document is null, push context object on document
's fullscreen element | 226 // 2. If following document is null, push context object on document
's fullscreen element |
236 // stack, and queue a task to fire an event named fullscreenchange w
ith its bubbles attribute | 227 // stack, and queue a task to fire an event named fullscreenchange w
ith its bubbles attribute |
237 // set to true on the document. | 228 // set to true on the document. |
238 if (!followingDoc) { | 229 if (!followingDoc) { |
239 from(*currentDoc).pushFullscreenElementStack(element); | 230 from(*currentDoc).pushFullscreenElementStack(element); |
240 addDocumentToFullScreenChangeEventQueue(currentDoc); | 231 addDocumentToFullScreenChangeEventQueue(*currentDoc); |
241 continue; | 232 continue; |
242 } | 233 } |
243 | 234 |
244 // 3. Otherwise, if document's fullscreen element stack is either em
pty or its top element | 235 // 3. Otherwise, if document's fullscreen element stack is either em
pty or its top element |
245 // is not following document's browsing context container, | 236 // is not following document's browsing context container, |
246 Element* topElement = fullscreenElementFrom(*currentDoc); | 237 Element* topElement = fullscreenElementFrom(*currentDoc); |
247 if (!topElement || topElement != followingDoc->ownerElement()) { | 238 if (!topElement || topElement != followingDoc->ownerElement()) { |
248 // ...push following document's browsing context container on do
cument's fullscreen element | 239 // ...push following document's browsing context container on do
cument's fullscreen element |
249 // stack, and queue a task to fire an event named fullscreenchan
ge with its bubbles attribute | 240 // stack, and queue a task to fire an event named fullscreenchan
ge with its bubbles attribute |
250 // set to true on document. | 241 // set to true on document. |
251 from(*currentDoc).pushFullscreenElementStack(followingDoc->owner
Element()); | 242 from(*currentDoc).pushFullscreenElementStack(*followingDoc->owne
rElement()); |
252 addDocumentToFullScreenChangeEventQueue(currentDoc); | 243 addDocumentToFullScreenChangeEventQueue(*currentDoc); |
253 continue; | 244 continue; |
254 } | 245 } |
255 | 246 |
256 // 4. Otherwise, do nothing for this document. It stays the same. | 247 // 4. Otherwise, do nothing for this document. It stays the same. |
257 } while (++current != docs.end()); | 248 } while (++current != docs.end()); |
258 | 249 |
259 // 5. Return, and run the remaining steps asynchronously. | 250 // 5. Return, and run the remaining steps asynchronously. |
260 // 6. Optionally, perform some animation. | 251 // 6. Optionally, perform some animation. |
261 m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT; | 252 m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT; |
262 document()->frameHost()->chrome().client().enterFullScreenForElement(ele
ment); | 253 document()->frameHost()->chrome().client().enterFullScreenForElement(&el
ement); |
263 | 254 |
264 // 7. Optionally, display a message indicating how the user can exit dis
playing the context object fullscreen. | 255 // 7. Optionally, display a message indicating how the user can exit dis
playing the context object fullscreen. |
265 return; | 256 return; |
266 } while (0); | 257 } while (0); |
267 | 258 |
268 m_fullScreenErrorEventTargetQueue.append(element ? element : document()->doc
umentElement()); | 259 m_fullScreenErrorEventTargetQueue.append(&element); |
269 m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE); | 260 m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE); |
270 } | 261 } |
271 | 262 |
272 void FullscreenElementStack::webkitCancelFullScreen() | 263 void FullscreenElementStack::webkitCancelFullScreen() |
273 { | 264 { |
274 // The Mozilla "cancelFullScreen()" API behaves like the W3C "fully exit ful
lscreen" behavior, which | 265 // The Mozilla "cancelFullScreen()" API behaves like the W3C "fully exit ful
lscreen" behavior, which |
275 // is defined as: | 266 // is defined as: |
276 // "To fully exit fullscreen act as if the exitFullscreen() method was invok
ed on the top-level browsing | 267 // "To fully exit fullscreen act as if the exitFullscreen() method was invok
ed on the top-level browsing |
277 // context's document and subsequently empty that document's fullscreen elem
ent stack." | 268 // context's document and subsequently empty that document's fullscreen elem
ent stack." |
278 if (!fullscreenElementFrom(document()->topDocument())) | 269 if (!fullscreenElementFrom(document()->topDocument())) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 ASSERT(toLocalFrame(descendant)->document()); | 301 ASSERT(toLocalFrame(descendant)->document()); |
311 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) | 302 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) |
312 descendants.prepend(toLocalFrame(descendant)->document()); | 303 descendants.prepend(toLocalFrame(descendant)->document()); |
313 } | 304 } |
314 | 305 |
315 // 4. For each descendant in descendants, empty descendant's fullscreen elem
ent stack, and queue a | 306 // 4. For each descendant in descendants, empty descendant's fullscreen elem
ent stack, and queue a |
316 // task to fire an event named fullscreenchange with its bubbles attribute s
et to true on descendant. | 307 // task to fire an event named fullscreenchange with its bubbles attribute s
et to true on descendant. |
317 for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendant
s.begin(); i != descendants.end(); ++i) { | 308 for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendant
s.begin(); i != descendants.end(); ++i) { |
318 ASSERT(*i); | 309 ASSERT(*i); |
319 from(**i).clearFullscreenElementStack(); | 310 from(**i).clearFullscreenElementStack(); |
320 addDocumentToFullScreenChangeEventQueue(i->get()); | 311 addDocumentToFullScreenChangeEventQueue(**i); |
321 } | 312 } |
322 | 313 |
323 // 5. While doc is not null, run these substeps: | 314 // 5. While doc is not null, run these substeps: |
324 Element* newTop = 0; | 315 Element* newTop = 0; |
325 while (currentDoc) { | 316 while (currentDoc) { |
326 // 1. Pop the top element of doc's fullscreen element stack. | 317 // 1. Pop the top element of doc's fullscreen element stack. |
327 from(*currentDoc).popFullscreenElementStack(); | 318 from(*currentDoc).popFullscreenElementStack(); |
328 | 319 |
329 // If doc's fullscreen element stack is non-empty and the element now
at the top is either | 320 // If doc's fullscreen element stack is non-empty and the element now
at the top is either |
330 // not in a document or its node document is not doc, repeat this sub
step. | 321 // not in a document or its node document is not doc, repeat this sub
step. |
331 newTop = fullscreenElementFrom(*currentDoc); | 322 newTop = fullscreenElementFrom(*currentDoc); |
332 if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc
)) | 323 if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc
)) |
333 continue; | 324 continue; |
334 | 325 |
335 // 2. Queue a task to fire an event named fullscreenchange with its bubb
les attribute set to true | 326 // 2. Queue a task to fire an event named fullscreenchange with its bubb
les attribute set to true |
336 // on doc. | 327 // on doc. |
337 addDocumentToFullScreenChangeEventQueue(currentDoc); | 328 addDocumentToFullScreenChangeEventQueue(*currentDoc); |
338 | 329 |
339 // 3. If doc's fullscreen element stack is empty and doc's browsing cont
ext has a browsing context | 330 // 3. If doc's fullscreen element stack is empty and doc's browsing cont
ext has a browsing context |
340 // container, set doc to that browsing context container's node document
. | 331 // container, set doc to that browsing context container's node document
. |
341 if (!newTop && currentDoc->ownerElement()) { | 332 if (!newTop && currentDoc->ownerElement()) { |
342 currentDoc = ¤tDoc->ownerElement()->document(); | 333 currentDoc = ¤tDoc->ownerElement()->document(); |
343 continue; | 334 continue; |
344 } | 335 } |
345 | 336 |
346 // 4. Otherwise, set doc to null. | 337 // 4. Otherwise, set doc to null. |
347 currentDoc = 0; | 338 currentDoc = 0; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 } | 552 } |
562 | 553 |
563 void FullscreenElementStack::popFullscreenElementStack() | 554 void FullscreenElementStack::popFullscreenElementStack() |
564 { | 555 { |
565 if (m_fullScreenElementStack.isEmpty()) | 556 if (m_fullScreenElementStack.isEmpty()) |
566 return; | 557 return; |
567 | 558 |
568 m_fullScreenElementStack.removeLast(); | 559 m_fullScreenElementStack.removeLast(); |
569 } | 560 } |
570 | 561 |
571 void FullscreenElementStack::pushFullscreenElementStack(Element* element) | 562 void FullscreenElementStack::pushFullscreenElementStack(Element& element) |
572 { | 563 { |
573 m_fullScreenElementStack.append(element); | 564 m_fullScreenElementStack.append(&element); |
574 } | 565 } |
575 | 566 |
576 void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
oc) | 567 void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document& d
oc) |
577 { | 568 { |
578 ASSERT(doc); | |
579 | |
580 Node* target = 0; | 569 Node* target = 0; |
581 if (FullscreenElementStack* fullscreen = fromIfExists(*doc)) { | 570 if (FullscreenElementStack* fullscreen = fromIfExists(doc)) { |
582 target = fullscreen->webkitFullscreenElement(); | 571 target = fullscreen->webkitFullscreenElement(); |
583 if (!target) | 572 if (!target) |
584 target = fullscreen->webkitCurrentFullScreenElement(); | 573 target = fullscreen->webkitCurrentFullScreenElement(); |
585 } | 574 } |
586 | 575 |
587 if (!target) | 576 if (!target) |
588 target = doc; | 577 target = &doc; |
589 m_fullScreenChangeEventTargetQueue.append(target); | 578 m_fullScreenChangeEventTargetQueue.append(target); |
590 } | 579 } |
591 | 580 |
592 void FullscreenElementStack::trace(Visitor* visitor) | 581 void FullscreenElementStack::trace(Visitor* visitor) |
593 { | 582 { |
594 visitor->trace(m_fullScreenElement); | 583 visitor->trace(m_fullScreenElement); |
595 visitor->trace(m_fullScreenElementStack); | 584 visitor->trace(m_fullScreenElementStack); |
596 visitor->trace(m_fullScreenChangeEventTargetQueue); | 585 visitor->trace(m_fullScreenChangeEventTargetQueue); |
597 visitor->trace(m_fullScreenErrorEventTargetQueue); | 586 visitor->trace(m_fullScreenErrorEventTargetQueue); |
598 DocumentSupplement::trace(visitor); | 587 DocumentSupplement::trace(visitor); |
599 } | 588 } |
600 | 589 |
601 } // namespace WebCore | 590 } // namespace WebCore |
OLD | NEW |