| Index: third_party/WebKit/Source/core/html/MediaDocument.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/MediaDocument.cpp b/third_party/WebKit/Source/core/html/MediaDocument.cpp
|
| index f5e4963e1d05e31893349e555354525e1db3428a..8a3652abad94bb47187de8c688323d6c44ab660f 100644
|
| --- a/third_party/WebKit/Source/core/html/MediaDocument.cpp
|
| +++ b/third_party/WebKit/Source/core/html/MediaDocument.cpp
|
| @@ -29,23 +29,46 @@
|
| #include "core/HTMLNames.h"
|
| #include "core/dom/ElementTraversal.h"
|
| #include "core/dom/RawDataDocumentParser.h"
|
| +#include "core/dom/shadow/ShadowRoot.h"
|
| +#include "core/events/Event.h"
|
| +#include "core/events/EventListener.h"
|
| #include "core/events/KeyboardEvent.h"
|
| #include "core/frame/LocalFrame.h"
|
| +#include "core/html/HTMLAnchorElement.h"
|
| #include "core/html/HTMLBodyElement.h"
|
| +#include "core/html/HTMLContentElement.h"
|
| +#include "core/html/HTMLDivElement.h"
|
| #include "core/html/HTMLHeadElement.h"
|
| #include "core/html/HTMLHtmlElement.h"
|
| #include "core/html/HTMLMetaElement.h"
|
| #include "core/html/HTMLSourceElement.h"
|
| +#include "core/html/HTMLStyleElement.h"
|
| #include "core/html/HTMLVideoElement.h"
|
| #include "core/loader/DocumentLoader.h"
|
| #include "core/loader/FrameLoader.h"
|
| #include "core/loader/FrameLoaderClient.h"
|
| +#include "platform/Histogram.h"
|
| #include "platform/KeyboardCodes.h"
|
| +#include "platform/text/PlatformLocale.h"
|
|
|
| namespace blink {
|
|
|
| using namespace HTMLNames;
|
|
|
| +// Enums used for UMA histogram.
|
| +enum MediaDocumentDownloadButtonValue {
|
| + MediaDocumentDownloadButtonShown,
|
| + MediaDocumentDownloadButtonClicked,
|
| + // Only append new enums here.
|
| + MediaDocumentDownloadButtonMax
|
| +};
|
| +
|
| +void recordDownloadMetric(MediaDocumentDownloadButtonValue value)
|
| +{
|
| + DEFINE_STATIC_LOCAL(EnumerationHistogram, mediaDocumentDownloadButtonHistogram, ("Blink.MediaDocument.DownloadButton", MediaDocumentDownloadButtonMax));
|
| + mediaDocumentDownloadButtonHistogram.count(value);
|
| +}
|
| +
|
| // FIXME: Share more code with PluginDocumentParser.
|
| class MediaDocumentParser : public RawDataDocumentParser {
|
| public:
|
| @@ -68,6 +91,36 @@ private:
|
| bool m_didBuildDocumentStructure;
|
| };
|
|
|
| +class MediaDownloadEventListener final : public EventListener {
|
| +public:
|
| + static RawPtr<MediaDownloadEventListener> create()
|
| + {
|
| + return new MediaDownloadEventListener();
|
| + }
|
| +
|
| + bool operator==(const EventListener& other) const override
|
| + {
|
| + return this == &other;
|
| + }
|
| +
|
| +private:
|
| + MediaDownloadEventListener()
|
| + : EventListener(CPPEventListenerType)
|
| + , m_clicked(false)
|
| + {
|
| + }
|
| +
|
| + void handleEvent(ExecutionContext* context, Event* event) override
|
| + {
|
| + if (!m_clicked) {
|
| + recordDownloadMetric(MediaDocumentDownloadButtonClicked);
|
| + m_clicked = true;
|
| + }
|
| + }
|
| +
|
| + bool m_clicked;
|
| +};
|
| +
|
| void MediaDocumentParser::createDocumentStructure()
|
| {
|
| ASSERT(document());
|
| @@ -100,8 +153,63 @@ void MediaDocumentParser::createDocumentStructure()
|
| media->appendChild(source.release());
|
|
|
| RawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
|
| - body->appendChild(media.release());
|
| + body->setAttribute(styleAttr, "margin: 0px;");
|
| +
|
| + RawPtr<HTMLDivElement> div = HTMLDivElement::create(*document());
|
| + // Style sheets for media controls are lazily loaded until a media element is encountered.
|
| + // As a result, elements encountered before the media element will not get the right
|
| + // style at first if we put the styles in mediacontrols.css. To solve this issue, set the
|
| + // styles inline so that they will be applied when the page loads.
|
| + // See w3c example on how to centering an element: https://www.w3.org/Style/Examples/007/center.en.html
|
| + div->setAttribute(styleAttr,
|
| + "display: flex;"
|
| + "flex-direction: column;"
|
| + "justify-content: center;"
|
| + "align-items: center;"
|
| + "min-height: min-content;"
|
| + "height: 100%;");
|
| + RawPtr<HTMLContentElement> content = HTMLContentElement::create(*document());
|
| + div->appendChild(content.release());
|
|
|
| + if (RuntimeEnabledFeatures::mediaDocumentDownloadButtonEnabled()) {
|
| + RawPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*document());
|
| + anchor->setAttribute(downloadAttr, "");
|
| + anchor->setURL(document()->url());
|
| + anchor->setTextContent(document()->getCachedLocale(document()->contentLanguage()).queryString(WebLocalizedString::DownloadButtonLabel).upper());
|
| + // Using CSS style according to Android material design.
|
| + anchor->setAttribute(styleAttr,
|
| + "display: inline-block;"
|
| + "margin-top: 32px;"
|
| + "padding: 0 16px 0 16px;"
|
| + "height: 36px;"
|
| + "background: #4285F4;"
|
| + "font-family: Roboto;"
|
| + "font-size: 14px;"
|
| + "border-radius: 5px;"
|
| + "color: white;"
|
| + "font-weight: bold;"
|
| + "text-decoration: none;"
|
| + "min-width: 300px;"
|
| + "line-height: 36px;");
|
| + RawPtr<EventListener> listener = MediaDownloadEventListener::create();
|
| + anchor->addEventListener(EventTypeNames::click, listener, false);
|
| + RawPtr<HTMLDivElement> buttonContainer = HTMLDivElement::create(*document());
|
| + buttonContainer->setAttribute(styleAttr,
|
| + "position: absolute;"
|
| + "text-align: center;"
|
| + "left: 0;"
|
| + "right: 0;");
|
| + buttonContainer->appendChild(anchor.release());
|
| + div->appendChild(buttonContainer.release());
|
| + recordDownloadMetric(MediaDocumentDownloadButtonShown);
|
| + }
|
| +
|
| + // According to https://html.spec.whatwg.org/multipage/browsers.html#read-media,
|
| + // MediaDocument should have a single child which is the video element. Use
|
| + // shadow root to hide all the elements we added here.
|
| + ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot();
|
| + shadowRoot.appendChild(div.release());
|
| + body->appendChild(media.release());
|
| rootElement->appendChild(head.release());
|
| rootElement->appendChild(body.release());
|
|
|
|
|