WebCore: Implement WebKit Full Screen support.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Jan 2011 22:45:47 +0000 (22:45 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Jan 2011 22:45:47 +0000 (22:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2010-12-17
Reviewed by Simon Fraser.

Mark for export all those WebCore functions needed by WebFullscreenController.

* WebCore.exp.in:

WebCore: Implement WebKit Full Screen support.
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2010-12-17
Reviewed by Simon Fraser.

screenRect is useful for more than just HTMLMediaElements.  Promote it into
Element.

* dom/Element.cpp: Moved into Element from HTMLMediaElement.
* dom/Element.h: Ditto.
* dom/Node.cpp:
* html/HTMLMediaElement.cpp: Moved screenRect into Element.
* html/HTMLMediaElement.h: Ditto.
* WebCore.exp.in: Modify the exports list to reflect the new symbol name.

WebCore: Implement WebKit Full Screen support.
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2010-12-17
Reviewed by Simon Fraser.

The RenderFullScreen is intended to be used by clients of that API to allow a DOM subtree to
be rendered outside its original Frame. Because of this, there are a few areas of the
rendering code which need to be special cased: RenderFullScreen layers should not be clipped
to the viewport, as they will almost always be rendering outside the viewport area;
RenderFullScreen graphics layers should not be reparented by the RenderLayerCompositor, as
the client will likely want to reparent the platformLayer into their own fullscreen platform
window; the FrameView must update the RenderFullScreen graphics layer tree separately from
the root layer, as the two trees are disconnected.

* page/FrameView.cpp:
(WebCore::FrameView::updateCompositingLayers):  Special treatment for fullscreen renderer.
(WebCore::FrameView::syncCompositingStateRecursive): Ditto.
(WebCore::FrameView::paintContents): Ditto.
* rendering/RenderLayer.h: Add a new ContentChangeType enum entry for FullScreen.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::contentChanged): Add support for above.
* rendering/RenderLayerBacking.cpp:
(WebCore::layerOrAncestorIsFullScreen): New function.
(WebCore::RenderLayerBacking::updateCompositedBounds): Do not clip if the layerOrAncestorIsFullScreen.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Special treatment for fullscreen renderer.
(WebCore::RenderLayerCompositor::requiresCompositingLayer): Ditto.
(WebCore::RenderLayerCompositor::requiresCompositingForFullScreen): Ditto.
* rendering/RenderLayerCompositor.h:

WebCore: Implement WebKit Full Screen support.
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2010-12-17
Reviewed by Simon Fraser.

Implemented non-accelerated fullscreen support.  The Document will now vend a RenderFullScreen object for clients to
use to relocate the fullscreen element subtree.

* css/CSSStyleSelector.cpp:
(WebCore::loadFullScreenRulesIfNeeded): Change webkitFullScreen -> webkitIsFullScreen.
(WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): Ditto.
* dom/Document.cpp:
(WebCore::Document::Document): Initialize m_fullScreenRenderer.
(WebCore::Document::detach): Call setFullScreenRenderer(0).
(WebCore::Document::nodeWillBeRemoved): Replicate the logic in webkitWillEnterFullScreenForElement.
(WebCore::Document::webkitWillEnterFullScreenForElement):  Detach the fullscreen element to cause
    a new RenderFullScreen renderer to be created with the new fullscreen element.
(WebCore::Document::webkitDidEnterFullScreenForElement):  Notify clients of a fullscreen change
    here, rather in "willEnter", to avoid reentrancy problems when clients remove nodes in response
    to webkitfullscreenchange events.
(WebCore::Document::webkitWillExitFullScreenForElement): Recalculate the fullscreen element's style.
(WebCore::Document::webkitDidExitFullScreenForElement): Ditto.
(WebCore::Document::setFullScreenRenderer): Accessor for m_fullScreenRenderer.
(WebCore::Document::setFullScreenRendererSize): Set the style on the m_fullScreenRenderer with a new
    size; this keeps clients from having to access the renderer's style directly.
(WebCore::Document::setFullScreenRendererBackgroundColor): Ditto.
* dom/Document.h:
(WebCore::Document::webkitIsFullScreen): Change webkitFullScreen -> webkitIsFullScreen.
(WebCore::Document::fullScreenRenderer): Accessor.
* dom/Document.idl:
* dom/Node.cpp:
(WebCore::Node::createRendererIfNeeded): If the document is in fullscreen mode, create a RenderFullScreen
    object to insert between the fullscreen element and its parent.
* page/ChromeClient.h:
(WebCore::ChromeClient::fullScreenRendererChanged): Added.
* rendering/MediaControlElements.cpp:
(WebCore::MediaControlFullscreenButtonElement::defaultEventHandler): Change webkitFullScreen -> webkitIsFullScreen.

WebCore: Implement WebKit Full Screen support.
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2010-12-17
Reviewed by Simon Fraser.

This patch introduces a new RenderObject type: RenderFullScreen.  The RenderFullScreen renderer
will be used to implement new FullScreen APIs.  Because the RenderFullScreen object will be the
parent of the current fullscreen element, the style rules for fullscreen objects must change to
match.

* WebCore.xcodeproj/project.pbxproj:
* rendering/RenderFullScreen.cpp: Added.
(RenderFullScreen::setAnimating): Sets the m_isAnimating flag.
(RenderFullScreen::createFullScreenStyle): Returns a new RenderStyle containing the default stye
    for RenderFullScreen objects.
* rendering/RenderFullScreen.h: Added.
(WebCore::RenderFullScreen::isRenderFullScreen): Added.  Overrides the RenderObject version.
* rendering/RenderObject.h:
(WebCore::RenderObject::isRenderFullScreen): Added.  Used for type-checking RenderFullScreen objects.
* css/fullscreen.css:  Modified the contained fullscreen styles.

WebKit/mac: Implement WebKit Full Screen support.
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2011-01-05
Reviewed by Simon Fraser.

Support the new fullscreen Chrome client requests.  WebView will pass
through these requests to a WebFullscreenController.

* WebCoreSupport/WebChromeClient.h: Add fullScreenRendererChanged().
* WebView/WebView.mm:
(-[WebView _supportsFullScreenForElement:WebCore::]): Check to see if the fullscreen pref has been enabled.
(-[WebView _enterFullScreenForElement:WebCore::]): Create a WebFullScreenController.
(-[WebView _exitFullScreenForElement:WebCore::]): Request that the WebFullScreenController exit fullscreen.
(-[WebView _fullScreenRendererChanged:WebCore::]): Notify the WebFullScreenController that its renderer has changed.
* WebView/WebViewData.h: Add ivar newFullscreenController.

Patch by Jer Noble <jer@kokode.apple.com> on 2011-01-05
Reviewed by Simon Fraser.

This patch implements the FullScreen APIs using the new RenderFullScreen renderer and the new
Document client APIs. The RenderFullScreen renderer's CALayer is hosted in a new, fullscreen
window, and a custom CAAnimation animates that layer between the initial screen rect of the
full screen element, to its final value. WebFullscreenController will swap the WebView out of
its original window, and into the fullscreen window. The controller will replace the WebView
with a placeholder view, so that if the placeholder moves or resized while the WebView is
absent, the WebView will move back to the correct location when exiting fullscreen.

* WebView/WebFullscreenController.h: Added.
* WebView/WebFullscreenController.mm: Added.
(-[WebFullscreenController windowDidExitFullscreen:]):  Close the fullscreen window.
(-[WebFullscreenController windowDidEnterFullscreen:]): Swap the webView back into the fullscreen window.
(-[WebFullscreenController animationDidStop:finished:]): Call windowDid{Exit|Enter}FullScreen as appropriate.
(-[WebFullscreenController applicationDidResignActive:]):
(-[WebFullscreenController applicationDidChangeScreenParameters:]): Resize the fullscreen window to match
    the new screen parameters.
(-[WebFullscreenController enterFullscreen:]):  Set up the animation that will take the fullscreen element
    from its original screen rect into fullscreen.
(-[WebFullscreenController exitFullscreen]): Swap the webView back into its original window.
    Set up the animation that will take the fullscreen element back into its original screen
    rect.
(-[WebFullscreenController _updatePowerAssertions]): Now checks _isAnyMoviePlaying to determine
    whether to disable screensaver and sleep.
(-[WebFullscreenController _isAnyMoviePlaying]): Walks through the sub-tree starting at the fullscreen element
    looking for HTMLVideoElements; returns whether any are found to be playing.
(-[WebFullscreenController _animationDuration]): Returns the current animation duration, affected by control
    and shift keys.
(-[WebFullscreenWindow canBecomeKeyWindow]): Allow the window to become key.
(-[WebFullscreenWindow keyDown:]): Handle the 'Esc' key.
(-[WebFullscreenWindow cancelOperation:]): Request to exit fullscreen.
(-[WebFullscreenWindow rendererLayer]): Convenience accessor.
(-[WebFullscreenWindow setRendererLayer:]): Ditto.
(-[WebFullscreenWindow backgroundLayer]): Ditto.
(-[WebFullscreenWindow animationView]): Ditto.
(MediaEventListener::MediaEventListener): Implements the EventListener protocol.
(MediaEventListener::handleEvent): Tells its delegate to _updatePowerAssertions.

LayoutTests: Implement WebKit Full Screen support.
https://bugs.webkit.org/show_bug.cgi?id=49481
rdar://problem/8247444

Patch by Jer Noble <jer@kokode.apple.com> on 2011-01-05
Reviewed by Simon Fraser.

Update the tests with new API names and spec values.

* fullscreen/full-screen-api-expected.txt:
* fullscreen/full-screen-api.html:
* fullscreen/full-screen-css.html:
* fullscreen/full-screen-request-expected.txt:
* fullscreen/full-screen-request.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@75277 268f45cc-cd09-0410-ab3c-d52691b4dbfc

40 files changed:
LayoutTests/ChangeLog
LayoutTests/fullscreen/full-screen-api-expected.txt
LayoutTests/fullscreen/full-screen-api.html
LayoutTests/fullscreen/full-screen-css-expected.txt
LayoutTests/fullscreen/full-screen-css.html
LayoutTests/fullscreen/full-screen-request-expected.txt
LayoutTests/fullscreen/full-screen-request.html
WebCore/ChangeLog
WebCore/WebCore.exp.in
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/css/CSSStyleSelector.cpp
WebCore/css/fullscreen.css
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/dom/Document.idl
WebCore/dom/Element.cpp
WebCore/dom/Element.h
WebCore/dom/Node.cpp
WebCore/html/HTMLMediaElement.cpp
WebCore/html/HTMLMediaElement.h
WebCore/page/ChromeClient.h
WebCore/page/FrameView.cpp
WebCore/rendering/MediaControlElements.cpp
WebCore/rendering/RenderFullScreen.cpp [new file with mode: 0644]
WebCore/rendering/RenderFullScreen.h [new file with mode: 0644]
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderLayer.h
WebCore/rendering/RenderLayerBacking.cpp
WebCore/rendering/RenderLayerCompositor.cpp
WebCore/rendering/RenderLayerCompositor.h
WebCore/rendering/RenderObject.h
WebKit/WebKit.xcodeproj/project.pbxproj
WebKit/mac/ChangeLog
WebKit/mac/WebCoreSupport/WebChromeClient.h
WebKit/mac/WebCoreSupport/WebChromeClient.mm
WebKit/mac/WebView/WebFullScreenController.h [new file with mode: 0644]
WebKit/mac/WebView/WebFullScreenController.mm [new file with mode: 0644]
WebKit/mac/WebView/WebView.mm
WebKit/mac/WebView/WebViewData.h
WebKit/mac/WebView/WebViewInternal.h

index b4d8ce6..e73bfd3 100644 (file)
@@ -1,3 +1,19 @@
+2011-01-05  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+        
+        Update the tests with new API names and spec values.
+
+        * fullscreen/full-screen-api-expected.txt:
+        * fullscreen/full-screen-api.html:
+        * fullscreen/full-screen-css.html:
+        * fullscreen/full-screen-request-expected.txt:
+        * fullscreen/full-screen-request.html:
+
 2011-01-07  James Robinson  <jamesr@chromium.org>
 
         Revert "Implement mozilla's animationTime property"
index 9640804..8c4e812 100644 (file)
@@ -1,4 +1,4 @@
-EXPECTED (document.webkitFullScreen == 'false') OK
+EXPECTED (document.webkitIsFullScreen == 'false') OK
 EXPECTED (document.webkitCancelFullScreen != 'undefined') OK
 EXPECTED (document.webkitCurrentFullScreenElement == 'null') OK
 EXPECTED (document.onwebkitfullscreenchange == 'null') OK
index 859e627..78cf156 100644 (file)
@@ -3,7 +3,7 @@
 <span></span>
 <script>
     span = document.getElementsByTagName('span')[0];
-    testExpected("document.webkitFullScreen", false);
+    testExpected("document.webkitIsFullScreen", false);
     testExpected("document.webkitCancelFullScreen", undefined, "!=");
     testExpected("document.webkitCurrentFullScreenElement", null);
     testExpected("document.onwebkitfullscreenchange", null)
index ab993f8..3847c5d 100644 (file)
@@ -1,6 +1,6 @@
-EXPECTED (document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color') != 'rgb(0, 255, 0)') OK
-EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color') != 'rgb(255, 0, 0)') OK
-EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color') != 'rgb(0, 0, 255)') OK
+EXPECTED (document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color') == 'rgba(0, 0, 0, 0)') OK
+EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color') == 'rgba(0, 0, 0, 0)') OK
+EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color') == 'rgb(0, 0, 0)') OK
 EVENT(webkitfullscreenchange)
 EXPECTED (document.webkitCurrentFullScreenElement == '[object HTMLElement]') OK
 EXPECTED (document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color') == 'rgb(0, 255, 0)') OK
@@ -8,8 +8,8 @@ EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).
 EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color') == 'rgb(0, 0, 255)') OK
 EVENT(webkitfullscreenchange)
 EXPECTED (document.webkitCurrentFullScreenElement == '[object HTMLHtmlElement]') OK
-EXPECTED (document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color') == 'rgb(0, 255, 0)') OK
-EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color') != 'rgb(255, 0, 0)') OK
+EXPECTED (document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color') == 'rgba(0, 0, 0, 0)') OK
+EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color') == 'rgb(0, 255, 0)') OK
 EXPECTED (document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color') == 'rgb(0, 0, 255)') OK
 END OF TEST
 
index 3115927..9fa9de3 100644 (file)
@@ -22,9 +22,9 @@
 
         var span = document.getElementsByTagName('span')[0];
     
-        testExpected("document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color')", "rgb(0, 255, 0)", "!=");
-        testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color')", "rgb(255, 0, 0)", "!=");
-        testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color')", "rgb(0, 0, 255)", "!=");
+        testExpected("document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color')", "rgba(0, 0, 0, 0)");
+        testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color')", "rgba(0, 0, 0, 0)");
+        testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color')", "rgb(0, 0, 0)");
     
         var spanEnteredFullScreen = function(event) {
             testExpected("document.webkitCurrentFullScreenElement", span);
@@ -38,8 +38,8 @@
     
         var documentEnteredFullScreen = function(event) {
             testExpected("document.webkitCurrentFullScreenElement", document.documentElement);
-            testExpected("document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color')", "rgb(0, 255, 0)");
-            testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color')", "rgb(255, 0, 0)", "!=");
+            testExpected("document.defaultView.getComputedStyle(span, null).getPropertyValue('background-color')", "rgba(0, 0, 0, 0)");
+            testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('background-color')", "rgb(0, 255, 0)");
             testExpected("document.defaultView.getComputedStyle(document.documentElement, null).getPropertyValue('color')", "rgb(0, 0, 255)");
             endTest();
         };
index 4bf81ef..c681dab 100644 (file)
@@ -1,3 +1,3 @@
-EVENT(webkitfullscreenchange) TEST(document.webkitFullScreen==true) OK
+EVENT(webkitfullscreenchange) TEST(document.webkitIsFullScreen==true) OK
 END OF TEST
 
index 2adb97f..3f2cfa5 100644 (file)
@@ -6,7 +6,7 @@
         logResult(false, "Element.prototype.webkitRequestFullScreen == undefined");
         endTest();
     } else {
-        waitForEventTestAndEnd(document, 'webkitfullscreenchange', "document.webkitFullScreen==true");
+        waitForEventTestAndEnd(document, 'webkitfullscreenchange', "document.webkitIsFullScreen==true");
         document.documentElement.webkitRequestFullScreen();
     }
 </script>
index 98cbc73..309e6af 100644 (file)
@@ -1,3 +1,131 @@
+2010-12-17  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+
+        Mark for export all those WebCore functions needed by WebFullscreenController.
+
+        * WebCore.exp.in:
+
+2010-12-17  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+        
+        screenRect is useful for more than just HTMLMediaElements.  Promote it into
+        Element.
+
+        * dom/Element.cpp: Moved into Element from HTMLMediaElement.
+        * dom/Element.h: Ditto.
+        * dom/Node.cpp:
+        * html/HTMLMediaElement.cpp: Moved screenRect into Element.
+        * html/HTMLMediaElement.h: Ditto.
+        * WebCore.exp.in: Modify the exports list to reflect the new symbol name.
+
+2010-12-17  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+
+        The RenderFullScreen is intended to be used by clients of that API to allow a DOM subtree to
+        be rendered outside its original Frame. Because of this, there are a few areas of the
+        rendering code which need to be special cased: RenderFullScreen layers should not be clipped
+        to the viewport, as they will almost always be rendering outside the viewport area;
+        RenderFullScreen graphics layers should not be reparented by the RenderLayerCompositor, as
+        the client will likely want to reparent the platformLayer into their own fullscreen platform
+        window; the FrameView must update the RenderFullScreen graphics layer tree separately from
+        the root layer, as the two trees are disconnected.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::updateCompositingLayers):  Special treatment for fullscreen renderer.
+        (WebCore::FrameView::syncCompositingStateRecursive): Ditto.
+        (WebCore::FrameView::paintContents): Ditto.
+        * rendering/RenderLayer.h: Add a new ContentChangeType enum entry for FullScreen.
+        * rendering/RenderLayer.cpp: 
+        (WebCore::RenderLayer::contentChanged): Add support for above.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::layerOrAncestorIsFullScreen): New function.
+        (WebCore::RenderLayerBacking::updateCompositedBounds): Do not clip if the layerOrAncestorIsFullScreen.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Special treatment for fullscreen renderer.
+        (WebCore::RenderLayerCompositor::requiresCompositingLayer): Ditto.
+        (WebCore::RenderLayerCompositor::requiresCompositingForFullScreen): Ditto.
+        * rendering/RenderLayerCompositor.h:
+
+2010-12-17  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implemented non-accelerated fullscreen support.  The Document will now vend a RenderFullScreen object for clients to
+        use to relocate the fullscreen element subtree.
+
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::loadFullScreenRulesIfNeeded): Change webkitFullScreen -> webkitIsFullScreen.
+        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): Ditto.
+        * dom/Document.cpp:
+        (WebCore::Document::Document): Initialize m_fullScreenRenderer.
+        (WebCore::Document::detach): Call setFullScreenRenderer(0).
+        (WebCore::Document::nodeWillBeRemoved): Replicate the logic in webkitWillEnterFullScreenForElement.
+        (WebCore::Document::webkitWillEnterFullScreenForElement):  Detach the fullscreen element to cause
+            a new RenderFullScreen renderer to be created with the new fullscreen element.
+        (WebCore::Document::webkitDidEnterFullScreenForElement):  Notify clients of a fullscreen change
+            here, rather in "willEnter", to avoid reentrancy problems when clients remove nodes in response
+            to webkitfullscreenchange events.
+        (WebCore::Document::webkitWillExitFullScreenForElement): Recalculate the fullscreen element's style.
+        (WebCore::Document::webkitDidExitFullScreenForElement): Ditto.
+        (WebCore::Document::setFullScreenRenderer): Accessor for m_fullScreenRenderer.
+        (WebCore::Document::setFullScreenRendererSize): Set the style on the m_fullScreenRenderer with a new
+            size; this keeps clients from having to access the renderer's style directly.
+        (WebCore::Document::setFullScreenRendererBackgroundColor): Ditto.
+        * dom/Document.h:
+        (WebCore::Document::webkitIsFullScreen): Change webkitFullScreen -> webkitIsFullScreen.
+        (WebCore::Document::fullScreenRenderer): Accessor.
+        * dom/Document.idl:
+        * dom/Node.cpp:
+        (WebCore::Node::createRendererIfNeeded): If the document is in fullscreen mode, create a RenderFullScreen
+            object to insert between the fullscreen element and its parent.
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::fullScreenRendererChanged): Added.
+        * rendering/MediaControlElements.cpp:
+        (WebCore::MediaControlFullscreenButtonElement::defaultEventHandler): Change webkitFullScreen -> webkitIsFullScreen.
+
+2010-12-17  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+        
+        This patch introduces a new RenderObject type: RenderFullScreen.  The RenderFullScreen renderer 
+        will be used to implement new FullScreen APIs.  Because the RenderFullScreen object will be the
+        parent of the current fullscreen element, the style rules for fullscreen objects must change to
+        match.
+        
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/RenderFullScreen.cpp: Added.
+        (RenderFullScreen::setAnimating): Sets the m_isAnimating flag.
+        (RenderFullScreen::createFullScreenStyle): Returns a new RenderStyle containing the default stye
+            for RenderFullScreen objects.
+        * rendering/RenderFullScreen.h: Added.
+        (WebCore::RenderFullScreen::isRenderFullScreen): Added.  Overrides the RenderObject version.
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::isRenderFullScreen): Added.  Used for type-checking RenderFullScreen objects.
+        * css/fullscreen.css:  Modified the contained fullscreen styles.
+
+
 2011-01-07  James Robinson  <jamesr@chromium.org>
 
         Revert "Implement mozilla's animationTime property"
index 7e3608d..baa6f7d 100644 (file)
@@ -1165,6 +1165,7 @@ __ZNK7WebCore7Element19boundsInWindowSpaceEv
 __ZNK7WebCore7Element9innerTextEv
 __ZNK7WebCore7IntRect8containsERKS0_
 __ZNK7WebCore7IntRect10intersectsERKS0_
+__ZNK7WebCore7Element10screenRectEv
 __ZNK7WebCore7IntRectcv6CGRectEv
 __ZNK7WebCore7IntRectcv7_NSRectEv
 __ZNK7WebCore7IntSizecv7_NSSizeEv
@@ -1606,7 +1607,6 @@ _wkSupportsMultipartXMixedReplace
 #endif
 
 #if ENABLE(VIDEO)
-__ZN7WebCore16HTMLMediaElement10screenRectEv
 __ZN7WebCore16HTMLMediaElement12endScrubbingEv
 __ZN7WebCore16HTMLMediaElement14beginScrubbingEv
 __ZN7WebCore16HTMLMediaElement14exitFullscreenEv
@@ -1638,6 +1638,13 @@ __ZN7WebCore8Document33webkitDidExitFullScreenForElementEPNS_7ElementE
 __ZN7WebCore8Document34webkitDidEnterFullScreenForElementEPNS_7ElementE
 __ZN7WebCore8Document34webkitWillExitFullScreenForElementEPNS_7ElementE
 __ZN7WebCore8Document35webkitWillEnterFullScreenForElementEPNS_7ElementE
+__ZN7WebCore8Document25setFullScreenRendererSizeERKNS_7IntSizeE
+__ZN7WebCore8Document36setFullScreenRendererBackgroundColorENS_5ColorE
+__ZNK7WebCore8Document9domWindowEv
+__ZNK7WebCore16HTMLMediaElement5endedEv
+__ZNK7WebCore16HTMLMediaElement6pausedEv
+__ZN7WebCore8Document12updateLayoutEv
+__ZNK7WebCore4Node16traverseNextNodeEPKS0_
 #endif
 
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
index 3db3d1c..be10fe9 100644 (file)
                C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
                CA3BF67C10D99BAE00E6CE53 /* ScrollAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */; };
                CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; };
+               CDEA7C841276230400B846DD /* RenderFullScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEA7C821276230400B846DD /* RenderFullScreen.h */; };
+               CDEA7C851276230400B846DD /* RenderFullScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA7C831276230400B846DD /* RenderFullScreen.cpp */; };
                CE02F0C411E83ADD00C6684A /* ScriptControllerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */; };
                CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE057FA41220731100A476D5 /* DocumentMarkerController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimator.cpp; sourceTree = "<group>"; };
                CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; };
                CD4E0AFA11F7BC27009D3811 /* fullscreen.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreen.css; sourceTree = "<group>"; };
+               CDEA7C821276230400B846DD /* RenderFullScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFullScreen.h; sourceTree = "<group>"; };
+               CDEA7C831276230400B846DD /* RenderFullScreen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFullScreen.cpp; sourceTree = "<group>"; };
                CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptControllerBase.h; sourceTree = "<group>"; };
                CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
                CE057FA41220731100A476D5 /* DocumentMarkerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentMarkerController.h; sourceTree = "<group>"; };
                                0FD3080D117CF7E700A791F7 /* RenderFrameBase.h */,
                                A871DECA0A1530C700B12A68 /* RenderFrameSet.cpp */,
                                A871DEC90A1530C700B12A68 /* RenderFrameSet.h */,
+                               CDEA7C831276230400B846DD /* RenderFullScreen.cpp */,
+                               CDEA7C821276230400B846DD /* RenderFullScreen.h */,
                                BCEA482A097D93020094C9E4 /* RenderHTMLCanvas.cpp */,
                                BCEA482B097D93020094C9E4 /* RenderHTMLCanvas.h */,
                                0FD308D3117D168400A791F7 /* RenderIFrame.cpp */,
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               CDEA7C841276230400B846DD /* RenderFullScreen.h in Headers */,
                                B5B5DC6A119BB3D5002A8790 /* AbstractDatabase.h in Headers */,
                                41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */,
                                29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */,
                                7EE6847512D26E7000E79415 /* ResourceLoaderCFNet.cpp in Sources */,
                                93F1D5BA12D532C400832BEC /* WebKitLoseContext.cpp in Sources */,
                                93F1D5C012D5335600832BEC /* JSWebKitLoseContext.cpp in Sources */,
+                               CDEA7C851276230400B846DD /* RenderFullScreen.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index edb216f..fd9da77 100644 (file)
@@ -603,7 +603,7 @@ static void loadFullDefaultStyle()
 #if ENABLE(FULLSCREEN_API)
 static void loadFullScreenRulesIfNeeded(Document* document)
 {
-    if (!document->webkitFullScreen())
+    if (!document->webkitIsFullScreen())
         return;
     // Full-screen rules.
     String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet();
@@ -2664,17 +2664,15 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
                 // element is an element in the document, the 'full-screen' pseudoclass applies to 
                 // that element. Also, an <iframe>, <object> or <embed> element whose child browsing 
                 // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
-                if (!e->document()->webkitFullScreen())
+                if (!e->document()->webkitIsFullScreen())
                     return false;
                 if (e != e->document()->webkitCurrentFullScreenElement())
                     return false;
                 return true;
             case CSSSelector::PseudoFullScreenDocument:
                 // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies 
-                // to the root element of that Document.
-                if (!e->document()->webkitFullScreen())
-                    return false;
-                if (e != e->document()->documentElement())
+                // to all elements of that Document.
+                if (!e->document()->webkitIsFullScreen())
                     return false;
                 return true;
 #endif
index ebf3a02..2e38c95 100644 (file)
@@ -1,9 +1,5 @@
 :-webkit-full-screen {
-    position:fixed;
-    top:0;
-    left:0;
-    right:0;
-    bottom:0;
+    background-color: white;
 }
 
 :root:full-screen-document:not(:full-screen) {
 }
 
 video:-webkit-full-screen {
-    width: 100%;
-    height: 100%
-    image-fit: fill;
+    background-color: black;
+    width: auto;   
+    height: 100%;
+    max-width: 100%;
 }
 
 img:-webkit-full-screen {
-    width: 100%;
+    width: auto;   
     height: 100%;
-    image-fit: fill;
+    max-width: 100%;
 }
 
 video:-webkit-full-page-media:-webkit-full-screen::-webkit-media-controls-panel {
index 5bfee03..b943f63 100644 (file)
 #include "HTMLNoScriptElement.h"
 #endif
 
+#if ENABLE(FULLSCREEN_API)
+#include "RenderFullScreen.h"
+#endif
+
 using namespace std;
 using namespace WTF;
 using namespace Unicode;
@@ -414,6 +418,8 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML, con
 #if ENABLE(FULLSCREEN_API)
     , m_isFullScreen(0)
     , m_areKeysEnabledInFullScreen(0)
+    , m_fullScreenRenderer(0)
+    , m_fullScreenChangeDelayTimer(this, &Document::fullScreenChangeDelayTimerFired)
 #endif
     , m_loadEventDelayCount(0)
     , m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
@@ -1816,6 +1822,11 @@ void Document::detach()
 
     // indicate destruction mode,  i.e. attached() but renderer == 0
     setRenderer(0);
+    
+#if ENABLE(FULLSCREEN_API)
+    if (m_fullScreenRenderer)
+        setFullScreenRenderer(0);
+#endif
 
     m_hoverNode = 0;
     m_focusedNode = 0;
@@ -3372,9 +3383,12 @@ void Document::nodeWillBeRemoved(Node* n)
     ASSERT(n);
     if (n->contains(m_fullScreenElement.get())) {
         ASSERT(n != documentElement());
+        setFullScreenRenderer(0);
         m_fullScreenElement = documentElement();
         m_fullScreenElement->setNeedsStyleRecalc();
-        m_fullScreenElement->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+        m_fullScreenElement->detach();
+        updateStyleIfNeeded();
+        m_fullScreenChangeDelayTimer.startOneShot(0);
     }
 #endif
 }
@@ -4822,19 +4836,29 @@ void Document::webkitWillEnterFullScreenForElement(Element* element)
 
     m_fullScreenElement = element;
     m_isFullScreen = true;
-    documentElement()->setNeedsStyleRecalc(FullStyleChange);
-    m_fullScreenElement->setNeedsStyleRecalc(FullStyleChange);
-    updateStyleIfNeeded();
     
-    m_fullScreenElement->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+    if (m_fullScreenElement != documentElement())
+        m_fullScreenElement->detach();
+
+    recalcStyle(Force);
+    
+    if (m_fullScreenRenderer)
+        m_fullScreenRenderer->setAnimating(true);
 }
     
 void Document::webkitDidEnterFullScreenForElement(Element*)
 {
+    if (m_fullScreenRenderer)
+        m_fullScreenRenderer->setAnimating(false);
+    m_fullScreenChangeDelayTimer.startOneShot(0);
 }
 
 void Document::webkitWillExitFullScreenForElement(Element*)
 {
+    if (m_fullScreenRenderer)
+        m_fullScreenRenderer->setAnimating(true);
+
+    recalcStyle(Force);
 }
 
 void Document::webkitDidExitFullScreenForElement(Element* element)
@@ -4843,16 +4867,62 @@ void Document::webkitDidExitFullScreenForElement(Element* element)
     m_isFullScreen = false;
     m_areKeysEnabledInFullScreen = false;
 
-    // m_fullScreenElement has already been cleared; recalc the style of 
-    // the passed in element instead.
-    element->setNeedsStyleRecalc(FullStyleChange);
-    if (element != documentElement())
-        documentElement()->setNeedsStyleRecalc(FullStyleChange);
-    updateStyleIfNeeded();
+    if (m_fullScreenRenderer)
+        m_fullScreenRenderer->remove();
     
-    element->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+    if (m_fullScreenElement != documentElement())
+        m_fullScreenElement->detach();
+    
+    setFullScreenRenderer(0);
+    recalcStyle(Force);
+    
+    m_fullScreenChangeDelayTimer.startOneShot(0);
+}
+    
+void Document::setFullScreenRenderer(RenderFullScreen* renderer)
+{
+    m_fullScreenRenderer = renderer;
+    
+    // This notification can come in after the page has been destroyed.
+    if (page())
+        page()->chrome()->client()->fullScreenRendererChanged(m_fullScreenRenderer);
+}
+    
+void Document::setFullScreenRendererSize(const IntSize& size)
+{
+    ASSERT(m_fullScreenRenderer);
+    if (!m_fullScreenRenderer)
+        return;
+    
+    if (m_fullScreenRenderer) {
+        RefPtr<RenderStyle> newStyle = RenderStyle::clone(m_fullScreenRenderer->style());
+        newStyle->setWidth(Length(size.width(), WebCore::Fixed));
+        newStyle->setHeight(Length(size.height(), WebCore::Fixed));
+        newStyle->setTop(Length(0, WebCore::Fixed));
+        newStyle->setLeft(Length(0, WebCore::Fixed));
+        m_fullScreenRenderer->setStyle(newStyle);
+    }
+}
+    
+void Document::setFullScreenRendererBackgroundColor(Color backgroundColor)
+{
+    if (!m_fullScreenRenderer)
+        return;
+    
+    RefPtr<RenderStyle> newStyle = RenderStyle::clone(m_fullScreenRenderer->style());
+    newStyle->setBackgroundColor(backgroundColor);
+    m_fullScreenRenderer->setStyle(newStyle);
 }
     
+void Document::fullScreenChangeDelayTimerFired(Timer<Document>*)
+{
+    Element* element = m_fullScreenElement.get();
+    if (!element)
+        element = documentElement();
+    
+    element->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+}
+
 #endif
 
 void Document::decrementLoadEventDelayCount()
index 7e7967f..fb1ae31 100644 (file)
@@ -108,6 +108,7 @@ class Range;
 class RegisteredEventListener;
 class RenderArena;
 class RenderView;
+class RenderFullScreen;
 class ScriptableDocumentParser;
 class ScriptElementData;
 class SecurityOrigin;
@@ -1039,7 +1040,7 @@ public:
     const QualifiedName& idAttributeName() const { return m_idAttributeName; }
     
 #if ENABLE(FULLSCREEN_API)
-    bool webkitFullScreen() const { return m_isFullScreen; }
+    bool webkitIsFullScreen() const { return m_isFullScreen; }
     bool webkitFullScreenKeyboardInputAllowed() const { return m_isFullScreen && m_areKeysEnabledInFullScreen; }
     Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); }
     void webkitRequestFullScreenForElement(Element*, unsigned short flags);
@@ -1049,6 +1050,14 @@ public:
     void webkitDidEnterFullScreenForElement(Element*);
     void webkitWillExitFullScreenForElement(Element*);
     void webkitDidExitFullScreenForElement(Element*);
+    
+    void setFullScreenRenderer(RenderFullScreen*);
+    RenderFullScreen* fullScreenRenderer() const { return m_fullScreenRenderer; }
+    
+    void setFullScreenRendererSize(const IntSize&);
+    void setFullScreenRendererBackgroundColor(Color);
+    
+    void fullScreenChangeDelayTimerFired(Timer<Document>*);
 #endif
 
     // Used to allow element that loads data without going through a FrameLoader to delay the 'load' event.
@@ -1368,6 +1377,8 @@ private:
     bool m_isFullScreen;
     bool m_areKeysEnabledInFullScreen;
     RefPtr<Element> m_fullScreenElement;
+    RenderFullScreen* m_fullScreenRenderer;
+    Timer<Document> m_fullScreenChangeDelayTimer;
 #endif
 
     int m_loadEventDelayCount;
index 062e42d..89f53ec 100644 (file)
@@ -243,7 +243,7 @@ module core {
 #endif
 
 #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API
-        readonly attribute boolean webkitFullScreen;
+        readonly attribute boolean webkitIsFullScreen;
         readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
         readonly attribute Element webkitCurrentFullScreenElement;
         void webkitCancelFullScreen();
index 9b4578f..6d183ef 100644 (file)
@@ -558,6 +558,13 @@ PassRefPtr<ClientRect> Element::getBoundingClientRect() const
     adjustFloatRectForAbsoluteZoom(result, renderer());
     return ClientRect::create(result);
 }
+    
+IntRect Element::screenRect() const
+{
+    if (!renderer())
+        return IntRect();
+    return renderer()->view()->frameView()->contentsToScreen(renderer()->absoluteBoundingBoxRect());
+}
 
 static inline bool shouldIgnoreAttributeCase(const Element* e)
 {
index 9bad66f..e552376 100644 (file)
@@ -169,6 +169,9 @@ public:
 
     PassRefPtr<ClientRectList> getClientRects() const;
     PassRefPtr<ClientRect> getBoundingClientRect() const;
+    
+    // Returns the absolute bounding box translated into screen coordinates:
+    IntRect screenRect() const;
 
     void removeAttribute(const String& name, ExceptionCode&);
     void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
index c0d47e4..db36e5e 100644 (file)
 #include "ProcessingInstruction.h"
 #include "ProgressEvent.h"
 #include "RegisteredEventListener.h"
+#include "RenderBlock.h"
 #include "RenderBox.h"
+#include "RenderFullScreen.h"
+#include "RenderView.h"
 #include "ScopedEventQueue.h"
 #include "ScriptController.h"
 #include "SelectorNodeList.h"
@@ -1357,6 +1360,21 @@ void Node::createRendererIfNeeded()
     ASSERT(parent);
     
     RenderObject* parentRenderer = parent->renderer();
+    RenderObject* nextRenderer = this->nextRenderer();
+    
+#if ENABLE(FULLSCREEN_API)
+    // If this node is a fullscreen node, create a new anonymous full screen
+    // renderer.
+    if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this) {
+        RenderFullScreen* fullscreenRenderer = new (document()->renderArena()) RenderFullScreen(document());
+        fullscreenRenderer->setStyle(RenderFullScreen::createFullScreenStyle());
+        parentRenderer->addChild(fullscreenRenderer, 0);
+        parentRenderer = fullscreenRenderer;
+        nextRenderer = 0;
+        document()->setFullScreenRenderer(fullscreenRenderer);
+    }
+#endif
+    
     if (parentRenderer && parentRenderer->canHaveChildren() && parent->childShouldCreateRenderer(this)) {
         RefPtr<RenderStyle> style = styleForRenderer();
         if (rendererIsNeeded(style.get())) {
@@ -1366,7 +1384,7 @@ void Node::createRendererIfNeeded()
                 else {
                     setRenderer(r);
                     renderer()->setAnimatableStyle(style.release());
-                    parentRenderer->addChild(renderer(), nextRenderer());
+                    parentRenderer->addChild(renderer(), nextRenderer);
                 }
             }
         }
index 5442e93..3a63a33 100644 (file)
@@ -2270,13 +2270,6 @@ void HTMLMediaElement::mediaVolumeDidChange()
     updateVolume();
 }
 
-IntRect HTMLMediaElement::screenRect()
-{
-    if (!renderer())
-        return IntRect();
-    return renderer()->view()->frameView()->contentsToScreen(renderer()->absoluteBoundingBoxRect());
-}
-    
 void HTMLMediaElement::defaultEventHandler(Event* event)
 {
 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
index edaf76c..bdc3447 100644 (file)
@@ -140,8 +140,6 @@ public:
     void beginScrubbing();
     void endScrubbing();
 
-    IntRect screenRect();
-
     bool canPlay() const;
 
     float percentLoaded() const;
index 3eb48a0..cbbaa87 100644 (file)
@@ -262,6 +262,7 @@ namespace WebCore {
         virtual bool supportsFullScreenForElement(const Element*) { return false; }
         virtual void enterFullScreenForElement(Element*) { }
         virtual void exitFullScreenForElement(Element*) { }
+        virtual void fullScreenRendererChanged(RenderBox*) { }
 #endif
         
 #if ENABLE(TILED_BACKING_STORE)
index 426ebb3..3958192 100644 (file)
@@ -49,6 +49,7 @@
 #include "InspectorInstrumentation.h"
 #include "OverflowEvent.h"
 #include "RenderEmbeddedObject.h"
+#include "RenderFullScreen.h"
 #include "RenderLayer.h"
 #include "RenderPart.h"
 #include "RenderScrollbar.h"
@@ -528,6 +529,12 @@ void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, Scrollbar
     }    
 }
 
+#if ENABLE(FULLSCREEN_API)
+static bool isDocumentRunningFullScreenAnimation(Document* document)
+{
+    return document->webkitIsFullScreen() && document->fullScreenRenderer() && document->fullScreenRenderer()->isAnimating();
+}
+#endif
     
 #if USE(ACCELERATED_COMPOSITING)
 void FrameView::updateCompositingLayers()
@@ -539,6 +546,12 @@ void FrameView::updateCompositingLayers()
     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
     view->compositor()->cacheAcceleratedCompositingFlags();
     view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
+    
+#if ENABLE(FULLSCREEN_API)
+    Document* document = m_frame->document();
+    if (isDocumentRunningFullScreenAnimation(document))
+        view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange, document->fullScreenRenderer()->layer());
+#endif
 }
 
 void FrameView::setNeedsOneShotDrawingSynchronization()
@@ -616,7 +629,7 @@ bool FrameView::isEnclosedInCompositingLayer() const
 #endif
     return false;
 }
-
+    
 bool FrameView::syncCompositingStateRecursive()
 {
 #if USE(ACCELERATED_COMPOSITING)
@@ -632,6 +645,18 @@ bool FrameView::syncCompositingStateRecursive()
     
     if (GraphicsLayer* rootLayer = contentRenderer->compositor()->rootPlatformLayer())
         rootLayer->syncCompositingState();
+    
+#if ENABLE(FULLSCREEN_API)
+    // The fullScreenRenderer's graphicsLayer  has been re-parented, and the above recursive syncCompositingState
+    // call will not cause the subtree under it to repaint.  Explicitly call the syncCompositingState on 
+    // the fullScreenRenderer's graphicsLayer here:
+    Document* document = m_frame->document();
+    if (isDocumentRunningFullScreenAnimation(document)) {
+        RenderLayerBacking* backing = document->fullScreenRenderer()->layer()->backing();
+        if (GraphicsLayer* fullScreenLayer = backing->graphicsLayer())
+            fullScreenLayer->syncCompositingState();
+    }
+#endif    
 
     bool allSubframesSynced = true;
     const HashSet<RefPtr<Widget> >* viewChildren = children();
@@ -2132,6 +2157,16 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
     if (!p->paintingDisabled()) {
         if (GraphicsLayer* rootLayer = contentRenderer->compositor()->rootPlatformLayer())
             rootLayer->syncCompositingState();
+#if ENABLE(FULLSCREEN_API)
+        // The fullScreenRenderer's graphicsLayer  has been re-parented, and the above recursive syncCompositingState
+        // call will not cause the subtree under it to repaint.  Explicitly call the syncCompositingState on 
+        // the fullScreenRenderer's graphicsLayer here:
+        if (isDocumentRunningFullScreenAnimation(document)) {
+            RenderLayerBacking* backing = document->fullScreenRenderer()->layer()->backing();
+            if (GraphicsLayer* fullScreenLayer = backing->graphicsLayer())
+                fullScreenLayer->syncCompositingState();
+        }
+#endif
     }
 #endif
 
index 8dfdc81..e5e5ae5 100644 (file)
@@ -811,7 +811,7 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
         // video implementation without requiring them to implement their own full 
         // screen behavior.
         if (document()->settings() && document()->settings()->fullScreenEnabled()) {
-            if (document()->webkitFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement())
+            if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement())
                 document()->webkitCancelFullScreen();
             else
                 mediaElement()->webkitRequestFullScreen(0);
diff --git a/WebCore/rendering/RenderFullScreen.cpp b/WebCore/rendering/RenderFullScreen.cpp
new file mode 100644 (file)
index 0000000..f1c9efa
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FULLSCREEN_API)
+
+#include "RenderFullScreen.h"
+
+#include "RenderLayer.h"
+
+using namespace WebCore;
+
+void RenderFullScreen::setAnimating(bool animating)
+{
+    m_isAnimating = animating;
+    if (layer())
+        layer()->contentChanged(RenderLayer::FullScreenChanged);
+}
+
+PassRefPtr<RenderStyle> RenderFullScreen::createFullScreenStyle()
+{
+    RefPtr<RenderStyle> fullscreenStyle = RenderStyle::createDefaultStyle();
+
+    // Create a stacking context:
+    fullscreenStyle->setZIndex(0);
+
+    fullscreenStyle->setFontDescription(FontDescription());
+    fullscreenStyle->font().update(0);
+
+    fullscreenStyle->setDisplay(BOX);
+    fullscreenStyle->setBoxPack(BCENTER);
+    fullscreenStyle->setBoxAlign(BCENTER);
+    fullscreenStyle->setBoxOrient(HORIZONTAL);
+    
+    fullscreenStyle->setPosition(FixedPosition);
+    fullscreenStyle->setWidth(Length(100.0, Percent));
+    fullscreenStyle->setHeight(Length(100.0, Percent));
+    fullscreenStyle->setLeft(Length(0, Fixed));
+    fullscreenStyle->setTop(Length(0, Fixed));
+    
+    fullscreenStyle->setBackgroundColor(Color::black);
+    
+    return fullscreenStyle;
+}
+
+#endif
diff --git a/WebCore/rendering/RenderFullScreen.h b/WebCore/rendering/RenderFullScreen.h
new file mode 100644 (file)
index 0000000..52d4ee2
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderFullScreen_h
+#define RenderFullScreen_h
+
+#if ENABLE(FULLSCREEN_API)
+
+#include "RenderFlexibleBox.h"
+
+namespace WebCore {
+
+class RenderFullScreen : public RenderFlexibleBox {
+public:
+    RenderFullScreen(Node* node) : RenderFlexibleBox(node) { setReplaced(false); setIsAnonymous(false); }
+    virtual bool isRenderFullScreen() const { return true; }
+    virtual const char* renderName() const { return "RenderFullScreen"; }
+    
+    bool isAnimating() const { return m_isAnimating; }
+    void setAnimating(bool);
+    
+    static PassRefPtr<RenderStyle> createFullScreenStyle();
+    
+protected:
+    bool m_isAnimating;
+};
+    
+inline RenderFullScreen* toRenderFullScreen(RenderObject* object)
+{
+    ASSERT(object->isRenderFullScreen());
+    return static_cast<RenderFullScreen*>(object);
+}
+    
+// This will catch anyone doing an unnecessary cast:
+void toRenderFullScreen(RenderFullScreen*);
+}
+
+#endif
+
+#endif
index 88533c4..bd954ed 100644 (file)
@@ -232,7 +232,7 @@ RenderLayerCompositor* RenderLayer::compositor() const
 void RenderLayer::contentChanged(ContentChangeType changeType)
 {
     // This can get called when video becomes accelerated, so the layers may change.
-    if ((changeType == CanvasChanged || changeType == VideoChanged) && compositor()->updateLayerCompositingState(this))
+    if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor()->updateLayerCompositingState(this))
         compositor()->setCompositingLayersNeedRebuild();
 
     if (m_backing)
index e0c6047..e4be767 100644 (file)
@@ -283,7 +283,7 @@ public:
     
     // Notification from the renderer that its content changed (e.g. current frame of image changed).
     // Allows updates of layer content without repainting.
-    enum ContentChangeType { ImageChanged, MaskImageChanged, CanvasChanged, VideoChanged };
+    enum ContentChangeType { ImageChanged, MaskImageChanged, CanvasChanged, VideoChanged, FullScreenChanged };
     void contentChanged(ContentChangeType);
 #endif
 
index 1649372..112f348 100644 (file)
@@ -154,6 +154,22 @@ static bool layerOrAncestorIsTransformed(RenderLayer* layer)
     
     return false;
 }
+    
+#if ENABLE(FULLSCREEN_API)
+static bool layerOrAncestorIsFullScreen(RenderLayer* layer)
+{
+    // Don't traverse through the render layer tree if we do not yet have a full screen renderer.        
+    if (!layer->renderer()->document()->fullScreenRenderer())
+        return false;
+
+    for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
+        if (curr->renderer()->isRenderFullScreen())
+            return true;
+    }
+    
+    return false;
+}
+#endif
 
 void RenderLayerBacking::updateCompositedBounds()
 {
@@ -161,8 +177,14 @@ void RenderLayerBacking::updateCompositedBounds()
 
     // Clip to the size of the document or enclosing overflow-scroll layer.
     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
-    // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
-    if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer)) {
+    // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.  If this
+    // is a fullscreen renderer, don't clip to the viewport, as the renderer will be asked to
+    // display outside of the viewport bounds.
+    if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer) 
+#if ENABLE(FULLSCREEN_API)
+        && !layerOrAncestorIsFullScreen(m_owningLayer)
+#endif
+        ) {
         RenderView* view = m_owningLayer->renderer()->view();
         RenderLayer* rootLayer = view->layer();
 
index ce2224f..343eb89 100644 (file)
@@ -44,6 +44,7 @@
 #include "Page.h"
 #include "RenderApplet.h"
 #include "RenderEmbeddedObject.h"
+#include "RenderFullScreen.h"
 #include "RenderIFrame.h"
 #include "RenderLayerBacking.h"
 #include "RenderReplica.h"
@@ -817,6 +818,13 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons
         if (!parented)
             layerBacking->parentForSublayers()->setChildren(layerChildren);
 
+#if ENABLE(FULLSCREEN_API)
+        // For the sake of clients of the full screen renderer, don't reparent
+        // the full screen layer out from under them if they're in the middle of
+        // animating.
+        if (layer->renderer()->isRenderFullScreen() && toRenderFullScreen(layer->renderer())->isAnimating())
+            return;
+#endif
         childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
     }
 }
@@ -1147,7 +1155,8 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c
              || requiresCompositingForIFrame(renderer)
              || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden)
              || clipsCompositingDescendants(layer)
-             || requiresCompositingForAnimation(renderer);
+             || requiresCompositingForAnimation(renderer)
+             || requiresCompositingForFullScreen(renderer);
 }
 
 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
@@ -1313,6 +1322,11 @@ bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(Ren
 {
     return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection();
 }
+    
+bool RenderLayerCompositor::requiresCompositingForFullScreen(RenderObject* renderer) const
+{
+    return renderer->isRenderFullScreen() && toRenderFullScreen(renderer)->isAnimating();
+}
 
 // If an element has negative z-index children, those children render in front of the 
 // layer background, so we need an extra 'contents' layer for the foreground of the layer
index 1409c06..6218c04 100644 (file)
@@ -238,6 +238,7 @@ private:
     bool requiresCompositingForPlugin(RenderObject*) const;
     bool requiresCompositingForIFrame(RenderObject*) const;
     bool requiresCompositingWhenDescendantsAreCompositing(RenderObject*) const;
+    bool requiresCompositingForFullScreen(RenderObject*) const;
 
     bool requiresScrollLayer(RootLayerAttachment) const;
     
index 9cb4e36..2f443ef 100644 (file)
@@ -286,6 +286,9 @@ public:
     virtual bool isVideo() const { return false; }
     virtual bool isWidget() const { return false; }
     virtual bool isCanvas() const { return false; }
+#if ENABLE(FULLSCREEN_API)
+    virtual bool isRenderFullScreen() const { return false; }
+#endif
 
     bool isRoot() const { return document()->documentElement() == m_node; }
     bool isBody() const;
index 75254f2..5856175 100644 (file)
                C0C5B3EE1177A4A0002B0AEF /* WebUserContentURLPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = C0C5B3EC1177A4A0002B0AEF /* WebUserContentURLPattern.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C0C5B3EF1177A4A0002B0AEF /* WebUserContentURLPattern.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0C5B3ED1177A4A0002B0AEF /* WebUserContentURLPattern.mm */; };
                CD8EAC7311CAC9A300774075 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD8EAC7211CAC9A300774075 /* IOKit.framework */; };
+               CDA62AE2125F87C2007FD118 /* WebFullScreenController.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA62AE0125F87C2007FD118 /* WebFullScreenController.h */; };
+               CDA62AE3125F87C2007FD118 /* WebFullScreenController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDA62AE1125F87C2007FD118 /* WebFullScreenController.mm */; };
                DD7CDEE70A23BA9E00069928 /* WebTypesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DD7CDEE60A23BA9E00069928 /* WebTypesInternal.h */; };
                DD89682009AA87240097E7F0 /* WebElementDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = DD89681E09AA87240097E7F0 /* WebElementDictionary.h */; };
                DD89682109AA87240097E7F0 /* WebElementDictionary.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD89681F09AA87240097E7F0 /* WebElementDictionary.mm */; };
                C0C5B3EC1177A4A0002B0AEF /* WebUserContentURLPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebUserContentURLPattern.h; sourceTree = "<group>"; };
                C0C5B3ED1177A4A0002B0AEF /* WebUserContentURLPattern.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebUserContentURLPattern.mm; sourceTree = "<group>"; };
                CD8EAC7211CAC9A300774075 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+               CDA62AE0125F87C2007FD118 /* WebFullScreenController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFullScreenController.h; sourceTree = "<group>"; };
+               CDA62AE1125F87C2007FD118 /* WebFullScreenController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebFullScreenController.mm; sourceTree = "<group>"; };
                DD7CDEE60A23BA9E00069928 /* WebTypesInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebTypesInternal.h; sourceTree = "<group>"; };
                DD89681E09AA87240097E7F0 /* WebElementDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebElementDictionary.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                DD89681F09AA87240097E7F0 /* WebElementDictionary.mm */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebElementDictionary.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                                51A8B52F04282B5900CA2D3A /* WebFrameView.mm */,
                                51A8B53204282BD200CA2D3A /* WebFrameViewInternal.h */,
                                93C6F14507920B93002449CD /* WebFrameViewPrivate.h */,
+                               CDA62AE0125F87C2007FD118 /* WebFullScreenController.h */,
+                               CDA62AE1125F87C2007FD118 /* WebFullScreenController.mm */,
                                BC7F889C10C9D30C00D6133D /* WebGeolocationPosition.h */,
                                BC7F889D10C9D30C00D6133D /* WebGeolocationPosition.mm */,
                                BC7F88A410C9D88B00D6133D /* WebGeolocationPositionInternal.h */,
                                598AD92A1201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h in Headers */,
                                598ADA461202275000ABAE4E /* WebDeviceOrientationProvider.h in Headers */,
                                93E2A1A4123B0B3C009FE12A /* WebDashboardRegion.h in Headers */,
+                               CDA62AE2125F87C2007FD118 /* WebFullScreenController.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                598AD9221201CF1000ABAE4E /* WebDeviceOrientation.mm in Sources */,
                                598AD9281201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm in Sources */,
                                93E2A1A5123B0B3C009FE12A /* WebDashboardRegion.mm in Sources */,
+                               CDA62AE3125F87C2007FD118 /* WebFullScreenController.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 9bc2994..9a48549 100644 (file)
@@ -1,3 +1,67 @@
+2010-12-21  Jer Noble  <jer.noble@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+
+        Support the new fullscreen Chrome client requests.  WebView will pass
+        through these requests to a WebFullscreenController.
+
+        * WebCoreSupport/WebChromeClient.h: Add fullScreenRendererChanged().
+        * WebView/WebView.mm:
+        (-[WebView _supportsFullScreenForElement:WebCore::]): Check to see if the fullscreen pref has been enabled.
+        (-[WebView _enterFullScreenForElement:WebCore::]): Create a WebFullScreenController.
+        (-[WebView _exitFullScreenForElement:WebCore::]): Request that the WebFullScreenController exit fullscreen.
+        (-[WebView _fullScreenRendererChanged:WebCore::]): Notify the WebFullScreenController that its renderer has changed.
+        * WebView/WebViewData.h: Add ivar newFullscreenController.
+
+2010-12-17  Jer Noble  <jer@kokode.apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Implement WebKit Full Screen support.
+        https://bugs.webkit.org/show_bug.cgi?id=49481
+        rdar://problem/8247444
+        
+        This patch implements the FullScreen APIs using the new RenderFullScreen renderer and the new
+        Document client APIs. The RenderFullScreen renderer's CALayer is hosted in a new, fullscreen
+        window, and a custom CAAnimation animates that layer between the initial screen rect of the
+        full screen element, to its final value. WebFullscreenController will swap the WebView out of
+        its original window, and into the fullscreen window. The controller will replace the WebView
+        with a placeholder view, so that if the placeholder moves or resized while the WebView is
+        absent, the WebView will move back to the correct location when exiting fullscreen.
+
+        * WebView/WebFullscreenController.h: Added.
+        * WebView/WebFullscreenController.mm: Added.
+        (-[WebFullscreenController windowDidExitFullscreen:]):  Close the fullscreen window.
+        (-[WebFullscreenController windowDidEnterFullscreen:]): Swap the webView back into the fullscreen window. 
+        (-[WebFullscreenController animationDidStop:finished:]): Call windowDid{Exit|Enter}FullScreen as appropriate.
+        (-[WebFullscreenController applicationDidResignActive:]):
+        (-[WebFullscreenController applicationDidChangeScreenParameters:]): Resize the fullscreen window to match
+            the new screen parameters.
+        (-[WebFullscreenController enterFullscreen:]):  Set up the animation that will take the fullscreen element
+            from its original screen rect into fullscreen.
+        (-[WebFullscreenController exitFullscreen]): Swap the webView back into its original window.
+            Set up the animation that will take the fullscreen element back into its original screen
+            rect.
+        (-[WebFullscreenController _updatePowerAssertions]): Now checks _isAnyMoviePlaying to determine 
+            whether to disable screensaver and sleep.
+        (-[WebFullscreenController _isAnyMoviePlaying]): Walks through the sub-tree starting at the fullscreen element
+            looking for HTMLVideoElements; returns whether any are found to be playing.
+        (-[WebFullscreenController _animationDuration]): Returns the current animation duration, affected by control
+            and shift keys.
+        (-[WebFullscreenWindow canBecomeKeyWindow]): Allow the window to become key.
+        (-[WebFullscreenWindow keyDown:]): Handle the 'Esc' key.
+        (-[WebFullscreenWindow cancelOperation:]): Request to exit fullscreen.
+        (-[WebFullscreenWindow rendererLayer]): Convenience accessor.
+        (-[WebFullscreenWindow setRendererLayer:]): Ditto.
+        (-[WebFullscreenWindow backgroundLayer]): Ditto.
+        (-[WebFullscreenWindow animationView]): Ditto.
+        (MediaEventListener::MediaEventListener): Implements the EventListener protocol.
+        (MediaEventListener::handleEvent): Tells its delegate to _updatePowerAssertions.
+        
 2011-01-07  James Robinson  <jamesr@chromium.org>
 
         Revert "Implement mozilla's animationTime property"
index 8649662..05db524 100644 (file)
@@ -164,6 +164,7 @@ public:
     virtual bool supportsFullscreenForNode(const WebCore::Node*);
     virtual void enterFullscreenForNode(WebCore::Node*);
     virtual void exitFullscreenForNode(WebCore::Node*);
+    virtual void fullScreenRendererChanged(WebCore::RenderBox*);
 #endif
     
 #if ENABLE(FULLSCREEN_API)
index 965e607..a2c4ee5 100644 (file)
@@ -29,6 +29,7 @@
 
 #import "WebChromeClient.h"
 
+#import "DOMElementInternal.h"
 #import "DOMNodeInternal.h"
 #import "WebDefaultUIDelegate.h"
 #import "WebDelegateImplementationCaching.h"
@@ -822,21 +823,41 @@ void WebChromeClient::exitFullscreenForNode(Node*)
 
 bool WebChromeClient::supportsFullScreenForElement(const Element* element)
 {
-    return CallUIDelegateReturningBoolean(false, m_webView, @selector(webView:supportsFullScreenForElement:), kit(const_cast<WebCore::Element*>(element)));
+    SEL selector = @selector(webView:supportsFullScreenForElement:);
+    if ([[m_webView UIDelegate] respondsToSelector:selector])
+        return CallUIDelegateReturningBoolean(false, m_webView, selector, kit(const_cast<WebCore::Element*>(element)));
+    return [m_webView _supportsFullScreenForElement:const_cast<WebCore::Element*>(element)];
 }
 
 void WebChromeClient::enterFullScreenForElement(Element* element)
 {
-    WebKitFullScreenListener* listener = [[WebKitFullScreenListener alloc] initWithElement:element];
-    CallUIDelegate(m_webView, @selector(webView:enterFullScreenForElement:listener:), kit(element), listener);
-    [listener release];
+    SEL selector = @selector(webView:enterFullScreenForElement:listener:);
+    if ([[m_webView UIDelegate] respondsToSelector:selector]) {
+        WebKitFullScreenListener* listener = [[WebKitFullScreenListener alloc] initWithElement:element];
+        CallUIDelegate(m_webView, selector, kit(element), listener);
+        [listener release];
+    } else
+        [m_webView _enterFullScreenForElement:element];
 }
 
 void WebChromeClient::exitFullScreenForElement(Element* element)
 {
-    WebKitFullScreenListener* listener = [[WebKitFullScreenListener alloc] initWithElement:element];
-    CallUIDelegate(m_webView, @selector(webView:exitFullScreenForElement:listener:), kit(element), listener);
-    [listener release];
+    SEL selector = @selector(webView:exitFullScreenForElement:listener:);
+    if ([[m_webView UIDelegate] respondsToSelector:selector]) {
+        WebKitFullScreenListener* listener = [[WebKitFullScreenListener alloc] initWithElement:element];
+        CallUIDelegate(m_webView, selector, kit(element), listener);
+        [listener release];
+    } else
+        [m_webView _exitFullScreenForElement:element];
+}
+
+void WebChromeClient::fullScreenRendererChanged(RenderBox* renderer)
+{
+    SEL selector = @selector(webView:fullScreenRendererChanged:);
+    if ([[m_webView UIDelegate] respondsToSelector:selector])
+        CallUIDelegate(m_webView, selector, (id)renderer);
+    else
+        [m_webView _fullScreenRendererChanged:renderer];
 }
 
 #endif
diff --git a/WebKit/mac/WebView/WebFullScreenController.h b/WebKit/mac/WebView/WebFullScreenController.h
new file mode 100644 (file)
index 0000000..f867dc2
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(FULLSCREEN_API)
+
+#import <wtf/RefPtr.h>
+
+@class WebWindowFadeAnimation;
+@class WebView;
+namespace WebCore {
+    class Element;
+    class RenderBox;
+    class EventListener;
+}
+
+@interface WebFullScreenController : NSWindowController {
+@private
+    RefPtr<WebCore::Element> _element;
+    WebCore::RenderBox* _renderer; // (set)
+    RefPtr<WebCore::Element> _replacementElement; 
+    NSWindow *_backgroundFullscreenWindow; // (retain)
+    WebWindowFadeAnimation *_fadeAnimation; // (retain)
+    WebView *_webView;
+    NSView* _placeholderView;
+    CALayer* _rendererLayer;
+    CALayer* _backgroundLayer;
+    RefPtr<WebCore::EventListener> _mediaEventListener; 
+
+    BOOL _isAnimating;
+    BOOL _isFullscreen;
+    BOOL _isWindowLoaded;
+    BOOL _forceDisableAnimation;
+    BOOL _isPlaying;
+    uint32_t _idleDisplaySleepAssertion;
+    uint32_t _idleSystemSleepAssertion;
+    NSTimer *_tickleTimer;
+    SystemUIMode _savedUIMode;
+    SystemUIOptions _savedUIOptions;
+    CGRect _initialFrame;
+}
+
+- (WebView*)webView;
+- (void)setWebView:(WebView*)webView;
+
+- (void)setElement:(PassRefPtr<WebCore::Element>)element;
+- (WebCore::Element*)element;
+
+- (void)setRenderer:(WebCore::RenderBox*)renderer;
+- (WebCore::RenderBox*)renderer;
+
+- (void)enterFullscreen:(NSScreen *)screen;
+- (void)exitFullscreen;
+
+@end
+
+#endif // ENABLE(FULLSCREEN_API)
diff --git a/WebKit/mac/WebView/WebFullScreenController.mm b/WebKit/mac/WebView/WebFullScreenController.mm
new file mode 100644 (file)
index 0000000..800a650
--- /dev/null
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(FULLSCREEN_API)
+
+#import "WebFullScreenController.h"
+
+#import "WebPreferencesPrivate.h"
+#import "WebWindowAnimation.h"
+#import "WebViewInternal.h"
+#import <IOKit/pwr_mgt/IOPMLib.h>
+#import <WebCore/AnimationList.h>
+#import <WebCore/CSSPropertyNames.h>
+#import <WebCore/Color.h>
+#import <WebCore/Document.h>
+#import <WebCore/DOMDocument.h>
+#import <WebCore/DOMDocumentInternal.h>
+#import <WebCore/DOMHTMLElement.h>
+#import <WebCore/DOMWindow.h>
+#import <WebCore/EventListener.h>
+#import <WebCore/EventNames.h>
+#import <WebCore/HTMLElement.h>
+#import <WebCore/HTMLNames.h>
+#import <WebCore/HTMLMediaElement.h>
+#import <WebCore/IntRect.h>
+#import <WebCore/NodeList.h>
+#import <WebCore/SoftLinking.h>
+#import <WebCore/RenderBlock.h>
+#import <WebCore/RenderLayer.h>
+#import <WebCore/RenderLayerBacking.h>
+#import <objc/objc-runtime.h>
+#import <wtf/UnusedParam.h>
+
+static const NSTimeInterval tickleTimerInterval = 1.0;
+static NSString* const isEnteringFullscreenKey = @"isEnteringFullscreen";
+
+using namespace WebCore;
+
+@interface WebFullscreenWindow : NSWindow
+#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER)
+<NSAnimationDelegate>
+#endif
+{
+    NSView* _animationView;
+    
+    CALayer* _rendererLayer;
+    CALayer* _backgroundLayer;
+}
+- (CALayer*)rendererLayer;
+- (void)setRendererLayer:(CALayer*)rendererLayer;
+- (CALayer*)backgroundLayer;
+- (NSView*)animationView;
+@end
+
+class MediaEventListener : public EventListener {
+public:
+    static PassRefPtr<MediaEventListener> create(WebFullScreenController* delegate);
+    virtual bool operator==(const EventListener&);
+    virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+private:
+    MediaEventListener(WebFullScreenController* delegate); 
+    WebFullScreenController* delegate;
+};
+
+@interface WebFullScreenController(Private)
+- (void)_requestExitFullscreenWithAnimation:(BOOL)animation;
+- (void)_updateMenuAndDockForFullscreen;
+- (void)_updatePowerAssertions;
+- (WebFullscreenWindow *)_fullscreenWindow;
+- (Document*)_document;
+- (CFTimeInterval)_animationDuration;
+- (BOOL)_isAnyMoviePlaying;
+@end
+
+@interface NSWindow(IsOnActiveSpaceAdditionForTigerAndLeopard)
+- (BOOL)isOnActiveSpace;
+@end
+
+@implementation WebFullScreenController
+
+#pragma mark -
+#pragma mark Initialization
+- (id)init
+{
+    // Do not defer window creation, to make sure -windowNumber is created (needed by WebWindowScaleAnimation).
+    NSWindow *window = [[WebFullscreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+    self = [super initWithWindow:window];
+    [window release];
+    if (!self)
+        return nil;
+    [self windowDidLoad];
+    _mediaEventListener = MediaEventListener::create(self);
+    return self;
+    
+}
+
+- (void)dealloc
+{
+    ASSERT(!_tickleTimer);
+    
+    [self setWebView:nil];
+    [_placeholderView release];
+    
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    [super dealloc];
+}
+
+- (void)windowDidLoad
+{
+#ifdef BUILDING_ON_TIGER
+    // WebFullScreenController is not supported on Tiger:
+    ASSERT_NOT_REACHED();
+#else
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:NSApp];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeScreenParameters:) name:NSApplicationDidChangeScreenParametersNotification object:NSApp];
+#endif
+}
+
+#pragma mark -
+#pragma mark Accessors
+
+- (WebView*)webView
+{
+    return _webView;
+}
+
+- (void)setWebView:(WebView *)webView
+{
+    [webView retain];
+    [_webView release];
+    _webView = webView;
+}
+
+- (Element*)element
+{
+    return _element.get();
+}
+
+- (void)setElement:(PassRefPtr<Element>)element
+{
+#ifdef BUILDING_ON_TIGER
+    // WebFullScreenController is not supported on Tiger:
+    ASSERT_NOT_REACHED();
+#else
+    // When a new Element is set as the current full screen element, register event
+    // listeners on that Element's window, listening for changes in media play states.
+    // We will use these events to determine whether to disable the screensaver and 
+    // display sleep timers when playing video in full screen. Make sure to unregister
+    // the events on the old element's window, if necessary, as well.
+    
+    EventNames& eventNames = WebCore::eventNames();
+    
+    if (_element) {
+        DOMWindow* window = _element->document()->domWindow();
+        if (window) {
+            window->removeEventListener(eventNames.playEvent,  _mediaEventListener.get(), true);
+            window->removeEventListener(eventNames.pauseEvent, _mediaEventListener.get(), true);
+            window->removeEventListener(eventNames.endedEvent, _mediaEventListener.get(), true);
+        }
+    }
+        
+    _element = element;
+    
+    if (_element) {
+        DOMWindow* window = _element->document()->domWindow();
+        if (window) {
+            window->addEventListener(eventNames.playEvent,  _mediaEventListener, true);
+            window->addEventListener(eventNames.pauseEvent, _mediaEventListener, true);
+            window->addEventListener(eventNames.endedEvent, _mediaEventListener, true);
+        }
+    }
+#endif
+}
+
+- (RenderBox*)renderer 
+{
+    return _renderer;
+}
+
+- (void)setRenderer:(RenderBox*)renderer
+{
+#ifdef BUILDING_ON_TIGER
+    // WebFullScreenController is not supported on Tiger:
+    ASSERT_NOT_REACHED();
+#else
+    _renderer = renderer;
+#endif
+}
+
+#pragma mark -
+#pragma mark Notifications
+
+- (void)windowDidExitFullscreen:(BOOL)finished
+{
+    if (!_isAnimating)
+        return;
+    
+    if (_isFullscreen)
+        return;
+    
+    NSDisableScreenUpdates();
+    ASSERT(_element);
+    [self _document]->setFullScreenRendererBackgroundColor(Color::black);
+    [self _document]->webkitDidExitFullScreenForElement(_element.get());
+    [self setElement:nil];
+
+    if (finished) {
+        [self _updateMenuAndDockForFullscreen];   
+        [self _updatePowerAssertions];
+        
+        [[_webView window] display];
+        [[self _fullscreenWindow] setRendererLayer:nil];
+        [[self window] close];
+    }
+
+    NSEnableScreenUpdates();
+
+    _isAnimating = NO;
+    [self autorelease]; // Associated -retain is in -exitFullscreen.
+}
+
+- (void)windowDidEnterFullscreen:(BOOL)finished
+{
+    if (!_isAnimating)
+        return;
+    
+    if (!_isFullscreen)
+        return;
+    
+    NSDisableScreenUpdates();
+    [self _document]->webkitDidEnterFullScreenForElement(_element.get());
+    [self _document]->setFullScreenRendererBackgroundColor(Color::black);
+    
+    if (finished) {
+        [self _updateMenuAndDockForFullscreen];
+        [self _updatePowerAssertions];
+        [NSCursor setHiddenUntilMouseMoves:YES];
+    
+        // Move the webView into our fullscreen Window
+        if (!_placeholderView)
+            _placeholderView = [[NSView alloc] init];
+
+        // Do not swap the placeholder into place if already is in a window,
+        // assuming the placeholder's window will always be the webView's 
+        // original window.
+        if (![_placeholderView window]) {
+            WebView* webView = [self webView];
+            [_placeholderView setFrame:[webView frame]];        
+            [_placeholderView setAutoresizingMask:[webView autoresizingMask]];
+            [_placeholderView removeFromSuperview];
+            [[webView superview] replaceSubview:webView with:_placeholderView];
+            
+            [[[self window] contentView] addSubview:webView];
+            [webView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
+            [webView setFrame:[[[self window] contentView] bounds]];
+        }
+        
+        WebFullscreenWindow* window = [self _fullscreenWindow];
+        [window setBackgroundColor:[NSColor blackColor]];
+        [window setOpaque:YES];
+
+        [CATransaction begin];
+        [CATransaction setDisableActions:YES];
+        [[[window animationView] layer] setOpacity:0];
+        [CATransaction commit];
+    }
+    NSEnableScreenUpdates();
+
+    _isAnimating = NO;
+}
+
+- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)finished
+{
+    BOOL isEnteringFullscreenAnimation = [[anim valueForKey:isEnteringFullscreenKey] boolValue];
+    
+    if (!isEnteringFullscreenAnimation)
+        [self windowDidExitFullscreen:finished];
+    else
+        [self windowDidEnterFullscreen:finished];
+}
+
+- (void)applicationDidResignActive:(NSNotification*)notification
+{   
+    // Check to see if the fullscreenWindow is on the active space; this function is available
+    // on 10.6 and later, so default to YES if the function is not available:
+    NSWindow* fullscreenWindow = [self _fullscreenWindow];
+    BOOL isOnActiveSpace = ([fullscreenWindow respondsToSelector:@selector(isOnActiveSpace)] ? [fullscreenWindow isOnActiveSpace] : YES);
+
+    // Replicate the QuickTime Player (X) behavior when losing active application status:
+    // Is the fullscreen screen the main screen? (Note: this covers the case where only a 
+    // single screen is available.)  Is the fullscreen screen on the current space? IFF so, 
+    // then exit fullscreen mode. 
+    if ([fullscreenWindow screen] == [[NSScreen screens] objectAtIndex:0] && isOnActiveSpace)
+         [self _requestExitFullscreenWithAnimation:NO];
+}
+
+- (void)applicationDidChangeScreenParameters:(NSNotification*)notification
+{
+    // The user may have changed the main screen by moving the menu bar, or they may have changed
+    // the Dock's size or location, or they may have changed the fullscreen screen's dimensions. 
+    // Update our presentation parameters, and ensure that the full screen window occupies the 
+    // entire screen:
+    [self _updateMenuAndDockForFullscreen];
+    NSWindow* window = [self window];
+    [window setFrame:[[window screen] frame] display:YES];
+}
+
+#pragma mark -
+#pragma mark Exposed Interface
+
+- (void)enterFullscreen:(NSScreen *)screen
+{
+    // Disable animation if we are already in full-screen mode.
+    BOOL shouldAnimate = !_isFullscreen;
+    
+    if (_isAnimating) {
+        // The CAAnimation delegate functions will only be called the
+        // next trip through the run-loop, so manually call the delegate
+        // function here, letting it know the animation did not complete:
+        [self windowDidExitFullscreen:NO];
+        ASSERT(!_isAnimating);
+    }
+    _isFullscreen = YES;
+    _isAnimating = YES;
+    
+    // setElement: must be called with a non-nil value before calling enterFullscreen:.
+    ASSERT(_element);
+    
+    NSDisableScreenUpdates();
+    
+    if (!screen)
+        screen = [NSScreen mainScreen];
+    NSRect screenFrame = [screen frame];
+    
+    WebView* webView = [self webView];
+    NSRect webViewFrame = [webView convertRectToBase:[webView frame]];
+    webViewFrame.origin = [[webView window] convertBaseToScreen:webViewFrame.origin];
+    
+    NSRect elementFrame = _element->screenRect();
+    
+    // In the case of a multi-monitor setup where the webView straddles two
+    // monitors, we must create a window large enough to contain the destination
+    // frame and the initial frame.
+    NSRect windowFrame = NSUnionRect(screenFrame, elementFrame);
+    [[self window] setFrame:windowFrame display:YES];
+    
+    // In a previous incarnation, the NSWindow attached to this controller may have
+    // been on a different screen. Temporarily change the collectionBehavior of the window:
+    NSWindowCollectionBehavior behavior = [[self window] collectionBehavior];
+    [[self window] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
+    [[self window] makeKeyAndOrderFront:self];
+    [[self window] setCollectionBehavior:behavior];
+    
+    NSView* animationView = [[self _fullscreenWindow] animationView];
+    NSRect viewBounds = [animationView bounds];
+    
+    NSRect backgroundBounds = {[[self window] convertScreenToBase:screenFrame.origin], screenFrame.size};
+    backgroundBounds = [animationView convertRectFromBase:backgroundBounds];
+    // Flip the background layer's coordinate system.
+    backgroundBounds.origin.y = windowFrame.size.height - NSMaxY(backgroundBounds);
+    
+    // Set our fullscreen element's initial frame, and flip the coordinate systems from
+    // screen coordinates (bottom/left) to layer coordinates (top/left):
+    _initialFrame = NSRectToCGRect(NSIntersectionRect(elementFrame, webViewFrame));
+    _initialFrame.origin.y = screenFrame.size.height - CGRectGetMaxY(_initialFrame);
+    
+    // Inform the document that we will begin entering full screen. This will change
+    // pseudo-classes on the fullscreen element and the document element.
+    Document* document = [self _document];
+    document->webkitWillEnterFullScreenForElement(_element.get());
+    
+    // Check to see if the fullscreen renderer is composited. If not, accelerated graphics 
+    // may be disabled. In this case, do not attempt to animate the contents into place; 
+    // merely snap to the final position:
+    if (!shouldAnimate || !_renderer || !_renderer->layer()->isComposited()) {
+        [self windowDidEnterFullscreen:YES];
+        NSEnableScreenUpdates();
+        return;
+    }    
+    
+    // Set up the final style of the FullScreen render block. Set an absolute
+    // width and height equal to the size of the screen, and anchor the layer
+    // at the top, left at (0,0). The RenderFullScreen style is already set 
+    // to position:fixed.
+    [self _document]->setFullScreenRendererSize(IntSize(screenFrame.size));
+    [self _document]->setFullScreenRendererBackgroundColor(Color::transparent);
+    
+    // Cause the document to layout, thus calculating a new fullscreen element size:
+    [self _document]->updateLayout();
+    
+    // FIXME: try to use the fullscreen element's calculated x, y, width, and height instead of the
+    // renderBox functions:
+    RenderBox* childRenderer = _renderer->firstChildBox();
+    CGRect destinationFrame = CGRectMake(childRenderer->x(), childRenderer->y(), childRenderer->width(), childRenderer->height());    
+    
+    // Some properties haven't propogated from the GraphicsLayer to the CALayer yet. So
+    // tell the renderer's layer to sync it's compositing state:
+    GraphicsLayer* rendererGraphics = _renderer->layer()->backing()->graphicsLayer();
+    rendererGraphics->syncCompositingState();    
+
+    CALayer* rendererLayer = rendererGraphics->platformLayer();
+    [[self _fullscreenWindow] setRendererLayer:rendererLayer];    
+    
+    CFTimeInterval duration = [self _animationDuration];
+
+    // Create a transformation matrix that will transform the renderer layer such that 
+    // the fullscreen element appears to move from its starting position and size to its
+    // final one. Perform the transformation in two steps, using the CALayer's matrix 
+    // math to calculate the effects of each step:
+    // 1. Apply a scale tranform to shrink the apparent size of the layer to the original
+    //    element screen size.
+    // 2. Apply a translation transform to move the shrunk layer into the same screen position
+    //    as the original element.
+    CATransform3D shrinkTransform = CATransform3DMakeScale(_initialFrame.size.width / destinationFrame.size.width, _initialFrame.size.height / destinationFrame.size.height, 1);
+    [rendererLayer setTransform:shrinkTransform];
+    CGRect shrunkDestinationFrame = [rendererLayer convertRect:destinationFrame toLayer:[animationView layer]];
+    CATransform3D moveTransform = CATransform3DMakeTranslation(_initialFrame.origin.x - shrunkDestinationFrame.origin.x, _initialFrame.origin.y - shrunkDestinationFrame.origin.y, 0);
+    CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, moveTransform);
+    [rendererLayer setTransform:finalTransform];
+    CGRect translatedDestinationFrame = [rendererLayer convertRect:destinationFrame toLayer:[animationView layer]];
+    
+    CALayer* backgroundLayer = [[self _fullscreenWindow] backgroundLayer];
+
+    // Start the opacity animation. We can use implicit animations here because we don't care when
+    // the animation finishes.
+    [CATransaction begin];
+    [CATransaction setAnimationDuration:duration];
+    [backgroundLayer setOpacity:1];
+    [CATransaction commit];
+    
+    // Use a CABasicAnimation here for the zoom effect. We want to be notified that the animation has 
+    // completed by way of the CAAnimation delegate.
+    CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
+    [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:finalTransform]];
+    [zoomAnimation setToValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]];
+    [zoomAnimation setDelegate:self];
+    [zoomAnimation setDuration:duration];
+    [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+    [zoomAnimation setFillMode:kCAFillModeForwards];
+    [zoomAnimation setValue:(id)kCFBooleanTrue forKey:isEnteringFullscreenKey];
+    
+    // Disable implicit animations and set the layer's transformation matrix to its final state.
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+    [rendererLayer setTransform:CATransform3DIdentity];
+    [rendererLayer addAnimation:zoomAnimation forKey:@"zoom"];
+    [backgroundLayer setFrame:NSRectToCGRect(backgroundBounds)];
+    [CATransaction commit];
+    
+    NSEnableScreenUpdates();
+}
+
+- (void)exitFullscreen
+{
+    if (!_isFullscreen)
+        return;    
+      
+    CATransform3D startTransform = CATransform3DIdentity;
+    if (_isAnimating) {
+        if (_renderer && _renderer->layer()->isComposited()) {
+            CALayer* rendererLayer = _renderer->layer()->backing()->graphicsLayer()->platformLayer();
+            startTransform = [[rendererLayer presentationLayer] transform];
+        }
+        
+        // The CAAnimation delegate functions will only be called the
+        // next trip through the run-loop, so manually call the delegate
+        // function here, letting it know the animation did not complete:
+        [self windowDidEnterFullscreen:NO];
+        ASSERT(!_isAnimating);
+    }
+    _isFullscreen = NO;
+    _isAnimating = YES;
+    
+    NSDisableScreenUpdates();
+    
+    // The user may have moved the fullscreen window in Spaces, so temporarily change 
+    // the collectionBehavior of the webView's window:
+    NSWindow* webWindow = [[self webView] window];
+    NSWindowCollectionBehavior behavior = [webWindow collectionBehavior];
+    [webWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
+    [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
+    [webWindow setCollectionBehavior:behavior];
+    
+    // The fullscreen animation may have been cancelled before the 
+    // webView was moved to the fullscreen window. Check to see
+    // if the _placeholderView exists and is in a window before
+    // attempting to swap the webView back to it's original tree:
+    if (_placeholderView && [_placeholderView window]) {
+        // Move the webView back to its own native window:
+        WebView* webView = [self webView];
+        [webView setFrame:[_placeholderView frame]];
+        [webView setAutoresizingMask:[_placeholderView autoresizingMask]];
+        [webView removeFromSuperview];
+        [[_placeholderView superview] replaceSubview:_placeholderView with:webView];
+        
+        // Because the animation view is layer-hosted, make sure to 
+        // disable animations when changing the layer's opacity. Other-
+        // wise, the content will appear to fade into view.
+        [CATransaction begin];
+        [CATransaction setDisableActions:YES];
+        WebFullscreenWindow* window = [self _fullscreenWindow];
+        [[[window animationView] layer] setOpacity:1];
+        [window setBackgroundColor:[NSColor clearColor]];
+        [window setOpaque:NO];
+        [CATransaction commit];
+    }
+
+    NSView* animationView = [[self _fullscreenWindow] animationView];
+    CGRect layerEndFrame = NSRectToCGRect([animationView convertRect:_initialFrame fromView:nil]);
+
+    // The _renderer might be NULL due to its ancestor being removed:
+    CGRect layerStartFrame = CGRectZero;
+    if (_renderer) {
+        RenderBox* childRenderer = _renderer->firstChildBox();
+        layerStartFrame = CGRectMake(childRenderer->x(), childRenderer->y(), childRenderer->width(), childRenderer->height());
+    }
+    
+    [self _document]->webkitWillExitFullScreenForElement(_element.get());
+    [self _document]->updateLayout();
+    
+    // We have to retain ourselves because we want to be alive for the end of the animation.
+    // If our owner releases us we could crash if this is not the case.
+    // Balanced in windowDidExitFullscreen
+    [self retain];
+    
+    // Check to see if the fullscreen renderer is composited. If not, accelerated graphics 
+    // may be disabled. In this case, do not attempt to animate the contents into place; 
+    // merely snap to the final position:
+    if (!_renderer || !_renderer->layer()->isComposited()) {
+        [self windowDidExitFullscreen:YES];
+        NSEnableScreenUpdates();
+        return;
+    }
+        
+    GraphicsLayer* rendererGraphics = _renderer->layer()->backing()->graphicsLayer();
+    
+    [self _document]->setFullScreenRendererBackgroundColor(Color::transparent);
+
+    rendererGraphics->syncCompositingState();    
+
+    CALayer* rendererLayer = rendererGraphics->platformLayer();
+    [[self _fullscreenWindow] setRendererLayer:rendererLayer];    
+    
+    // Create a transformation matrix that will transform the renderer layer such that 
+    // the fullscreen element appears to move from the full screen to its original position 
+    // and size. Perform the transformation in two steps, using the CALayer's matrix 
+    // math to calculate the effects of each step:
+    // 1. Apply a scale tranform to shrink the apparent size of the layer to the original
+    //    element screen size.
+    // 2. Apply a translation transform to move the shrunk layer into the same screen position
+    //    as the original element.
+    CATransform3D shrinkTransform = CATransform3DMakeScale(layerEndFrame.size.width / layerStartFrame.size.width, layerEndFrame.size.height / layerStartFrame.size.height, 1);
+    [rendererLayer setTransform:shrinkTransform];
+    CGRect shrunkDestinationFrame = [rendererLayer convertRect:layerStartFrame toLayer:[animationView layer]];
+    CATransform3D moveTransform = CATransform3DMakeTranslation(layerEndFrame.origin.x - shrunkDestinationFrame.origin.x, layerEndFrame.origin.y - shrunkDestinationFrame.origin.y, 0);
+    CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, moveTransform);
+    [rendererLayer setTransform:finalTransform];
+    CGRect translatedDestinationFrame = [rendererLayer convertRect:layerStartFrame toLayer:[animationView layer]];
+    
+    CFTimeInterval duration = [self _animationDuration];
+        
+    CALayer* backgroundLayer = [[self _fullscreenWindow] backgroundLayer];
+    [CATransaction begin];
+    [CATransaction setAnimationDuration:duration];
+    [backgroundLayer setOpacity:0];
+    [CATransaction commit];
+    
+    CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
+    [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:startTransform]];
+    [zoomAnimation setToValue:[NSValue valueWithCATransform3D:finalTransform]];
+    [zoomAnimation setDelegate:self];
+    [zoomAnimation setDuration:duration];
+    [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+    [zoomAnimation setFillMode:kCAFillModeBoth];
+    [zoomAnimation setRemovedOnCompletion:NO];
+    [zoomAnimation setValue:(id)kCFBooleanFalse forKey:isEnteringFullscreenKey];
+    
+    [rendererLayer addAnimation:zoomAnimation forKey:@"zoom"];
+    
+    NSEnableScreenUpdates();
+}
+
+#pragma mark -
+#pragma mark Internal Interface
+
+- (void)_updateMenuAndDockForFullscreen
+{
+    // NSApplicationPresentationOptions is available on > 10.6 only:
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+    NSApplicationPresentationOptions options = NSApplicationPresentationDefault;
+    NSScreen* fullscreenScreen = [[self window] screen];
+    
+    if (_isFullscreen) {
+        // Auto-hide the menu bar if the fullscreenScreen contains the menu bar:
+        // NOTE: if the fullscreenScreen contains the menu bar but not the dock, we must still 
+        // auto-hide the dock, or an exception will be thrown.
+        if ([[NSScreen screens] objectAtIndex:0] == fullscreenScreen)
+            options |= (NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock);
+        // Check if the current screen contains the dock by comparing the screen's frame to its
+        // visibleFrame; if a dock is present, the visibleFrame will differ. If the current screen
+        // contains the dock, hide it.
+        else if (!NSEqualRects([fullscreenScreen frame], [fullscreenScreen visibleFrame]))
+            options |= NSApplicationPresentationAutoHideDock;
+    }
+    
+    if ([NSApp respondsToSelector:@selector(setPresentationOptions:)])
+        [NSApp setPresentationOptions:options];
+    else
+#endif
+        SetSystemUIMode(_isFullscreen ? kUIModeNormal : kUIModeAllHidden, 0);
+}
+
+#if !defined(BUILDING_ON_TIGER) // IOPMAssertionCreateWithName not defined on < 10.5
+- (void)_disableIdleDisplaySleep
+{
+    if (_idleDisplaySleepAssertion == kIOPMNullAssertionID) 
+#if defined(BUILDING_ON_LEOPARD) // IOPMAssertionCreateWithName is not defined in the 10.5 SDK
+        IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &_idleDisplaySleepAssertion);
+#else // IOPMAssertionCreate is depreciated in > 10.5
+        IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, CFSTR("WebKit playing a video fullscreen."), &_idleDisplaySleepAssertion);
+#endif
+}
+
+- (void)_enableIdleDisplaySleep
+{
+    if (_idleDisplaySleepAssertion != kIOPMNullAssertionID) {
+        IOPMAssertionRelease(_idleDisplaySleepAssertion);
+        _idleDisplaySleepAssertion = kIOPMNullAssertionID;
+    }
+}
+
+- (void)_disableIdleSystemSleep
+{
+    if (_idleSystemSleepAssertion == kIOPMNullAssertionID) 
+#if defined(BUILDING_ON_LEOPARD) // IOPMAssertionCreateWithName is not defined in the 10.5 SDK
+        IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &_idleSystemSleepAssertion);
+#else // IOPMAssertionCreate is depreciated in > 10.5
+    IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR("WebKit playing a video fullscreen."), &_idleSystemSleepAssertion);
+#endif
+}
+
+- (void)_enableIdleSystemSleep
+{
+    if (_idleSystemSleepAssertion != kIOPMNullAssertionID) {
+        IOPMAssertionRelease(_idleSystemSleepAssertion);
+        _idleSystemSleepAssertion = kIOPMNullAssertionID;
+    }
+}
+
+- (void)_enableTickleTimer
+{
+    [_tickleTimer invalidate];
+    [_tickleTimer release];
+    _tickleTimer = [[NSTimer scheduledTimerWithTimeInterval:tickleTimerInterval target:self selector:@selector(_tickleTimerFired) userInfo:nil repeats:YES] retain];
+}
+
+- (void)_disableTickleTimer
+{
+    [_tickleTimer invalidate];
+    [_tickleTimer release];
+    _tickleTimer = nil;
+}
+
+- (void)_tickleTimerFired
+{
+    UpdateSystemActivity(OverallAct);
+}
+#endif
+
+- (void)_updatePowerAssertions
+{
+#if !defined(BUILDING_ON_TIGER) 
+    BOOL isPlaying = [self _isAnyMoviePlaying];
+    
+    if (isPlaying && _isFullscreen) {
+        [self _disableIdleSystemSleep];
+        [self _disableIdleDisplaySleep];
+        [self _enableTickleTimer];
+    } else {
+        [self _enableIdleSystemSleep];
+        [self _enableIdleDisplaySleep];
+        [self _disableTickleTimer];
+    }
+#endif
+}
+
+- (void)_requestExit
+{
+    [self exitFullscreen];
+    _forceDisableAnimation = NO;
+}
+
+- (void)_requestExitFullscreenWithAnimation:(BOOL)animation
+{
+    _forceDisableAnimation = !animation;
+    [self performSelector:@selector(_requestExit) withObject:nil afterDelay:0];
+
+}
+
+- (BOOL)_isAnyMoviePlaying
+{
+    if (!_element)
+        return NO;
+    
+    Node* nextNode = _element.get();
+    while (nextNode)
+    {
+        if (nextNode->hasTagName(HTMLNames::videoTag)) {
+            HTMLMediaElement* element = static_cast<HTMLMediaElement*>(nextNode);
+            if (!element->paused() && !element->ended())
+                return YES;
+        }
+        
+        nextNode = nextNode->traverseNextNode(_element.get());
+    }
+    
+    return NO;
+}
+
+#pragma mark -
+#pragma mark Utility Functions
+
+- (WebFullscreenWindow *)_fullscreenWindow
+{
+    return (WebFullscreenWindow *)[self window];
+}
+
+- (Document*)_document 
+{
+    return core([[[self webView] mainFrame] DOMDocument]);
+}
+
+- (CFTimeInterval)_animationDuration
+{
+    static const CFTimeInterval defaultDuration = 0.5;
+    CFTimeInterval duration = defaultDuration;
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+    NSUInteger modifierFlags = [NSEvent modifierFlags];
+#else
+    NSUInteger modifierFlags = [[NSEvent currentEvent] modifierFlags];
+#endif
+    if ((modifierFlags & NSControlKeyMask) == NSControlKeyMask)
+        duration *= 2;
+    if ((modifierFlags & NSShiftKeyMask) == NSShiftKeyMask)
+        duration *= 10;
+    if (_forceDisableAnimation) {
+        // This will disable scale animation
+        duration = 0;
+    }
+    return duration;
+}
+
+@end
+
+#pragma mark -
+@implementation WebFullscreenWindow
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
+{
+    UNUSED_PARAM(aStyle);
+    self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag];
+    if (!self)
+        return nil;
+    [self setOpaque:NO];
+    [self setBackgroundColor:[NSColor clearColor]];
+    [self setIgnoresMouseEvents:NO];
+    [self setAcceptsMouseMovedEvents:YES];
+    [self setReleasedWhenClosed:NO];
+    [self setHasShadow:YES];
+    [self setMovable:NO];
+    
+    NSView* contentView = [self contentView];
+    _animationView = [[NSView alloc] initWithFrame:[contentView bounds]];
+    
+    CALayer* contentLayer = [[CALayer alloc] init];
+    [_animationView setLayer:contentLayer];
+    [_animationView setWantsLayer:YES];
+    [_animationView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
+    [contentView addSubview:_animationView];
+    
+    _backgroundLayer = [[CALayer alloc] init];
+    [contentLayer addSublayer:_backgroundLayer];
+    [contentLayer setGeometryFlipped:YES];
+    [contentLayer setOpacity:0];
+    
+    [_backgroundLayer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];
+    [_backgroundLayer setOpacity:0];
+    return self;
+}
+
+- (void)dealloc
+{
+    [_animationView release];
+    [_backgroundLayer release];
+    [_rendererLayer release];
+    [super dealloc];
+}
+
+- (BOOL)canBecomeKeyWindow
+{
+    return YES;
+}
+
+- (void)keyDown:(NSEvent *)theEvent
+{
+    if ([[theEvent charactersIgnoringModifiers] isEqual:@"\e"]) // Esacpe key-code
+        [self cancelOperation:self];
+    else [super keyDown:theEvent];
+}
+
+- (void)cancelOperation:(id)sender
+{
+    UNUSED_PARAM(sender);
+    [[self windowController] _requestExitFullscreenWithAnimation:YES];
+}
+
+- (CALayer*)rendererLayer
+{
+    return _rendererLayer;
+}
+
+- (void)setRendererLayer:(CALayer *)rendererLayer
+{
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES];
+    [rendererLayer retain];
+    [_rendererLayer removeFromSuperlayer];
+    [_rendererLayer release];
+    _rendererLayer = rendererLayer;
+    
+    if (_rendererLayer)
+        [[[self animationView] layer] addSublayer:_rendererLayer];
+    [CATransaction commit];
+}
+
+- (CALayer*)backgroundLayer
+{
+    return _backgroundLayer;
+}
+
+- (NSView*)animationView
+{
+    return _animationView;
+}
+@end
+
+#pragma mark -
+#pragma mark MediaEventListener
+
+MediaEventListener::MediaEventListener(WebFullScreenController* delegate)
+    : EventListener(CPPEventListenerType)
+    , delegate(delegate)
+{ 
+}
+
+PassRefPtr<MediaEventListener> MediaEventListener::create(WebFullScreenController* delegate) 
+{ 
+    return adoptRef(new MediaEventListener(delegate)); 
+}
+
+bool MediaEventListener::operator==(const EventListener& listener)
+{
+    return this == &listener;
+}
+
+void MediaEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
+{
+    [delegate _updatePowerAssertions];
+}
+
+#endif /* ENABLE(FULLSCREEN_API) */
index 96ea7d0..9c7de2c 100644 (file)
@@ -60,6 +60,7 @@
 #import "WebFormDelegatePrivate.h"
 #import "WebFrameInternal.h"
 #import "WebFrameViewInternal.h"
+#import "WebFullScreenController.h"
 #import "WebGeolocationClient.h"
 #import "WebGeolocationPositionInternal.h"
 #import "WebHTMLRepresentation.h"
@@ -6027,6 +6028,42 @@ static void layerSyncRunLoopObserverCallBack(CFRunLoopObserverRef, CFRunLoopActi
 
 #endif
 
+#if ENABLE(FULLSCREEN_API)
+- (BOOL)_supportsFullScreenForElement:(const WebCore::Element*)element
+{
+    if (![[WebPreferences standardPreferences] fullScreenEnabled])
+        return NO;
+
+    // FIXME: If the element is in an IFrame, we should ensure it has 
+    // an AllowsFullScreen=YES attribute before allowing fullscreen access.
+    return YES;
+}
+
+- (void)_enterFullScreenForElement:(WebCore::Element*)element
+{
+    if (!_private->newFullscreenController)
+        _private->newFullscreenController = [[WebFullScreenController alloc] init];
+
+    [_private->newFullscreenController setElement:element];
+    [_private->newFullscreenController setWebView:self];
+    [_private->newFullscreenController enterFullscreen:[[self window] screen]];        
+}
+
+- (void)_exitFullScreenForElement:(WebCore::Element*)element
+{
+    if (!_private->newFullscreenController)
+        return;
+    [_private->newFullscreenController exitFullscreen];
+}
+
+- (void)_fullScreenRendererChanged:(WebCore::RenderBox*)renderer
+{
+    if (!_private->newFullscreenController)
+        _private->newFullscreenController = [[WebFullScreenController alloc] init];
+    [_private->newFullscreenController setRenderer:renderer];
+}
+#endif
+
 #if ENABLE(GLIB_SUPPORT)
 
 static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*)
index 8b834ca..97d0fc3 100644 (file)
@@ -49,6 +49,9 @@ namespace WebCore {
 #if ENABLE(VIDEO)
 @class WebVideoFullscreenController;
 #endif
+#if ENABLE(FULLSCREEN_API)
+@class WebFullScreenController;
+#endif
 
 extern BOOL applicationIsTerminating;
 extern int pluginDatabaseClientCount;
@@ -171,6 +174,10 @@ extern int pluginDatabaseClientCount;
 #if ENABLE(VIDEO)
     WebVideoFullscreenController *fullscreenController;
 #endif
+    
+#if ENABLE(FULLSCREEN_API)
+    WebFullScreenController *newFullscreenController;
+#endif
 
 #if ENABLE(GLIB_SUPPORT)
     CFRunLoopObserverRef glibRunLoopObserver;
index 0a6f462..555c4d1 100644 (file)
 #include <wtf/Forward.h>
 
 namespace WebCore {
+    class Element;
     class Frame;
     class KURL;
     class KeyboardEvent;
     class Page;
+    class RenderBox;
     class Node;
 }
 #endif
@@ -185,6 +187,13 @@ namespace WebCore {
 - (void)_exitFullscreen;
 #endif
 
+#if ENABLE(FULLSCREEN_API) && defined(__cplusplus)
+- (BOOL)_supportsFullScreenForElement:(WebCore::Element*)element;
+- (void)_enterFullScreenForElement:(WebCore::Element*)element;
+- (void)_exitFullScreenForElement:(WebCore::Element*)element;
+- (void)_fullScreenRendererChanged:(WebCore::RenderBox*)renderer;
+#endif
+
 - (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value;
 
 @end