[yelp-xsl/wip/html5] Use inline SVG icons for media controls
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp-xsl/wip/html5] Use inline SVG icons for media controls
- Date: Fri, 12 Feb 2016 21:48:26 +0000 (UTC)
commit d8598cd77077d8d71b5f04d5d1c10030728bc3c4
Author: Shaun McCance <shaunm gnome org>
Date: Fri Feb 12 16:48:05 2016 -0500
Use inline SVG icons for media controls
xslt/common/html.xsl | 193 +++++++++++++++++-----------------
xslt/common/icons.xsl | 35 ++++++
xslt/docbook/html/db2html-media.xsl | 10 ++-
xslt/mallard/html/mal2html-media.xsl | 20 ++--
4 files changed, 149 insertions(+), 109 deletions(-)
---
diff --git a/xslt/common/html.xsl b/xslt/common/html.xsl
index 931c756..b6473cb 100644
--- a/xslt/common/html.xsl
+++ b/xslt/common/html.xsl
@@ -1430,7 +1430,7 @@ span.var { font-style: italic; }
span.media-audio, span.media-video { display: inline-block; }
audio, video { display: block; margin: 0; }
div.media > div.inner { display: inline-block; text-align: center; }
-div.media-controls {
+.media-controls {
min-width: 24em;
height: 24px;
margin: 0; padding: 0;
@@ -1444,14 +1444,14 @@ div.media-controls {
display: flex;
align-items: center;
}
-.media-audio div.media-controls {
+.media-audio .media-controls {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
-div.media-controls > * {
+.media-controls > * {
flex: 0 1 auto;
}
-div.media-controls > input.media-range {
+.media-controls > input.media-range {
flex: 1 0 auto;
background-color: </xsl:text><xsl:value-of select="$color.fg.dark"/><xsl:text>;
margin: 0 10px;
@@ -1489,7 +1489,7 @@ input.media-range::-moz-range-thumb {
border: solid 1px </xsl:text><xsl:value-of select="$color.fg.dark"/><xsl:text>;
margin-top: -6px;
}
-div.media-controls-audio {
+.media-controls-audio {
border-top: solid 1px </xsl:text><xsl:value-of select="$color.fg"/><xsl:text>;;
border-radius: 4px;
}
@@ -1504,17 +1504,21 @@ button.media-play {
button.media-play:hover, button.media-play:focus {
background-color: </xsl:text><xsl:value-of select="$color.fg.blue"/><xsl:text>;
}
-button.media-play canvas { margin: 0; }
-div.media-time {
+button.media-play .yelp-svg-fill { fill: </xsl:text>
+ <xsl:value-of select="$color.bg.gray"/><xsl:text>; }
+button.media-play .media-pause { display: none; }
+button.media-play-playing .media-play { display: none; }
+button.media-play-playing .media-pause { display: inline; }
+.media-time {
margin: 0;
font-size: 16px;
height: 24px;
line-height: 24px;
}
-div.media-time > span {
+.media-time > span {
padding-</xsl:text><xsl:value-of select="$right"/><xsl:text>: 8px;
}
-span.media-duration {
+.media-duration {
font-size: 12px;
color: </xsl:text><xsl:value-of select="$color.bg.dark"/><xsl:text>;
opacity: 0.8;
@@ -2188,84 +2192,60 @@ function yelp_media_init (media) {
media.pause();
}, false);
- var controls = document.createElement('div');
- controls.className = 'media-controls media-controls-' + media.nodeName;
- media.parentNode.insertBefore(controls, media.nextSibling);
-
- var playControl = document.createElement('button');
- playControl.className = 'media-play';
- playControl.setAttribute('data-play-label', media.getAttribute('data-play-label'));
- playControl.setAttribute('data-pause-label', media.getAttribute('data-pause-label'));
- playControl.setAttribute('value', media.getAttribute('data-play-label'));
- controls.appendChild(playControl);
-
- var playCanvas = document.createElement('canvas');
- playCanvas.setAttribute('width', '20');
- playCanvas.setAttribute('height', '20');
- playControl.appendChild(playCanvas);
-
- var rangeControl = document.createElement('input');
- rangeControl.className = 'media-range'
- rangeControl.setAttribute('type', 'range');
- rangeControl.value = 0;
- controls.appendChild(rangeControl);
-
- var curSpan = document.createElement('span');
- curSpan.className = 'media-current';
- curSpan.textContent = '0:00';
- var durSpan = document.createElement('span');
- durSpan.className = 'media-duration';
- durSpan.textContent = '-:--';
- var timeDiv = document.createElement('div');
- timeDiv.className = 'media-time';
- timeDiv.appendChild(curSpan);
- timeDiv.appendChild(durSpan);
- controls.appendChild(timeDiv);
-
- var playCanvasCtxt = playCanvas.getContext('2d');
- var paintPlayButton = function () {
- playCanvasCtxt.fillStyle = yelp_color_gray_background;
- playCanvasCtxt.clearRect(0, 0, 20, 20);
- playCanvasCtxt.beginPath();
- playCanvasCtxt.moveTo(5, 5); playCanvasCtxt.lineTo(5, 15);
- playCanvasCtxt.lineTo(15, 10); playCanvasCtxt.lineTo(5, 5);
- playCanvasCtxt.fill();
+ var controls = null;
+ for (var cur = media.nextSibling; cur instanceof Element; cur = cur.nextSibling) {
+ if (cur.classList.contains('media-controls')) {
+ controls = cur;
+ break;
+ }
}
- var paintPauseButton = function () {
- playCanvasCtxt.fillStyle = yelp_color_gray_background;
- playCanvasCtxt.clearRect(0, 0, 20, 20);
- playCanvasCtxt.beginPath();
- playCanvasCtxt.moveTo(5, 5); playCanvasCtxt.lineTo(9, 5);
- playCanvasCtxt.lineTo(9, 15); playCanvasCtxt.lineTo(5, 15);
- playCanvasCtxt.lineTo(5, 5); playCanvasCtxt.fill();
- playCanvasCtxt.beginPath();
- playCanvasCtxt.moveTo(11, 5); playCanvasCtxt.lineTo(15, 5);
- playCanvasCtxt.lineTo(15, 15); playCanvasCtxt.lineTo(11, 15);
- playCanvasCtxt.lineTo(11, 5); playCanvasCtxt.fill();
+ if (controls == null) {
+ media.setAttribute('controls', 'controls');
+ return;
}
- paintPlayButton();
+ var playbutton = controls.querySelector('button.media-play');
+ playbutton.addEventListener('click', function () {
+ if (media.paused || media.ended)
+ media.play();
+ else
+ media.pause();
+ }, false);
- var mediaChange = function () {
+ var mediachange = function () {
if (media.ended)
media.pause()
if (media.paused) {
- playControl.setAttribute('value', playControl.getAttribute('data-play-label'));
- paintPlayButton();
+ playbutton.setAttribute('value', playbutton.getAttribute('data-play-label'));
+ playbutton.classList.remove('media-play-playing');
}
else {
- playControl.setAttribute('value', playControl.getAttribute('data-pause-label'));
- paintPauseButton();
+ playbutton.setAttribute('value', playbutton.getAttribute('data-pause-label'));
+ playbutton.classList.add('media-play-playing');
}
}
- media.addEventListener('play', mediaChange, false);
- media.addEventListener('pause', mediaChange, false);
- media.addEventListener('ended', mediaChange, false);
- playControl.addEventListener('click', function () {
- if (media.paused || media.ended)
- media.play();
- else
- media.pause();
+ media.addEventListener('play', mediachange, false);
+ media.addEventListener('pause', mediachange, false);
+ media.addEventListener('ended', mediachange, false);
+
+ var mediarange = controls.querySelector('input.media-range');
+ mediarange.addEventListener('input', function () {
+ var pct = this.value;
+ if (pct < 0)
+ pct = 0;
+ if (pct > 100)
+ pct = 100;
+ media.currentTime = (pct / 100.0) * media.duration;
}, false);
+ var curspan = controls.querySelector('span.media-current');
+ var durspan = controls.querySelector('span.media-duration');
+ var durationUpdate = function () {
+ if (!isNaN(media.duration)) {
+ mins = parseInt(media.duration / 60);
+ secs = parseInt(media.duration - (60 * mins));
+ durspan.textContent = (mins + (secs < 10 ? ':0' : ':') + secs);
+ }
+ };
+ media.addEventListener('durationchange', durationUpdate, false);
var ttmlDiv = null;
var ttmlNodes = null;
@@ -2280,10 +2260,10 @@ function yelp_media_init (media) {
var timeUpdate = function () {
var pct = (media.currentTime / media.duration) * 100;
- rangeControl.value = pct;
+ mediarange.value = pct;
var mins = parseInt(media.currentTime / 60);
var secs = parseInt(media.currentTime - (60 * mins))
- curSpan.textContent = (mins + (secs < 10 ? ':0' : ':') + secs);
+ curspan.textContent = (mins + (secs < 10 ? ':0' : ':') + secs);
if (ttmlNodes != null) {
for (var i = 0; i < ttmlNodes.length; i++) {
var ttml = ttmlNodes[i];
@@ -2302,23 +2282,6 @@ function yelp_media_init (media) {
}
};
media.addEventListener('timeupdate', timeUpdate, false);
- var durationUpdate = function () {
- if (!isNaN(media.duration)) {
- mins = parseInt(media.duration / 60);
- secs = parseInt(media.duration - (60 * mins));
- durSpan.textContent = (mins + (secs < 10 ? ':0' : ':') + secs);
- }
- };
- media.addEventListener('durationchange', durationUpdate, false);
-
- rangeControl.addEventListener('input', function () {
- var pct = this.value;
- if (pct < 0)
- pct = 0;
- if (pct > 100)
- pct = 100;
- media.currentTime = (pct / 100.0) * media.duration;
- }, false);
};
document.addEventListener('DOMContentLoaded', function() {
var matches = document.querySelectorAll('video, audio');
@@ -2527,4 +2490,44 @@ It should return a simple language identifier.
-->
<xsl:template mode="html.syntax.class.mode" match="*"/>
+
+<!--**==========================================================================
+html.media.controls
+Output media controls for a video or audio object.
+:Revision:version="3.20" date="2016-02-12" status="final"
+
+This template outputs HTML containing controls for a media play for audio or
+video HTML elements. To work with the built-in JavaScript binding code, it
+should be placed immediately after the #{audio} or #{video} element.
+-->
+<xsl:template name="html.media.controls">
+ <xsl:param name="type" select="'video'"/>
+ <span class="media-controls media-controls-{$type}">
+ <button class="media-play">
+ <xsl:attribute name="data-play-label">
+ <xsl:call-template name="l10n.gettext">
+ <xsl:with-param name="msgid" select="'Play'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="data-pause-label">
+ <xsl:call-template name="l10n.gettext">
+ <xsl:with-param name="msgid" select="'Pause'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="value">
+ <xsl:call-template name="l10n.gettext">
+ <xsl:with-param name="msgid" select="'Play'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:call-template name="icons.svg.media.play"/>
+ <xsl:call-template name="icons.svg.media.pause"/>
+ </button>
+ <input type="range" class="media-range" value="0"/>
+ <span class="media-time">
+ <span class="media-current">0:00</span>
+ <span class="media-duration">-:--</span>
+ </span>
+ </span>
+</xsl:template>
+
</xsl:stylesheet>
diff --git a/xslt/common/icons.xsl b/xslt/common/icons.xsl
index 88906a3..e118ee0 100644
--- a/xslt/common/icons.xsl
+++ b/xslt/common/icons.xsl
@@ -172,4 +172,39 @@ names.
</svg:svg>
</xsl:template>
+
+<!--**==========================================================================
+icons.svg.media.play
+Output an #{svg} element for a figure zoom-out icon.
+:Revision: version="3.20" date="2016-02-12" status="final"
+
+This template outputs an SVG #{svg} element with a play icon for media controls.
+
+SVG icons can use CSS class names to pick up colors from the !{colors} module.
+By default, this icon uses the #{yelp-svg-fill} class name.
+-->
+<xsl:template name="icons.svg.media.play">
+ <svg:svg width="20" height="20" class="media-play">
+ <svg:polygon points="5,4 5,16 15,10" class="yelp-svg-fill"/>
+ </svg:svg>
+</xsl:template>
+
+
+<!--**==========================================================================
+icons.svg.media.pause
+Output an #{svg} element for a figure zoom-out icon.
+:Revision: version="3.20" date="2016-02-12" status="final"
+
+This template outputs an SVG #{svg} element with a pause icon for media controls.
+
+SVG icons can use CSS class names to pick up colors from the !{colors} module.
+By default, this icon uses the #{yelp-svg-fill} class name.
+-->
+<xsl:template name="icons.svg.media.pause">
+ <svg:svg width="20" height="20" class="media-pause">
+ <svg:rect x="4" y="4" width="4" height="12" class="yelp-svg-fill"/>
+ <svg:rect x="12" y="4" width="4" height="12" class="yelp-svg-fill"/>
+ </svg:svg>
+</xsl:template>
+
</xsl:stylesheet>
diff --git a/xslt/docbook/html/db2html-media.xsl b/xslt/docbook/html/db2html-media.xsl
index f1c96fd..3122123 100644
--- a/xslt/docbook/html/db2html-media.xsl
+++ b/xslt/docbook/html/db2html-media.xsl
@@ -50,7 +50,7 @@ calls *{db2html.mediaobject.fallback} for the contents of the #{audio} element.
$node/ancestor::db:mediaobject[1] |
$node/ancestor::db:inlinemediaobject[1]
)[last()]"/>
- <audio preload="auto" controls="controls">
+ <audio preload="auto">
<xsl:attribute name="src">
<xsl:choose>
<xsl:when test="$node/@fileref">
@@ -75,6 +75,9 @@ calls *{db2html.mediaobject.fallback} for the contents of the #{audio} element.
<xsl:with-param name="node" select="$media"/>
</xsl:call-template>
</audio>
+ <xsl:call-template name="html.media.controls">
+ <xsl:with-param name="type" select="'audio'"/>
+ </xsl:call-template>
</xsl:template>
@@ -160,7 +163,7 @@ attribute on the HTML #{video} element. This template calls
$node/ancestor::db:mediaobject[1] |
$node/ancestor::db:inlinemediaobject[1]
)[last()]"/>
- <video preload="auto" controls="controls">
+ <video preload="auto">
<xsl:attribute name="src">
<xsl:choose>
<xsl:when test="$node/@fileref">
@@ -210,6 +213,9 @@ attribute on the HTML #{video} element. This template calls
<xsl:with-param name="node" select="$media"/>
</xsl:call-template>
</video>
+ <xsl:call-template name="html.media.controls">
+ <xsl:with-param name="type" select="'video'"/>
+ </xsl:call-template>
</xsl:template>
diff --git a/xslt/mallard/html/mal2html-media.xsl b/xslt/mallard/html/mal2html-media.xsl
index 71c7a4c..cb643a0 100644
--- a/xslt/mallard/html/mal2html-media.xsl
+++ b/xslt/mallard/html/mal2html-media.xsl
@@ -108,7 +108,7 @@ HTML #{video} element.
<xsl:template name="mal2html.media.video">
<xsl:param name="node" select="."/>
<xsl:param name="inline" select="false()"/>
- <video src="{$node/@src}" preload="auto" controls="controls">
+ <video src="{$node/@src}" preload="auto">
<xsl:attribute name="class">
<xsl:text>media </xsl:text>
<xsl:choose>
@@ -129,16 +129,6 @@ HTML #{video} element.
<xsl:value-of select="$poster[1]/@src"/>
</xsl:attribute>
</xsl:if>
- <xsl:attribute name="data-play-label">
- <xsl:call-template name="l10n.gettext">
- <xsl:with-param name="msgid" select="'Play'"/>
- </xsl:call-template>
- </xsl:attribute>
- <xsl:attribute name="data-pause-label">
- <xsl:call-template name="l10n.gettext">
- <xsl:with-param name="msgid" select="'Pause'"/>
- </xsl:call-template>
- </xsl:attribute>
<xsl:choose>
<xsl:when test="$inline">
<xsl:apply-templates mode="mal2html.inline.mode" select="$node/node()"/>
@@ -148,6 +138,9 @@ HTML #{video} element.
</xsl:otherwise>
</xsl:choose>
</video>
+ <xsl:call-template name="html.media.controls">
+ <xsl:with-param name="type" select="'video'"/>
+ </xsl:call-template>
<xsl:if test="not($inline)">
<xsl:apply-templates mode="mal2html.ttml.mode" select="tt:tt[1]"/>
</xsl:if>
@@ -169,7 +162,7 @@ in the source to the #{audio} element's fallback content. If ${inline} is
<xsl:template name="mal2html.media.audio">
<xsl:param name="node" select="."/>
<xsl:param name="inline" select="false()"/>
- <audio src="{$node/@src}" preload="auto" controls="controls">
+ <audio src="{$node/@src}" preload="auto">
<xsl:attribute name="class">
<xsl:text>media </xsl:text>
<xsl:choose>
@@ -200,6 +193,9 @@ in the source to the #{audio} element's fallback content. If ${inline} is
</xsl:otherwise>
</xsl:choose>
</audio>
+ <xsl:call-template name="html.media.controls">
+ <xsl:with-param name="type" select="'audio'"/>
+ </xsl:call-template>
<xsl:if test="not($inline)">
<xsl:apply-templates mode="mal2html.ttml.mode" select="tt:tt[1]"/>
</xsl:if>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]