Rubber-stamped by Brady Eidson.
[webbrowser.git] / WebCore / html / HTMLVideoElement.cpp
blobd0b10426ac9efe9375718a0bf7cf76e46f5f2797
1 /*
2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "config.h"
28 #if ENABLE(VIDEO)
29 #include "HTMLVideoElement.h"
31 #include "ChromeClient.h"
32 #include "CSSHelper.h"
33 #include "CSSPropertyNames.h"
34 #include "Document.h"
35 #include "HTMLImageLoader.h"
36 #include "HTMLNames.h"
37 #include "MappedAttribute.h"
38 #include "Page.h"
39 #include "RenderImage.h"
40 #include "RenderVideo.h"
42 namespace WebCore {
44 using namespace HTMLNames;
46 HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc)
47 : HTMLMediaElement(tagName, doc)
48 , m_shouldShowPosterImage(false)
50 ASSERT(hasTagName(videoTag));
53 bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
55 return HTMLElement::rendererIsNeeded(style);
58 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
59 RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
61 if (m_shouldShowPosterImage)
62 return new (arena) RenderImage(this);
63 return new (arena) RenderVideo(this);
65 #endif
67 void HTMLVideoElement::attach()
69 HTMLMediaElement::attach();
71 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
72 if (m_shouldShowPosterImage) {
73 if (!m_imageLoader)
74 m_imageLoader.set(new HTMLImageLoader(this));
75 m_imageLoader->updateFromElement();
76 if (renderer() && renderer()->isImage()) {
77 RenderImage* imageRenderer = toRenderImage(renderer());
78 imageRenderer->setCachedImage(m_imageLoader->image());
81 #endif
84 void HTMLVideoElement::detach()
86 HTMLMediaElement::detach();
88 if (!m_shouldShowPosterImage)
89 if (m_imageLoader)
90 m_imageLoader.clear();
93 void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
95 const QualifiedName& attrName = attr->name();
97 if (attrName == posterAttr) {
98 updatePosterImage();
99 if (m_shouldShowPosterImage) {
100 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
101 if (!m_imageLoader)
102 m_imageLoader.set(new HTMLImageLoader(this));
103 m_imageLoader->updateFromElementIgnoringPreviousError();
104 #else
105 if (m_player)
106 m_player->setPoster(poster());
107 #endif
109 } else if (attrName == widthAttr)
110 addCSSLength(attr, CSSPropertyWidth, attr->value());
111 else if (attrName == heightAttr)
112 addCSSLength(attr, CSSPropertyHeight, attr->value());
113 else
114 HTMLMediaElement::parseMappedAttribute(attr);
117 bool HTMLVideoElement::supportsFullscreen() const
119 Page* page = document() ? document()->page() : 0;
120 if (!page)
121 return false;
123 if (!m_player || !m_player->supportsFullscreen() || !m_player->hasVideo())
124 return false;
126 // Check with the platform client.
127 return page->chrome()->client()->supportsFullscreenForNode(this);
130 unsigned HTMLVideoElement::videoWidth() const
132 if (!m_player)
133 return 0;
134 return m_player->naturalSize().width();
137 unsigned HTMLVideoElement::videoHeight() const
139 if (!m_player)
140 return 0;
141 return m_player->naturalSize().height();
144 unsigned HTMLVideoElement::width() const
146 bool ok;
147 unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
148 return ok ? w : 0;
151 void HTMLVideoElement::setWidth(unsigned value)
153 setAttribute(widthAttr, String::number(value));
156 unsigned HTMLVideoElement::height() const
158 bool ok;
159 unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
160 return ok ? h : 0;
163 void HTMLVideoElement::setHeight(unsigned value)
165 setAttribute(heightAttr, String::number(value));
168 KURL HTMLVideoElement::poster() const
170 return document()->completeURL(getAttribute(posterAttr));
173 void HTMLVideoElement::setPoster(const String& value)
175 setAttribute(posterAttr, value);
178 bool HTMLVideoElement::isURLAttribute(Attribute* attr) const
180 return attr->name() == posterAttr;
183 const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
185 return posterAttr;
188 void HTMLVideoElement::updatePosterImage()
190 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
191 bool oldShouldShowPosterImage = m_shouldShowPosterImage;
192 #endif
194 m_shouldShowPosterImage = !poster().isEmpty() && readyState() < HAVE_CURRENT_DATA;
196 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
197 if (attached() && oldShouldShowPosterImage != m_shouldShowPosterImage) {
198 detach();
199 attach();
201 #endif
204 void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& destRect)
206 // FIXME: We should also be able to paint the poster image.
208 MediaPlayer* player = HTMLMediaElement::player();
209 if (!player)
210 return;
212 player->setVisible(true); // Make player visible or it won't draw.
213 player->paint(context, destRect);
216 void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
218 // FIXME: We should also be able to paint the poster image.
220 MediaPlayer* player = HTMLMediaElement::player();
221 if (!player)
222 return;
224 player->setVisible(true); // Make player visible or it won't draw.
225 player->paintCurrentFrameInContext(context, destRect);
229 #endif