WebCore/html/HTMLVideoElement.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 "Attribute.h"
       
    32 #include "CSSHelper.h"
       
    33 #include "CSSPropertyNames.h"
       
    34 #include "Chrome.h"
       
    35 #include "ChromeClient.h"
       
    36 #include "Document.h"
       
    37 #include "ExceptionCode.h"
       
    38 #include "HTMLImageLoader.h"
       
    39 #include "HTMLNames.h"
       
    40 #include "Page.h"
       
    41 #include "RenderImage.h"
       
    42 #include "RenderVideo.h"
       
    43 
       
    44 namespace WebCore {
       
    45 
       
    46 using namespace HTMLNames;
       
    47 
       
    48 inline HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* document)
       
    49     : HTMLMediaElement(tagName, document)
       
    50     , m_shouldDisplayPosterImage(false)
       
    51 {
       
    52     ASSERT(hasTagName(videoTag));
       
    53 }
       
    54 
       
    55 PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(const QualifiedName& tagName, Document* document)
       
    56 {
       
    57     return adoptRef(new HTMLVideoElement(tagName, document));
       
    58 }
       
    59 
       
    60 bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style) 
       
    61 {
       
    62     return HTMLElement::rendererIsNeeded(style); 
       
    63 }
       
    64 
       
    65 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
       
    66 RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
       
    67 {
       
    68     return new (arena) RenderVideo(this);
       
    69 }
       
    70 #endif
       
    71 
       
    72 void HTMLVideoElement::attach()
       
    73 {
       
    74     HTMLMediaElement::attach();
       
    75 
       
    76 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
       
    77     updatePosterImage();
       
    78     if (m_shouldDisplayPosterImage) {
       
    79         if (!m_imageLoader)
       
    80             m_imageLoader.set(new HTMLImageLoader(this));
       
    81         m_imageLoader->updateFromElement();
       
    82         if (renderer()) {
       
    83             RenderImage* imageRenderer = toRenderImage(renderer());
       
    84             imageRenderer->setCachedImage(m_imageLoader->image()); 
       
    85         }
       
    86     }
       
    87 #endif
       
    88 }
       
    89 
       
    90 void HTMLVideoElement::detach()
       
    91 {
       
    92     HTMLMediaElement::detach();
       
    93     
       
    94     if (!m_shouldDisplayPosterImage)
       
    95         if (m_imageLoader)
       
    96             m_imageLoader.clear();
       
    97 }
       
    98 
       
    99 void HTMLVideoElement::parseMappedAttribute(Attribute* attr)
       
   100 {
       
   101     const QualifiedName& attrName = attr->name();
       
   102 
       
   103     if (attrName == posterAttr) {
       
   104         m_posterURL = getNonEmptyURLAttribute(posterAttr);
       
   105         updatePosterImage();
       
   106         if (m_shouldDisplayPosterImage) {
       
   107 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
       
   108             if (!m_imageLoader)
       
   109                 m_imageLoader.set(new HTMLImageLoader(this));
       
   110             m_imageLoader->updateFromElementIgnoringPreviousError();
       
   111 #else
       
   112             if (player())
       
   113                 player()->setPoster(poster());
       
   114 #endif
       
   115         }
       
   116     } else if (attrName == widthAttr)
       
   117         addCSSLength(attr, CSSPropertyWidth, attr->value());
       
   118     else if (attrName == heightAttr)
       
   119         addCSSLength(attr, CSSPropertyHeight, attr->value());
       
   120     else
       
   121         HTMLMediaElement::parseMappedAttribute(attr);
       
   122 }
       
   123 
       
   124 bool HTMLVideoElement::supportsFullscreen() const
       
   125 {
       
   126     Page* page = document() ? document()->page() : 0;
       
   127     if (!page) 
       
   128         return false;
       
   129 
       
   130     if (!player() || !player()->supportsFullscreen() || !player()->hasVideo())
       
   131         return false;
       
   132 
       
   133     // Check with the platform client.
       
   134     return page->chrome()->client()->supportsFullscreenForNode(this);
       
   135 }
       
   136 
       
   137 unsigned HTMLVideoElement::videoWidth() const
       
   138 {
       
   139     if (!player())
       
   140         return 0;
       
   141     return player()->naturalSize().width();
       
   142 }
       
   143 
       
   144 unsigned HTMLVideoElement::videoHeight() const
       
   145 {
       
   146     if (!player())
       
   147         return 0;
       
   148     return player()->naturalSize().height();
       
   149 }
       
   150 
       
   151 unsigned HTMLVideoElement::width() const
       
   152 {
       
   153     bool ok;
       
   154     unsigned w = getAttribute(widthAttr).string().toUInt(&ok);
       
   155     return ok ? w : 0;
       
   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 bool HTMLVideoElement::isURLAttribute(Attribute* attribute) const
       
   166 {
       
   167     return HTMLMediaElement::isURLAttribute(attribute)
       
   168         || attribute->name() == posterAttr;
       
   169 }
       
   170 
       
   171 const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
       
   172 {
       
   173     return posterAttr;
       
   174 }
       
   175 
       
   176 void HTMLVideoElement::updatePosterImage()
       
   177 {
       
   178 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
       
   179     bool oldShouldShowPosterImage = m_shouldDisplayPosterImage;
       
   180 #endif
       
   181 
       
   182     m_shouldDisplayPosterImage = !poster().isEmpty() && !hasAvailableVideoFrame();
       
   183 
       
   184 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
       
   185     if (renderer() && oldShouldShowPosterImage != m_shouldDisplayPosterImage)
       
   186         renderer()->updateFromElement();
       
   187 #endif
       
   188 }
       
   189 
       
   190 void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
       
   191 {
       
   192     MediaPlayer* player = HTMLMediaElement::player();
       
   193     if (!player)
       
   194         return;
       
   195     
       
   196     player->setVisible(true); // Make player visible or it won't draw.
       
   197     player->paintCurrentFrameInContext(context, destRect);
       
   198 }
       
   199 
       
   200 bool HTMLVideoElement::hasAvailableVideoFrame() const
       
   201 {
       
   202     if (!player())
       
   203         return false;
       
   204     
       
   205     return player()->hasAvailableVideoFrame();
       
   206 }
       
   207 
       
   208 void HTMLVideoElement::webkitEnterFullscreen(bool isUserGesture, ExceptionCode& ec)
       
   209 {
       
   210     if (isFullscreen())
       
   211         return;
       
   212 
       
   213     // Generate an exception if this isn't called in response to a user gesture, or if the 
       
   214     // element does not support fullscreen.
       
   215     if (!isUserGesture || !supportsFullscreen()) {
       
   216         ec = INVALID_STATE_ERR;
       
   217         return;
       
   218     }
       
   219 
       
   220     enterFullscreen();
       
   221 }
       
   222 
       
   223 void HTMLVideoElement::webkitExitFullscreen()
       
   224 {
       
   225     if (isFullscreen())
       
   226         exitFullscreen();
       
   227 }
       
   228 
       
   229 bool HTMLVideoElement::webkitSupportsFullscreen()
       
   230 {
       
   231     return supportsFullscreen();
       
   232 }
       
   233 
       
   234 bool HTMLVideoElement::webkitDisplayingFullscreen()
       
   235 {
       
   236     return isFullscreen();
       
   237 }
       
   238 
       
   239 void HTMLVideoElement::willMoveToNewOwnerDocument()
       
   240 {
       
   241     if (m_imageLoader)
       
   242         m_imageLoader->elementWillMoveToNewOwnerDocument();
       
   243     HTMLMediaElement::willMoveToNewOwnerDocument();
       
   244 }
       
   245 
       
   246 }
       
   247 
       
   248 #endif