2009-04-17 Simon Fraser <simon.fraser@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 19 Apr 2009 05:00:39 +0000 (05:00 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 19 Apr 2009 05:00:39 +0000 (05:00 +0000)
        Reviewed by Antti Koivisto.

        https://bugs.webkit.org/show_bug.cgi?id=25066

        When a <video> element gained a RenderLayer via opacity, reflection etc., the
        layer hierarchy was not correctly updated because RenderMedia skipped a level
        when asked for its children; it skipped m_controlsShadowRoot's renderer, which
        actually has a layer.

        Test: fast/layers/video-layer.html

        * rendering/MediaControlElements.cpp:
        (WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
        Don't manually call setParent() on the renderer. It will happen later
        as a result of addChild().

        * rendering/RenderMedia.cpp:
        (WebCore::RenderMedia::createControlsShadowRoot):
        Add m_controlsShadowRoot's renderer as a child.

        * rendering/RenderMedia.h:
        (WebCore::RenderMedia::children):
        Now maintain a RenderObjectChildList, m_children, and remove the unneeded
        removeChild() method. Make the two children() methods inline.

        * rendering/RenderObject.cpp:
        (WebCore::RenderObject::moveLayers):
        Assert if moveLayers() is called with an oldParent that is not the
        layer's actual parent (which would have revealed this bug).

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

LayoutTests/ChangeLog
LayoutTests/fast/layers/video-layer.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/layers/video-layer-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/fast/layers/video-layer-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/layers/video-layer-expected.txt [new file with mode: 0644]
WebCore/ChangeLog
WebCore/rendering/MediaControlElements.cpp
WebCore/rendering/RenderMedia.cpp
WebCore/rendering/RenderMedia.h
WebCore/rendering/RenderObject.cpp

index 3ad2ae3..d28a124 100644 (file)
@@ -1,3 +1,16 @@
+2009-04-17  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Antti Koivisto.
+        
+        https://bugs.webkit.org/show_bug.cgi?id=25066
+        
+        Add testcase for dynamically giving <video> a layer, via opacity.
+
+        * fast/layers/video-layer.html: Added.
+        * platform/mac/fast/layers/video-layer-expected.checksum: Added.
+        * platform/mac/fast/layers/video-layer-expected.png: Added.
+        * platform/mac/fast/layers/video-layer-expected.txt: Added.
+
 2009-04-18  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Cameron Zwarich.
diff --git a/LayoutTests/fast/layers/video-layer.html b/LayoutTests/fast/layers/video-layer.html
new file mode 100644 (file)
index 0000000..171f09b
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+<head>
+  <title>Video element gets layer</title>
+  <style type="text/css">
+    video {
+      border: 1px solid black;
+      margin: 50px;
+    }
+  </style>
+</head>
+<body>
+  <p><a href="https://bugs.webkit.org/show_bug.cgi?id=25066">https://bugs.webkit.org/show_bug.cgi?id=25066</a><br> controls should not be misplaced when video gets a RenderLayer.</p>
+  <video id="video" controls></video>
+  <script type="text/javascript" charset="utf-8">
+    document.getElementById('video').style.opacity = 0.5;
+  </script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/layers/video-layer-expected.checksum b/LayoutTests/platform/mac/fast/layers/video-layer-expected.checksum
new file mode 100644 (file)
index 0000000..f4f542a
--- /dev/null
@@ -0,0 +1 @@
+278c725b9fe345ad701598b01b393195
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/layers/video-layer-expected.png b/LayoutTests/platform/mac/fast/layers/video-layer-expected.png
new file mode 100644 (file)
index 0000000..94d0f8c
Binary files /dev/null and b/LayoutTests/platform/mac/fast/layers/video-layer-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/layers/video-layer-expected.txt b/LayoutTests/platform/mac/fast/layers/video-layer-expected.txt
new file mode 100644 (file)
index 0000000..d03c735
--- /dev/null
@@ -0,0 +1,37 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {P} at (0,0) size 784x36
+        RenderInline {A} at (0,0) size 305x18 [color=#0000EE]
+          RenderText {#text} at (0,0) size 305x18
+            text run at (0,0) width 305: "https://bugs.webkit.org/show_bug.cgi?id=25066"
+        RenderBR {BR} at (305,14) size 0x0
+        RenderText {#text} at (0,18) size 415x18
+          text run at (0,18) width 415: "controls should not be misplaced when video gets a RenderLayer."
+      RenderBlock (anonymous) at (0,52) size 784x252
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+layer at (58,110) size 302x152
+  RenderVideo {VIDEO} at (50,50) size 302x152 [border: (1px solid #000000)]
+layer at (59,111) size 300x150
+  RenderBlock (relative positioned) {DIV} at (1,1) size 300x150
+layer at (59,111) size 300x150
+  RenderBlock (positioned) {DIV} at (0,0) size 300x150
+    RenderButton {INPUT} at (0,0) size 300x18
+layer at (59,245) size 17x16
+  RenderButton {INPUT} at (0,134) size 17x16
+layer at (75,245) size 17x16
+  RenderButton {INPUT} at (16,134) size 17x16
+layer at (91,245) size 236x16
+  RenderBlock (positioned) {DIV} at (32,134) size 236x16
+layer at (91,245) size 236x16
+  RenderSlider {INPUT} at (0,0) size 236x16
+    RenderBlock {DIV} at (2,1) size 13x14
+layer at (326,245) size 17x16
+  RenderButton {INPUT} at (267,134) size 17x16
+layer at (342,245) size 17x16
+  RenderButton {INPUT} at (283,134) size 17x16
index 85a4e90..19a0714 100644 (file)
@@ -1,3 +1,35 @@
+2009-04-17  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Antti Koivisto.
+        
+        https://bugs.webkit.org/show_bug.cgi?id=25066
+        
+        When a <video> element gained a RenderLayer via opacity, reflection etc., the
+        layer hierarchy was not correctly updated because RenderMedia skipped a level
+        when asked for its children; it skipped m_controlsShadowRoot's renderer, which
+        actually has a layer.
+
+        Test: fast/layers/video-layer.html
+
+        * rendering/MediaControlElements.cpp:
+        (WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
+        Don't manually call setParent() on the renderer. It will happen later
+        as a result of addChild().
+        
+        * rendering/RenderMedia.cpp:
+        (WebCore::RenderMedia::createControlsShadowRoot):
+        Add m_controlsShadowRoot's renderer as a child. 
+
+        * rendering/RenderMedia.h:
+        (WebCore::RenderMedia::children):
+        Now maintain a RenderObjectChildList, m_children, and remove the unneeded
+        removeChild() method. Make the two children() methods inline.
+
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::moveLayers):
+        Assert if moveLayers() is called with an oldParent that is not the
+        layer's actual parent (which would have revealed this bug).
+
 2009-04-18  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Cameron Zwarich.
index d84e9ad..ddd6170 100644 (file)
@@ -61,7 +61,6 @@ MediaControlShadowRootElement::MediaControlShadowRootElement(Document* doc, HTML
     rootStyle->setDisplay(BLOCK);
     rootStyle->setPosition(RelativePosition);
     RenderMediaControlShadowRoot* renderer = new (mediaElement->renderer()->renderArena()) RenderMediaControlShadowRoot(this);
-    renderer->setParent(mediaElement->renderer());
     renderer->setStyle(rootStyle.release());
     setRenderer(renderer);
     setAttached();
index 42cd709..6585fa4 100644 (file)
@@ -145,28 +145,11 @@ void RenderMedia::layout()
     }
 }
 
-const RenderObjectChildList* RenderMedia::children() const
-{
-    return m_controlsShadowRoot ? m_controlsShadowRoot->renderer()->virtualChildren() : 0; 
-}
-
-RenderObjectChildList* RenderMedia::children()
-{
-    return m_controlsShadowRoot ? m_controlsShadowRoot->renderer()->virtualChildren() : 0; 
-}
-   
-void RenderMedia::removeChild(RenderObject* child)
-{
-    ASSERT(m_controlsShadowRoot);
-    ASSERT(child == m_controlsShadowRoot->renderer());
-    child->removeLayers(enclosingLayer());
-    static_cast<RenderMediaControlShadowRoot*>(child)->setParent(0);
-}
-    
 void RenderMedia::createControlsShadowRoot()
 {
     ASSERT(!m_controlsShadowRoot);
     m_controlsShadowRoot = new MediaControlShadowRootElement(document(), mediaElement());
+    addChild(m_controlsShadowRoot->renderer());
 }
 
 void RenderMedia::createPanel()
index 0e56dab..6013d7b 100644 (file)
@@ -51,10 +51,9 @@ public:
     
     virtual RenderObjectChildList* virtualChildren() { return children(); }
     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
-    const RenderObjectChildList* children() const;
-    RenderObjectChildList* children();
+    const RenderObjectChildList* children() const { return &m_children; }
+    RenderObjectChildList* children() { return &m_children; }
 
-    virtual void removeChild(RenderObject*);
     virtual void destroy();
     
     virtual void layout();
@@ -111,6 +110,7 @@ private:
     RefPtr<HTMLElement> m_timelineContainer;
     RefPtr<MediaTimeDisplayElement> m_currentTimeDisplay;
     RefPtr<MediaTimeDisplayElement> m_timeRemainingDisplay;
+    RenderObjectChildList m_children;
     Node* m_lastUnderNode;
     Node* m_nodeUnderMouse;
     
index e0e4e09..2fe55dc 100644 (file)
@@ -461,6 +461,7 @@ void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
 
     if (hasLayer()) {
         RenderLayer* layer = toRenderBoxModelObject(this)->layer();
+        ASSERT(oldParent == layer->parent());
         if (oldParent)
             oldParent->removeChild(layer);
         newParent->addChild(layer);