WebCore:
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Dec 2007 19:21:09 +0000 (19:21 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Dec 2007 19:21:09 +0000 (19:21 +0000)
        Reviewed by Adele.

        Fix <rdar://problem/5624802>
        Controller displays outside of <video> element when width and height aren't specified

        - Explicitly adjust size of the controls tree root.
        - Switch RenderMedia base class back to RenderReplaced. It is easier to manage the shadow tree
          by hand. This also allows better code sharing with other replaced element classes.
        - Move duplicated layout and painting code from subclasses up to RenderReplaced.

        Test: media/video-controls-rendering.html

        * rendering/RenderHTMLCanvas.cpp:
        (WebCore::RenderHTMLCanvas::paintReplaced):
        * rendering/RenderHTMLCanvas.h:
            Share code.
        * rendering/RenderImage.cpp:
        (WebCore::RenderImage::paintReplaced):
        (WebCore::RenderImage::minimumReplacedHeight):
        * rendering/RenderImage.h:
            Share code.
        * rendering/RenderMedia.cpp:
        (WebCore::RenderMediaControlShadowRoot::RenderMediaControlShadowRoot):
        (WebCore::RenderMediaControlShadowRoot::setParent):
            Add a subclass just to get through encapsulation to use setParent().
        (WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
            Move initialization to the constructor.
        (WebCore::RenderMedia::RenderMedia):
        (WebCore::RenderMedia::~RenderMedia):
        (WebCore::RenderMedia::layout):
            Resize and layout the controller root by hand.
        (WebCore::RenderMedia::firstChild):
        (WebCore::RenderMedia::lastChild):
        (WebCore::RenderMedia::removeChild):
            Support one child renderer for controls.
        (WebCore::RenderMedia::createControlsShadowRoot):
        * rendering/RenderMedia.h:
        (WebCore::RenderMedia::isMedia):
            Switch base class to RenderReplaced, delete the now unnecessary stuff.
        * rendering/RenderReplaced.cpp:
        (WebCore::RenderReplaced::layout):
        (WebCore::RenderReplaced::paint):
        * rendering/RenderReplaced.h:
        (WebCore::RenderReplaced::minimumReplacedHeight):
        (WebCore::RenderReplaced::paintReplaced):
            Share code.
        * rendering/RenderVideo.cpp:
        (WebCore::RenderVideo::videoSizeChanged):
            Simplify, just request relayout.
        (WebCore::RenderVideo::paintReplaced):
        (WebCore::RenderVideo::layout):
        * rendering/RenderVideo.h:
            Share code.

LayoutTests:

        Reviewed by Adele.

        Test for <rdar://problem/5624802>
        Controller displays outside of <video> element when width and height aren't specified

        * media/remove-from-document.html: Improve coverage by doing relayout before finishing.
        * media/video-controls-rendering.html: Added.
        * platform/mac/media/video-controls-rendering-expected.checksum: Added.
        * platform/mac/media/video-controls-rendering-expected.png: Added.
        * platform/mac/media/video-controls-rendering-expected.txt: Added.

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

17 files changed:
LayoutTests/ChangeLog
LayoutTests/media/remove-from-document.html
LayoutTests/media/video-controls-rendering.html [new file with mode: 0644]
LayoutTests/platform/mac/media/video-controls-rendering-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/media/video-controls-rendering-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/media/video-controls-rendering-expected.txt [new file with mode: 0644]
WebCore/ChangeLog
WebCore/rendering/RenderHTMLCanvas.cpp
WebCore/rendering/RenderHTMLCanvas.h
WebCore/rendering/RenderImage.cpp
WebCore/rendering/RenderImage.h
WebCore/rendering/RenderMedia.cpp
WebCore/rendering/RenderMedia.h
WebCore/rendering/RenderReplaced.cpp
WebCore/rendering/RenderReplaced.h
WebCore/rendering/RenderVideo.cpp
WebCore/rendering/RenderVideo.h

index 181bbb0..5a59f7e 100644 (file)
@@ -1,3 +1,16 @@
+2007-12-03  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Adele.
+        
+        Test for <rdar://problem/5624802> 
+        Controller displays outside of <video> element when width and height aren't specified 
+
+        * media/remove-from-document.html: Improve coverage by doing relayout before finishing.
+        * media/video-controls-rendering.html: Added.
+        * platform/mac/media/video-controls-rendering-expected.checksum: Added.
+        * platform/mac/media/video-controls-rendering-expected.png: Added.
+        * platform/mac/media/video-controls-rendering-expected.txt: Added.
+
 2007-12-04  Darin Adler  <darin@apple.com>
 
         Reviewed by Geoff.
index 0775a73..e2d7751 100644 (file)
@@ -8,6 +8,7 @@ waitForEvent('load', function () {
     run("document.body.removeChild(video)");
     test("video.networkState == HTMLMediaElement.LOADED");
     test("video.paused");
+    document.body.offsetTop;
     endTest();
 } );
 video.src = "content/test.mp4";
diff --git a/LayoutTests/media/video-controls-rendering.html b/LayoutTests/media/video-controls-rendering.html
new file mode 100644 (file)
index 0000000..a0369f3
--- /dev/null
@@ -0,0 +1,24 @@
+<p>Test controls placement. </p>
+<video controls src="content/test.mp4"></video><br>
+<video controls src="content/test.mp4" style="width: 320px;"></video><br>
+<video controls src="content/test.mp4" style="position: absolute; width: 320px;"></video><br>
+
+<script>
+if (window.layoutTestController) {
+    layoutTestController.waitUntilDone();
+    setTimeout(function() { 
+        document.body.appendChild(document.createTextNode('FAIL')); 
+        if (window.layoutTestController)
+                layoutTestController.notifyDone();
+    } , 8000);
+}
+var count = document.getElementsByTagName('video').length;
+document.addEventListener("load", function () {
+    if (!--count) {
+        document.body.offsetLeft;
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
+}, true);
+</script>
+
diff --git a/LayoutTests/platform/mac/media/video-controls-rendering-expected.checksum b/LayoutTests/platform/mac/media/video-controls-rendering-expected.checksum
new file mode 100644 (file)
index 0000000..e05bdff
--- /dev/null
@@ -0,0 +1 @@
+743910ccf010e7b8bf0835d51979124f
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/media/video-controls-rendering-expected.png b/LayoutTests/platform/mac/media/video-controls-rendering-expected.png
new file mode 100644 (file)
index 0000000..ed754df
Binary files /dev/null and b/LayoutTests/platform/mac/media/video-controls-rendering-expected.png differ
diff --git a/LayoutTests/platform/mac/media/video-controls-rendering-expected.txt b/LayoutTests/platform/mac/media/video-controls-rendering-expected.txt
new file mode 100644 (file)
index 0000000..4a246a1
--- /dev/null
@@ -0,0 +1,68 @@
+layer at (0,0) size 785x762
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x600
+  RenderBlock {HTML} at (0,0) size 785x600
+    RenderBody {BODY} at (8,8) size 769x584
+      RenderBlock {P} at (0,0) size 769x18
+        RenderText {#text} at (0,0) size 153x18
+          text run at (0,0) width 153: "Test controls placement."
+      RenderBlock (anonymous) at (0,34) size 769x480
+        RenderVideo {VIDEO} at (0,0) size 320x240
+        RenderBR {BR} at (320,240) size 0x0
+        RenderVideo {VIDEO} at (0,240) size 320x240
+        RenderBR {BR} at (320,480) size 0x0
+      RenderBlock (anonymous) at (0,514) size 769x18
+        RenderBR {BR} at (0,0) size 0x18
+layer at (8,42) size 320x240
+  RenderBlock (positioned) {DIV} at (8,42) size 320x240
+layer at (51,189) size 234x69
+  RenderBlock (positioned) {DIV} at (43,147) size 234x69 [bgcolor=#00000099] [border: (2px solid #EEEEEE)]
+layer at (135,196) size 66x40
+  RenderButton {INPUT} at (84,7) size 66x40 [color=#FFFFFF]
+    RenderBlock (anonymous) at (0,0) size 66x40
+      RenderText at (18,0) size 30x38
+        text run at (18,0) width 30: "\x{25B6}"
+layer at (58,235) size 220x16
+  RenderBlock (positioned) {DIV} at (7,46) size 220x16 [bgcolor=#EEEEEE]
+    RenderText {#text} at (165,0) size 50x15
+      text run at (165,0) width 50: "00:00:00"
+layer at (8,282) size 320x240
+  RenderBlock (positioned) {DIV} at (8,282) size 320x240
+layer at (51,429) size 234x69
+  RenderBlock (positioned) {DIV} at (43,147) size 234x69 [bgcolor=#00000099] [border: (2px solid #EEEEEE)]
+layer at (135,436) size 66x40
+  RenderButton {INPUT} at (84,7) size 66x40 [color=#FFFFFF]
+    RenderBlock (anonymous) at (0,0) size 66x40
+      RenderText at (18,0) size 30x38
+        text run at (18,0) width 30: "\x{25B6}"
+layer at (58,475) size 220x16
+  RenderBlock (positioned) {DIV} at (7,46) size 220x16 [bgcolor=#EEEEEE]
+    RenderText {#text} at (165,0) size 50x15
+      text run at (165,0) width 50: "00:00:00"
+layer at (8,522) size 320x240
+  RenderVideo {VIDEO} at (8,522) size 320x240
+layer at (8,522) size 320x240
+  RenderBlock (positioned) {DIV} at (0,0) size 320x240
+layer at (51,669) size 234x69
+  RenderBlock (positioned) {DIV} at (43,147) size 234x69 [bgcolor=#00000099] [border: (2px solid #EEEEEE)]
+layer at (135,676) size 66x40
+  RenderButton {INPUT} at (84,7) size 66x40 [color=#FFFFFF]
+    RenderBlock (anonymous) at (0,0) size 66x40
+      RenderText at (18,0) size 30x38
+        text run at (18,0) width 30: "\x{25B6}"
+layer at (58,715) size 220x16
+  RenderBlock (positioned) {DIV} at (7,46) size 220x16 [bgcolor=#EEEEEE]
+    RenderText {#text} at (165,0) size 50x15
+      text run at (165,0) width 50: "00:00:00"
+layer at (63,234) size 142x17
+  RenderSlider zI: 1 {INPUT} at (12,45) size 142x16 [border: (2px solid #FFFFFF)]
+layer at (65,237) size 15x15
+  RenderBlock (relative positioned) {DIV} at (2,2) size 15x15
+layer at (63,474) size 142x17
+  RenderSlider zI: 1 {INPUT} at (12,45) size 142x16 [border: (2px solid #FFFFFF)]
+layer at (65,477) size 15x15
+  RenderBlock (relative positioned) {DIV} at (2,2) size 15x15
+layer at (63,714) size 142x17
+  RenderSlider zI: 1 {INPUT} at (12,45) size 142x16 [border: (2px solid #FFFFFF)]
+layer at (65,717) size 15x15
+  RenderBlock (relative positioned) {DIV} at (2,2) size 15x15
index 8cbe1e1..41cc7bb 100644 (file)
@@ -1,3 +1,59 @@
+2007-12-03  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Adele.
+        
+        Fix <rdar://problem/5624802> 
+        Controller displays outside of <video> element when width and height aren't specified 
+
+        - Explicitly adjust size of the controls tree root.
+        - Switch RenderMedia base class back to RenderReplaced. It is easier to manage the shadow tree
+          by hand. This also allows better code sharing with other replaced element classes.
+        - Move duplicated layout and painting code from subclasses up to RenderReplaced.
+
+        Test: media/video-controls-rendering.html
+
+        * rendering/RenderHTMLCanvas.cpp:
+        (WebCore::RenderHTMLCanvas::paintReplaced):
+        * rendering/RenderHTMLCanvas.h:
+            Share code.
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::paintReplaced):
+        (WebCore::RenderImage::minimumReplacedHeight):
+        * rendering/RenderImage.h:
+            Share code.
+        * rendering/RenderMedia.cpp:
+        (WebCore::RenderMediaControlShadowRoot::RenderMediaControlShadowRoot):
+        (WebCore::RenderMediaControlShadowRoot::setParent):
+            Add a subclass just to get through encapsulation to use setParent().
+        (WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
+            Move initialization to the constructor.
+        (WebCore::RenderMedia::RenderMedia):
+        (WebCore::RenderMedia::~RenderMedia):
+        (WebCore::RenderMedia::layout):
+            Resize and layout the controller root by hand.
+        (WebCore::RenderMedia::firstChild):
+        (WebCore::RenderMedia::lastChild):
+        (WebCore::RenderMedia::removeChild):
+            Support one child renderer for controls.
+        (WebCore::RenderMedia::createControlsShadowRoot):
+        * rendering/RenderMedia.h:
+        (WebCore::RenderMedia::isMedia):
+            Switch base class to RenderReplaced, delete the now unnecessary stuff.
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::layout):
+        (WebCore::RenderReplaced::paint):
+        * rendering/RenderReplaced.h:
+        (WebCore::RenderReplaced::minimumReplacedHeight):
+        (WebCore::RenderReplaced::paintReplaced):
+            Share code.
+        * rendering/RenderVideo.cpp:
+        (WebCore::RenderVideo::videoSizeChanged):
+            Simplify, just request relayout.
+        (WebCore::RenderVideo::paintReplaced):
+        (WebCore::RenderVideo::layout):
+        * rendering/RenderVideo.h:
+            Share code.
+
 2007-12-04  Michael Natterer  <mitch@imendio.com>
 
         Reviewed by Alp Toker.
index ef4eb7b..4e556df 100644 (file)
@@ -41,58 +41,11 @@ RenderHTMLCanvas::RenderHTMLCanvas(HTMLCanvasElement* element)
 {
 }
 
-void RenderHTMLCanvas::paint(PaintInfo& paintInfo, int tx, int ty)
+void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 {
-    if (!shouldPaint(paintInfo, tx, ty))
-        return;
-
-    int x = tx + m_x;
-    int y = ty + m_y;
-
-    if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) 
-        paintBoxDecorations(paintInfo, x, y);
-
-    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
-        paintOutline(paintInfo.context, x, y, width(), height(), style());
-
-    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
-        return;
-
-    if (!shouldPaintWithinRoot(paintInfo))
-        return;
-
-    bool drawSelectionTint = selectionState() != SelectionNone && !document()->printing();
-    if (paintInfo.phase == PaintPhaseSelection) {
-        if (selectionState() == SelectionNone)
-            return;
-        drawSelectionTint = false;
-    }
-
-    static_cast<HTMLCanvasElement*>(node())->paint(paintInfo.context,
-        IntRect(x + borderLeft() + paddingLeft(), y + borderTop() + paddingTop(), contentWidth(), contentHeight()));
-
-    if (drawSelectionTint)
-        paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor());
-}
-
-void RenderHTMLCanvas::layout()
-{
-    ASSERT(needsLayout());
-
-    IntRect oldBounds;
-    IntRect oldOutlineBox;
-    bool checkForRepaint = checkForRepaintDuringLayout();
-    if (checkForRepaint) {
-        oldBounds = absoluteClippedOverflowRect();
-        oldOutlineBox = absoluteOutlineBox();
-    }
-    calcWidth();
-    calcHeight();
-    adjustOverflowForBoxShadow();
-    if (checkForRepaint)
-        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
-
-    setNeedsLayout(false);
+    IntRect rect = contentBox();
+    rect.move(tx, ty);
+    static_cast<HTMLCanvasElement*>(node())->paint(paintInfo.context, rect);
 }
 
 void RenderHTMLCanvas::canvasSizeChanged()
index 3004eb2..754b837 100644 (file)
@@ -38,8 +38,7 @@ namespace WebCore {
 
         virtual const char* renderName() const { return "RenderHTMLCanvas"; }
 
-        virtual void paint(PaintInfo&, int tx, int ty);
-        virtual void layout();
+        virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty);
 
         void canvasSizeChanged();
     };
index 581aac5..c4479b5 100644 (file)
@@ -177,36 +177,8 @@ void RenderImage::resetAnimation()
     }
 }
 
-void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
+void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 {
-    if (!shouldPaint(paintInfo, tx, ty))
-        return;
-
-    tx += m_x;
-    ty += m_y;
-        
-    if (hasBoxDecorations() && paintInfo.phase != PaintPhaseOutline && paintInfo.phase != PaintPhaseSelfOutline) 
-        paintBoxDecorations(paintInfo, tx, ty);
-
-    GraphicsContext* context = paintInfo.context;
-
-    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
-        paintOutline(context, tx, ty, width(), height(), style());
-
-    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
-        return;
-
-    if (!shouldPaintWithinRoot(paintInfo))
-        return;
-        
-    bool isPrinting = document()->printing();
-    bool drawSelectionTint = isSelected() && !isPrinting;
-    if (paintInfo.phase == PaintPhaseSelection) {
-        if (selectionState() == SelectionNone)
-            return;
-        drawSelectionTint = false;
-    }
-        
     int cWidth = contentWidth();
     int cHeight = contentHeight();
     int leftBorder = borderLeft();
@@ -214,9 +186,11 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
     int leftPad = paddingLeft();
     int topPad = paddingTop();
 
-    if (isPrinting && !view()->printImages())
+    if (document()->printing() && !view()->printImages())
         return;
 
+    GraphicsContext* context = paintInfo.context;
+
     if (!m_cachedImage || errorOccurred()) {
         if (paintInfo.phase == PaintPhaseSelection)
             return;
@@ -283,35 +257,11 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
         CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
         context->drawImage(image(), rect, compositeOperator, document()->page()->inLowQualityImageInterpolationMode());
     }
-
-    // draw the selection tint even if the image itself is not available
-    if (drawSelectionTint)
-        context->fillRect(selectionRect(), selectionBackgroundColor());
 }
 
-void RenderImage::layout()
+int RenderImage::minimumReplacedHeight() const
 {
-    ASSERT(needsLayout());
-
-    IntRect oldBounds;
-    IntRect oldOutlineBox;
-    bool checkForRepaint = checkForRepaintDuringLayout();
-    if (checkForRepaint) {
-        oldBounds = absoluteClippedOverflowRect();
-        oldOutlineBox = absoluteOutlineBox();
-    }
-
-    // minimum height
-    m_height = errorOccurred() ? intrinsicSize().height() : 0;
-
-    calcWidth();
-    calcHeight();
-    adjustOverflowForBoxShadow();
-
-    if (checkForRepaint)
-        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
-    
-    setNeedsLayout(false);
+    return errorOccurred() ? intrinsicSize().height() : 0;
 }
 
 HTMLMapElement* RenderImage::imageMap()
index 7139b27..7b63b06 100644 (file)
@@ -41,9 +41,9 @@ public:
 
     virtual bool isImage() const { return true; }
     
-    virtual void paint(PaintInfo&, int tx, int ty);
+    virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty);
 
-    virtual void layout();
+    virtual int minimumReplacedHeight() const;
 
     virtual void imageChanged(CachedImage*);
     
index 48a6633..fcc433b 100644 (file)
@@ -55,12 +55,16 @@ static const double cTimeUpdateRepeatDelay = 0.2;
 static const double cOpacityAnimationRepeatDelay = 0.05;
 // FIXME get this from style
 static const double cOpacityAnimationDuration = 0.5;
-    
+
+class RenderMediaControlShadowRoot : public RenderBlock {
+public:
+    RenderMediaControlShadowRoot(Element* e) : RenderBlock(e) { }
+    void setParent(RenderObject* p) { RenderObject::setParent(p); }
+};
+
 class MediaControlShadowRootElement : public HTMLDivElement {
 public:
-    MediaControlShadowRootElement(Document* doc, HTMLMediaElement* mediaElement) 
-        : HTMLDivElement(doc)
-        , m_mediaElement(mediaElement) { }
+    MediaControlShadowRootElement(Document* doc, HTMLMediaElement* mediaElement);
     
     virtual bool isShadowNode() const { return true; }
     virtual Node* shadowParentNode() { return m_mediaElement; }
@@ -69,6 +73,21 @@ private:
     HTMLMediaElement* m_mediaElement;    
 };
     
+MediaControlShadowRootElement::MediaControlShadowRootElement(Document* doc, HTMLMediaElement* mediaElement) 
+    : HTMLDivElement(doc)
+    , m_mediaElement(mediaElement) 
+{
+    RenderStyle* rootStyle = new (mediaElement->renderer()->renderArena()) RenderStyle();
+    rootStyle->setDisplay(BLOCK);
+    rootStyle->setPosition(AbsolutePosition);
+    RenderMediaControlShadowRoot* renderer = new (mediaElement->renderer()->renderArena()) RenderMediaControlShadowRoot(this);
+    renderer->setParent(mediaElement->renderer());
+    renderer->setStyle(rootStyle);
+    setRenderer(renderer);
+    setAttached();
+    setInDocument(true);
+}
+    
 // ----------------------------
 
 class MediaControlInputElement : public HTMLInputElement {
@@ -172,7 +191,7 @@ void MediaControlTimelineElement::update(bool updateDuration)
 // ----------------------------
 
 RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
-    : RenderBlock(video)
+    : RenderReplaced(video)
     , m_controlsShadowRoot(0)
     , m_panel(0)
     , m_playButton(0)
@@ -184,13 +203,15 @@ RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
     , m_opacityAnimationStartTime(0)
     , m_opacityAnimationFrom(0)
     , m_opacityAnimationTo(1.0f)
-    , m_intrinsicSize(intrinsicSize)
 {
-    setReplaced();
 }
 
 RenderMedia::~RenderMedia()
 {
+    if (m_controlsShadowRoot && m_controlsShadowRoot->renderer()) {
+        static_cast<RenderMediaControlShadowRoot*>(m_controlsShadowRoot->renderer())->setParent(0);
+        m_controlsShadowRoot->detach();
+    }
 }
  
 HTMLMediaElement* RenderMedia::mediaElement() const
@@ -203,27 +224,46 @@ Movie* RenderMedia::movie() const
     return mediaElement()->movie();
 }
 
-void RenderMedia::setStyle(RenderStyle* newStyle)
+void RenderMedia::layout()
 {
-    RenderBlock::setStyle(newStyle);
-    setReplaced();
+    IntSize oldSize = contentBox().size();
+
+    RenderReplaced::layout();
+
+    RenderObject* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0;
+    if (!controlsRenderer)
+        return;
+    IntSize newSize = contentBox().size();
+    if (newSize != oldSize || controlsRenderer->needsLayout()) {
+        controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
+        controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed));
+        controlsRenderer->setNeedsLayout(true, false);
+        controlsRenderer->layout();
+        setChildNeedsLayout(false);
+    }
+}
+
+RenderObject* RenderMedia::firstChild() const 
+{ 
+    return m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0; 
 }
 
+RenderObject* RenderMedia::lastChild() const 
+{ 
+    return m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0;
+}
+    
+void RenderMedia::removeChild(RenderObject* child)
+{
+    ASSERT(m_controlsShadowRoot);
+    ASSERT(child == m_controlsShadowRoot->renderer());
+    child->removeLayers(enclosingLayer());
+}
+    
 void RenderMedia::createControlsShadowRoot()
 {
     ASSERT(!m_controlsShadowRoot);
     m_controlsShadowRoot = new MediaControlShadowRootElement(document(), mediaElement());
-    RenderStyle* rootStyle = new (renderArena()) RenderStyle();
-    rootStyle->setDisplay(BLOCK);
-    rootStyle->setPosition(RelativePosition);
-    rootStyle->setHeight(Length(100.0, Percent));
-    RenderObject* renderer = m_controlsShadowRoot->createRenderer(renderArena(), rootStyle);
-    m_controlsShadowRoot->setRenderer(renderer);
-    renderer->setStyle(rootStyle);
-    renderer->updateFromElement();
-    m_controlsShadowRoot->setAttached();
-    m_controlsShadowRoot->setInDocument(true);
-    addChild(renderer);
 }
 
 void RenderMedia::createPanel()
index e232a0a..67e6c38 100644 (file)
@@ -28,7 +28,7 @@
 
 #if ENABLE(VIDEO)
 
-#include "RenderBlock.h"
+#include "RenderReplaced.h"
 #include "Timer.h"
 
 namespace WebCore {
@@ -39,21 +39,19 @@ class MediaControlPlayButtonElement;
 class MediaControlTimelineElement;
 class Movie;
 
-class RenderMedia : public RenderBlock {
+class RenderMedia : public RenderReplaced {
 public:
     RenderMedia(HTMLMediaElement*, const IntSize& intrinsicSize);
     virtual ~RenderMedia();
     
-    virtual void setStyle(RenderStyle* newStyle);
+    virtual RenderObject* firstChild() const;
+    virtual RenderObject* lastChild() const;
+    virtual void removeChild(RenderObject*);
     
-    virtual bool canHaveChildren() const { return false; }
-    
-    virtual bool shouldCalculateSizeAsReplaced() const { return true; }
+    virtual void layout();
 
     virtual const char* renderName() const { return "RenderMedia"; }
     virtual bool isMedia() const { return true; }
-
-    virtual IntSize intrinsicSize() const { return m_intrinsicSize; }
     
     HTMLMediaElement* mediaElement() const;
     Movie* movie() const;
@@ -66,8 +64,6 @@ public:
     
     void forwardEvent(Event*);
     
-    void setIntrinsicSize(IntSize size) { m_intrinsicSize = size; }
-    
 private:
     void createControlsShadowRoot();
     void createPanel();
@@ -94,7 +90,6 @@ private:
     double m_opacityAnimationStartTime;
     float m_opacityAnimationFrom;
     float m_opacityAnimationTo;
-    IntSize m_intrinsicSize;
 };
 
 } // namespace WebCore
index dce692b..32d6332 100644 (file)
@@ -23,6 +23,7 @@
 #include "config.h"
 #include "RenderReplaced.h"
 
+#include "GraphicsContext.h"
 #include "RenderBlock.h"
 #include "RenderLayer.h"
 
@@ -56,6 +57,63 @@ RenderReplaced::~RenderReplaced()
     if (m_hasOverflow)
         gOverflowRectMap->remove(this);
 }
+    
+void RenderReplaced::layout()
+{
+    ASSERT(needsLayout());
+    
+    IntRect oldBounds;
+    IntRect oldOutlineBox;
+    bool checkForRepaint = checkForRepaintDuringLayout();
+    if (checkForRepaint) {
+        oldBounds = absoluteClippedOverflowRect();
+        oldOutlineBox = absoluteOutlineBox();
+    }
+    
+    m_height = minimumReplacedHeight();
+    
+    calcWidth();
+    calcHeight();
+    adjustOverflowForBoxShadow();
+    
+    if (checkForRepaint)
+        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+    
+    setNeedsLayout(false);
+}
+    
+void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
+{
+    if (!shouldPaint(paintInfo, tx, ty))
+        return;
+    
+    tx += m_x;
+    ty += m_y;
+    
+    if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) 
+        paintBoxDecorations(paintInfo, tx, ty);
+    
+    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
+        paintOutline(paintInfo.context, tx, ty, width(), height(), style());
+    
+    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
+        return;
+    
+    if (!shouldPaintWithinRoot(paintInfo))
+        return;
+    
+    bool drawSelectionTint = selectionState() != SelectionNone && !document()->printing();
+    if (paintInfo.phase == PaintPhaseSelection) {
+        if (selectionState() == SelectionNone)
+            return;
+        drawSelectionTint = false;
+    }
+
+    paintReplaced(paintInfo, tx, ty);
+    
+    if (drawSelectionTint)
+        paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor());
+}
 
 bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, int& tx, int& ty)
 {
index 7b15a8f..3e96960 100644 (file)
@@ -38,8 +38,12 @@ public:
     virtual short baselinePosition(bool firstLine, bool isRootLineBox = false) const;
 
     virtual void calcPrefWidths();
+    
+    virtual void layout();
+    virtual int minimumReplacedHeight() const { return 0; }
 
-    virtual void paint(PaintInfo&, int tx, int ty) = 0;
+    virtual void paint(PaintInfo&, int tx, int ty);
+    virtual void paintReplaced(PaintInfo&, int tx, int ty) { }
 
     virtual IntSize intrinsicSize() const;
 
index 5275b2a..639bc32 100644 (file)
@@ -61,40 +61,24 @@ void RenderVideo::videoSizeChanged()
     IntSize size = movie()->naturalSize();
     if (size != intrinsicSize()) {
         setIntrinsicSize(size);
-        
-        int oldWidth = width();
-        int oldHeight = height();
-        
-        calcWidth();
-        calcHeight();
-        
-        if (oldWidth != m_width || oldHeight != m_height) {
-            setPrefWidthsDirty(true);
-            setNeedsLayout(true);
-        }
+        setPrefWidthsDirty(true);
+        setNeedsLayout(true);
     }
 }
 
-void RenderVideo::paintObject(PaintInfo& paintInfo, int tx, int ty)
+void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 {
-    if (style()->visibility() != VISIBLE)
-        return;
-
-    if (paintInfo.phase == PaintPhaseForeground && movie() && !document()->printing()) {
+    if (Movie* video = movie()) {
         updateMovie();
-            
         IntRect rect = contentBox();
         rect.move(tx, ty);
-        movie()->paint(paintInfo.context, rect);
+        video->paint(paintInfo.context, rect);
     }
-    
-    // Paint the children.
-    RenderBlock::paintObject(paintInfo, tx, ty);
 }
 
 void RenderVideo::layout()
 {
-    RenderBlock::layout();
+    RenderMedia::layout();
     updateMovie();
 }
     
index e227b83..aa2d58b 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     virtual const char* renderName() const { return "RenderVideo"; }
 
-    virtual void paintObject(PaintInfo&, int tx, int ty);
+    virtual void paintReplaced(PaintInfo& paintInfo, int tx, int ty);
 
     virtual void layout();