Home | History | Annotate | Download | only in html
      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 
     48 HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc)
     49     : HTMLMediaElement(tagName, doc)
     50     , m_shouldDisplayPosterImage(false)
     51 {
     52     ASSERT(hasTagName(videoTag));
     53 }
     54 
     55 bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
     56 {
     57     return HTMLElement::rendererIsNeeded(style);
     58 }
     59 
     60 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
     61 RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
     62 {
     63     return new (arena) RenderVideo(this);
     64 }
     65 #endif
     66 
     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 
     85 void HTMLVideoElement::detach()
     86 {
     87     HTMLMediaElement::detach();
     88 
     89     if (!m_shouldDisplayPosterImage)
     90         if (m_imageLoader)
     91             m_imageLoader.clear();
     92 }
     93 
     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 
    119 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 
    132 unsigned HTMLVideoElement::videoWidth() const
    133 {
    134     if (!m_player)
    135         return 0;
    136     return m_player->naturalSize().width();
    137 }
    138 
    139 unsigned HTMLVideoElement::videoHeight() const
    140 {
    141     if (!m_player)
    142         return 0;
    143     return m_player->naturalSize().height();
    144 }
    145 
    146 unsigned HTMLVideoElement::width() const
    147 {
    148     bool ok;
    149     unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
    150     return ok ? w : 0;
    151 }
    152 
    153 void HTMLVideoElement::setWidth(unsigned value)
    154 {
    155     setAttribute(widthAttr, String::number(value));
    156 }
    157 
    158 unsigned HTMLVideoElement::height() const
    159 {
    160     bool ok;
    161     unsigned h = getAttribute(heightAttr).string().toUInt(&ok);
    162     return ok ? h : 0;
    163 }
    164 
    165 void HTMLVideoElement::setHeight(unsigned value)
    166 {
    167     setAttribute(heightAttr, String::number(value));
    168 }
    169 
    170 void HTMLVideoElement::setPoster(const String& value)
    171 {
    172     setAttribute(posterAttr, value);
    173 }
    174 
    175 bool HTMLVideoElement::isURLAttribute(Attribute* attr) const
    176 {
    177     return attr->name() == posterAttr;
    178 }
    179 
    180 const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
    181 {
    182     return posterAttr;
    183 }
    184 
    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 
    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 
    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 
    219 bool HTMLVideoElement::hasAvailableVideoFrame() const
    220 {
    221     if (!m_player)
    222         return false;
    223 
    224     return m_player->hasAvailableVideoFrame();
    225 }
    226 
    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 
    242 void HTMLVideoElement::webkitExitFullScreen()
    243 {
    244     if (m_isFullscreen)
    245         exitFullscreen();
    246 }
    247 
    248 bool HTMLVideoElement::webkitSupportsFullscreen()
    249 {
    250     return supportsFullscreen();
    251 }
    252 
    253 bool HTMLVideoElement::webkitDisplayingFullscreen()
    254 {
    255     return m_isFullscreen;
    256 }
    257 
    258 
    259 }
    260 #endif
    261