Add the default video poster if it doesn't exist in video tag
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2013 21:16:50 +0000 (21:16 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Mar 2013 21:16:50 +0000 (21:16 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@145750 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 files changed:
LayoutTests/ChangeLog
LayoutTests/media/video-default-poster-expected.txt [new file with mode: 0644]
LayoutTests/media/video-default-poster.html [new file with mode: 0644]
LayoutTests/media/video-no-default-poster-expected.txt [new file with mode: 0644]
LayoutTests/media/video-no-default-poster.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/html/HTMLEmbedElement.cpp
Source/WebCore/html/HTMLEmbedElement.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLObjectElement.cpp
Source/WebCore/html/HTMLObjectElement.h
Source/WebCore/html/HTMLVideoElement.cpp
Source/WebCore/html/HTMLVideoElement.h
Source/WebCore/loader/ImageLoader.cpp
Source/WebCore/page/Settings.in
Source/WebCore/platform/chromium/PasteboardChromium.cpp
Source/WebCore/platform/gtk/PasteboardGtk.cpp
Source/WebCore/rendering/HitTestResult.cpp
Source/WebCore/svg/SVGImageElement.cpp
Source/WebCore/svg/SVGImageElement.h
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index 7b26a01..f29acd3 100644 (file)
@@ -1,3 +1,41 @@
+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
diff --git a/LayoutTests/media/video-default-poster-expected.txt b/LayoutTests/media/video-default-poster-expected.txt
new file mode 100644 (file)
index 0000000..5c50a8e
--- /dev/null
@@ -0,0 +1,4 @@
+PASS
+PASS
+PASS
+
diff --git a/LayoutTests/media/video-default-poster.html b/LayoutTests/media/video-default-poster.html
new file mode 100644 (file)
index 0000000..e45b01b
--- /dev/null
@@ -0,0 +1,54 @@
+<!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>
diff --git a/LayoutTests/media/video-no-default-poster-expected.txt b/LayoutTests/media/video-no-default-poster-expected.txt
new file mode 100644 (file)
index 0000000..f7f0fa5
--- /dev/null
@@ -0,0 +1,3 @@
+PASS
+PASS
+
diff --git a/LayoutTests/media/video-no-default-poster.html b/LayoutTests/media/video-no-default-poster.html
new file mode 100644 (file)
index 0000000..368ba06
--- /dev/null
@@ -0,0 +1,39 @@
+<!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>
index 6cc637e..bc99200 100644 (file)
@@ -1,3 +1,82 @@
+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.
index 9d38043..2eb9d40 100644 (file)
@@ -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)
index 4988b1d..4627b69 100644 (file)
@@ -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);
index c33e2f8..df2c16b 100644 (file)
@@ -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
index a595ba4..442dcb9 100644 (file)
@@ -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;
 
index ac5c0b2..9a5ae9a 100644 (file)
@@ -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());
index 24e1929..ecb0297 100644 (file)
@@ -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()
index 5b7e720..bf717da 100644 (file)
@@ -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;
 
index a377b56..ba70dce 100644 (file)
 #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
index 0c3fd68..2463945 100644 (file)
@@ -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
index 4411a8c..df211e7 100644 (file)
@@ -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;
index e7991ea..286636c 100644 (file)
@@ -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
index 3d5a6b6..e5353a4 100644 (file)
@@ -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();
index ef394c4..d42554f 100644 (file)
@@ -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));
 }
index 23da31c..c636f57 100644 (file)
@@ -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();
 
index afb4ddc..0d23be3 100644 (file)
@@ -222,9 +222,9 @@ Node::InsertionNotificationRequest SVGImageElement::insertedInto(ContainerNode*
     return InsertionDone;
 }
 
-const QualifiedName& SVGImageElement::imageSourceAttributeName() const
+const AtomicString& SVGImageElement::imageSourceURL() const
 {
-    return XLinkNames::hrefAttr;
+    return getAttribute(XLinkNames::hrefAttr);
 }
 
 void SVGImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
index ca0b62e..de7a64a 100644 (file)
@@ -58,8 +58,8 @@ private:
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual const QualifiedName& imageSourceAttributeName() const;       
+
+    virtual const AtomicString& imageSourceURL() const OVERRIDE;
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
 
     virtual bool haveLoadedRequiredResources();
index c0f5877..c3f90d5 100644 (file)
@@ -94,6 +94,7 @@ InternalSettings::Backup::Backup(Settings* settings)
     , m_shouldDisplayCaptions(settings->shouldDisplayCaptions())
     , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions())
 #endif
+    , m_defaultVideoPosterURL(settings->defaultVideoPosterURL())
     , m_originalTimeWithoutMouseMovementBeforeHidingControls(settings->timeWithoutMouseMovementBeforeHidingControls())
 {
 }
@@ -130,6 +131,7 @@ void InternalSettings::Backup::restoreTo(Settings* settings)
     settings->setShouldDisplayCaptions(m_shouldDisplayCaptions);
     settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
 #endif
+    settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL);
     settings->setTimeWithoutMouseMovementBeforeHidingControls(m_originalTimeWithoutMouseMovementBeforeHidingControls);
 }
 
@@ -489,6 +491,12 @@ void InternalSettings::setMinimumTimerInterval(double intervalInSeconds, Excepti
     settings()->setMinDOMTimerInterval(intervalInSeconds);
 }
 
+void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionCode& ec)
+{
+    InternalSettingsGuardForSettings();
+    settings()->setDefaultVideoPosterURL(url);
+}
+
 void InternalSettings::setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode& ec)
 {
     InternalSettingsGuardForSettings();
index 25c25fe..549b0fa 100644 (file)
@@ -82,6 +82,7 @@ public:
         bool m_shouldDisplayCaptions;
         bool m_shouldDisplayTextDescriptions;
 #endif
+        String m_defaultVideoPosterURL;
         bool m_originalTimeWithoutMouseMovementBeforeHidingControls;
     };
 
@@ -127,6 +128,7 @@ public:
     void setLangAttributeAwareFormControlUIEnabled(bool);
     void setImagesEnabled(bool enabled, ExceptionCode&);
     void setMinimumTimerInterval(double intervalInSeconds, ExceptionCode&);
+    void setDefaultVideoPosterURL(const String& url, ExceptionCode&);
     void setTimeWithoutMouseMovementBeforeHidingControls(double time, ExceptionCode&);
 
 private:
index dd34160..cde8df6 100644 (file)
@@ -59,5 +59,6 @@
     void setStorageBlockingPolicy(in DOMString policy) raises(DOMException);
     void setImagesEnabled(in boolean enabled) raises(DOMException);
     void setMinimumTimerInterval(in double intervalInSeconds) raises(DOMException);
+    void setDefaultVideoPosterURL(in DOMString poster) raises(DOMException);
     void setTimeWithoutMouseMovementBeforeHidingControls(in double time) raises(DOMException);
 };
index 3c39fa1..c037533 100644 (file)
@@ -2062,4 +2062,13 @@ String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
     return WebCore::markerTextForListItem(element);
 }
 
+String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
+{
+    if (!element) {
+        ec = INVALID_ACCESS_ERR;
+        return String();
+    }
+    return element->imageSourceURL();
+}
+
 }
index 07bdad3..2883fae 100644 (file)
@@ -297,6 +297,8 @@ public:
 #if ENABLE(SPEECH_SYNTHESIS)
     void enableMockSpeechSynthesizer();
 #endif
+
+    String getImageSourceURL(Element*, ExceptionCode&);
                     
 private:
     explicit Internals(Document*);
index 3ef23d5..6fc26a6 100644 (file)
     [Conditional=ENCRYPTED_MEDIA_V2] void initializeMockCDM();
 
     [Conditional=SPEECH_SYNTHESIS] void enableMockSpeechSynthesizer();
+
+    DOMString getImageSourceURL(in Element element) raises(DOMException);
 };