OLD | NEW |
---|---|
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 Loading... | |
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/events/Event.h" | |
33 #include "core/events/EventListener.h" | |
32 #include "core/events/KeyboardEvent.h" | 34 #include "core/events/KeyboardEvent.h" |
33 #include "core/frame/LocalFrame.h" | 35 #include "core/frame/LocalFrame.h" |
36 #include "core/html/HTMLAnchorElement.h" | |
34 #include "core/html/HTMLBodyElement.h" | 37 #include "core/html/HTMLBodyElement.h" |
38 #include "core/html/HTMLDivElement.h" | |
35 #include "core/html/HTMLHeadElement.h" | 39 #include "core/html/HTMLHeadElement.h" |
36 #include "core/html/HTMLHtmlElement.h" | 40 #include "core/html/HTMLHtmlElement.h" |
37 #include "core/html/HTMLMetaElement.h" | 41 #include "core/html/HTMLMetaElement.h" |
38 #include "core/html/HTMLSourceElement.h" | 42 #include "core/html/HTMLSourceElement.h" |
43 #include "core/html/HTMLStyleElement.h" | |
39 #include "core/html/HTMLVideoElement.h" | 44 #include "core/html/HTMLVideoElement.h" |
40 #include "core/loader/DocumentLoader.h" | 45 #include "core/loader/DocumentLoader.h" |
41 #include "core/loader/FrameLoader.h" | 46 #include "core/loader/FrameLoader.h" |
42 #include "core/loader/FrameLoaderClient.h" | 47 #include "core/loader/FrameLoaderClient.h" |
48 #include "platform/Histogram.h" | |
43 #include "platform/KeyboardCodes.h" | 49 #include "platform/KeyboardCodes.h" |
50 #include "platform/text/PlatformLocale.h" | |
44 | 51 |
45 namespace blink { | 52 namespace blink { |
46 | 53 |
47 using namespace HTMLNames; | 54 using namespace HTMLNames; |
48 | 55 |
56 enum MediaDocumentDownloadButtonValue { | |
57 MediaDocumentDownloadButtonShown, | |
58 MediaDocumentDownloadButtonClicked, | |
59 MediaDocumentDownloadButtonMax | |
60 }; | |
Ilya Sherman
2016/03/31 00:34:59
Please document that this enum is used to back a h
qinmin
2016/04/06 17:27:13
Done.
| |
61 | |
62 void recordDownloadMetric(MediaDocumentDownloadButtonValue value) | |
63 { | |
64 DEFINE_STATIC_LOCAL(EnumerationHistogram, mediaDocumentDownloadButtonHistogr am, ("Blink.MediaDocument.DownloadButton", MediaDocumentDownloadButtonMax)); | |
65 mediaDocumentDownloadButtonHistogram.count(value); | |
66 } | |
67 | |
49 // FIXME: Share more code with PluginDocumentParser. | 68 // FIXME: Share more code with PluginDocumentParser. |
50 class MediaDocumentParser : public RawDataDocumentParser { | 69 class MediaDocumentParser : public RawDataDocumentParser { |
51 public: | 70 public: |
52 static PassRefPtrWillBeRawPtr<MediaDocumentParser> create(MediaDocument* doc ument) | 71 static PassRefPtrWillBeRawPtr<MediaDocumentParser> create(MediaDocument* doc ument) |
53 { | 72 { |
54 return adoptRefWillBeNoop(new MediaDocumentParser(document)); | 73 return adoptRefWillBeNoop(new MediaDocumentParser(document)); |
55 } | 74 } |
56 | 75 |
57 private: | 76 private: |
58 explicit MediaDocumentParser(Document* document) | 77 explicit MediaDocumentParser(Document* document) |
59 : RawDataDocumentParser(document) | 78 : RawDataDocumentParser(document) |
60 , m_didBuildDocumentStructure(false) | 79 , m_didBuildDocumentStructure(false) |
61 { | 80 { |
62 } | 81 } |
63 | 82 |
64 void appendBytes(const char*, size_t) override; | 83 void appendBytes(const char*, size_t) override; |
65 | 84 |
66 void createDocumentStructure(); | 85 void createDocumentStructure(); |
67 | 86 |
68 bool m_didBuildDocumentStructure; | 87 bool m_didBuildDocumentStructure; |
69 }; | 88 }; |
70 | 89 |
90 class MediaDownloadEventListener final : public EventListener { | |
91 public: | |
92 static PassRefPtrWillBeRawPtr<MediaDownloadEventListener> create() | |
93 { | |
94 return adoptRefWillBeNoop(new MediaDownloadEventListener()); | |
95 } | |
96 | |
97 bool operator==(const EventListener& other) const override | |
98 { | |
99 return this == &other; | |
100 } | |
101 | |
102 private: | |
103 MediaDownloadEventListener() | |
104 : EventListener(CPPEventListenerType) | |
105 , m_clicked(false) | |
106 { | |
107 } | |
108 | |
109 void handleEvent(ExecutionContext* context, Event* event) override | |
110 { | |
111 if (event->type() == EventTypeNames::click && !m_clicked) { | |
112 recordDownloadMetric(MediaDocumentDownloadButtonClicked); | |
113 m_clicked = true; | |
114 } | |
115 } | |
116 | |
117 bool m_clicked; | |
118 }; | |
119 | |
71 void MediaDocumentParser::createDocumentStructure() | 120 void MediaDocumentParser::createDocumentStructure() |
72 { | 121 { |
73 ASSERT(document()); | 122 ASSERT(document()); |
74 RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*d ocument()); | 123 RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*d ocument()); |
75 rootElement->insertedByParser(); | 124 rootElement->insertedByParser(); |
76 document()->appendChild(rootElement); | 125 document()->appendChild(rootElement); |
77 | 126 |
78 document()->frame()->loader().dispatchDocumentElementAvailable(); | 127 document()->frame()->loader().dispatchDocumentElementAvailable(); |
79 document()->frame()->loader().runScriptsAtDocumentElementAvailable(); | 128 document()->frame()->loader().runScriptsAtDocumentElementAvailable(); |
80 if (isDetached()) | 129 if (isDetached()) |
(...skipping 12 matching lines...) Expand all Loading... | |
93 | 142 |
94 RefPtrWillBeRawPtr<HTMLSourceElement> source = HTMLSourceElement::create(*do cument()); | 143 RefPtrWillBeRawPtr<HTMLSourceElement> source = HTMLSourceElement::create(*do cument()); |
95 source->setSrc(document()->url()); | 144 source->setSrc(document()->url()); |
96 | 145 |
97 if (DocumentLoader* loader = document()->loader()) | 146 if (DocumentLoader* loader = document()->loader()) |
98 source->setType(loader->responseMIMEType()); | 147 source->setType(loader->responseMIMEType()); |
99 | 148 |
100 media->appendChild(source.release()); | 149 media->appendChild(source.release()); |
101 | 150 |
102 RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document ()); | 151 RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document ()); |
103 body->appendChild(media.release()); | 152 body->setAttribute(styleAttr, "margin: 0px;"); |
153 | |
154 RefPtrWillBeRawPtr<HTMLDivElement> div = HTMLDivElement::create(*document()) ; | |
155 // Style sheets for media controls are lazily loaded until a media element i s encountered. | |
156 // As a result, elements encountered before the media element will not get t he right | |
157 // style at first if we put the styles in mediacontrols.css. To solve this i ssue, set the | |
158 // styles inline so that they will be applied when the page loads. | |
159 // See w3c example on how to centering an element: https://www.w3.org/Style/ Examples/007/center.en.html | |
160 div->setAttribute(styleAttr, | |
161 "display: flex;" | |
162 "flex-direction: column;" | |
163 "justify-content: center;" | |
164 "align-items: center;" | |
165 "min-height: min-content;" | |
166 "height: 100%;"); | |
167 div->appendChild(media.release()); | |
168 | |
169 if (RuntimeEnabledFeatures::mediaDocumentDownloadButtonEnabled()) { | |
170 RefPtrWillBeRawPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create (*document()); | |
171 anchor->setAttribute(downloadAttr, ""); | |
172 anchor->setURL(document()->url()); | |
173 anchor->setTextContent(document()->getCachedLocale(document()->contentLa nguage()).queryString(WebLocalizedString::DownloadButtonLabel).upper()); | |
174 // Using CSS style according to Android material design. | |
175 anchor->setAttribute(styleAttr, | |
176 "display: inline-block;" | |
177 "margin-top: 32px;" | |
178 "padding: 0 16px 0 16px;" | |
179 "height: 36px;" | |
180 "background: #4285F4;" | |
181 "font-family: Roboto;" | |
182 "font-size: 14px;" | |
183 "border-radius: 5px;" | |
184 "color: white;" | |
185 "font-weight: bold;" | |
186 "text-decoration: none;" | |
187 "line-height: 36px;"); | |
188 RefPtrWillBeRawPtr<EventListener> listener = MediaDownloadEventListener: :create(); | |
189 anchor->addEventListener(EventTypeNames::click, listener, false); | |
190 RefPtrWillBeRawPtr<HTMLDivElement> buttonContainer = HTMLDivElement::cre ate(*document()); | |
191 buttonContainer->setAttribute(styleAttr, | |
192 "position: absolute;" | |
193 "text-align: center;" | |
194 "left: 0;" | |
195 "right: 0;"); | |
196 buttonContainer->appendChild(anchor.release()); | |
197 div->appendChild(buttonContainer.release()); | |
198 recordDownloadMetric(MediaDocumentDownloadButtonShown); | |
199 } | |
200 | |
201 body->appendChild(div.release()); | |
104 | 202 |
105 rootElement->appendChild(head.release()); | 203 rootElement->appendChild(head.release()); |
106 rootElement->appendChild(body.release()); | 204 rootElement->appendChild(body.release()); |
107 | 205 |
108 m_didBuildDocumentStructure = true; | 206 m_didBuildDocumentStructure = true; |
109 } | 207 } |
110 | 208 |
111 void MediaDocumentParser::appendBytes(const char*, size_t) | 209 void MediaDocumentParser::appendBytes(const char*, size_t) |
112 { | 210 { |
113 if (m_didBuildDocumentStructure) | 211 if (m_didBuildDocumentStructure) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 KeyboardEvent* keyboardEvent = toKeyboardEvent(event); | 245 KeyboardEvent* keyboardEvent = toKeyboardEvent(event); |
148 if (keyboardEvent->keyIdentifier() == "U+0020" || keyboardEvent->keyCode () == VKEY_MEDIA_PLAY_PAUSE) { | 246 if (keyboardEvent->keyIdentifier() == "U+0020" || keyboardEvent->keyCode () == VKEY_MEDIA_PLAY_PAUSE) { |
149 // space or media key (play/pause) | 247 // space or media key (play/pause) |
150 video->togglePlayState(); | 248 video->togglePlayState(); |
151 event->setDefaultHandled(); | 249 event->setDefaultHandled(); |
152 } | 250 } |
153 } | 251 } |
154 } | 252 } |
155 | 253 |
156 } // namespace blink | 254 } // namespace blink |
OLD | NEW |