blob: 5bbc16747efd5290760298a9618b1d7384f730ce [file] [log] [blame]
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -08001/*
Ben Murdoch0bf48ef2009-08-11 17:01:47 +01002 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -08003 *
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.
12 *
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.
24 */
25
26#include "config.h"
27
28#if ENABLE(VIDEO)
29#include "HTMLVideoElement.h"
30
Steve Block231d4e32009-10-08 17:19:54 +010031#include "ChromeClient.h"
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080032#include "CSSHelper.h"
33#include "CSSPropertyNames.h"
34#include "Document.h"
35#include "HTMLImageLoader.h"
36#include "HTMLNames.h"
Feng Qian5f1ab042009-06-17 12:12:20 -070037#include "MappedAttribute.h"
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080038#include "RenderImage.h"
39#include "RenderVideo.h"
40
41namespace WebCore {
42
43using namespace HTMLNames;
44
The Android Open Source Project63586082009-03-05 14:34:32 -080045HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc)
46 : HTMLMediaElement(tagName, doc)
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080047 , m_shouldShowPosterImage(false)
48{
The Android Open Source Project63586082009-03-05 14:34:32 -080049 ASSERT(hasTagName(videoTag));
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080050}
51
52bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
53{
54 return HTMLElement::rendererIsNeeded(style);
55}
56
Feng Qian8f72e702009-04-10 18:11:29 -070057#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080058RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
59{
60 if (m_shouldShowPosterImage)
61 return new (arena) RenderImage(this);
62 return new (arena) RenderVideo(this);
63}
Feng Qian8f72e702009-04-10 18:11:29 -070064#endif
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080065
66void HTMLVideoElement::attach()
67{
68 HTMLMediaElement::attach();
Feng Qian8f72e702009-04-10 18:11:29 -070069
70#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080071 if (m_shouldShowPosterImage) {
72 if (!m_imageLoader)
73 m_imageLoader.set(new HTMLImageLoader(this));
74 m_imageLoader->updateFromElement();
75 if (renderer() && renderer()->isImage()) {
Feng Qian8f72e702009-04-10 18:11:29 -070076 RenderImage* imageRenderer = toRenderImage(renderer());
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080077 imageRenderer->setCachedImage(m_imageLoader->image());
78 }
79 }
Feng Qian8f72e702009-04-10 18:11:29 -070080#endif
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -080081}
82
83void HTMLVideoElement::detach()
84{
85 HTMLMediaElement::detach();
86
87 if (!m_shouldShowPosterImage)
88 if (m_imageLoader)
89 m_imageLoader.clear();
90}
91
92void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
93{
94 const QualifiedName& attrName = attr->name();
95
96 if (attrName == posterAttr) {
97 updatePosterImage();
98 if (m_shouldShowPosterImage) {
Feng Qian8f72e702009-04-10 18:11:29 -070099#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800100 if (!m_imageLoader)
101 m_imageLoader.set(new HTMLImageLoader(this));
The Android Open Source Project63586082009-03-05 14:34:32 -0800102 m_imageLoader->updateFromElementIgnoringPreviousError();
Feng Qian8f72e702009-04-10 18:11:29 -0700103#else
104 if (m_player)
105 m_player->setPoster(poster());
106#endif
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800107 }
108 } else if (attrName == widthAttr)
109 addCSSLength(attr, CSSPropertyWidth, attr->value());
110 else if (attrName == heightAttr)
111 addCSSLength(attr, CSSPropertyHeight, attr->value());
112 else
113 HTMLMediaElement::parseMappedAttribute(attr);
114}
115
Steve Block231d4e32009-10-08 17:19:54 +0100116bool HTMLVideoElement::supportsFullscreen() const
117{
118 Page* page = document() ? document()->page() : 0;
119 if (!page)
120 return false;
121
122 if (!m_player || !m_player->supportsFullscreen())
123 return false;
124
125 return page->chrome()->client()->supportsFullscreenForNode(this);
126}
127
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800128unsigned HTMLVideoElement::videoWidth() const
129{
130 if (!m_player)
131 return 0;
132 return m_player->naturalSize().width();
133}
134
135unsigned HTMLVideoElement::videoHeight() const
136{
137 if (!m_player)
138 return 0;
139 return m_player->naturalSize().height();
140}
141
142unsigned HTMLVideoElement::width() const
143{
144 bool ok;
145 unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
146 return ok ? w : 0;
147}
148
149void HTMLVideoElement::setWidth(unsigned value)
150{
151 setAttribute(widthAttr, String::number(value));
152}
153
154unsigned HTMLVideoElement::height() const
155{
156 bool ok;
157 unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
158 return ok ? h : 0;
159}
160
161void HTMLVideoElement::setHeight(unsigned value)
162{
163 setAttribute(heightAttr, String::number(value));
164}
165
166KURL HTMLVideoElement::poster() const
167{
168 return document()->completeURL(getAttribute(posterAttr));
169}
170
171void HTMLVideoElement::setPoster(const String& value)
172{
173 setAttribute(posterAttr, value);
174}
175
176bool HTMLVideoElement::isURLAttribute(Attribute* attr) const
177{
178 return attr->name() == posterAttr;
179}
180
181const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
182{
183 return posterAttr;
184}
185
186void HTMLVideoElement::updatePosterImage()
187{
Feng Qian8f72e702009-04-10 18:11:29 -0700188#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800189 bool oldShouldShowPosterImage = m_shouldShowPosterImage;
Feng Qian8f72e702009-04-10 18:11:29 -0700190#endif
191
192 m_shouldShowPosterImage = !poster().isEmpty() && readyState() < HAVE_CURRENT_DATA;
193
194#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800195 if (attached() && oldShouldShowPosterImage != m_shouldShowPosterImage) {
196 detach();
197 attach();
198 }
Feng Qian8f72e702009-04-10 18:11:29 -0700199#endif
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800200}
201
Ben Murdoch0bf48ef2009-08-11 17:01:47 +0100202void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& destRect)
203{
204 // FIXME: We should also be able to paint the poster image.
205
206 MediaPlayer* player = HTMLMediaElement::player();
207 if (!player)
208 return;
209
210 player->setVisible(true); // Make player visible or it won't draw.
211 player->paint(context, destRect);
212}
213
214void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
215{
216 // FIXME: We should also be able to paint the poster image.
217
218 MediaPlayer* player = HTMLMediaElement::player();
219 if (!player)
220 return;
221
222 player->setVisible(true); // Make player visible or it won't draw.
223 player->paintCurrentFrameInContext(context, destRect);
224}
225
The Android Open Source Project8e35f3c2009-03-03 19:30:52 -0800226}
227#endif