diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-01-16 13:48:06 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-16 18:20:33 +0100 |
commit | 1ca1ca150c8a362980bb11123d416ff136da155c (patch) | |
tree | cc15d6f99ec5c62535c69bfa59a80a669267becc /Source | |
parent | b38b96c88cd732f47940aed453f5cacf833ee1c2 (diff) | |
download | qtwebkit-1ca1ca150c8a362980bb11123d416ff136da155c.tar.gz |
Enable HTML5 video track support
This patch enables support for the HTML5 video track standard
which defines subtitles and captions for HTML5 video.
The HTML5 video controls will now have a popup button when
captions are available that allows the user to select the
preferred caption or turn them off.
Change-Id: Id5b837d1a7b536935cd5038812594b11c48c3480
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'Source')
-rw-r--r-- | Source/WebCore/css/mediaControlsQt.css | 91 | ||||
-rw-r--r-- | Source/WebCore/html/shadow/MediaControlElements.cpp | 6 | ||||
-rw-r--r-- | Source/WebCore/html/shadow/MediaControlElements.h | 2 | ||||
-rw-r--r-- | Source/WebCore/page/CaptionUserPreferences.cpp | 8 | ||||
-rw-r--r-- | Source/WebCore/platform/qt/LocalizedStringsQt.cpp | 16 | ||||
-rw-r--r-- | Source/WebCore/platform/qt/RenderThemeQt.cpp | 31 | ||||
-rw-r--r-- | Source/WebCore/platform/qt/RenderThemeQt.h | 4 |
7 files changed, 144 insertions, 14 deletions
diff --git a/Source/WebCore/css/mediaControlsQt.css b/Source/WebCore/css/mediaControlsQt.css index 715a37f66..5ed490f1b 100644 --- a/Source/WebCore/css/mediaControlsQt.css +++ b/Source/WebCore/css/mediaControlsQt.css @@ -23,7 +23,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* QtWebKit media controls. Extends mediaControls.css */ @@ -151,14 +151,99 @@ audio::-webkit-media-controls-return-to-realtime-button, video::-webkit-media-co } audio::-webkit-media-controls-toggle-closed-captions-button, video::-webkit-media-controls-toggle-closed-captions-button { - display: none; + -webkit-appearance: media-toggle-closed-captions-button; + width: 12px; + height: 12px; + padding: 6px; + margin: 5px 5px 5px 3px; + -webkit-order: 3; /* between mute and fullscreen */ + border: none !important; +} + +video::-webkit-media-controls-closed-captions-container { + -webkit-appearance: media-closed-captions-container; + position: absolute; + display: block; + right: 38px; + bottom: 29px; + max-width: -webkit-calc(100% - 48px); /* right + 10px */ + max-height: -webkit-calc(100% - 39px); /* bottom + 10px */ + overflow-x: hidden; + overflow-y: auto; + background-color: rgba(0, 0, 0, 0.85); + border-radius: 10px; + cursor: default; + z-index: 2; +} + +video::-webkit-media-controls-closed-captions-track-list { + display: block; + font-size: 10pt; +} + +video::-webkit-media-controls-closed-captions-track-list h3 { + margin: 0; + color: #757575; + text-shadow: 0 1px 0 black; + -webkit-margin-start: 23px; + padding-top: 4px; + font-weight: bold; + font-size: 10pt; +} + +video::-webkit-media-controls-closed-captions-track-list ul { + list-style-type: none; + margin: 0 0 4px 0; + padding: 0; + font-weight: bold; +} + +video::-webkit-media-controls-closed-captions-track-list li { + position: relative; + color: white; + background-image: none; + text-shadow: 0 1px 0 black; + margin: 0; + padding-left: 37px; + padding-right: 35px; + padding-top: 0.15em; + padding-bottom: 0.2em; + box-sizing: border-box; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + border-top: 1px solid rgba(0, 0, 0, 0); + border-bottom: 1px solid rgba(0, 0, 0, 0); +} + +video::-webkit-media-controls-closed-captions-track-list li:hover { + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #4f70f6), color-stop(1, #1a44f3)); + border-top: 1px solid #4667ea; + border-bottom: 1px solid #0336e5; +} + +video::-webkit-media-controls-closed-captions-track-list li.selected::before { + display: block; + content: ""; + position: absolute; + top: 0.25em; + width: 1.1em; + height: 1.1em; + -webkit-margin-start: -20px; + background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><polygon fill="#a3a3a3" points="252.301,4.477 126.667,194.104 43.358,108.3 6.868,161.408 132.515,290.814 297.732,49.926"/></svg>'); + background-repeat: no-repeat; +} + +video::-webkit-media-controls-closed-captions-track-list li.selected:hover::before { + background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><polygon fill="white" points="252.301,4.477 126.667,194.104 43.358,108.3 6.868,161.408 132.515,290.814 297.732,49.926"/></svg>'); } ::-webkit-media-controls-mute-button, ::-webkit-media-controls-play-button, ::-webkit-media-controls-timeline, ::-webkit-media-controls-volume-slider, -::-webkit-media-controls-fullscreen-button +::-webkit-media-controls-fullscreen-button, +::-webkit-media-controls-toggle-closed-captions-button { box-sizing: content-box !important; } diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp index 4f5bd4591..99a11150c 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.cpp +++ b/Source/WebCore/html/shadow/MediaControlElements.cpp @@ -676,11 +676,11 @@ const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document* document, MediaControls* controls) : MediaControlInputElement(document, MediaShowClosedCaptionsButton) -#if PLATFORM(MAC) || PLATFORM(WIN) +#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT) , m_controls(controls) #endif { -#if !PLATFORM(MAC) && !PLATFORM(WIN) +#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(QT) UNUSED_PARAM(controls); #endif } @@ -710,7 +710,7 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e // UI. Not all ports may want the closed captions button to toggle a list of tracks, so // we have to use #if. // https://bugs.webkit.org/show_bug.cgi?id=101877 -#if !PLATFORM(MAC) && !PLATFORM(WIN) +#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(QT) mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible()); setChecked(mediaController()->closedCaptionsVisible()); updateDisplayType(); diff --git a/Source/WebCore/html/shadow/MediaControlElements.h b/Source/WebCore/html/shadow/MediaControlElements.h index 68262d377..06b19cd5c 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.h +++ b/Source/WebCore/html/shadow/MediaControlElements.h @@ -280,7 +280,7 @@ private: virtual const AtomicString& shadowPseudoId() const OVERRIDE; virtual void defaultEventHandler(Event*) OVERRIDE; -#if PLATFORM(MAC) || PLATFORM(WIN) +#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT) MediaControls* m_controls; #endif }; diff --git a/Source/WebCore/page/CaptionUserPreferences.cpp b/Source/WebCore/page/CaptionUserPreferences.cpp index 5b1590f6f..966fce3aa 100644 --- a/Source/WebCore/page/CaptionUserPreferences.cpp +++ b/Source/WebCore/page/CaptionUserPreferences.cpp @@ -157,6 +157,11 @@ void CaptionUserPreferences::setPreferredLanguage(const String& language) static String trackDisplayName(TextTrack* track) { + if (track == TextTrack::captionMenuOffItem()) + return textTrackOffMenuItemText(); + if (track == TextTrack::captionMenuAutomaticItem()) + return textTrackAutomaticMenuItemText(); + if (track->label().isEmpty() && track->language().isEmpty()) return textTrackNoLabelText(); if (!track->label().isEmpty()) @@ -185,6 +190,9 @@ Vector<RefPtr<TextTrack> > CaptionUserPreferences::sortedTrackListForMenu(TextTr nonCopyingSort(tracksForMenu.begin(), tracksForMenu.end(), textTrackCompare); + tracksForMenu.insert(0, TextTrack::captionMenuOffItem()); + tracksForMenu.insert(1, TextTrack::captionMenuAutomaticItem()); + return tracksForMenu; } diff --git a/Source/WebCore/platform/qt/LocalizedStringsQt.cpp b/Source/WebCore/platform/qt/LocalizedStringsQt.cpp index def96e1e4..585544429 100644 --- a/Source/WebCore/platform/qt/LocalizedStringsQt.cpp +++ b/Source/WebCore/platform/qt/LocalizedStringsQt.cpp @@ -787,20 +787,22 @@ String validationMessageBadInputForNumberText() #if ENABLE(VIDEO_TRACK) String textTrackSubtitlesText() { - notImplemented(); - return String(); + return QCoreApplication::translate("QWebPage", "Subtitles", "Menu section heading for subtitles"); } -String textTrackOffText() +String textTrackOffMenuItemText() { - notImplemented(); - return String(); + return QCoreApplication::translate("QWebPage", "Off", "Menu item label for the track that represents disabling closed captions"); +} + +String textTrackAutomaticMenuItemText() +{ + return QCoreApplication::translate("QWebPage", "Auto", "Menu item label for the track that represents automatic closed captions selection"); } String textTrackNoLabelText() { - notImplemented(); - return String(); + return QCoreApplication::translate("QWebPage", "No label", "Menu item label for a closed captions track that has no other name"); } #endif diff --git a/Source/WebCore/platform/qt/RenderThemeQt.cpp b/Source/WebCore/platform/qt/RenderThemeQt.cpp index a486ba2a8..208a492a5 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQt.cpp @@ -678,6 +678,37 @@ bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const PaintInfo& paint return false; } +bool RenderThemeQt::paintMediaToggleClosedCaptionsButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +{ + HTMLMediaElement* mediaElement = toParentMediaElement(o); + if (!mediaElement) + return false; + + QSharedPointer<StylePainter> p = getStylePainter(paintInfo); + if (p.isNull() || !p->isValid()) + return true; + + p->painter->setRenderHint(QPainter::Antialiasing, true); + + paintMediaBackground(p->painter, r); + + WorldMatrixTransformer transformer(p->painter, o, r); + p->painter->setBrush(getMediaControlForegroundColor(o)); + + QPainterPath captionBubble; + captionBubble.moveTo(98.766, 43.244); + captionBubble.cubicTo(captionBubble.currentPosition() + QPointF(0, -23.163), captionBubble.currentPosition() + QPointF(-21.775, -41.94), captionBubble.currentPosition() + QPointF(-48.637, -41.94)); + captionBubble.cubicTo(captionBubble.currentPosition() + QPointF(-26.859, 0), captionBubble.currentPosition() + QPointF(-48.635, 18.777), captionBubble.currentPosition() + QPointF(-48.635, 41.94)); + captionBubble.cubicTo(captionBubble.currentPosition() + QPointF(0, 18.266), captionBubble.currentPosition() + QPointF(13.546, 33.796), captionBubble.currentPosition() + QPointF(32.444, 39.549)); + captionBubble.cubicTo(captionBubble.currentPosition() + QPointF(1.131, 8.356), captionBubble.currentPosition() + QPointF(26.037, 24.255), captionBubble.currentPosition() + QPointF(22.864, 19.921)); + captionBubble.cubicTo(captionBubble.currentPosition() + QPointF(-4.462, -6.096), captionBubble.currentPosition() + QPointF(-5.159, -13.183), captionBubble.currentPosition() + QPointF(-5.07, -17.566)); + captionBubble.cubicTo(QPointF(77.85, 84.397), QPointF(98.766, 65.923), QPointF(98.766, 43.224)); + captionBubble.closeSubpath(); + + p->painter->drawPath(captionBubble); + return false; +} + bool RenderThemeQt::paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&) { // We don't want to paint this at the moment. diff --git a/Source/WebCore/platform/qt/RenderThemeQt.h b/Source/WebCore/platform/qt/RenderThemeQt.h index 0872b9486..1b137c9b6 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.h +++ b/Source/WebCore/platform/qt/RenderThemeQt.h @@ -146,6 +146,7 @@ protected: virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&); @@ -154,6 +155,9 @@ protected: virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const; virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const; virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; } +#if ENABLE(VIDEO_TRACK) + virtual bool supportsClosedCaptioning() const { return true; } +#endif void paintMediaBackground(QPainter*, const IntRect&) const; double mediaControlsBaselineOpacity() const; |