Commit 25fd37ef authored by commit-queue@webkit.org's avatar commit-queue@webkit.org
Browse files

Add the default video poster if it doesn't exist in video tag

https://bugs.webkit.org/show_bug.cgi?id=110263

Patch by Tao Bai <michaelbai@chromium.org> on 2013-03-13
Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/video-default-poster.html
       media/video-no-default-poster.html

The Android web view application could provide the default poster
for a video that doesn't have the poster attribute.

To provide the default poster, the application must set defaultVideoPosterURL
setting and return the image in the response of that URL.

The way to do this would be:

A) Replace the Element::imageSourceAttributeName function with an
   Element::imageSourceURL function that returns the imageSourceURL as a
   const AtomicString&. The body will be the same as before, it will just also
   include a call to getAttribute. Also will need to revise the four classes
   that override that function.

B) Add a new HTMLVideoElement::posterImageURL function that implements the
   default poster URL logic.

C) Update the four functions that get the poster attribute to handle poster
   loading and display to call posterImageURL.

   1) HTMLVideoElement::imageSourceURL.
   2) HTMLVideoElement::setDisplayMode.
   3) HTMLVideoElement::updateDisplayState.
   4) HTMLMediaElement::getPluginProxyParams. Will need to cast to
      HTMLVideoElement after checking isVideo.

* dom/Element.cpp:
(WebCore::Element::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* dom/Element.h: Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLEmbedElement.h: Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::getPluginProxyParams): Change to use posterImageURL
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLObjectElement.h: Replace imageSourceAttributeName with imageSourceURL
* html/HTMLVideoElement.cpp:
(WebCore::HTMLVideoElement::HTMLVideoElement): set m_defaultPosterURL if there is such settings
(WebCore::HTMLVideoElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
(WebCore::HTMLVideoElement::setDisplayMode): Use imageSourceURL()
(WebCore::HTMLVideoElement::updateDisplayState): Use imageSourceURL()
(WebCore::HTMLVideoElement::posterImageURL): Return image source's KURL
* html/HTMLVideoElement.h: Replace imageSourceAttributeName() with imageSourceURL() and add m_defaultPosterURL
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement): Use imageSourceURL()
* page/Settings.in: Add defaultVideoPosterURL setting.
* platform/chromium/PasteboardChromium.cpp:
(WebCore::Pasteboard::writeImage): use imageSourceURL()
* platform/gtk/PasteboardGtk.cpp:
(WebCore::getURLForImageNode): use imageSourceURL()
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::absoluteImageURL): use imageSourceURL()
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* svg/SVGImageElement.h: Replace imageSourceAttributeName() with imageSourceURL()
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup): support backup defaultVideoPosterURL.
(WebCore::InternalSettings::Backup::restoreTo): support restore defaultVideoPosterURL.
(WebCore::InternalSettings::setDefaultVideoPosterURL): set defaultVideoPosterURL.
* testing/InternalSettings.h:
(Backup): support backup defaultVideoPosterURL.
(InternalSettings): Add setDefaultVidoePosterURL method.
* testing/InternalSettings.idl: Add setDefaultVideoPosterURL for test purpose.
* testing/Internals.cpp:
(WebCore::Internals::getImageSourceURL): Add getImageSourceURL method.
* testing/Internals.h: Add getImageSourceURL method.
* testing/Internals.idl: Add getImageSourceURL method.

LayoutTests:

The Android web view application could provide the default poster
for a video that doesn't have the poster attribute.

To provide the default poster, the application must set defaultVideoPosterURL
setting and return the image in the response of that URL.

The way to do this would be:

A) Replace the Element::imageSourceAttributeName function with an
   Element::imageSourceURL function that returns the imageSourceURL as a
   const AtomicString&. The body will be the same as before, it will just also
   include a call to getAttribute. Also will need to revise the four classes
   that override that function.

B) Add a new HTMLVideoElement::posterImageURL function that implements the
   default poster URL logic.

C) Update the four functions that get the poster attribute to handle poster
   loading and display to call posterImageURL.

   1) HTMLVideoElement::imageSourceURL.
   2) HTMLVideoElement::setDisplayMode.
   3) HTMLVideoElement::updateDisplayState.
   4) HTMLMediaElement::getPluginProxyParams. Will need to cast to
      HTMLVideoElement after checking isVideo.

* media/video-default-poster-expected.txt: Added.
* media/video-default-poster.html: Added.
* media/video-no-default-poster-expected.txt: Added.
* media/video-no-default-poster.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145750 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 4d7702d7
2013-03-13 Tao Bai <michaelbai@chromium.org>
Add the default video poster if it doesn't exist in video tag
https://bugs.webkit.org/show_bug.cgi?id=110263
Reviewed by Eric Carlson.
The Android web view application could provide the default poster
for a video that doesn't have the poster attribute.
To provide the default poster, the application must set defaultVideoPosterURL
setting and return the image in the response of that URL.
The way to do this would be:
A) Replace the Element::imageSourceAttributeName function with an
Element::imageSourceURL function that returns the imageSourceURL as a
const AtomicString&. The body will be the same as before, it will just also
include a call to getAttribute. Also will need to revise the four classes
that override that function.
B) Add a new HTMLVideoElement::posterImageURL function that implements the
default poster URL logic.
C) Update the four functions that get the poster attribute to handle poster
loading and display to call posterImageURL.
1) HTMLVideoElement::imageSourceURL.
2) HTMLVideoElement::setDisplayMode.
3) HTMLVideoElement::updateDisplayState.
4) HTMLMediaElement::getPluginProxyParams. Will need to cast to
HTMLVideoElement after checking isVideo.
* media/video-default-poster-expected.txt: Added.
* media/video-default-poster.html: Added.
* media/video-no-default-poster-expected.txt: Added.
* media/video-no-default-poster.html: Added.
2013-03-13 James Robinson <jamesr@chromium.org>
 
Force clip in fast/regions/autoheight-break-after-expected.html to match test
<!DOCTYPE html>
<html>
<head>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
if (window.internals) {
var default_poster = 'content/greenbox.png';
window.internals.settings.setDefaultVideoPosterURL(default_poster);
addEventListener("load", function() {
var poster = window.internals.getImageSourceURL(document.getElementById("video-no-poster"));
if (poster) {
if (poster == default_poster)
document.getElementById("result-no-poster").innerText = "PASS";
else
document.getElementById("result-no-poster").innerText = "FAIL";
} else
document.getElementById("result-no-poster").innerText = "FAIL: image source is null";
poster = window.internals.getImageSourceURL(document.getElementById("video-has-poster"));
if (poster) {
if (poster == "content/abe.png")
document.getElementById("result-has-poster").innerText = "PASS";
else
document.getElementById("result-has-poster").innerText = "FAIL: poster was changed";
} else
document.getElementById("result-has-poster").innerText = "FAIL: image source is null";
poster = window.internals.getImageSourceURL(document.getElementById("video-has-empty-poster"));
if (poster) {
if (poster == default_poster)
document.getElementById("result-has-empty-poster").innerText = "PASS";
else
document.getElementById("result-has-empty-poster").innerText = "FAIL";
} else
document.getElementById("result-has-empty-poster").innerText = "FAIL: image source is null";
testRunner.notifyDone();
}, false);
}
</script>
</head>
<body>
<pre id="result-no-poster"></pre>
<pre id="result-has-poster"></pre>
<pre id="result-has-empty-poster"></pre>
<video id="video-no-poster" src="content/test.mp4" preload="none" />
<video id="video-has-poster" src="content/test.mp4" poster="content/abe.png" preload="none" />
<video id="video-has-empty-poster" src="content/test.mp4" poster="" preload="none" />
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
if (window.internals) {
addEventListener("load", function() {
var poster = window.internals.getImageSourceURL(document.getElementById("video-no-poster"));
if (poster)
document.getElementById("result-no-poster").innerText = "FAIL : poster was added.";
else
document.getElementById("result-no-poster").innerText = "PASS";
poster = window.internals.getImageSourceURL(document.getElementById("video-has-poster"));
if (poster) {
if (poster == "content/abe.png")
document.getElementById("result-has-poster").innerText = "PASS";
else
document.getElementById("result-has-poster").innerText = "FAIL: poster was changed";
} else
document.getElementById("result-has-poster").innerText = "FAIL: Image source is null";
testRunner.notifyDone();
}, false);
}
</script>
</head>
<body>
<pre id="result-no-poster"></pre>
<pre id="result-has-poster"></pre>
<video id="video-no-poster" src="content/test.mp4" preload="none" />
<video id="video-has-poster" src="content/test.mp4" poster="content/abe.png" preload="none" />
</body>
</html>
2013-03-13 Tao Bai <michaelbai@chromium.org>
Add the default video poster if it doesn't exist in video tag
https://bugs.webkit.org/show_bug.cgi?id=110263
Reviewed by Eric Carlson.
Tests: media/video-default-poster.html
media/video-no-default-poster.html
The Android web view application could provide the default poster
for a video that doesn't have the poster attribute.
To provide the default poster, the application must set defaultVideoPosterURL
setting and return the image in the response of that URL.
The way to do this would be:
A) Replace the Element::imageSourceAttributeName function with an
Element::imageSourceURL function that returns the imageSourceURL as a
const AtomicString&. The body will be the same as before, it will just also
include a call to getAttribute. Also will need to revise the four classes
that override that function.
B) Add a new HTMLVideoElement::posterImageURL function that implements the
default poster URL logic.
C) Update the four functions that get the poster attribute to handle poster
loading and display to call posterImageURL.
1) HTMLVideoElement::imageSourceURL.
2) HTMLVideoElement::setDisplayMode.
3) HTMLVideoElement::updateDisplayState.
4) HTMLMediaElement::getPluginProxyParams. Will need to cast to
HTMLVideoElement after checking isVideo.
* dom/Element.cpp:
(WebCore::Element::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* dom/Element.h: Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLEmbedElement.h: Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::getPluginProxyParams): Change to use posterImageURL
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* html/HTMLObjectElement.h: Replace imageSourceAttributeName with imageSourceURL
* html/HTMLVideoElement.cpp:
(WebCore::HTMLVideoElement::HTMLVideoElement): set m_defaultPosterURL if there is such settings
(WebCore::HTMLVideoElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
(WebCore::HTMLVideoElement::setDisplayMode): Use imageSourceURL()
(WebCore::HTMLVideoElement::updateDisplayState): Use imageSourceURL()
(WebCore::HTMLVideoElement::posterImageURL): Return image source's KURL
* html/HTMLVideoElement.h: Replace imageSourceAttributeName() with imageSourceURL() and add m_defaultPosterURL
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement): Use imageSourceURL()
* page/Settings.in: Add defaultVideoPosterURL setting.
* platform/chromium/PasteboardChromium.cpp:
(WebCore::Pasteboard::writeImage): use imageSourceURL()
* platform/gtk/PasteboardGtk.cpp:
(WebCore::getURLForImageNode): use imageSourceURL()
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::absoluteImageURL): use imageSourceURL()
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::imageSourceURL): Replace imageSourceAttributeName() with imageSourceURL()
* svg/SVGImageElement.h: Replace imageSourceAttributeName() with imageSourceURL()
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup): support backup defaultVideoPosterURL.
(WebCore::InternalSettings::Backup::restoreTo): support restore defaultVideoPosterURL.
(WebCore::InternalSettings::setDefaultVideoPosterURL): set defaultVideoPosterURL.
* testing/InternalSettings.h:
(Backup): support backup defaultVideoPosterURL.
(InternalSettings): Add setDefaultVidoePosterURL method.
* testing/InternalSettings.idl: Add setDefaultVideoPosterURL for test purpose.
* testing/Internals.cpp:
(WebCore::Internals::getImageSourceURL): Add getImageSourceURL method.
* testing/Internals.h: Add getImageSourceURL method.
* testing/Internals.idl: Add getImageSourceURL method.
2013-03-13 Abhishek Arya <inferno@chromium.org>
 
Replace static_casts with to* functions for document types.
......@@ -1121,9 +1121,9 @@ KURL Element::baseURI() const
return KURL(parentBase, baseAttribute);
}
const QualifiedName& Element::imageSourceAttributeName() const
const AtomicString& Element::imageSourceURL() const
{
return srcAttr;
return getAttribute(srcAttr);
}
bool Element::rendererIsNeeded(const NodeRenderingContext& context)
......
......@@ -451,7 +451,7 @@ public:
KURL getURLAttribute(const QualifiedName&) const;
KURL getNonEmptyURLAttribute(const QualifiedName&) const;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual const AtomicString& imageSourceURL() const;
virtual String target() const { return String(); }
virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone);
......
......@@ -210,9 +210,9 @@ bool HTMLEmbedElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLPlugInImageElement::isURLAttribute(attribute);
}
const QualifiedName& HTMLEmbedElement::imageSourceAttributeName() const
const AtomicString& HTMLEmbedElement::imageSourceURL() const
{
return srcAttr;
return getAttribute(srcAttr);
}
void HTMLEmbedElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
......
......@@ -41,7 +41,7 @@ private:
virtual bool rendererIsNeeded(const NodeRenderingContext&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual const AtomicString& imageSourceURL() const OVERRIDE;
virtual RenderWidget* renderWidgetForJSBindings() const;
......
......@@ -4140,7 +4140,8 @@ void HTMLMediaElement::getPluginProxyParams(KURL& url, Vector<String>& names, Ve
Frame* frame = document()->frame();
if (isVideo()) {
KURL posterURL = getNonEmptyURLAttribute(posterAttr);
HTMLVideoElement* video = static_cast<HTMLVideoElement*>(this);
KURL posterURL = video->posterImageURL();
if (!posterURL.isEmpty() && frame && frame->loader()->willLoadMediaElementURL(posterURL)) {
names.append(ASCIILiteral("_media_element_poster_"));
values.append(posterURL.string());
......
......@@ -364,9 +364,9 @@ bool HTMLObjectElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == dataAttr || (attribute.name() == usemapAttr && attribute.value().string()[0] != '#') || HTMLPlugInImageElement::isURLAttribute(attribute);
}
const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const
const AtomicString& HTMLObjectElement::imageSourceURL() const
{
return dataAttr;
return getAttribute(dataAttr);
}
void HTMLObjectElement::renderFallbackContent()
......
......@@ -79,7 +79,7 @@ private:
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual const AtomicString& imageSourceURL() const OVERRIDE;
virtual RenderWidget* renderWidgetForJSBindings() const;
......
......@@ -36,10 +36,12 @@
#include "Frame.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "Page.h"
#include "RenderImage.h"
#include "RenderVideo.h"
#include "ScriptController.h"
#include "Settings.h"
namespace WebCore {
......@@ -49,6 +51,8 @@ inline HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document
: HTMLMediaElement(tagName, document, createdByParser)
{
ASSERT(hasTagName(videoTag));
if (document->settings())
m_defaultPosterURL = document->settings()->defaultVideoPosterURL();
}
PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
......@@ -178,15 +182,18 @@ bool HTMLVideoElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == posterAttr || HTMLMediaElement::isURLAttribute(attribute);
}
const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
const AtomicString& HTMLVideoElement::imageSourceURL() const
{
return posterAttr;
const AtomicString& url = getAttribute(posterAttr);
if (!stripLeadingAndTrailingHTMLSpaces(url).isEmpty())
return url;
return m_defaultPosterURL;
}
void HTMLVideoElement::setDisplayMode(DisplayMode mode)
{
DisplayMode oldMode = displayMode();
KURL poster = getNonEmptyURLAttribute(posterAttr);
KURL poster = posterImageURL();
if (!poster.isEmpty()) {
// We have a poster path, but only show it until the user triggers display by playing or seeking and the
......@@ -221,7 +228,7 @@ void HTMLVideoElement::setDisplayMode(DisplayMode mode)
void HTMLVideoElement::updateDisplayState()
{
if (getNonEmptyURLAttribute(posterAttr).isEmpty())
if (posterImageURL().isEmpty())
setDisplayMode(Video);
else if (displayMode() < Poster)
setDisplayMode(Poster);
......@@ -308,6 +315,14 @@ unsigned HTMLVideoElement::webkitDroppedFrameCount() const
}
#endif
KURL HTMLVideoElement::posterImageURL() const
{
const AtomicString& url = stripLeadingAndTrailingHTMLSpaces(imageSourceURL());
if (url.isEmpty())
return KURL();
return document()->completeURL(url);
}
}
#endif
......@@ -69,6 +69,8 @@ public:
bool shouldDisplayPosterImage() const { return displayMode() == Poster || displayMode() == PosterWaitingForVideo; }
KURL posterImageURL() const;
private:
HTMLVideoElement(const QualifiedName&, Document*, bool);
......@@ -84,7 +86,7 @@ private:
virtual bool hasVideo() const { return player() && player()->hasVideo(); }
virtual bool supportsFullscreen() const;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual const AtomicString& imageSourceURL() const OVERRIDE;
virtual bool hasAvailableVideoFrame() const;
virtual void updateDisplayState();
......@@ -93,6 +95,7 @@ private:
OwnPtr<HTMLImageLoader> m_imageLoader;
AtomicString m_defaultPosterURL;
};
} //namespace
......
......@@ -172,7 +172,7 @@ void ImageLoader::updateFromElement()
if (!document->renderer())
return;
AtomicString attr = m_element->getAttribute(m_element->imageSourceAttributeName());
AtomicString attr = m_element->imageSourceURL();
if (attr == m_failedLoadURL)
return;
......
......@@ -195,4 +195,7 @@ unifiedTextCheckerEnabled initial=defaultUnifiedTextCheckerEnabled
logsPageMessagesToSystemConsoleEnabled initial=false
# Some apps could have a default video poster if it is not set.
defaultVideoPosterURL type=String
smartInsertDeleteEnabled initial=true
......@@ -153,7 +153,7 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String& title)
#endif
else if (node->hasTagName(HTMLNames::embedTag) || node->hasTagName(HTMLNames::objectTag)) {
Element* element = toElement(node);
urlString = element->getAttribute(element->imageSourceAttributeName());
urlString = element->imageSourceURL();
}
KURL url = urlString.isEmpty() ? KURL() : node->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
WebKit::WebImage webImage = bitmap->bitmap();
......
......@@ -107,7 +107,7 @@ static KURL getURLForImageNode(Node* node)
#endif
else if (node->hasTagName(HTMLNames::embedTag) || node->hasTagName(HTMLNames::objectTag)) {
Element* element = toElement(node);
urlString = element->getAttribute(element->imageSourceAttributeName());
urlString = element->imageSourceURL();
}
return urlString.isEmpty() ? KURL() : node->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
}
......
......@@ -320,7 +320,7 @@ KURL HitTestResult::absoluteImageURL() const
#endif
) {
Element* element = toElement(m_innerNonSharedNode.get());
urlString = element->getAttribute(element->imageSourceAttributeName());
urlString = element->imageSourceURL();
} else
return KURL();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment