Revision 8f2166cd

b/main/qm/static/qm/jplayer/add-on/jplayer.playlist.min.js
1
/*
2
 * Playlist Object for the jPlayer Plugin
3
 * http://www.jplayer.org
4
 *
5
 * Copyright (c) 2009 - 2011 Happyworm Ltd
6
 * Dual licensed under the MIT and GPL licenses.
7
 *  - http://www.opensource.org/licenses/mit-license.php
8
 *  - http://www.gnu.org/copyleft/gpl.html
9
 *
10
 * Author: Mark J Panaghiston
11
 * Version: 2.1.0 (jPlayer 2.1.0)
12
 * Date: 1st September 2011
13
 */
14

  
15
(function(b,f){jPlayerPlaylist=function(a,c,d){var e=this;this.current=0;this.removing=this.shuffled=this.loop=!1;this.cssSelector=b.extend({},this._cssSelector,a);this.options=b.extend(!0,{},this._options,d);this.playlist=[];this.original=[];this._initPlaylist(c);this.cssSelector.title=this.cssSelector.cssSelectorAncestor+" .jp-title";this.cssSelector.playlist=this.cssSelector.cssSelectorAncestor+" .jp-playlist";this.cssSelector.next=this.cssSelector.cssSelectorAncestor+" .jp-next";this.cssSelector.previous=
16
this.cssSelector.cssSelectorAncestor+" .jp-previous";this.cssSelector.shuffle=this.cssSelector.cssSelectorAncestor+" .jp-shuffle";this.cssSelector.shuffleOff=this.cssSelector.cssSelectorAncestor+" .jp-shuffle-off";this.options.cssSelectorAncestor=this.cssSelector.cssSelectorAncestor;this.options.repeat=function(a){e.loop=a.jPlayer.options.loop};b(this.cssSelector.jPlayer).bind(b.jPlayer.event.ready,function(){e._init()});b(this.cssSelector.jPlayer).bind(b.jPlayer.event.ended,function(){e.next()});
17
b(this.cssSelector.jPlayer).bind(b.jPlayer.event.play,function(){b(this).jPlayer("pauseOthers")});b(this.cssSelector.jPlayer).bind(b.jPlayer.event.resize,function(a){a.jPlayer.options.fullScreen?b(e.cssSelector.title).show():b(e.cssSelector.title).hide()});b(this.cssSelector.previous).click(function(){e.previous();b(this).blur();return!1});b(this.cssSelector.next).click(function(){e.next();b(this).blur();return!1});b(this.cssSelector.shuffle).click(function(){e.shuffle(!0);return!1});b(this.cssSelector.shuffleOff).click(function(){e.shuffle(!1);
18
return!1}).hide();this.options.fullScreen||b(this.cssSelector.title).hide();b(this.cssSelector.playlist+" ul").empty();this._createItemHandlers();b(this.cssSelector.jPlayer).jPlayer(this.options)};jPlayerPlaylist.prototype={_cssSelector:{jPlayer:"#jquery_jplayer_1",cssSelectorAncestor:"#jp_container_1"},_options:{playlistOptions:{autoPlay:!1,loopOnPrevious:!1,shuffleOnLoop:!0,enableRemoveControls:!1,displayTime:"slow",addTime:"fast",removeTime:"fast",shuffleTime:"slow",itemClass:"jp-playlist-item",
19
freeGroupClass:"jp-free-media",freeItemClass:"jp-playlist-item-free",removeItemClass:"jp-playlist-item-remove"}},option:function(a,b){if(b===f)return this.options.playlistOptions[a];this.options.playlistOptions[a]=b;switch(a){case "enableRemoveControls":this._updateControls();break;case "itemClass":case "freeGroupClass":case "freeItemClass":case "removeItemClass":this._refresh(!0),this._createItemHandlers()}return this},_init:function(){var a=this;this._refresh(function(){a.options.playlistOptions.autoPlay?
20
a.play(a.current):a.select(a.current)})},_initPlaylist:function(a){this.current=0;this.removing=this.shuffled=!1;this.original=b.extend(!0,[],a);this._originalPlaylist()},_originalPlaylist:function(){var a=this;this.playlist=[];b.each(this.original,function(b){a.playlist[b]=a.original[b]})},_refresh:function(a){var c=this;if(a&&!b.isFunction(a))b(this.cssSelector.playlist+" ul").empty(),b.each(this.playlist,function(a){b(c.cssSelector.playlist+" ul").append(c._createListItem(c.playlist[a]))}),this._updateControls();
21
else{var d=b(this.cssSelector.playlist+" ul").children().length?this.options.playlistOptions.displayTime:0;b(this.cssSelector.playlist+" ul").slideUp(d,function(){var d=b(this);b(this).empty();b.each(c.playlist,function(a){d.append(c._createListItem(c.playlist[a]))});c._updateControls();b.isFunction(a)&&a();c.playlist.length?b(this).slideDown(c.options.playlistOptions.displayTime):b(this).show()})}},_createListItem:function(a){var c=this,d="<li><div>";d+="<a href='javascript:;' class='"+this.options.playlistOptions.removeItemClass+
22
"'>&times;</a>";if(a.free){var e=!0;d+="<span class='"+this.options.playlistOptions.freeGroupClass+"'>(";b.each(a,function(a,f){b.jPlayer.prototype.format[a]&&(e?e=!1:d+=" | ",d+="<a class='"+c.options.playlistOptions.freeItemClass+"' href='"+f+"' tabindex='1'>"+a+"</a>")});d+=")</span>"}d+="<a href='javascript:;' class='"+this.options.playlistOptions.itemClass+"' tabindex='1'>"+a.title+(a.artist?" <span class='jp-artist'>by "+a.artist+"</span>":"")+"</a>";d+="</div></li>";return d},_createItemHandlers:function(){var a=
23
this;b(this.cssSelector.playlist+" a."+this.options.playlistOptions.itemClass).die("click").live("click",function(){var c=b(this).parent().parent().index();a.current!==c?a.play(c):b(a.cssSelector.jPlayer).jPlayer("play");b(this).blur();return!1});b(a.cssSelector.playlist+" a."+this.options.playlistOptions.freeItemClass).die("click").live("click",function(){b(this).parent().parent().find("."+a.options.playlistOptions.itemClass).click();b(this).blur();return!1});b(a.cssSelector.playlist+" a."+this.options.playlistOptions.removeItemClass).die("click").live("click",
24
function(){var c=b(this).parent().parent().index();a.remove(c);b(this).blur();return!1})},_updateControls:function(){this.options.playlistOptions.enableRemoveControls?b(this.cssSelector.playlist+" ."+this.options.playlistOptions.removeItemClass).show():b(this.cssSelector.playlist+" ."+this.options.playlistOptions.removeItemClass).hide();this.shuffled?(b(this.cssSelector.shuffleOff).show(),b(this.cssSelector.shuffle).hide()):(b(this.cssSelector.shuffleOff).hide(),b(this.cssSelector.shuffle).show())},
25
_highlight:function(a){this.playlist.length&&a!==f&&(b(this.cssSelector.playlist+" .jp-playlist-current").removeClass("jp-playlist-current"),b(this.cssSelector.playlist+" li:nth-child("+(a+1)+")").addClass("jp-playlist-current").find(".jp-playlist-item").addClass("jp-playlist-current"),b(this.cssSelector.title+" li").html(this.playlist[a].title+(this.playlist[a].artist?" <span class='jp-artist'>by "+this.playlist[a].artist+"</span>":"")))},setPlaylist:function(a){this._initPlaylist(a);this._init()},
26
add:function(a,c){b(this.cssSelector.playlist+" ul").append(this._createListItem(a)).find("li:last-child").hide().slideDown(this.options.playlistOptions.addTime);this._updateControls();this.original.push(a);this.playlist.push(a);c?this.play(this.playlist.length-1):this.original.length===1&&this.select(0)},remove:function(a){var c=this;if(a===f)return this._initPlaylist([]),this._refresh(function(){b(c.cssSelector.jPlayer).jPlayer("clearMedia")}),!0;else if(this.removing)return!1;else{a=a<0?c.original.length+
27
a:a;if(0<=a&&a<this.playlist.length)this.removing=!0,b(this.cssSelector.playlist+" li:nth-child("+(a+1)+")").slideUp(this.options.playlistOptions.removeTime,function(){b(this).remove();if(c.shuffled){var d=c.playlist[a];b.each(c.original,function(a){if(c.original[a]===d)return c.original.splice(a,1),!1})}else c.original.splice(a,1);c.playlist.splice(a,1);c.original.length?a===c.current?(c.current=a<c.original.length?c.current:c.original.length-1,c.select(c.current)):a<c.current&&c.current--:(b(c.cssSelector.jPlayer).jPlayer("clearMedia"),
28
c.current=0,c.shuffled=!1,c._updateControls());c.removing=!1});return!0}},select:function(a){a=a<0?this.original.length+a:a;0<=a&&a<this.playlist.length?(this.current=a,this._highlight(a),b(this.cssSelector.jPlayer).jPlayer("setMedia",this.playlist[this.current])):this.current=0},play:function(a){a=a<0?this.original.length+a:a;0<=a&&a<this.playlist.length?this.playlist.length&&(this.select(a),b(this.cssSelector.jPlayer).jPlayer("play")):a===f&&b(this.cssSelector.jPlayer).jPlayer("play")},pause:function(){b(this.cssSelector.jPlayer).jPlayer("pause")},
29
next:function(){var a=this.current+1<this.playlist.length?this.current+1:0;this.loop?a===0&&this.shuffled&&this.options.playlistOptions.shuffleOnLoop&&this.playlist.length>1?this.shuffle(!0,!0):this.play(a):a>0&&this.play(a)},previous:function(){var a=this.current-1>=0?this.current-1:this.playlist.length-1;(this.loop&&this.options.playlistOptions.loopOnPrevious||a<this.playlist.length-1)&&this.play(a)},shuffle:function(a,c){var d=this;a===f&&(a=!this.shuffled);(a||a!==this.shuffled)&&b(this.cssSelector.playlist+
30
" ul").slideUp(this.options.playlistOptions.shuffleTime,function(){(d.shuffled=a)?d.playlist.sort(function(){return 0.5-Math.random()}):d._originalPlaylist();d._refresh(!0);c||!b(d.cssSelector.jPlayer).data("jPlayer").status.paused?d.play(0):d.select(0);b(this).slideDown(d.options.playlistOptions.shuffleTime)})}}})(jQuery);
b/main/qm/static/qm/jplayer/add-on/jquery.jplayer.inspector.js
1
/*
2
 * jPlayerInspector Plugin for jPlayer (2.0.0+) Plugin for jQuery JavaScript Library
3
 * http://www.happyworm.com/jquery/jplayer
4
 *
5
 * Copyright (c) 2009 - 2011 Happyworm Ltd
6
 * Dual licensed under the MIT and GPL licenses.
7
 *  - http://www.opensource.org/licenses/mit-license.php
8
 *  - http://www.gnu.org/copyleft/gpl.html
9
 *
10
 * Author: Mark J Panaghiston
11
 * Version: 1.0.3
12
 * Date: 7th August 2011
13
 *
14
 * For use with jPlayer Version: 2.0.29
15
 *
16
 * Note: Declare inspector instances after jPlayer instances. ie., Otherwise the jPlayer instance is nonsense.
17
 */
18

  
19
(function($, undefined) {
20
	$.jPlayerInspector = {};
21
	$.jPlayerInspector.i = 0;
22
	$.jPlayerInspector.defaults = {
23
		jPlayer: undefined, // The jQuery selector of the jPlayer instance to inspect.
24
		idPrefix: "jplayer_inspector_",
25
		visible: false
26
	};
27
	
28
	var methods = {
29
		init: function(options) {
30
			var self = this;
31
			var $this = $(this);
32
			
33
			var config = $.extend({}, $.jPlayerInspector.defaults, options);
34
			$(this).data("jPlayerInspector", config);
35

  
36
			config.id = $(this).attr("id");
37
			config.jPlayerId = config.jPlayer.attr("id");
38

  
39
			config.windowId = config.idPrefix + "window_" + $.jPlayerInspector.i;
40
			config.statusId = config.idPrefix + "status_" + $.jPlayerInspector.i;
41
			config.configId = config.idPrefix + "config_" + $.jPlayerInspector.i;
42
			config.toggleId = config.idPrefix + "toggle_" + $.jPlayerInspector.i;
43
			config.eventResetId = config.idPrefix + "event_reset_" + $.jPlayerInspector.i;
44
			config.updateId = config.idPrefix + "update_" + $.jPlayerInspector.i;
45
			config.eventWindowId = config.idPrefix + "event_window_" + $.jPlayerInspector.i;
46
			
47
			config.eventId = {};
48
			config.eventJq = {};
49
			config.eventTimeout = {};
50
			config.eventOccurrence = {};
51
			
52
			$.each($.jPlayer.event, function(eventName,eventType) {
53
				config.eventId[eventType] = config.idPrefix + "event_" + eventName + "_" + $.jPlayerInspector.i;
54
				config.eventOccurrence[eventType] = 0;
55
			});
56
			
57
			var structure = 
58
				'<p><a href="#" id="' + config.toggleId + '">' + (config.visible ? "Hide" : "Show") + '</a> jPlayer Inspector</p>' 
59
				+ '<div id="' + config.windowId + '">'
60
					+ '<div id="' + config.statusId + '"></div>'
61
					+ '<div id="' + config.eventWindowId + '" style="padding:5px 5px 0 5px;background-color:#eee;border:1px dotted #000;">'
62
						+ '<p style="margin:0 0 10px 0;"><strong>jPlayer events that have occurred over the past 1 second:</strong>'
63
						+ '<br />(Backgrounds: <span style="padding:0 5px;background-color:#eee;border:1px dotted #000;">Never occurred</span> <span style="padding:0 5px;background-color:#fff;border:1px dotted #000;">Occurred before</span> <span style="padding:0 5px;background-color:#9f9;border:1px dotted #000;">Occurred</span> <span style="padding:0 5px;background-color:#ff9;border:1px dotted #000;">Multiple occurrences</span> <a href="#" id="' + config.eventResetId + '">reset</a>)</p>';
64
			
65
			// MJP: Would use the next 3 lines for ease, but the events are just slapped on the page.
66
			// $.each($.jPlayer.event, function(eventName,eventType) {
67
			// 	structure += '<div id="' + config.eventId[eventType] + '" style="float:left;">' + eventName + '</div>';
68
			// });
69
			
70
			var eventStyle = "float:left;margin:0 5px 5px 0;padding:0 5px;border:1px dotted #000;";
71
			// MJP: Doing it longhand so order and layout easier to control.
72
			structure +=
73
						'<div id="' + config.eventId[$.jPlayer.event.ready] + '" style="' + eventStyle + '"></div>'
74
						+ '<div id="' + config.eventId[$.jPlayer.event.flashreset] + '" style="' + eventStyle + '"></div>'
75
						+ '<div id="' + config.eventId[$.jPlayer.event.resize] + '" style="' + eventStyle + '"></div>'
76
						+ '<div id="' + config.eventId[$.jPlayer.event.repeat] + '" style="' + eventStyle + '"></div>'
77
						+ '<div id="' + config.eventId[$.jPlayer.event.click] + '" style="' + eventStyle + '"></div>'
78
						+ '<div id="' + config.eventId[$.jPlayer.event.error] + '" style="' + eventStyle + '"></div>'
79
						+ '<div id="' + config.eventId[$.jPlayer.event.warning] + '" style="' + eventStyle + '"></div>'
80

  
81
						+ '<div id="' + config.eventId[$.jPlayer.event.loadstart] + '" style="clear:left;' + eventStyle + '"></div>'
82
						+ '<div id="' + config.eventId[$.jPlayer.event.progress] + '" style="' + eventStyle + '"></div>'
83
						+ '<div id="' + config.eventId[$.jPlayer.event.timeupdate] + '" style="' + eventStyle + '"></div>'
84
						+ '<div id="' + config.eventId[$.jPlayer.event.volumechange] + '" style="' + eventStyle + '"></div>'
85

  
86
						+ '<div id="' + config.eventId[$.jPlayer.event.play] + '" style="clear:left;' + eventStyle + '"></div>'
87
						+ '<div id="' + config.eventId[$.jPlayer.event.pause] + '" style="' + eventStyle + '"></div>'
88
						+ '<div id="' + config.eventId[$.jPlayer.event.waiting] + '" style="' + eventStyle + '"></div>'
89
						+ '<div id="' + config.eventId[$.jPlayer.event.playing] + '" style="' + eventStyle + '"></div>'
90
						+ '<div id="' + config.eventId[$.jPlayer.event.seeking] + '" style="' + eventStyle + '"></div>'
91
						+ '<div id="' + config.eventId[$.jPlayer.event.seeked] + '" style="' + eventStyle + '"></div>'
92
						+ '<div id="' + config.eventId[$.jPlayer.event.ended] + '" style="' + eventStyle + '"></div>'
93

  
94
						+ '<div id="' + config.eventId[$.jPlayer.event.loadeddata] + '" style="clear:left;' + eventStyle + '"></div>'
95
						+ '<div id="' + config.eventId[$.jPlayer.event.loadedmetadata] + '" style="' + eventStyle + '"></div>'
96
						+ '<div id="' + config.eventId[$.jPlayer.event.canplay] + '" style="' + eventStyle + '"></div>'
97
						+ '<div id="' + config.eventId[$.jPlayer.event.canplaythrough] + '" style="' + eventStyle + '"></div>'
98

  
99
						+ '<div id="' + config.eventId[$.jPlayer.event.suspend] + '" style="clear:left;' + eventStyle + '"></div>'
100
						+ '<div id="' + config.eventId[$.jPlayer.event.abort] + '" style="' + eventStyle + '"></div>'
101
						+ '<div id="' + config.eventId[$.jPlayer.event.emptied] + '" style="' + eventStyle + '"></div>'
102
						+ '<div id="' + config.eventId[$.jPlayer.event.stalled] + '" style="' + eventStyle + '"></div>'
103
						+ '<div id="' + config.eventId[$.jPlayer.event.ratechange] + '" style="' + eventStyle + '"></div>'
104
						+ '<div id="' + config.eventId[$.jPlayer.event.durationchange] + '" style="' + eventStyle + '"></div>'
105

  
106
						+ '<div style="clear:both"></div>';
107

  
108
			// MJP: Would like a check here in case we missed an event.
109

  
110
			// MJP: Check fails, since it is not on the page yet.
111
/*			$.each($.jPlayer.event, function(eventName,eventType) {
112
				if($("#" + config.eventId[eventType])[0] === undefined) {
113
					structure += '<div id="' + config.eventId[eventType] + '" style="clear:left;' + eventStyle + '">' + eventName + '</div>';
114
				}
115
			});
116
*/
117
			structure +=
118
					'</div>'
119
					+ '<p><a href="#" id="' + config.updateId + '">Update</a> jPlayer Inspector</p>'
120
					+ '<div id="' + config.configId + '"></div>'
121
				+ '</div>';
122
			$(this).html(structure);
123
			
124
			config.windowJq = $("#" + config.windowId);
125
			config.statusJq = $("#" + config.statusId);
126
			config.configJq = $("#" + config.configId);
127
			config.toggleJq = $("#" + config.toggleId);
128
			config.eventResetJq = $("#" + config.eventResetId);
129
			config.updateJq = $("#" + config.updateId);
130

  
131
			$.each($.jPlayer.event, function(eventName,eventType) {
132
				config.eventJq[eventType] = $("#" + config.eventId[eventType]);
133
				config.eventJq[eventType].text(eventName + " (" + config.eventOccurrence[eventType] + ")"); // Sets the text to the event name and (0);
134
				
135
				config.jPlayer.bind(eventType + ".jPlayerInspector", function(e) {
136
					config.eventOccurrence[e.type]++;
137
					if(config.eventOccurrence[e.type] > 1) {
138
						config.eventJq[e.type].css("background-color","#ff9");
139
					} else {
140
						config.eventJq[e.type].css("background-color","#9f9");
141
					}
142
					config.eventJq[e.type].text(eventName + " (" + config.eventOccurrence[e.type] + ")");
143
					// The timer to handle the color
144
					clearTimeout(config.eventTimeout[e.type]);
145
					config.eventTimeout[e.type] = setTimeout(function() {
146
						config.eventJq[e.type].css("background-color","#fff");
147
					}, 1000);
148
					// The timer to handle the occurences.
149
					setTimeout(function() {
150
						config.eventOccurrence[e.type]--;
151
						config.eventJq[e.type].text(eventName + " (" + config.eventOccurrence[e.type] + ")");
152
					}, 1000);
153
					if(config.visible) { // Update the status, if inspector open.
154
						$this.jPlayerInspector("updateStatus");
155
					}
156
				});
157
			});
158

  
159
			config.jPlayer.bind($.jPlayer.event.ready + ".jPlayerInspector", function(e) {
160
				$this.jPlayerInspector("updateConfig");
161
			});
162

  
163
			config.toggleJq.click(function() {
164
				if(config.visible) {
165
					$(this).text("Show");
166
					config.windowJq.hide();
167
					config.statusJq.empty();
168
					config.configJq.empty();
169
				} else {
170
					$(this).text("Hide");
171
					config.windowJq.show();
172
					config.updateJq.click();
173
				}
174
				config.visible = !config.visible;
175
				$(this).blur();
176
				return false;
177
			});
178

  
179
			config.eventResetJq.click(function() {
180
				$.each($.jPlayer.event, function(eventName,eventType) {
181
					config.eventJq[eventType].css("background-color","#eee");
182
				});
183
				$(this).blur();
184
				return false;
185
			});
186

  
187
			config.updateJq.click(function() {
188
				$this.jPlayerInspector("updateStatus");
189
				$this.jPlayerInspector("updateConfig");
190
				return false;
191
			});
192

  
193
			if(!config.visible) {
194
				config.windowJq.hide();
195
			} else {
196
				// config.updateJq.click();
197
			}
198
			
199
			$.jPlayerInspector.i++;
200

  
201
			return this;
202
		},
203
		destroy: function() {
204
			$(this).data("jPlayerInspector") && $(this).data("jPlayerInspector").jPlayer.unbind(".jPlayerInspector");
205
			$(this).empty();
206
		},
207
		updateConfig: function() { // This displays information about jPlayer's configuration in inspector
208
		
209
			var jPlayerInfo = "<p>This jPlayer instance is running in your browser where:<br />"
210

  
211
			for(i = 0; i < $(this).data("jPlayerInspector").jPlayer.data("jPlayer").solutions.length; i++) {
212
				var solution = $(this).data("jPlayerInspector").jPlayer.data("jPlayer").solutions[i];
213
				jPlayerInfo += "&nbsp;jPlayer's <strong>" + solution + "</strong> solution is";				
214
				if($(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].used) {
215
					jPlayerInfo += " being <strong>used</strong> and will support:<strong>";
216
					for(format in $(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].support) {
217
						if($(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].support[format]) {
218
							jPlayerInfo += " " + format;
219
						}
220
					}
221
					jPlayerInfo += "</strong><br />";
222
				} else {
223
					jPlayerInfo += " <strong>not required</strong><br />";
224
				}
225
			}
226
			jPlayerInfo += "</p>";
227

  
228
			if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.active) {
229
				if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").flash.active) {
230
					jPlayerInfo += "<strong>Problem with jPlayer since both HTML5 and Flash are active.</strong>";
231
				} else {
232
					jPlayerInfo += "The <strong>HTML5 is active</strong>.";
233
				}
234
			} else {
235
				if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").flash.active) {
236
					jPlayerInfo += "The <strong>Flash is active</strong>.";
237
				} else {
238
					jPlayerInfo += "No solution is currently active. jPlayer needs a setMedia().";
239
				}
240
			}
241
			jPlayerInfo += "</p>";
242

  
243
			var formatType = $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.formatType;
244
			jPlayerInfo += "<p><code>status.formatType = '" + formatType + "'</code><br />";
245
			if(formatType) {
246
				jPlayerInfo += "<code>Browser canPlay('" + $.jPlayer.prototype.format[formatType].codec + "')</code>";
247
			} else {
248
				jPlayerInfo += "</p>";
249
			}
250
			
251
			jPlayerInfo += "<p><code>status.src = '" + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.src + "'</code></p>";
252

  
253
			jPlayerInfo += "<p><code>status.media = {<br />";
254
			for(prop in $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.media) {
255
				jPlayerInfo += "&nbsp;" + prop + ": " + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.media[prop] + "<br />"; // Some are strings
256
			}
257
			jPlayerInfo += "};</code></p>"
258

  
259
			+ "<p>Raw browser test for HTML5 support. Should equal a function if HTML5 is available.<br />";
260
			if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.audio.available) {
261
				jPlayerInfo += "<code>htmlElement.audio.canPlayType = " + (typeof $(this).data("jPlayerInspector").jPlayer.data("jPlayer").htmlElement.audio.canPlayType) +"</code><br />"
262
			}
263
			if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.video.available) {
264
				jPlayerInfo += "<code>htmlElement.video.canPlayType = " + (typeof $(this).data("jPlayerInspector").jPlayer.data("jPlayer").htmlElement.video.canPlayType) +"</code>";
265
			}
266
			jPlayerInfo += "</p>";
267

  
268
			jPlayerInfo += "<p>This instance is using the constructor options:<br />"
269
			+ "<code>$('#" + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").internal.self.id + "').jPlayer({<br />"
270

  
271
			+ "&nbsp;swfPath: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "swfPath") + "',<br />"
272

  
273
			+ "&nbsp;solution: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "solution") + "',<br />"
274

  
275
			+ "&nbsp;supplied: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "supplied") + "',<br />"
276

  
277
			+ "&nbsp;preload: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "preload") + "',<br />"
278
			
279
			+ "&nbsp;volume: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "volume") + ",<br />"
280
			
281
			+ "&nbsp;muted: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "muted") + ",<br />"
282

  
283
			+ "&nbsp;backgroundColor: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "backgroundColor") + "',<br />"
284

  
285
			+ "&nbsp;cssSelectorAncestor: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelectorAncestor") + "',<br />"
286

  
287
			+ "&nbsp;cssSelector: {";
288

  
289
			var cssSelector = $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelector");
290
			for(prop in cssSelector) {
291
				
292
				// jPlayerInfo += "<br />&nbsp;&nbsp;" + prop + ": '" + cssSelector[prop] + "'," // This works too of course, but want to use option method for deep keys.
293
				jPlayerInfo += "<br />&nbsp;&nbsp;" + prop + ": '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelector." + prop) + "',"
294
			}
295

  
296
			jPlayerInfo = jPlayerInfo.slice(0, -1); // Because the sloppy comma was bugging me.
297

  
298
			jPlayerInfo += "<br />&nbsp;},<br />"
299

  
300
			+ "&nbsp;errorAlerts: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "errorAlerts") + ",<br />"
301
			
302
			+ "&nbsp;warningAlerts: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "warningAlerts") + "<br />"
303

  
304
			+ "});</code></p>";
305
			$(this).data("jPlayerInspector").configJq.html(jPlayerInfo);
306
			return this;
307
		},
308
		updateStatus: function() { // This displays information about jPlayer's status in the inspector
309
			$(this).data("jPlayerInspector").statusJq.html(
310
				"<p>jPlayer is " +
311
				($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.paused ? "paused" : "playing") +
312
				" at time: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentTime*10)/10 + "s." +
313
				" (d: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.duration*10)/10 + "s" +
314
				", sp: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.seekPercent) + "%" +
315
				", cpr: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentPercentRelative) + "%" +
316
				", cpa: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentPercentAbsolute) + "%)</p>"
317
			);
318
			return this;
319
		}
320
	};
321
	$.fn.jPlayerInspector = function( method ) {
322
		// Method calling logic
323
		if ( methods[method] ) {
324
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
325
		} else if ( typeof method === 'object' || ! method ) {
326
			return methods.init.apply( this, arguments );
327
		} else {
328
			$.error( 'Method ' +  method + ' does not exist on jQuery.jPlayerInspector' );
329
		}    
330
	};
331
})(jQuery);
b/main/qm/static/qm/jplayer/blue.monday/jplayer.blue.monday.css
1
/*
2
 * Skin for jPlayer Plugin (jQuery JavaScript Library)
3
 * http://www.happyworm.com/jquery/jplayer
4
 *
5
 * Skin Name: Blue Monday
6
 *
7
 * Copyright (c) 2010-2011 Happyworm Ltd
8
 * Dual licensed under the MIT and GPL licenses.
9
 *  - http://www.opensource.org/licenses/mit-license.php
10
 *  - http://www.gnu.org/copyleft/gpl.html
11
 *
12
 * Author: Silvia Benvenuti
13
 * Skin Version: 4.0 (jPlayer 2.1.0)
14
 * Date: 1st September 2011
15
 */
16
#content-world ul {  }
17
 #content-work ul li {
18
     list-style: none;
19
     background-image:none;
20
     margin:0;
21
     padding:0;
22
 }
23
 div#content-work a{
24
    
25
 }
26

  
27
div.jp-audio,
28
div.jp-video {
29

  
30
	/* Edit the font-size to counteract inherited font sizing.
31
	 * Eg. 1.25em = 1 / 0.8em
32
	 */
33

  
34
	font-size:1.25em; /* 1.25em for testing in site pages */ /* No parent CSS that can effect the size in the demos ZIP */
35

  
36
	font-family:Verdana, Arial, sans-serif;
37
	line-height:1.6;
38
	color: #666;
39
	
40
	background-color:#333333;
41
	position:relative;
42
}
43
div.jp-audio {
44
	width:380px;
45
}
46
div.jp-video-270p {
47
	width:480px;
48
}
49
div.jp-video-360p {
50
	width:640px;
51
}
52
div.jp-video-full {
53
	/* Rules for IE6 (full-screen) */
54
	width:480px;
55
	height:270px;
56
	/* Rules for IE7 (full-screen) - Otherwise the relative container causes other page items that are not position:static (default) to appear over the video/gui. */
57
	position:static !important; position:relative
58
}
59

  
60
div.jp-video-full div.jp-jplayer {
61
	top: 0;
62
	left: 0;
63
	position: fixed !important; position: relative; /* Rules for IE6 (full-screen) */
64
	overflow: hidden;
65
	z-index:1000;
66
}
67

  
68
div.jp-video-full div.jp-gui {
69
	position: fixed !important; position: static; /* Rules for IE6 (full-screen) */
70
	top: 0;
71
	left: 0;
72
	width:100%;
73
	height:100%;
74
	z-index:1000;
75
}
76

  
77
div.jp-video-full div.jp-interface {
78
	position: absolute !important; position: relative; /* Rules for IE6 (full-screen) */
79
	bottom: 0;
80
	left: 0;
81
	z-index:1000;
82
}
83

  
84
div.jp-interface {
85
	position: relative;
86
	background-color:#333333;
87
	width:100%;
88
}
89

  
90
div.jp-audio div.jp-type-single div.jp-interface {
91
	height:44px;
92
}
93
div.jp-audio div.jp-type-playlist div.jp-interface {
94
	height:80px;
95
}
96

  
97
div.jp-video div.jp-interface {
98
	border-top:1px solid #009be3;
99
}
100

  
101
/* @group CONTROLS */
102

  
103
div.jp-controls-holder {
104
	clear: both;
105
	width:440px;
106
	margin:0 auto;
107
	position: relative;
108
	overflow:hidden;
109
	top:-8px; /* This negative value depends on the size of the text in jp-currentTime and jp-duration */
110
}
111

  
112
div.jp-interface ul.jp-controls {
113
	list-style-type:none;
114
	margin:0;
115
	padding: 0;
116
	overflow:hidden;
117
}
118

  
119
div.jp-audio ul.jp-controls {
120
	width: 380px;
121
	padding:2px 0 0;
122
        margin: 10px 0 0 0 !important;
123
}
124

  
125
div.jp-video div.jp-type-single ul.jp-controls {
126
	width: 78px;
127
	margin-left: 200px;
128
}
129

  
130
div.jp-video div.jp-type-playlist ul.jp-controls {
131
	width: 134px;
132
	margin-left: 172px;
133
}
134
div.jp-video ul.jp-controls,
135
div.jp-interface ul.jp-controls li {
136
	display:inline;
137
	float: left;
138
}
139

  
140
div.jp-interface ul.jp-controls a {
141
	display:block;
142
	overflow:hidden;
143
	text-indent:-9999px;
144
}
145
a.jp-play,
146
a.jp-pause {
147
	width:40px;
148
	height:40px;
149
}
150

  
151
a.jp-play {
152
	background: url("jplayer.blue.monday.jpg") 0 0 no-repeat;
153
}
154
a.jp-play:hover {
155
	background: url("jplayer.blue.monday.jpg") -41px 0 no-repeat;
156
        border:none!important;
157
}
158
a.jp-pause {
159
	background: url("jplayer.blue.monday.jpg") 0 -42px no-repeat;
160
	display: none;
161
}
162
a.jp-pause:hover {
163
	background: url("jplayer.blue.monday.jpg") -41px -42px no-repeat;
164
        border:none!important;
165
}
166

  
167
a.jp-stop, a.jp-previous, a.jp-next {
168
	width:28px;
169
	height:28px;
170
	margin-top:6px;
171
}
172

  
173
a.jp-stop {
174
	background: url("jplayer.blue.monday.jpg") 0 -83px no-repeat;
175
	margin-left:10px;
176
}
177

  
178
a.jp-stop:hover {
179
	background: url("jplayer.blue.monday.jpg") -29px -83px no-repeat;
180
        border:none!important;
181
}
182

  
183
a.jp-previous {
184
	background: url("jplayer.blue.monday.jpg") 0 -112px no-repeat;
185
}
186
a.jp-previous:hover {
187
	background: url("jplayer.blue.monday.jpg") -29px -112px no-repeat;
188
        border:none!important;
189
}
190

  
191
a.jp-next {
192
	background: url("jplayer.blue.monday.jpg") 0 -141px no-repeat;
193
}
194
a.jp-next:hover {
195
	background: url("jplayer.blue.monday.jpg") -29px -141px no-repeat;
196
        border:none!important;
197
}
198

  
199
/* @end */
200

  
201
/* @group progress bar */
202

  
203
div.jp-progress {
204
	overflow:hidden;
205
	background-color: #ddd;
206
}
207
div.jp-audio div.jp-progress {
208
	position: absolute;
209
	top:12px;
210
	height:15px;
211
}
212
div.jp-audio div.jp-type-single div.jp-progress {
213
	left:100px;
214
	width:186px;
215
}
216
div.jp-audio div.jp-type-playlist div.jp-progress {
217
	left:166px;
218
	width:130px;
219
}
220
div.jp-video div.jp-progress {
221
	top:0px;
222
	left:0px;
223
	width:100%;
224
	height:10px;
225
}
226
div.jp-seek-bar {
227
	background: url("jplayer.blue.monday.jpg") 0 -202px repeat-x;
228
	width:0px;
229
	height:100%;
230
	cursor: pointer;
231
}
232
div.jp-play-bar {
233
	background: url("jplayer.blue.monday.jpg") 0 -218px repeat-x ;
234
	width:0px;
235
	height:100%;
236
}
237

  
238
/* The seeking class is added/removed inside jPlayer */
239
div.jp-seeking-bg {
240
	background: url("jplayer.blue.monday.seeking.gif");
241
}
242

  
243
/* @end */
244

  
245
/* @group volume controls */
246

  
247

  
248
a.jp-mute,
249
a.jp-unmute,
250
a.jp-volume-max {
251
	width:18px;
252
	height:15px;
253
	margin-top:12px;
254
}
255

  
256
div.jp-audio div.jp-type-single a.jp-mute,
257
div.jp-audio div.jp-type-single a.jp-unmute {
258
	margin-left: 210px;	
259
}
260

  
261
div.jp-audio div.jp-type-playlist a.jp-mute,
262
div.jp-audio div.jp-type-playlist a.jp-unmute {
263
	margin-left: 154px;
264
}
265

  
266
div.jp-audio a.jp-volume-max {
267
	margin-left: 51px;	
268
}
269

  
270
div.jp-video a.jp-mute,
271
div.jp-video a.jp-unmute,
272
div.jp-video a.jp-volume-max {
273
	position: absolute;
274
	top:12px;
275
	margin-top:0;
276
}
277

  
278
div.jp-video a.jp-mute,
279
div.jp-video a.jp-unmute {
280
	left: 50px;
281
}
282

  
283

  
284
div.jp-video a.jp-volume-max {
285
	left: 134px;
286
}
287

  
288
a.jp-mute {
289
	background: url("jplayer.blue.monday.jpg") 0 -170px no-repeat;
290
}
291
a.jp-mute:hover {
292
	background: url("jplayer.blue.monday.jpg") -19px -170px no-repeat;
293
        border:none!important;
294
}
295
a.jp-unmute {
296
	background: url("jplayer.blue.monday.jpg") -60px -170px no-repeat;
297
	display: none;
298
}
299
a.jp-unmute:hover {
300
	background: url("jplayer.blue.monday.jpg") -79px -170px no-repeat;
301
        border:none!important;
302
}
303

  
304
a.jp-volume-max {
305
	background: url("jplayer.blue.monday.jpg") 0 -186px no-repeat;
306
}
307
a.jp-volume-max:hover {
308
	background: url("jplayer.blue.monday.jpg") -19px -186px no-repeat;
309
        border:none!important;
310
}
311

  
312
div.jp-volume-bar {
313
	position: absolute;
314
	overflow:hidden;
315
	background: url("jplayer.blue.monday.jpg") 0 -250px repeat-x;
316
	width:46px;
317
	height:5px;
318
	cursor: pointer;
319
}
320
div.jp-audio div.jp-volume-bar {
321
	top:19px;
322
	left:305px;
323
}
324
div.jp-video div.jp-volume-bar {
325
	top:19px;
326
	left:72px;
327
}
328
div.jp-volume-bar-value {
329
	background: url("jplayer.blue.monday.jpg") 0 -256px repeat-x;
330
	width:0px;
331
	height:5px;
332
}
333

  
334
/* @end */
335

  
336
/* @group current time and duration */
337

  
338
div.jp-audio div.jp-time-holder {
339
	position:absolute;
340
	top:27px;
341
}
342
div.jp-audio div.jp-type-single div.jp-time-holder {
343
	left:100px;
344
	width:186px;
345
}
346
div.jp-audio div.jp-type-playlist div.jp-time-holder {
347
	left:166px;
348
	width:130px;
349
}
350

  
351
div.jp-current-time,
352
div.jp-duration {
353
	width:60px;
354
	font-size:.64em;
355
	font-style:oblique;
356
}
357
div.jp-current-time {
358
	float: left;
359
	display:inline;
360
}
361
div.jp-duration {
362
	float: right;
363
	display:inline;
364
	text-align: right;
365
}
366

  
367
div.jp-video div.jp-current-time {
368
	margin-left:20px;
369
}
370
div.jp-video div.jp-duration {
371
	margin-right:20px;
372
}
373

  
374
/* @end */
375

  
376
/* @group playlist */
377

  
378
div.jp-title {
379
	font-weight:bold;
380
	text-align:center;
381
}
382

  
383
div.jp-title,
384
div.jp-playlist {
385
	width:100%;
386
	background-color:#ccc;
387
	border-top:1px solid #009be3;
388
}
389
div.jp-type-single div.jp-title,
390
div.jp-type-playlist div.jp-title,
391
div.jp-type-single div.jp-playlist {
392
	border-top:none;
393
}
394
div.jp-title ul,
395
div.jp-playlist ul {
396
	list-style-type:none;
397
	margin:0!important;
398
	padding:0 20px;
399
	font-size:.72em;
400
         
401
}
402

  
403
div.jp-title li {
404
	padding:5px 0;
405
	font-weight:bold;
406
}
407
div.jp-playlist li {
408
	padding:5px 0 4px 20px;
409
	border-bottom:1px solid #eee;
410
}
411

  
412
div.jp-playlist li div {
413
	display:inline;
414
}
415

  
416
/* Note that the first-child (IE6) and last-child (IE6/7/8) selectors do not work on IE */
417

  
418
div.jp-type-playlist div.jp-playlist li:last-child {
419
	padding:5px 0 5px 20px;
420
	border-bottom:none;
421
}
422
div.jp-type-playlist div.jp-playlist li.jp-playlist-current {
423
	list-style-type:square;
424
	list-style-position:inside;
425
	padding-left:7px;
426
}
427
div.jp-type-playlist div.jp-playlist a {
428
	color: #333;
429
	text-decoration: none;
430
}
431
div.jp-type-playlist div.jp-playlist a:hover {
432
	color:#0d88c1;
433
        border:none!important;
434
}
435
div.jp-type-playlist div.jp-playlist a.jp-playlist-current {
436
	color:#0d88c1;
437
}
438

  
439
div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove {
440
	float:right;
441
	display:inline;
442
	text-align:right;
443
	margin-right:10px;
444
	font-weight:bold;
445
	color:#666;
446
}
447
div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove:hover {
448
	color:#0d88c1;
449
        border:none!important;
450
}
451
div.jp-type-playlist div.jp-playlist span.jp-free-media {
452
	float:right;
453
	display:inline;
454
	text-align:right;
455
	margin-right:10px;
456
}
457
div.jp-type-playlist div.jp-playlist span.jp-free-media a{
458
	color:#666;
459
}
460
div.jp-type-playlist div.jp-playlist span.jp-free-media a:hover{
461
	color:#0d88c1;
462
        border:none!important;
463
}
464
span.jp-artist {
465
	font-size:.8em;
466
	color:#666;
467
}
468

  
469
/* @end */
470

  
471
div.jp-video-play {
472
	position:absolute;
473
	top:0;
474
	left:0;
475
	width:100%;
476
	cursor:pointer;
477
	background-color:rgba(0,0,0,0); /* Makes IE9 work with the active area over the whole video area. IE6/7/8 only have the button as active area. */
478
}
479
div.jp-video-270p div.jp-video-play {
480
	height:270px;
481
}
482
div.jp-video-360p div.jp-video-play {
483
	height:360px;
484
}
485
div.jp-video-full div.jp-video-play {
486
	height:100%;
487
	z-index:1000;
488
}
489
a.jp-video-play-icon {
490
	position:relative;
491
	display:block;
492
	width: 112px;
493
	height: 100px;
494

  
495
	margin-left:-56px;
496
	margin-top:-50px;
497
	left:50%;
498
	top:50%;
499

  
500
	background: url("jplayer.blue.monday.video.play.png") 0 0 no-repeat;
501
	text-indent:-9999px;
502
}
503
div.jp-video-play:hover a.jp-video-play-icon {
504
	background: url("jplayer.blue.monday.video.play.png") 0 -100px no-repeat;
505
        border:none!important;
506
}
507

  
508

  
509

  
510

  
511

  
512
div.jp-jplayer audio,
513
div.jp-jplayer {
514
	width:0px;
515
	height:0px;
516
}
517

  
518
div.jp-jplayer {
519
	background-color: #000000;
520
}
521

  
522

  
523

  
524

  
525

  
526
/* @group TOGGLES */
527

  
528
/* The audio toggles are nested inside jp-time-holder */
529

  
530
ul.jp-toggles {
531
	list-style-type:none;
532
	padding:0;
533
	margin:0 auto;
534
	overflow:hidden;
535
}
536

  
537
div.jp-audio .jp-type-single ul.jp-toggles {
538
	width:25px;
539
        margin: 0 auto!important;
540
}
541
div.jp-audio .jp-type-playlist ul.jp-toggles {
542
	width:55px;
543
	margin: 0;
544
	position: absolute;
545
	left: 325px;
546
	top: 50px;
547
}
548

  
549
div.jp-video ul.jp-toggles {
550
	margin-top:10px;
551
	width:100px;
552
}
553

  
554
ul.jp-toggles li {
555
	display:block;
556
	float:right;
557
}
558

  
559
ul.jp-toggles li a {
560
	display:block;
561
	width:25px;
562
	height:18px;
563
	text-indent:-9999px;
564
	line-height:100%; /* need this for IE6 */
565
}
566

  
567
a.jp-full-screen {
568
	background: url("jplayer.blue.monday.jpg") 0 -310px no-repeat;
569
	margin-left: 20px;
570
}
571

  
572
a.jp-full-screen:hover {
573
	background: url("jplayer.blue.monday.jpg") -30px -310px no-repeat;
574
        border:none!important;
575
}
576

  
577
a.jp-restore-screen {
578
	background: url("jplayer.blue.monday.jpg") -60px -310px no-repeat;
579
	margin-left: 20px;
580
}
581

  
582
a.jp-restore-screen:hover {
583
	background: url("jplayer.blue.monday.jpg") -90px -310px no-repeat;
584
        border:none!important;
585
}
586

  
587
a.jp-repeat {
588
	background: url("jplayer.blue.monday.jpg") 0 -290px no-repeat;
589
}
590

  
591
a.jp-repeat:hover {
592
	background: url("jplayer.blue.monday.jpg") -30px -290px no-repeat;
593
        border:none!important;
594
}
595

  
596
a.jp-repeat-off {
597
	background: url("jplayer.blue.monday.jpg") -60px -290px no-repeat;
598
}
599

  
600
a.jp-repeat-off:hover {
601
	background: url("jplayer.blue.monday.jpg") -90px -290px no-repeat;
602
        border:none!important;
603
}
604

  
605
a.jp-shuffle {
606
	background: url("jplayer.blue.monday.jpg") 0 -270px no-repeat;
607
	margin-left: 5px;
608
}
609

  
610
a.jp-shuffle:hover {
611
	background: url("jplayer.blue.monday.jpg") -30px -270px no-repeat;
612
        border:none!important;
613
}
614

  
615
a.jp-shuffle-off {
616
	background: url("jplayer.blue.monday.jpg") -60px -270px no-repeat;
617
	margin-left: 5px;
618
}
619

  
620
a.jp-shuffle-off:hover {
621
	background: url("jplayer.blue.monday.jpg") -90px -270px no-repeat;
622
        border:none!important;
623
}
624

  
625

  
626
/* @end */
627

  
628
/* @group NO SOLUTION error feedback */
629

  
630
.jp-no-solution {
631

  
632
	width:335px;
633
	padding:3px 10px 3px 30px!important;
634
                    margin : -40px 0 20px -100px!important;
635
                    float:left;
636
	background-color:#eee;
637
	color:#000;
638
	display:none;
639
                    font-size: 0.9em!important;
640
                    z-index: 1000;
641
}
642

  
643
.jp-no-solution a {
644
	color:#000;
645
}
646

  
647
.jp-no-solution span {
648
	font-size:1em;
649
	display:block;
650
	text-align:center;
651
	font-weight:bold;
652
}
653

  
654
/* @end */
b/main/qm/static/qm/jplayer/circle.player.js
1
/*
2
 * CirclePlayer for the jPlayer Plugin (jQuery)
3
 * http://www.jplayer.org
4
 *
5
 * Copyright (c) 2009 - 2011 Happyworm Ltd
6
 * Dual licensed under the MIT and GPL licenses.
7
 *  - http://www.opensource.org/licenses/mit-license.php
8
 *  - http://www.gnu.org/copyleft/gpl.html
9
 *
10
 * Version: 1.0.1 (jPlayer 2.0.9)
11
 * Date: 30th May 2011
12
 *
13
 * Author: Mark J Panaghiston @thepag
14
 *
15
 * CirclePlayer prototype developed by:
16
 * Mark Boas @maboa
17
 * Silvia Benvenuti @aulentina
18
 * Jussi Kalliokoski @quinirill
19
 *
20
 * Inspired by :
21
 * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt
22
 * and
23
 * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause
24
 *
25
 * Standing on the shoulders of :
26
 * John Resig @jresig
27
 * Mark Panaghiston @thepag
28
 * Louis-Rémi Babé @Louis_Remi
29
 */
30

  
31

  
32
var CirclePlayer = function(jPlayerSelector, media, options) {
33
	var	self = this,
34

  
35
		defaults = {
36
			// solution: "flash, html", // For testing Flash with CSS3
37
			supplied: "m4a, oga",
38
			// Android 2.3 corrupts media element if preload:"none" is used.
39
			// preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too.
40
			cssSelectorAncestor: "#cp_container_1",
41
			cssSelector: {
42
				play: ".cp-play",
43
				pause: ".cp-pause"
44
			}
45
		},
46

  
47
		cssSelector = {
48
			bufferHolder: ".cp-buffer-holder",
49
			buffer1: ".cp-buffer-1",
50
			buffer2: ".cp-buffer-2",
51
			progressHolder: ".cp-progress-holder",
52
			progress1: ".cp-progress-1",
53
			progress2: ".cp-progress-2",
54
			circleControl: ".cp-circle-control"
55
		};
56

  
57
	this.cssClass = {
58
		gt50: "cp-gt50",
59
		fallback: "cp-fallback"
60
	};
61

  
62
	this.spritePitch = 104;
63
	this.spriteRatio = 0.24; // Number of steps / 100
64

  
65
	this.player = $(jPlayerSelector);
66
	this.media = $.extend({}, media);
67
	this.options = $.extend(true, {}, defaults, options); // Deep copy
68

  
69
	this.cssTransforms = Modernizr.csstransforms;
70
	this.audio = {};
71
	this.dragging = false; // Indicates if the progressbar is being 'dragged'.
72

  
73
	this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy.
74

  
75
	this.jq = {};
76
	$.each(cssSelector, function(entity, cssSel) {
77
		self.jq[entity] = $(self.options.cssSelectorAncestor + " " + cssSel);
78
	});
79

  
80
	this._initSolution();
81
	this._initPlayer();
82
};
83

  
84
CirclePlayer.prototype = {
85
	_createHtml: function() {
86
	},
87
	_initPlayer: function() {
88
		var self = this;
89
		this.player.jPlayer(this.options);
90

  
91
		this.player.bind($.jPlayer.event.ready + this.eventNamespace, function(event) {
92
			if(event.jPlayer.html.used && event.jPlayer.html.audio.available) {
93
				self.audio = $(this).data("jPlayer").htmlElement.audio;
94
			}
95
			$(this).jPlayer("setMedia", self.media);
96
			self._initCircleControl();
97
		});
98

  
99
		this.player.bind($.jPlayer.event.play + this.eventNamespace, function(event) {
100
			$(this).jPlayer("pauseOthers");
101
		});
102

  
103
		// This event fired as play time increments
104
		this.player.bind($.jPlayer.event.timeupdate + this.eventNamespace, function(event) {
105
			if (!self.dragging) {
106
				self._timeupdate(event.jPlayer.status.currentPercentAbsolute);
107
			}
108
		});
109

  
110
		// This event fired as buffered time increments
111
		this.player.bind($.jPlayer.event.progress + this.eventNamespace, function(event) {
112
			var percent = 0;
113
			if((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) {
114
				if(self.audio.duration > 0) {
115
					var bufferTime = 0;
116
					for(var i = 0; i < self.audio.buffered.length; i++) {
117
						bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i);
118
						// console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration);
119
					}
120
					percent = 100 * bufferTime / self.audio.duration;
121
				} // else the Metadata has not been read yet.
122
				// console.log("percent = " + percent);
123
			} else { // Fallback if buffered not supported
124
				// percent = event.jPlayer.status.seekPercent;
125
				percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined.
126
			}
127
			self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill.
128
			// Firefox 4 does not always give the final progress event when buffered = 100%
129
		});
130

  
131
		this.player.bind($.jPlayer.event.ended + this.eventNamespace, function(event) {
132
			self._resetSolution();
133
		});
134
	},
135
	_initSolution: function() {
136
		if (this.cssTransforms) {
137
			this.jq.progressHolder.show();
138
			this.jq.bufferHolder.show();
139
		}
140
		else {
141
			this.jq.progressHolder.addClass(this.cssClass.gt50).show();
142
			this.jq.progress1.addClass(this.cssClass.fallback);
143
			this.jq.progress2.hide();
144
			this.jq.bufferHolder.hide();
145
		}
146
		this._resetSolution();
147
	},
148
	_resetSolution: function() {
149
		if (this.cssTransforms) {
150
			this.jq.progressHolder.removeClass(this.cssClass.gt50);
151
			this.jq.progress1.css({'transform': 'rotate(0deg)'});
152
			this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide();
153
		}
154
		else {
155
			this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px');
156
		}
157
	},
158
	_initCircleControl: function() {
159
		var self = this;
160
		this.jq.circleControl.grab({
161
			onstart: function(){
162
				self.dragging = true;
163
			}, onmove: function(event){
164
				var pc = self._getArcPercent(event.position.x, event.position.y);
165
				self.player.jPlayer("playHead", pc).jPlayer("play");
166
				self._timeupdate(pc);
167
			}, onfinish: function(event){
168
				self.dragging = false;
169
				var pc = self._getArcPercent(event.position.x, event.position.y);
170
				self.player.jPlayer("playHead", pc).jPlayer("play");
171
			}
172
		});
173
	},
174
	_timeupdate: function(percent) {
175
		var degs = percent * 3.6+"deg";
176

  
177
		var spriteOffset = (Math.floor((Math.round(percent))*this.spriteRatio)-1)*-this.spritePitch;
178

  
179
		if (percent <= 50) {
180
			if (this.cssTransforms) {
181
				this.jq.progressHolder.removeClass(this.cssClass.gt50);
182
				this.jq.progress1.css({'transform': 'rotate(' + degs + ')'});
183
				this.jq.progress2.hide();
184
			} else { // fall back
185
				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
186
			}
187
		} else if (percent <= 100) {
188
			if (this.cssTransforms) {
189
				this.jq.progressHolder.addClass(this.cssClass.gt50);
190
				this.jq.progress1.css({'transform': 'rotate(180deg)'});
191
				this.jq.progress2.css({'transform': 'rotate(' + degs + ')'});
192
				this.jq.progress2.show();
193
			} else { // fall back
194
				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
195
			}
196
		}
197
	},
198
	_progress: function(percent) {
199
		var degs = percent * 3.6+"deg";
200

  
201
		if (this.cssTransforms) {
202
			if (percent <= 50) {
203
				this.jq.bufferHolder.removeClass(this.cssClass.gt50);
204
				this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'});
205
				this.jq.buffer2.hide();
206
			} else if (percent <= 100) {
207
				this.jq.bufferHolder.addClass(this.cssClass.gt50);
208
				this.jq.buffer1.css({'transform': 'rotate(180deg)'});
209
				this.jq.buffer2.show();
210
				this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'});
211
			}
212
		}
213
	},
214
	_getArcPercent: function(pageX, pageY) {
215
		var	offset	= this.jq.circleControl.offset(),
216
			x	= pageX - offset.left - this.jq.circleControl.width()/2,
217
			y	= pageY - offset.top - this.jq.circleControl.height()/2,
218
			theta	= Math.atan2(y,x);
219

  
220
		if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) {
221
			theta = 2 * Math.PI + theta;
222
		}
223

  
224
		// theta is now value between -0.5PI and 1.5PI
225
		// ready to be normalized and applied
226

  
227
		return (theta + Math.PI / 2) / 2 * Math.PI * 10;
228
	},
229
	setMedia: function(media) {
230
		this.media = $.extend({}, media);
231
		this.player.jPlayer("setMedia", this.media);
232
	},
233
	play: function(time) {
234
		this.player.jPlayer("play", time);
235
	},
236
	pause: function(time) {
237
		this.player.jPlayer("pause", time);
238
	},
239
	destroy: function() {
240
		this.player.unbind(this.eventNamespace);
241
		this.player.jPlayer("destroy");
242
	}
243
};
b/main/qm/static/qm/jplayer/jplayer.playlist.min.js
1
/*
2
 * Playlist Object for the jPlayer Plugin
3
 * http://www.jplayer.org
4
 *
5
 * Copyright (c) 2009 - 2011 Happyworm Ltd
6
 * Dual licensed under the MIT and GPL licenses.
7
 *  - http://www.opensource.org/licenses/mit-license.php
8
 *  - http://www.gnu.org/copyleft/gpl.html
9
 *
10
 * Author: Mark J Panaghiston
11
 * Version: 2.1.0 (jPlayer 2.1.0)
12
 * Date: 1st September 2011
13
 */
14

  
15
(function(b,f){jPlayerPlaylist=function(a,c,d){var e=this;this.current=0;this.removing=this.shuffled=this.loop=!1;this.cssSelector=b.extend({},this._cssSelector,a);this.options=b.extend(!0,{},this._options,d);this.playlist=[];this.original=[];this._initPlaylist(c);this.cssSelector.title=this.cssSelector.cssSelectorAncestor+" .jp-title";this.cssSelector.playlist=this.cssSelector.cssSelectorAncestor+" .jp-playlist";this.cssSelector.next=this.cssSelector.cssSelectorAncestor+" .jp-next";this.cssSelector.previous=
16
this.cssSelector.cssSelectorAncestor+" .jp-previous";this.cssSelector.shuffle=this.cssSelector.cssSelectorAncestor+" .jp-shuffle";this.cssSelector.shuffleOff=this.cssSelector.cssSelectorAncestor+" .jp-shuffle-off";this.options.cssSelectorAncestor=this.cssSelector.cssSelectorAncestor;this.options.repeat=function(a){e.loop=a.jPlayer.options.loop};b(this.cssSelector.jPlayer).bind(b.jPlayer.event.ready,function(){e._init()});b(this.cssSelector.jPlayer).bind(b.jPlayer.event.ended,function(){e.next()});
17
b(this.cssSelector.jPlayer).bind(b.jPlayer.event.play,function(){b(this).jPlayer("pauseOthers")});b(this.cssSelector.jPlayer).bind(b.jPlayer.event.resize,function(a){a.jPlayer.options.fullScreen?b(e.cssSelector.title).show():b(e.cssSelector.title).hide()});b(this.cssSelector.previous).click(function(){e.previous();b(this).blur();return!1});b(this.cssSelector.next).click(function(){e.next();b(this).blur();return!1});b(this.cssSelector.shuffle).click(function(){e.shuffle(!0);return!1});b(this.cssSelector.shuffleOff).click(function(){e.shuffle(!1);
18
return!1}).hide();this.options.fullScreen||b(this.cssSelector.title).hide();b(this.cssSelector.playlist+" ul").empty();this._createItemHandlers();b(this.cssSelector.jPlayer).jPlayer(this.options)};jPlayerPlaylist.prototype={_cssSelector:{jPlayer:"#jquery_jplayer_1",cssSelectorAncestor:"#jp_container_1"},_options:{playlistOptions:{autoPlay:!1,loopOnPrevious:!1,shuffleOnLoop:!0,enableRemoveControls:!1,displayTime:"slow",addTime:"fast",removeTime:"fast",shuffleTime:"slow",itemClass:"jp-playlist-item",
19
freeGroupClass:"jp-free-media",freeItemClass:"jp-playlist-item-free",removeItemClass:"jp-playlist-item-remove"}},option:function(a,b){if(b===f)return this.options.playlistOptions[a];this.options.playlistOptions[a]=b;switch(a){case "enableRemoveControls":this._updateControls();break;case "itemClass":case "freeGroupClass":case "freeItemClass":case "removeItemClass":this._refresh(!0),this._createItemHandlers()}return this},_init:function(){var a=this;this._refresh(function(){a.options.playlistOptions.autoPlay?
20
a.play(a.current):a.select(a.current)})},_initPlaylist:function(a){this.current=0;this.removing=this.shuffled=!1;this.original=b.extend(!0,[],a);this._originalPlaylist()},_originalPlaylist:function(){var a=this;this.playlist=[];b.each(this.original,function(b){a.playlist[b]=a.original[b]})},_refresh:function(a){var c=this;if(a&&!b.isFunction(a))b(this.cssSelector.playlist+" ul").empty(),b.each(this.playlist,function(a){b(c.cssSelector.playlist+" ul").append(c._createListItem(c.playlist[a]))}),this._updateControls();
21
else{var d=b(this.cssSelector.playlist+" ul").children().length?this.options.playlistOptions.displayTime:0;b(this.cssSelector.playlist+" ul").slideUp(d,function(){var d=b(this);b(this).empty();b.each(c.playlist,function(a){d.append(c._createListItem(c.playlist[a]))});c._updateControls();b.isFunction(a)&&a();c.playlist.length?b(this).slideDown(c.options.playlistOptions.displayTime):b(this).show()})}},_createListItem:function(a){var c=this,d="<li><div>";d+="<a href='javascript:;' class='"+this.options.playlistOptions.removeItemClass+
22
"'>&times;</a>";if(a.free){var e=!0;d+="<span class='"+this.options.playlistOptions.freeGroupClass+"'>(";b.each(a,function(a,f){b.jPlayer.prototype.format[a]&&(e?e=!1:d+=" | ",d+="<a class='"+c.options.playlistOptions.freeItemClass+"' href='"+f+"' tabindex='1'>"+a+"</a>")});d+=")</span>"}d+="<a href='javascript:;' class='"+this.options.playlistOptions.itemClass+"' tabindex='1'>"+a.title+(a.artist?" <span class='jp-artist'>by "+a.artist+"</span>":"")+"</a>";d+="</div></li>";return d},_createItemHandlers:function(){var a=
23
this;b(this.cssSelector.playlist+" a."+this.options.playlistOptions.itemClass).die("click").live("click",function(){var c=b(this).parent().parent().index();a.current!==c?a.play(c):b(a.cssSelector.jPlayer).jPlayer("play");b(this).blur();return!1});b(a.cssSelector.playlist+" a."+this.options.playlistOptions.freeItemClass).die("click").live("click",function(){b(this).parent().parent().find("."+a.options.playlistOptions.itemClass).click();b(this).blur();return!1});b(a.cssSelector.playlist+" a."+this.options.playlistOptions.removeItemClass).die("click").live("click",
24
function(){var c=b(this).parent().parent().index();a.remove(c);b(this).blur();return!1})},_updateControls:function(){this.options.playlistOptions.enableRemoveControls?b(this.cssSelector.playlist+" ."+this.options.playlistOptions.removeItemClass).show():b(this.cssSelector.playlist+" ."+this.options.playlistOptions.removeItemClass).hide();this.shuffled?(b(this.cssSelector.shuffleOff).show(),b(this.cssSelector.shuffle).hide()):(b(this.cssSelector.shuffleOff).hide(),b(this.cssSelector.shuffle).show())},
25
_highlight:function(a){this.playlist.length&&a!==f&&(b(this.cssSelector.playlist+" .jp-playlist-current").removeClass("jp-playlist-current"),b(this.cssSelector.playlist+" li:nth-child("+(a+1)+")").addClass("jp-playlist-current").find(".jp-playlist-item").addClass("jp-playlist-current"),b(this.cssSelector.title+" li").html(this.playlist[a].title+(this.playlist[a].artist?" <span class='jp-artist'>by "+this.playlist[a].artist+"</span>":"")))},setPlaylist:function(a){this._initPlaylist(a);this._init()},
26
add:function(a,c){b(this.cssSelector.playlist+" ul").append(this._createListItem(a)).find("li:last-child").hide().slideDown(this.options.playlistOptions.addTime);this._updateControls();this.original.push(a);this.playlist.push(a);c?this.play(this.playlist.length-1):this.original.length===1&&this.select(0)},remove:function(a){var c=this;if(a===f)return this._initPlaylist([]),this._refresh(function(){b(c.cssSelector.jPlayer).jPlayer("clearMedia")}),!0;else if(this.removing)return!1;else{a=a<0?c.original.length+
27
a:a;if(0<=a&&a<this.playlist.length)this.removing=!0,b(this.cssSelector.playlist+" li:nth-child("+(a+1)+")").slideUp(this.options.playlistOptions.removeTime,function(){b(this).remove();if(c.shuffled){var d=c.playlist[a];b.each(c.original,function(a){if(c.original[a]===d)return c.original.splice(a,1),!1})}else c.original.splice(a,1);c.playlist.splice(a,1);c.original.length?a===c.current?(c.current=a<c.original.length?c.current:c.original.length-1,c.select(c.current)):a<c.current&&c.current--:(b(c.cssSelector.jPlayer).jPlayer("clearMedia"),
28
c.current=0,c.shuffled=!1,c._updateControls());c.removing=!1});return!0}},select:function(a){a=a<0?this.original.length+a:a;0<=a&&a<this.playlist.length?(this.current=a,this._highlight(a),b(this.cssSelector.jPlayer).jPlayer("setMedia",this.playlist[this.current])):this.current=0},play:function(a){a=a<0?this.original.length+a:a;0<=a&&a<this.playlist.length?this.playlist.length&&(this.select(a),b(this.cssSelector.jPlayer).jPlayer("play")):a===f&&b(this.cssSelector.jPlayer).jPlayer("play")},pause:function(){b(this.cssSelector.jPlayer).jPlayer("pause")},
29
next:function(){var a=this.current+1<this.playlist.length?this.current+1:0;this.loop?a===0&&this.shuffled&&this.options.playlistOptions.shuffleOnLoop&&this.playlist.length>1?this.shuffle(!0,!0):this.play(a):a>0&&this.play(a)},previous:function(){var a=this.current-1>=0?this.current-1:this.playlist.length-1;(this.loop&&this.options.playlistOptions.loopOnPrevious||a<this.playlist.length-1)&&this.play(a)},shuffle:function(a,c){var d=this;a===f&&(a=!this.shuffled);(a||a!==this.shuffled)&&b(this.cssSelector.playlist+
30
" ul").slideUp(this.options.playlistOptions.shuffleTime,function(){(d.shuffled=a)?d.playlist.sort(function(){return 0.5-Math.random()}):d._originalPlaylist();d._refresh(!0);c||!b(d.cssSelector.jPlayer).data("jPlayer").status.paused?d.play(0):d.select(0);b(this).slideDown(d.options.playlistOptions.shuffleTime)})}}})(jQuery);
b/main/qm/static/qm/jplayer/jplayer_qm/jplayer_qm.css
1
/*
2
 * Skin for jPlayer Plugin (jQuery JavaScript Library)
3
 * http://www.happyworm.com/jquery/jplayer
4
 *
5
 * Skin Name: Blue Monday
6
 *
7
 * Copyright (c) 2010-2011 Happyworm Ltd
8
 * Dual licensed under the MIT and GPL licenses.
9
 *  - http://www.opensource.org/licenses/mit-license.php
10
 *  - http://www.gnu.org/copyleft/gpl.html
11
 *
12
 * Author: Silvia Benvenuti
13
 * Skin Version: 4.0 (jPlayer 2.1.0)
14
 * Date: 1st September 2011
15
 */
16
#content-world ul {  }
17
 #content-work ul li {
18
     list-style: none;
19
     background-image:none;
20
     margin:0;
21
     padding:0;
22
 }
23
 div#content-work a{
24
    
25
 }
26

  
27
div.jp-audio,
28
div.jp-video {
29

  
30
	/* Edit the font-size to counteract inherited font sizing.
31
	 * Eg. 1.25em = 1 / 0.8em
32
	 */
33

  
34
	font-size:1.25em; /* 1.25em for testing in site pages */ /* No parent CSS that can effect the size in the demos ZIP */
35

  
36
	font-family:Verdana, Arial, sans-serif;
37
	line-height:1.6;
38
	color: #666;
39
	position:relative;
40
}
41
div.jp-audio {
42
	width:100%;
43
                    position : absolute;
44
                    bottom : 0;
45
}
46
div.jp-video-270p {
47
	width:480px;
48
}
49
div.jp-video-360p {
50
	width:640px;
51
}
52
div.jp-video-full {
53
	/* Rules for IE6 (full-screen) */
54
	width:480px;
55
	height:270px;
56
	/* Rules for IE7 (full-screen) - Otherwise the relative container causes other page items that are not position:static (default) to appear over the video/gui. */
57
	position:static !important; position:relative
58
}
59

  
60
div.jp-video-full div.jp-jplayer {
61
	top: 0;
62
	left: 0;
63
	position: fixed !important; position: relative; /* Rules for IE6 (full-screen) */
64
	overflow: hidden;
65
	z-index:1000;
66
}
67

  
68
div.jp-video-full div.jp-gui {
69
	position: fixed !important; position: static; /* Rules for IE6 (full-screen) */
70
	top: 0;
71
	left: 0;
72
	width:100%;
73
	height:100%;
74
	z-index:1000;
75
}
76

  
77
div.jp-video-full div.jp-interface {
78
	position: absolute !important; position: relative; /* Rules for IE6 (full-screen) */
79
	bottom: 0;
80
	left: 0;
81
	z-index:1000;
82
}
83

  
84
div.jp-interface {
85
	position: relative;
86
	background-color:#333333;
87
                    padding : 0 10px;
88
}
89

  
90
div.jp-audio div.jp-type-single div.jp-interface {
91
	height:44px;
92
}
93
div.jp-audio div.jp-type-playlist div.jp-interface {
94
	height:80px;
95
}
96

  
97
div.jp-video div.jp-interface {
98
	border-top:1px solid #009be3;
99
}
100

  
101
/* @group CONTROLS */
102

  
103
div.jp-controls-holder {
104
	clear: both;
105
	width:440px;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff