• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  *
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 
31 #include "Chrome.h"
32 #include "ChromeClient.h"
33 #include "CSSHelper.h"
34 #include "CSSPropertyNames.h"
35 #include "Document.h"
36 #include "ExceptionCode.h"
37 #include "HTMLImageLoader.h"
38 #include "HTMLNames.h"
39 #include "MappedAttribute.h"
40 #include "Page.h"
41 #include "RenderImage.h"
42 #include "RenderVideo.h"
43 
44 namespace WebCore {
45 
46 using namespace HTMLNames;
47 
HTMLVideoElement(const QualifiedName & tagName,Document * doc)48 HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc)
49     : HTMLMediaElement(tagName, doc)
50     , m_shouldDisplayPosterImage(false)
51 {
52     ASSERT(hasTagName(videoTag));
53 }
54 
rendererIsNeeded(RenderStyle * style)55 bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
56 {
57     return HTMLElement::rendererIsNeeded(style);
58 }
59 
60 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
createRenderer(RenderArena * arena,RenderStyle *)61 RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
62 {
63     return new (arena) RenderVideo(this);
64 }
65 #endif
66 
attach()67 void HTMLVideoElement::attach()
68 {
69     HTMLMediaElement::attach();
70 
71 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
72     updatePosterImage();
73     if (m_shouldDisplayPosterImage) {
74         if (!m_imageLoader)
75             m_imageLoader.set(new HTMLImageLoader(this));
76         m_imageLoader->updateFromElement();
77         if (renderer()) {
78             RenderImage* imageRenderer = toRenderImage(renderer());
79             imageRenderer->setCachedImage(m_imageLoader->image());
80         }
81     }
82 #endif
83 }
84 
detach()85 void HTMLVideoElement::detach()
86 {
87     HTMLMediaElement::detach();
88 
89     if (!m_shouldDisplayPosterImage)
90         if (m_imageLoader)
91             m_imageLoader.clear();
92 }
93 
parseMappedAttribute(MappedAttribute * attr)94 void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
95 {
96     const QualifiedName& attrName = attr->name();
97 
98     if (attrName == posterAttr) {
99         m_posterURL = document()->completeURL(attr->value());
100         updatePosterImage();
101         if (m_shouldDisplayPosterImage) {
102 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
103             if (!m_imageLoader)
104                 m_imageLoader.set(new HTMLImageLoader(this));
105             m_imageLoader->updateFromElementIgnoringPreviousError();
106 #else
107             if (m_player)
108                 m_player->setPoster(poster());
109 #endif
110         }
111     } else if (attrName == widthAttr)
112         addCSSLength(attr, CSSPropertyWidth, attr->value());
113     else if (attrName == heightAttr)
114         addCSSLength(attr, CSSPropertyHeight, attr->value());
115     else
116         HTMLMediaElement::parseMappedAttribute(attr);
117 }
118 
supportsFullscreen() const119 bool HTMLVideoElement::supportsFullscreen() const
120 {
121     Page* page = document() ? document()->page() : 0;
122     if (!page)
123         return false;
124 
125     if (!m_player || !m_player->supportsFullscreen() || !m_player->hasVideo())
126         return false;
127 
128     // Check with the platform client.
129     return page->chrome()->client()->supportsFullscreenForNode(this);
130 }
131 
videoWidth() const132 unsigned HTMLVideoElement::videoWidth() const
133 {
134     if (!m_player)
135         return 0;
136     return m_player->naturalSize().width();
137 }
138 
videoHeight() const139 unsigned HTMLVideoElement::videoHeight() const
140 {
141     if (!m_player)
142         return 0;
143     return m_player->naturalSize().height();
144 }
145 
width() const146 unsigned HTMLVideoElement::width() const
147 {
148     bool ok;
149     unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
150     return ok ? w : 0;
151 }
152 
setWidth(unsigned value)153 void HTMLVideoElement::setWidth(unsigned value)
154 {
155     setAttribute(widthAttr, String::number(value));
156 }
157 
height() const158 unsigned HTMLVideoElement::height() const
159 {
160     bool ok;
161     unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
162     return ok ? h : 0;
163 }
164 
setHeight(unsigned value)165 void HTMLVideoElement::setHeight(unsigned value)
166 {
167     setAttribute(heightAttr, String::number(value));
168 }
169 
setPoster(const String & value)170 void HTMLVideoElement::setPoster(const String& value)
171 {
172     setAttribute(posterAttr, value);
173 }
174 
isURLAttribute(Attribute * attr) const175 bool HTMLVideoElement::isURLAttribute(Attribute* attr) const
176 {
177     return attr->name() == posterAttr;
178 }
179 
imageSourceAttributeName() const180 const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
181 {
182     return posterAttr;
183 }
184 
updatePosterImage()185 void HTMLVideoElement::updatePosterImage()
186 {
187 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
188     bool oldShouldShowPosterImage = m_shouldDisplayPosterImage;
189 #endif
190 
191     m_shouldDisplayPosterImage = !poster().isEmpty() && !hasAvailableVideoFrame();
192 
193 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
194     if (renderer() && oldShouldShowPosterImage != m_shouldDisplayPosterImage)
195         renderer()->updateFromElement();
196 #endif
197 }
198 
paint(GraphicsContext * context,const IntRect & destRect)199 void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& destRect)
200 {
201     MediaPlayer* player = HTMLMediaElement::player();
202     if (!player)
203         return;
204 
205     player->setVisible(true); // Make player visible or it won't draw.
206     player->paint(context, destRect);
207 }
208 
paintCurrentFrameInContext(GraphicsContext * context,const IntRect & destRect)209 void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
210 {
211     MediaPlayer* player = HTMLMediaElement::player();
212     if (!player)
213         return;
214 
215     player->setVisible(true); // Make player visible or it won't draw.
216     player->paintCurrentFrameInContext(context, destRect);
217 }
218 
hasAvailableVideoFrame() const219 bool HTMLVideoElement::hasAvailableVideoFrame() const
220 {
221     if (!m_player)
222         return false;
223 
224     return m_player->hasAvailableVideoFrame();
225 }
226 
webkitEnterFullScreen(bool isUserGesture,ExceptionCode & ec)227 void HTMLVideoElement::webkitEnterFullScreen(bool isUserGesture, ExceptionCode& ec)
228 {
229     if (m_isFullscreen)
230         return;
231 
232     // Generate an exception if this isn't called in response to a user gesture, or if the
233     // element does not support fullscreen.
234     if (!isUserGesture || !supportsFullscreen()) {
235         ec = INVALID_STATE_ERR;
236         return;
237     }
238 
239     enterFullscreen();
240 }
241 
webkitExitFullScreen()242 void HTMLVideoElement::webkitExitFullScreen()
243 {
244     if (m_isFullscreen)
245         exitFullscreen();
246 }
247 
webkitSupportsFullscreen()248 bool HTMLVideoElement::webkitSupportsFullscreen()
249 {
250     return supportsFullscreen();
251 }
252 
webkitDisplayingFullscreen()253 bool HTMLVideoElement::webkitDisplayingFullscreen()
254 {
255     return m_isFullscreen;
256 }
257 
258 
259 }
260 #endif
261