Don't detach elements from the render tree when entering fullscreen mode
authorkoz@chromium.org <koz@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Sep 2011 06:07:42 +0000 (06:07 +0000)
committerkoz@chromium.org <koz@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Sep 2011 06:07:42 +0000 (06:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=66531

Source/WebCore:

This prevents plugin instances from being destroyed and reinstantiated
when entering fullscreen mode.

Reviewed by James Robinson.

Test: plugins/fullscreen-plugins-dont-reload.html

* dom/Document.cpp:
(WebCore::Document::webkitWillEnterFullScreenForElement):
(WebCore::Document::webkitDidExitFullScreenForElement):
* dom/NodeRenderingContext.cpp:
(WebCore::NodeRendererFactory::createRendererIfNeeded):
* rendering/RenderFullScreen.cpp:
(createFullScreenStyle):
(RenderFullScreen::wrapRenderer):
(RenderFullScreen::unwrapRenderer):
* rendering/RenderFullScreen.h:

LayoutTests:

Test that the plugin is not reloaded when entering fullscreen.

Reviewed by James Robinson.

* plugins/fullscreen-plugins-dont-reload-expected.txt: Added.
* plugins/fullscreen-plugins-dont-reload.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/plugins/fullscreen-plugins-dont-reload-expected.txt [new file with mode: 0644]
LayoutTests/plugins/fullscreen-plugins-dont-reload.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/NodeRenderingContext.cpp
Source/WebCore/rendering/RenderFullScreen.cpp
Source/WebCore/rendering/RenderFullScreen.h

index 1cb08c2..d81641b 100644 (file)
@@ -1,3 +1,15 @@
+2011-09-16  Jeremy Apthorp <jeremya@chromium.org> and James Kozianski  <koz@chromium.org>
+
+        Don't detach elements from the render tree when entering fullscreen mode
+        https://bugs.webkit.org/show_bug.cgi?id=66531
+
+        Test that the plugin is not reloaded when entering fullscreen.
+
+        Reviewed by James Robinson.
+
+        * plugins/fullscreen-plugins-dont-reload-expected.txt: Added.
+        * plugins/fullscreen-plugins-dont-reload.html: Added.
+
 2011-09-16  Jochen Eisinger  <jochen@chromium.org>
 
         Add tests for FrameLoaderClient::allowImage.
diff --git a/LayoutTests/plugins/fullscreen-plugins-dont-reload-expected.txt b/LayoutTests/plugins/fullscreen-plugins-dont-reload-expected.txt
new file mode 100644 (file)
index 0000000..60dec7e
--- /dev/null
@@ -0,0 +1,5 @@
+ALERT: Plugin Loaded!
+go fullscreen
+There should only be one ALERT. If there were two, the plugin was reloaded during the transition to fullscreen.
+
+
diff --git a/LayoutTests/plugins/fullscreen-plugins-dont-reload.html b/LayoutTests/plugins/fullscreen-plugins-dont-reload.html
new file mode 100644 (file)
index 0000000..2ade376
--- /dev/null
@@ -0,0 +1,25 @@
+<html>
+<a id='link' href="javascript:document.getElementById('plg').webkitRequestFullScreen()">go
+fullscreen</a>
+<p>
+There should only be one ALERT. If there were two, the plugin was reloaded
+during the transition to fullscreen.
+</p>
+<embed id="plg" type="application/x-webkit-test-netscape" src="data:application/x-webkit-test-netscape,alertwhenloaded"></iframe>
+
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+
+    var plugin = document.getElementById('plg');
+    plugin.addEventListener('webkitfullscreenchange', function () {
+        layoutTestController.notifyDone();
+    })
+    document.addEventListener('keydown', function () {
+        plugin.webkitRequestFullScreen();
+    })
+    eventSender.keyDown('a')
+}
+</script>
+</html>
index 6b555fc..db25fa2 100644 (file)
@@ -1,3 +1,26 @@
+2011-09-16  Jeremy Apthorp <jeremya@chromium.org> and James Kozianski  <koz@chromium.org>
+
+        Don't detach elements from the render tree when entering fullscreen mode
+        https://bugs.webkit.org/show_bug.cgi?id=66531
+
+        This prevents plugin instances from being destroyed and reinstantiated
+        when entering fullscreen mode.
+
+        Reviewed by James Robinson.
+
+        Test: plugins/fullscreen-plugins-dont-reload.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::webkitWillEnterFullScreenForElement):
+        (WebCore::Document::webkitDidExitFullScreenForElement):
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::NodeRendererFactory::createRendererIfNeeded):
+        * rendering/RenderFullScreen.cpp:
+        (createFullScreenStyle):
+        (RenderFullScreen::wrapRenderer):
+        (RenderFullScreen::unwrapRenderer):
+        * rendering/RenderFullScreen.h:
+
 2011-09-16  Jochen Eisinger  <jochen@chromium.org>
 
         Rename FrameLoaderClient::allowImages to FrameLoaderClient::allowImage and include the image URL as parameter
index 92dac70..1943fae 100644 (file)
@@ -4877,6 +4877,9 @@ void Document::webkitWillEnterFullScreenForElement(Element* element)
     ASSERT(element);
     ASSERT(page() && page()->settings()->fullScreenEnabled());
 
+    if (m_fullScreenRenderer)
+        m_fullScreenRenderer->unwrapRenderer();
+
     m_fullScreenElement = element;
 
     // Create a placeholder block for a the full-screen element, to keep the page from reflowing
@@ -4891,7 +4894,7 @@ void Document::webkitWillEnterFullScreenForElement(Element* element)
     }
 
     if (m_fullScreenElement != documentElement())
-        m_fullScreenElement->detach();
+        RenderFullScreen::wrapRenderer(renderer, this);
 
     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
     
@@ -4942,15 +4945,11 @@ void Document::webkitDidExitFullScreenForElement(Element*)
 {
     m_areKeysEnabledInFullScreen = false;
     setAnimatingFullScreen(false);
-
-    if (m_fullScreenRenderer)
-        m_fullScreenRenderer->remove();
     
-    if (m_fullScreenElement != documentElement())
-        m_fullScreenElement->detach();
+    if (m_fullScreenRenderer)
+        m_fullScreenRenderer->unwrapRenderer();
 
     m_fullScreenChangeEventTargetQueue.append(m_fullScreenElement.release());
-    setFullScreenRenderer(0);
 #if USE(ACCELERATED_COMPOSITING)
     page()->chrome()->client()->setRootFullScreenLayer(0);
 #endif
index f4743e4..c0a2dad 100644 (file)
@@ -303,22 +303,6 @@ RenderObject* NodeRendererFactory::createRenderer()
     return newRenderer;
 }
 
-#if ENABLE(FULLSCREEN_API)
-static RenderObject* wrapWithRenderFullScreen(RenderObject* object, Document* document)
-{
-    RenderFullScreen* fullscreenRenderer = new (document->renderArena()) RenderFullScreen(document);
-    fullscreenRenderer->setStyle(RenderFullScreen::createFullScreenStyle());
-    // It's possible that we failed to create the new render and end up wrapping nothing.
-    // We'll end up displaying a black screen, but Jer says this is expected.
-    if (object)
-        fullscreenRenderer->addChild(object);
-    document->setFullScreenRenderer(fullscreenRenderer);
-    if (fullscreenRenderer->placeholder())
-        return fullscreenRenderer->placeholder();
-    return fullscreenRenderer;
-}
-#endif
-
 void NodeRendererFactory::createRendererIfNeeded()
 {
     Node* node = m_context.node();
@@ -355,7 +339,7 @@ void NodeRendererFactory::createRendererIfNeeded()
 
 #if ENABLE(FULLSCREEN_API)
     if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == node)
-        newRenderer = wrapWithRenderFullScreen(newRenderer, document);
+        newRenderer = RenderFullScreen::wrapRenderer(newRenderer, document);
 #endif
 
     if (!newRenderer)
index 18dbc9f..9bc13c7 100644 (file)
@@ -79,7 +79,7 @@ void RenderFullScreen::willBeDestroyed()
     RenderDeprecatedFlexibleBox::willBeDestroyed();
 }
 
-PassRefPtr<RenderStyle> RenderFullScreen::createFullScreenStyle()
+static PassRefPtr<RenderStyle> createFullScreenStyle()
 {
     RefPtr<RenderStyle> fullscreenStyle = RenderStyle::createDefaultStyle();
 
@@ -97,14 +97,45 @@ PassRefPtr<RenderStyle> RenderFullScreen::createFullScreenStyle()
     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->setLeft(Length(0, WebCore::Fixed));
+    fullscreenStyle->setTop(Length(0, WebCore::Fixed));
     
     fullscreenStyle->setBackgroundColor(Color::black);
     
     return fullscreenStyle.release();
 }
 
+RenderObject* RenderFullScreen::wrapRenderer(RenderObject* object, Document* document)
+{
+    RenderFullScreen* fullscreenRenderer = new (document->renderArena()) RenderFullScreen(document);
+    fullscreenRenderer->setStyle(createFullScreenStyle());
+    if (object) {
+        if (RenderObject* parent = object->parent()) {
+            parent->addChild(fullscreenRenderer, object);
+            object->remove();
+        }
+        fullscreenRenderer->addChild(object);
+    }
+    document->setFullScreenRenderer(fullscreenRenderer);
+    if (fullscreenRenderer->placeholder())
+        return fullscreenRenderer->placeholder();
+    return fullscreenRenderer;
+}
+
+void RenderFullScreen::unwrapRenderer()
+{
+    RenderObject* wrappedRenderer = firstChild();
+    if (wrappedRenderer) {
+        wrappedRenderer->remove();
+        RenderObject* holder = placeholder() ? placeholder() : this;
+        RenderObject* parent = holder->parent();
+        if (parent)
+            parent->addChild(wrappedRenderer, holder);
+    }
+    remove();
+    document()->setFullScreenRenderer(0);
+}
+
 void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
 {
     m_placeholder = placeholder;
index 6f4c783..7968792 100644 (file)
@@ -41,7 +41,9 @@ public:
     RenderBlock* placeholder() { return m_placeholder; }
     void createPlaceholder(PassRefPtr<RenderStyle>, const IntRect& frameRect);
 
-    static PassRefPtr<RenderStyle> createFullScreenStyle();
+
+    static RenderObject* wrapRenderer(RenderObject* renderer, Document*);
+    void unwrapRenderer();
 
 private:
     virtual void willBeDestroyed();