[yelp-xsl] html.xsl: Work on the video JS/CSS
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp-xsl] html.xsl: Work on the video JS/CSS
- Date: Thu, 19 May 2011 23:31:34 +0000 (UTC)
commit 50c1120ae0cbe0b4ac948788b6035e5d9d20b3f6
Author: Shaun McCance <shaunm gnome org>
Date: Thu May 19 19:34:23 2011 -0400
html.xsl: Work on the video JS/CSS
Gave the play bar a dark theme. Replaced the range input with
a canvas+JS because range input isn't widely supported. Made
the HTML output include controls, and the JS disables controls
and creates its own custom, for non-JS interoperability.
xslt/common/html.xsl | 259 +++++++++++++++++-----------------
xslt/mallard/html/mal2html-media.xsl | 48 +++----
2 files changed, 149 insertions(+), 158 deletions(-)
---
diff --git a/xslt/common/html.xsl b/xslt/common/html.xsl
index e3e3c69..4d3f74e 100644
--- a/xslt/common/html.xsl
+++ b/xslt/common/html.xsl
@@ -982,27 +982,60 @@ pre span.prompt {
}
span.sys { font-family: monospace; }
span.var { font-style: italic; }
-div.media-video > div.inner { display: inline-block; }
+div.media-video > div.inner { display: inline-block; text-align: center; }
div.media-video > div.inner video { margin: 0; }
div.media-controls {
- margin: 0; padding: 2px;
+ min-width: 24em;
+ height: 24px;
+ margin: 0; padding: 4px;
+ border: solid 1px </xsl:text>
+ <xsl:value-of select="$color.text"/><xsl:text>;
+ background-color: </xsl:text>
+ <xsl:value-of select="$color.text_light"/><xsl:text>;
+ color: </xsl:text>
+ <xsl:value-of select="$color.background"/><xsl:text>;
+}
+button.media-play {
+ height: 24px;
+ float: </xsl:text><xsl:value-of select="$left"/><xsl:text>;
background-color: </xsl:text>
<xsl:value-of select="$color.gray_background"/><xsl:text>;
border: solid 1px </xsl:text>
<xsl:value-of select="$color.gray_border"/><xsl:text>;
+ padding: 0; line-height: 0;
+ border-radius: 2px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
}
-div.media-controls button, div.media-controls input { margin: 0; }
-div.media-controls button.media-play { padding: 0; line-height: 0; }
-div.media-controls button.media-play canvas { margin: 0; }
-div.media-controls input.media-range { height: 20px; }
-
-
-div.media-ttml {
- margin: 0; padding: 0;
+button.media-play:hover, button.media-play:focus {
+ background-color: </xsl:text>
+ <xsl:value-of select="$color.blue_background"/><xsl:text>;
+ border-color: </xsl:text>
+ <xsl:value-of select="$color.blue_border"/><xsl:text>;
+ box-shadow: 0 0 2px </xsl:text>
+ <xsl:value-of select="$color.blue_background"/><xsl:text>;
+ -moz-box-shadow: 0 0 2px </xsl:text>
+ <xsl:value-of select="$color.blue_background"/><xsl:text>;
+ -webkit-box-shadow: 0 0 2px </xsl:text>
+ <xsl:value-of select="$color.blue_background"/><xsl:text>;
+}
+button.media-play canvas { margin: 0; }
+div.media-range {
+ display: inline-block;
+ margin: 2px 8px 0 8px;
+ padding: 0;
+ height: 20px;
+}
+span.media-current {
+ float: </xsl:text><xsl:value-of select="$right"/><xsl:text>;
+ font-size: 16px;
+ line-height: 20px;
}
+div.media-ttml { margin: 0; padding: 0; }
div.media-ttml-p {
+ text-align: </xsl:text><xsl:value-of select="$left"/><xsl:text>;
display: none;
- margin: 6px 0 0 0;
+ margin: 6px auto 0 auto;
padding: 6px;
max-width: 24em;
border: solid 1px </xsl:text>
@@ -1194,10 +1227,13 @@ control for audio and video elements as well as support for captions.
<xsl:template name="html.js.media">
<xsl:param name="node" select="."/>
<xsl:text><![CDATA[
+yelp_color_text_light = ']]></xsl:text>
+<xsl:value-of select="$color.text_light"/><xsl:text><![CDATA[';
+yelp_color_gray_border = ']]></xsl:text>
+<xsl:value-of select="$color.gray_border"/><xsl:text><![CDATA[';
yelp_paint_zoom = function (zoom, zoomed) {
var ctxt = zoom.children('canvas')[0].getContext('2d');
- ctxt.strokeStyle = ctxt.fillStyle = ']]></xsl:text>
-<xsl:value-of select="$color.text_light"/><xsl:text><![CDATA['
+ ctxt.strokeStyle = ctxt.fillStyle = yelp_color_text_light;
ctxt.clearRect(0, 0, 10, 10);
ctxt.strokeRect(0.5, 0.5, 9, 9);
if (zoomed) {
@@ -1292,156 +1328,115 @@ $(document).ready(function () {
yelp_resize_imgs();
$(window).bind('resize', yelp_resize_imgs);
});
-Node.prototype.is_a = function (tag, cls) {
- if (this.nodeType == Node.ELEMENT_NODE) {
- if (tag == null || this.tagName.toLowerCase() == tag) {
- if (cls == null)
- return true;
- var clss = this.className.split(' ');
- for (var i = 0; i < clss.length; i++) {
- if (cls == clss[i])
- return true;
- }
- }
- }
- return false;
-};
-function yelp_init_media (media) {
- var control;
- var controlsDiv;
- var playControl;
- var rangeControl;
- var currentSpan;
- for (controlsDiv = media.nextSibling; controlsDiv; controlsDiv = controlsDiv.nextSibling)
-{
- if (controlsDiv.is_a('div', 'media-controls'))
- break;
-}
- if (!controlsDiv)
- return;
- for (control = controlsDiv.firstChild; control; control = control.nextSibling) {
- if (control.nodeType == Node.ELEMENT_NODE) {
- if (control.is_a('button', 'media-play'))
- playControl = control;
- else if (control.is_a('input', 'media-range'))
- rangeControl = control;
- else if (control.is_a('span', 'media-current'))
- currentSpan = control;
- }
- }
-
- var ttmlDiv;
- for (ttmlDiv = controlsDiv.nextSibling; ttmlDiv; ttmlDiv = ttmlDiv.nextSibling)
- if (ttmlDiv.is_a('div', 'media-ttml'))
- break;
-
- var playCanvas;
- for (playCanvas = playControl.firstChild; playCanvas; playCanvas = playCanvas.nextSibling)
- if (playCanvas.is_a('canvas', null))
- break;
- var playCanvasCtxt = playCanvas.getContext('2d');
+function yelp_init_video (element) {
+ var video = $(element);
+ video.removeAttr('controls');
+
+ var controls = $('<div class="media-controls"></div>');
+ var playControl = $('<button class="media-play"></button>').attr({
+ 'data-play-label': video.attr('data-play-label'),
+ 'data-pause-label': video.attr('data-pause-label'),
+ 'value': video.attr('data-play-label')
+ });
+ var playCanvas = $('<canvas width="20" height="20"></canvas>');
+ playControl.append(playCanvas);
+ var rangeCanvas = $('<canvas width="104" height="20"></canvas>');
+ var rangeCanvasCtxt = rangeCanvas[0].getContext('2d');
+ rangeCanvasCtxt.strokeStyle = yelp_color_gray_border;
+ rangeCanvasCtxt.strokeWidth = 1;
+ rangeCanvasCtxt.strokeRect(0.5, 0.5, 103, 19);
+ var currentSpan = $('<span class="media-current">0:00</span>');
+ controls.append(playControl, $('<div class="media-range"></div>').append(rangeCanvas), currentSpan);
+ video.after(controls);
+
+ var playCanvasCtxt = playCanvas[0].getContext('2d');
var paintPlayButton = function () {
- playCanvasCtxt.fillStyle = ']]></xsl:text>
-<xsl:value-of select="$color.text_light"/><xsl:text><![CDATA['
+ playCanvasCtxt.fillStyle = yelp_color_text_light;
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.moveTo(5, 5); playCanvasCtxt.lineTo(5, 15);
+ playCanvasCtxt.lineTo(15, 10); playCanvasCtxt.lineTo(5, 5);
playCanvasCtxt.fill();
}
var paintPauseButton = function () {
- playCanvasCtxt.fillStyle = ']]></xsl:text>
-<xsl:value-of select="$color.text_light"/><xsl:text><![CDATA['
+ playCanvasCtxt.fillStyle = yelp_color_text_light;
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.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();
+ playCanvasCtxt.moveTo(11, 5); playCanvasCtxt.lineTo(15, 5);
+ playCanvasCtxt.lineTo(15, 15); playCanvasCtxt.lineTo(11, 15);
+ playCanvasCtxt.lineTo(11, 5); playCanvasCtxt.fill();
}
paintPlayButton();
+ var video_el = video[0];
var mediaChange = function () {
- if (media.ended)
- media.pause()
- if (media.paused) {
- playControl.setAttribute('value', playControl.getAttribute('data-play-label'));
+ if (video_el.ended)
+ video_el.pause()
+ if (video_el.paused) {
+ playControl.attr('value', playControl.attr('data-play-label'));
paintPlayButton();
}
else {
- playControl.setAttribute('value', playControl.getAttribute('data-pause-label'));
+ playControl.attr('value', playControl.attr('data-pause-label'));
paintPauseButton();
}
}
- media.addEventListener('play', mediaChange, false);
- media.addEventListener('pause', mediaChange, false);
- media.addEventListener('ended', mediaChange, false);
+ video_el.addEventListener('play', mediaChange, false);
+ video_el.addEventListener('pause', mediaChange, false);
+ video_el.addEventListener('ended', mediaChange, false);
var playClick = function () {
- if (media.paused || media.ended)
- media.play();
+ if (video_el.paused || video_el.ended)
+ video_el.play();
else
- media.pause();
+ video_el.pause();
};
- playControl.addEventListener('click', playClick, false);
-
- var ttmlNodes = [];
- var ttmlNodesFill = function (node) {
- var child;
- if (node != null) {
- for (child = node.firstChild; child; child = child.nextSibling) {
- if (child.nodeType == Node.ELEMENT_NODE) {
- if (child.is_a(null, 'media-ttml-node'))
- ttmlNodes[ttmlNodes.length] = child;
- ttmlNodesFill(child);
- }
- }
- }
- }
- ttmlNodesFill(ttmlDiv);
+ playControl.click(playClick);
+
+ var ttmlDiv = video.parent().children('div.media-ttml');
+ var ttmlNodes = ttmlDiv.find('.media-ttml-node');
var timeUpdate = function () {
- rangeControl.value = parseInt((media.currentTime / media.duration) * 100);
- var mins = parseInt(media.currentTime / 60);
- var secs = parseInt(media.currentTime - (60 * mins))
- currentSpan.innerText = mins + (secs < 10 ? ':0' : ':') + secs;
- for (var i = 0; i < ttmlNodes.length; i++) {
- if (media.currentTime >= parseFloat(ttmlNodes[i].getAttribute('data-begin')) &&
- (!ttmlNodes[i].hasAttribute('data-end') ||
- media.currentTime < parseFloat(ttmlNodes[i].getAttribute('data-end')) )) {
- if (ttmlNodes[i].tagName == 'span')
- ttmlNodes[i].style.display = 'inline';
+ var pct = (element.currentTime / element.duration) * 100;
+ rangeCanvasCtxt.fillStyle = yelp_color_gray_border;
+ rangeCanvasCtxt.clearRect(2, 2, 100, 16);
+ rangeCanvasCtxt.fillRect(2, 2, pct, 16);
+ var mins = parseInt(element.currentTime / 60);
+ var secs = parseInt(element.currentTime - (60 * mins))
+ currentSpan.text(mins + (secs < 10 ? ':0' : ':') + secs);
+ ttmlNodes.each(function () {
+ var ttml = this;
+ if (element.currentTime >= parseFloat(ttml.getAttribute('data-begin')) &&
+ (!ttml.hasAttribute('data-end') ||
+ element.currentTime < parseFloat(ttml.getAttribute('data-end')) )) {
+ if (ttml.tagName == 'span')
+ ttml.style.display = 'inline';
else
- ttmlNodes[i].style.display = 'block';
+ ttml.style.display = 'block';
}
else {
- ttmlNodes[i].style.display = 'none';
+ ttml.style.display = 'none';
}
- }
- };
- media.addEventListener('timeupdate', timeUpdate, false);
-
- var rangeChange = function () {
- media.currentTime = (parseInt(rangeControl.value) / 100.0) * media.duration;
+ });
};
- rangeControl.addEventListener('change', rangeChange, false);
+ element.addEventListener('timeupdate', timeUpdate, false);
+
+ rangeCanvas.click(function (event) {
+ var pct = event.clientX - Math.floor(rangeCanvas.offset().left);
+ if (pct < 0)
+ pct = 0;
+ if (pct > 100)
+ pct = 100;
+ element.currentTime = (pct / 100.0) * element.duration;
+ });
};
-document.addEventListener("DOMContentLoaded", function () {
- var vids = document.getElementsByTagName('video');
- for (var i = 0; i < vids.length; i++)
- yelp_init_media(vids[i]);
-}, false);
+$(document).ready(function () {
+ $('video.media-block').each(function () { yelp_init_video(this) });;
+});
]]></xsl:text>
</xsl:template>
diff --git a/xslt/mallard/html/mal2html-media.xsl b/xslt/mallard/html/mal2html-media.xsl
index c70cfae..a314a90 100644
--- a/xslt/mallard/html/mal2html-media.xsl
+++ b/xslt/mallard/html/mal2html-media.xsl
@@ -75,14 +75,32 @@ FIXME
<xsl:template name="mal2html.media.video">
<xsl:param name="node" select="."/>
<xsl:param name="inline" select="false()"/>
- <video src="{$node/@src}" autobuffer="autobuffer">
+ <video src="{$node/@src}" autobuffer="autobuffer" controls="controls">
+ <xsl:attribute name="class">
+ <xsl:text>media </xsl:text>
+ <xsl:choose>
+ <xsl:when test="$inline">
+ <xsl:text>media-inline</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>media-block</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
<xsl:copy-of select="$node/@height"/>
<xsl:copy-of select="$node/@width"/>
+ <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:attribute name="controls">
- <xsl:text>controls</xsl:text>
- </xsl:attribute>
<xsl:apply-templates mode="mal2html.inline.mode" select="$node/node()"/>
</xsl:when>
<xsl:otherwise>
@@ -91,28 +109,6 @@ FIXME
</xsl:choose>
</video>
<xsl:if test="not($inline)">
- <div class="media-controls">
- <button class="media-play">
- <xsl:attribute name="value">
- <xsl:call-template name="l10n.gettext">
- <xsl:with-param name="msgid" select="'Play'"/>
- </xsl:call-template>
- </xsl:attribute>
- <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>
- <canvas width="20" height="20"/>
- </button>
- <input class="media-range" type="range" min="0" max="100" value="0" step="0"/>
- <span class="media-current"/>
- </div>
<xsl:apply-templates mode="mal2html.ttml.mode" select="tt:tt"/>
</xsl:if>
</xsl:template>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]