• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008, 2009 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 "CSSHelper.h"
32 #include "CSSPropertyNames.h"
33 #include "Document.h"
34 #include "HTMLImageLoader.h"
35 #include "HTMLNames.h"
36 #include "MappedAttribute.h"
37 #include "RenderImage.h"
38 #include "RenderVideo.h"
39 
40 namespace WebCore {
41 
42 using namespace HTMLNames;
43 
HTMLVideoElement(const QualifiedName & tagName,Document * doc)44 HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc)
45     : HTMLMediaElement(tagName, doc)
46     , m_shouldShowPosterImage(false)
47 {
48     ASSERT(hasTagName(videoTag));
49 }
50 
rendererIsNeeded(RenderStyle * style)51 bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
52 {
53     return HTMLElement::rendererIsNeeded(style);
54 }
55 
56 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
createRenderer(RenderArena * arena,RenderStyle *)57 RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
58 {
59     if (m_shouldShowPosterImage)
60         return new (arena) RenderImage(this);
61     return new (arena) RenderVideo(this);
62 }
63 #endif
64 
attach()65 void HTMLVideoElement::attach()
66 {
67     HTMLMediaElement::attach();
68 
69 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
70     if (m_shouldShowPosterImage) {
71         if (!m_imageLoader)
72             m_imageLoader.set(new HTMLImageLoader(this));
73         m_imageLoader->updateFromElement();
74         if (renderer() && renderer()->isImage()) {
75             RenderImage* imageRenderer = toRenderImage(renderer());
76             imageRenderer->setCachedImage(m_imageLoader->image());
77         }
78     }
79 #endif
80 }
81 
detach()82 void HTMLVideoElement::detach()
83 {
84     HTMLMediaElement::detach();
85 
86     if (!m_shouldShowPosterImage)
87         if (m_imageLoader)
88             m_imageLoader.clear();
89 }
90 
parseMappedAttribute(MappedAttribute * attr)91 void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
92 {
93     const QualifiedName& attrName = attr->name();
94 
95     if (attrName == posterAttr) {
96         updatePosterImage();
97         if (m_shouldShowPosterImage) {
98 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
99             if (!m_imageLoader)
100                 m_imageLoader.set(new HTMLImageLoader(this));
101             m_imageLoader->updateFromElementIgnoringPreviousError();
102 #else
103             if (m_player)
104                 m_player->setPoster(poster());
105 #endif
106         }
107     } else if (attrName == widthAttr)
108         addCSSLength(attr, CSSPropertyWidth, attr->value());
109     else if (attrName == heightAttr)
110         addCSSLength(attr, CSSPropertyHeight, attr->value());
111     else
112         HTMLMediaElement::parseMappedAttribute(attr);
113 }
114 
videoWidth() const115 unsigned HTMLVideoElement::videoWidth() const
116 {
117     if (!m_player)
118         return 0;
119     return m_player->naturalSize().width();
120 }
121 
videoHeight() const122 unsigned HTMLVideoElement::videoHeight() const
123 {
124     if (!m_player)
125         return 0;
126     return m_player->naturalSize().height();
127 }
128 
width() const129 unsigned HTMLVideoElement::width() const
130 {
131     bool ok;
132     unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
133     return ok ? w : 0;
134 }
135 
setWidth(unsigned value)136 void HTMLVideoElement::setWidth(unsigned value)
137 {
138     setAttribute(widthAttr, String::number(value));
139 }
140 
height() const141 unsigned HTMLVideoElement::height() const
142 {
143     bool ok;
144     unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
145     return ok ? h : 0;
146 }
147 
setHeight(unsigned value)148 void HTMLVideoElement::setHeight(unsigned value)
149 {
150     setAttribute(heightAttr, String::number(value));
151 }
152 
poster() const153 KURL HTMLVideoElement::poster() const
154 {
155     return document()->completeURL(getAttribute(posterAttr));
156 }
157 
setPoster(const String & value)158 void HTMLVideoElement::setPoster(const String& value)
159 {
160     setAttribute(posterAttr, value);
161 }
162 
isURLAttribute(Attribute * attr) const163 bool HTMLVideoElement::isURLAttribute(Attribute* attr) const
164 {
165     return attr->name() == posterAttr;
166 }
167 
imageSourceAttributeName() const168 const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
169 {
170     return posterAttr;
171 }
172 
updatePosterImage()173 void HTMLVideoElement::updatePosterImage()
174 {
175 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
176     bool oldShouldShowPosterImage = m_shouldShowPosterImage;
177 #endif
178 
179     m_shouldShowPosterImage = !poster().isEmpty() && readyState() < HAVE_CURRENT_DATA;
180 
181 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
182     if (attached() && oldShouldShowPosterImage != m_shouldShowPosterImage) {
183         detach();
184         attach();
185     }
186 #endif
187 }
188 
paint(GraphicsContext * context,const IntRect & destRect)189 void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& destRect)
190 {
191     // FIXME: We should also be able to paint the poster image.
192 
193     MediaPlayer* player = HTMLMediaElement::player();
194     if (!player)
195         return;
196 
197     player->setVisible(true); // Make player visible or it won't draw.
198     player->paint(context, destRect);
199 }
200 
paintCurrentFrameInContext(GraphicsContext * context,const IntRect & destRect)201 void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
202 {
203     // FIXME: We should also be able to paint the poster image.
204 
205     MediaPlayer* player = HTMLMediaElement::player();
206     if (!player)
207         return;
208 
209     player->setVisible(true); // Make player visible or it won't draw.
210     player->paintCurrentFrameInContext(context, destRect);
211 }
212 
213 }
214 #endif
215