Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: third_party/WebKit/Source/core/html/MediaDocument.cpp

Issue 1780043002: Add download button to MediaDocument on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 11 matching lines...) Expand all
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/html/MediaDocument.h" 26 #include "core/html/MediaDocument.h"
27 27
28 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 28 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
29 #include "core/HTMLNames.h" 29 #include "core/HTMLNames.h"
30 #include "core/dom/ElementTraversal.h" 30 #include "core/dom/ElementTraversal.h"
31 #include "core/dom/RawDataDocumentParser.h" 31 #include "core/dom/RawDataDocumentParser.h"
32 #include "core/dom/shadow/ShadowRoot.h"
33 #include "core/events/Event.h"
34 #include "core/events/EventListener.h"
32 #include "core/events/KeyboardEvent.h" 35 #include "core/events/KeyboardEvent.h"
33 #include "core/frame/LocalFrame.h" 36 #include "core/frame/LocalFrame.h"
37 #include "core/html/HTMLAnchorElement.h"
34 #include "core/html/HTMLBodyElement.h" 38 #include "core/html/HTMLBodyElement.h"
39 #include "core/html/HTMLContentElement.h"
40 #include "core/html/HTMLDivElement.h"
35 #include "core/html/HTMLHeadElement.h" 41 #include "core/html/HTMLHeadElement.h"
36 #include "core/html/HTMLHtmlElement.h" 42 #include "core/html/HTMLHtmlElement.h"
37 #include "core/html/HTMLMetaElement.h" 43 #include "core/html/HTMLMetaElement.h"
38 #include "core/html/HTMLSourceElement.h" 44 #include "core/html/HTMLSourceElement.h"
45 #include "core/html/HTMLStyleElement.h"
39 #include "core/html/HTMLVideoElement.h" 46 #include "core/html/HTMLVideoElement.h"
40 #include "core/loader/DocumentLoader.h" 47 #include "core/loader/DocumentLoader.h"
41 #include "core/loader/FrameLoader.h" 48 #include "core/loader/FrameLoader.h"
42 #include "core/loader/FrameLoaderClient.h" 49 #include "core/loader/FrameLoaderClient.h"
50 #include "platform/Histogram.h"
43 #include "platform/KeyboardCodes.h" 51 #include "platform/KeyboardCodes.h"
52 #include "platform/text/PlatformLocale.h"
44 53
45 namespace blink { 54 namespace blink {
46 55
47 using namespace HTMLNames; 56 using namespace HTMLNames;
48 57
58 // Enums used for UMA histogram.
59 enum MediaDocumentDownloadButtonValue {
60 MediaDocumentDownloadButtonShown,
61 MediaDocumentDownloadButtonClicked,
62 // Only append new enums here.
63 MediaDocumentDownloadButtonMax
64 };
65
66 void recordDownloadMetric(MediaDocumentDownloadButtonValue value)
67 {
68 DEFINE_STATIC_LOCAL(EnumerationHistogram, mediaDocumentDownloadButtonHistogr am, ("Blink.MediaDocument.DownloadButton", MediaDocumentDownloadButtonMax));
69 mediaDocumentDownloadButtonHistogram.count(value);
70 }
71
49 // FIXME: Share more code with PluginDocumentParser. 72 // FIXME: Share more code with PluginDocumentParser.
50 class MediaDocumentParser : public RawDataDocumentParser { 73 class MediaDocumentParser : public RawDataDocumentParser {
51 public: 74 public:
52 static RawPtr<MediaDocumentParser> create(MediaDocument* document) 75 static RawPtr<MediaDocumentParser> create(MediaDocument* document)
53 { 76 {
54 return new MediaDocumentParser(document); 77 return new MediaDocumentParser(document);
55 } 78 }
56 79
57 private: 80 private:
58 explicit MediaDocumentParser(Document* document) 81 explicit MediaDocumentParser(Document* document)
59 : RawDataDocumentParser(document) 82 : RawDataDocumentParser(document)
60 , m_didBuildDocumentStructure(false) 83 , m_didBuildDocumentStructure(false)
61 { 84 {
62 } 85 }
63 86
64 void appendBytes(const char*, size_t) override; 87 void appendBytes(const char*, size_t) override;
65 88
66 void createDocumentStructure(); 89 void createDocumentStructure();
67 90
68 bool m_didBuildDocumentStructure; 91 bool m_didBuildDocumentStructure;
69 }; 92 };
70 93
94 class MediaDownloadEventListener final : public EventListener {
95 public:
96 static RawPtr<MediaDownloadEventListener> create()
97 {
98 return new MediaDownloadEventListener();
99 }
100
101 bool operator==(const EventListener& other) const override
102 {
103 return this == &other;
104 }
105
106 private:
107 MediaDownloadEventListener()
108 : EventListener(CPPEventListenerType)
109 , m_clicked(false)
110 {
111 }
112
113 void handleEvent(ExecutionContext* context, Event* event) override
114 {
115 if (!m_clicked) {
116 recordDownloadMetric(MediaDocumentDownloadButtonClicked);
117 m_clicked = true;
118 }
119 }
120
121 bool m_clicked;
122 };
123
71 void MediaDocumentParser::createDocumentStructure() 124 void MediaDocumentParser::createDocumentStructure()
72 { 125 {
73 ASSERT(document()); 126 ASSERT(document());
74 RawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document()); 127 RawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
75 rootElement->insertedByParser(); 128 rootElement->insertedByParser();
76 document()->appendChild(rootElement); 129 document()->appendChild(rootElement);
77 130
78 document()->frame()->loader().dispatchDocumentElementAvailable(); 131 document()->frame()->loader().dispatchDocumentElementAvailable();
79 document()->frame()->loader().runScriptsAtDocumentElementAvailable(); 132 document()->frame()->loader().runScriptsAtDocumentElementAvailable();
80 if (isDetached()) 133 if (isDetached())
(...skipping 12 matching lines...) Expand all
93 146
94 RawPtr<HTMLSourceElement> source = HTMLSourceElement::create(*document()); 147 RawPtr<HTMLSourceElement> source = HTMLSourceElement::create(*document());
95 source->setSrc(document()->url()); 148 source->setSrc(document()->url());
96 149
97 if (DocumentLoader* loader = document()->loader()) 150 if (DocumentLoader* loader = document()->loader())
98 source->setType(loader->responseMIMEType()); 151 source->setType(loader->responseMIMEType());
99 152
100 media->appendChild(source.release()); 153 media->appendChild(source.release());
101 154
102 RawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document()); 155 RawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
156 body->setAttribute(styleAttr, "margin: 0px;");
157
158 RawPtr<HTMLDivElement> div = HTMLDivElement::create(*document());
159 // Style sheets for media controls are lazily loaded until a media element i s encountered.
160 // As a result, elements encountered before the media element will not get t he right
161 // style at first if we put the styles in mediacontrols.css. To solve this i ssue, set the
162 // styles inline so that they will be applied when the page loads.
163 // See w3c example on how to centering an element: https://www.w3.org/Style/ Examples/007/center.en.html
164 div->setAttribute(styleAttr,
165 "display: flex;"
166 "flex-direction: column;"
167 "justify-content: center;"
168 "align-items: center;"
169 "min-height: min-content;"
170 "height: 100%;");
171 RawPtr<HTMLContentElement> content = HTMLContentElement::create(*document()) ;
172 div->appendChild(content.release());
173
174 if (RuntimeEnabledFeatures::mediaDocumentDownloadButtonEnabled()) {
175 RawPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*document() );
176 anchor->setAttribute(downloadAttr, "");
177 anchor->setURL(document()->url());
178 anchor->setTextContent(document()->getCachedLocale(document()->contentLa nguage()).queryString(WebLocalizedString::DownloadButtonLabel).upper());
179 // Using CSS style according to Android material design.
180 anchor->setAttribute(styleAttr,
181 "display: inline-block;"
182 "margin-top: 32px;"
183 "padding: 0 16px 0 16px;"
184 "height: 36px;"
185 "background: #4285F4;"
186 "font-family: Roboto;"
187 "font-size: 14px;"
188 "border-radius: 5px;"
189 "color: white;"
190 "font-weight: bold;"
191 "text-decoration: none;"
192 "min-width: 300px;"
193 "line-height: 36px;");
194 RawPtr<EventListener> listener = MediaDownloadEventListener::create();
195 anchor->addEventListener(EventTypeNames::click, listener, false);
196 RawPtr<HTMLDivElement> buttonContainer = HTMLDivElement::create(*documen t());
197 buttonContainer->setAttribute(styleAttr,
198 "position: absolute;"
199 "text-align: center;"
200 "left: 0;"
201 "right: 0;");
202 buttonContainer->appendChild(anchor.release());
203 div->appendChild(buttonContainer.release());
204 recordDownloadMetric(MediaDocumentDownloadButtonShown);
205 }
206
207 // According to https://html.spec.whatwg.org/multipage/browsers.html#read-me dia,
208 // MediaDocument should have a single child which is the video element. Use
209 // shadow root to hide all the elements we added here.
210 ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot();
211 shadowRoot.appendChild(div.release());
103 body->appendChild(media.release()); 212 body->appendChild(media.release());
104
105 rootElement->appendChild(head.release()); 213 rootElement->appendChild(head.release());
106 rootElement->appendChild(body.release()); 214 rootElement->appendChild(body.release());
107 215
108 m_didBuildDocumentStructure = true; 216 m_didBuildDocumentStructure = true;
109 } 217 }
110 218
111 void MediaDocumentParser::appendBytes(const char*, size_t) 219 void MediaDocumentParser::appendBytes(const char*, size_t)
112 { 220 {
113 if (m_didBuildDocumentStructure) 221 if (m_didBuildDocumentStructure)
114 return; 222 return;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 KeyboardEvent* keyboardEvent = toKeyboardEvent(event); 255 KeyboardEvent* keyboardEvent = toKeyboardEvent(event);
148 if (keyboardEvent->keyIdentifier() == "U+0020" || keyboardEvent->keyCode () == VKEY_MEDIA_PLAY_PAUSE) { 256 if (keyboardEvent->keyIdentifier() == "U+0020" || keyboardEvent->keyCode () == VKEY_MEDIA_PLAY_PAUSE) {
149 // space or media key (play/pause) 257 // space or media key (play/pause)
150 video->togglePlayState(); 258 video->togglePlayState();
151 event->setDefaultHandled(); 259 event->setDefaultHandled();
152 } 260 }
153 } 261 }
154 } 262 }
155 263
156 } // namespace blink 264 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/css/mediaControlsNew.css ('k') | third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698