commit
fb4c3bd9ce
Binary file not shown.
@ -0,0 +1,452 @@ |
||||
/* |
||||
* Playlist Object for the jPlayer Plugin |
||||
* http://www.jplayer.org
|
||||
* |
||||
* Copyright (c) 2009 - 2011 Happyworm Ltd |
||||
* Dual licensed under the MIT and GPL licenses. |
||||
* - http://www.opensource.org/licenses/mit-license.php
|
||||
* - http://www.gnu.org/copyleft/gpl.html
|
||||
* |
||||
* Author: Mark J Panaghiston |
||||
* Version: 2.1.0 (jPlayer 2.1.0) |
||||
* Date: 1st September 2011 |
||||
*/ |
||||
|
||||
/* Code verified using http://www.jshint.com/ */ |
||||
/*jshint asi:false, bitwise:false, boss:false, browser:true, curly:true, debug:false, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:true, noarg:true, noempty:true, nonew:true, nomem:false, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false */ |
||||
/*global jPlayerPlaylist: true, jQuery:false, alert:false */ |
||||
|
||||
(function($, undefined) { |
||||
|
||||
jPlayerPlaylist = function(cssSelector, playlist, options) { |
||||
var self = this; |
||||
|
||||
this.current = 0; |
||||
this.loop = false; // Flag used with the jPlayer repeat event
|
||||
this.shuffled = false; |
||||
this.removing = false; // Flag is true during remove animation, disabling the remove() method until complete.
|
||||
|
||||
this.cssSelector = $.extend({}, this._cssSelector, cssSelector); // Object: Containing the css selectors for jPlayer and its cssSelectorAncestor
|
||||
this.options = $.extend(true, {}, this._options, options); // Object: The jPlayer constructor options for this playlist and the playlist options
|
||||
|
||||
this.playlist = []; // Array of Objects: The current playlist displayed (Un-shuffled or Shuffled)
|
||||
this.original = []; // Array of Objects: The original playlist
|
||||
|
||||
this._initPlaylist(playlist); // Copies playlist to this.original. Then mirrors this.original to this.playlist. Creating two arrays, where the element pointers match. (Enables pointer comparison.)
|
||||
|
||||
// Setup the css selectors for the extra interface items used by the playlist.
|
||||
this.cssSelector.title = this.cssSelector.cssSelectorAncestor + " .jp-title"; // Note that the text is written to the decendant li node.
|
||||
this.cssSelector.playlist = this.cssSelector.cssSelectorAncestor + " .jp-playlist"; |
||||
this.cssSelector.next = this.cssSelector.cssSelectorAncestor + " .jp-next"; |
||||
this.cssSelector.previous = this.cssSelector.cssSelectorAncestor + " .jp-previous"; |
||||
this.cssSelector.shuffle = this.cssSelector.cssSelectorAncestor + " .jp-shuffle"; |
||||
this.cssSelector.shuffleOff = this.cssSelector.cssSelectorAncestor + " .jp-shuffle-off"; |
||||
|
||||
// Override the cssSelectorAncestor given in options
|
||||
this.options.cssSelectorAncestor = this.cssSelector.cssSelectorAncestor; |
||||
|
||||
// Override the default repeat event handler
|
||||
this.options.repeat = function(event) { |
||||
self.loop = event.jPlayer.options.loop; |
||||
}; |
||||
|
||||
// Create a ready event handler to initialize the playlist
|
||||
$(this.cssSelector.jPlayer).bind($.jPlayer.event.ready, function(event) { |
||||
self._init(); |
||||
}); |
||||
|
||||
// Create an ended event handler to move to the next item
|
||||
$(this.cssSelector.jPlayer).bind($.jPlayer.event.ended, function(event) { |
||||
self.next(); |
||||
}); |
||||
|
||||
// Create a play event handler to pause other instances
|
||||
$(this.cssSelector.jPlayer).bind($.jPlayer.event.play, function(event) { |
||||
$(this).jPlayer("pauseOthers"); |
||||
}); |
||||
|
||||
// Create a resize event handler to show the title in full screen mode.
|
||||
$(this.cssSelector.jPlayer).bind($.jPlayer.event.resize, function(event) { |
||||
if(event.jPlayer.options.fullScreen) { |
||||
$(self.cssSelector.title).show(); |
||||
} else { |
||||
$(self.cssSelector.title).hide(); |
||||
} |
||||
}); |
||||
|
||||
// Create click handlers for the extra buttons that do playlist functions.
|
||||
$(this.cssSelector.previous).click(function() { |
||||
self.previous(); |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
|
||||
$(this.cssSelector.next).click(function() { |
||||
self.next(); |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
|
||||
$(this.cssSelector.shuffle).click(function() { |
||||
self.shuffle(true); |
||||
return false; |
||||
}); |
||||
$(this.cssSelector.shuffleOff).click(function() { |
||||
self.shuffle(false); |
||||
return false; |
||||
}).hide(); |
||||
|
||||
// Put the title in its initial display state
|
||||
if(!this.options.fullScreen) { |
||||
$(this.cssSelector.title).hide(); |
||||
} |
||||
|
||||
// Remove the empty <li> from the page HTML. Allows page to be valid HTML, while not interfereing with display animations
|
||||
$(this.cssSelector.playlist + " ul").empty(); |
||||
|
||||
// Create .live() handlers for the playlist items along with the free media and remove controls.
|
||||
this._createItemHandlers(); |
||||
|
||||
// Instance jPlayer
|
||||
$(this.cssSelector.jPlayer).jPlayer(this.options); |
||||
}; |
||||
|
||||
jPlayerPlaylist.prototype = { |
||||
_cssSelector: { // static object, instanced in constructor
|
||||
jPlayer: "#jquery_jplayer_1", |
||||
cssSelectorAncestor: "#jp_container_1" |
||||
}, |
||||
_options: { // static object, instanced in constructor
|
||||
playlistOptions: { |
||||
autoPlay: false, |
||||
loopOnPrevious: false, |
||||
shuffleOnLoop: true, |
||||
enableRemoveControls: false, |
||||
displayTime: 'slow', |
||||
addTime: 'fast', |
||||
removeTime: 'fast', |
||||
shuffleTime: 'slow', |
||||
itemClass: "jp-playlist-item", |
||||
freeGroupClass: "jp-free-media", |
||||
freeItemClass: "jp-playlist-item-free", |
||||
removeItemClass: "jp-playlist-item-remove" |
||||
} |
||||
}, |
||||
option: function(option, value) { // For changing playlist options only
|
||||
if(value === undefined) { |
||||
return this.options.playlistOptions[option]; |
||||
} |
||||
|
||||
this.options.playlistOptions[option] = value; |
||||
|
||||
switch(option) { |
||||
case "enableRemoveControls": |
||||
this._updateControls(); |
||||
break; |
||||
case "itemClass": |
||||
case "freeGroupClass": |
||||
case "freeItemClass": |
||||
case "removeItemClass": |
||||
this._refresh(true); // Instant
|
||||
this._createItemHandlers(); |
||||
break; |
||||
} |
||||
return this; |
||||
}, |
||||
_init: function() { |
||||
var self = this; |
||||
this._refresh(function() { |
||||
if(self.options.playlistOptions.autoPlay) { |
||||
self.play(self.current); |
||||
} else { |
||||
self.select(self.current); |
||||
} |
||||
}); |
||||
}, |
||||
_initPlaylist: function(playlist) { |
||||
this.current = 0; |
||||
this.shuffled = false; |
||||
this.removing = false; |
||||
this.original = $.extend(true, [], playlist); // Copy the Array of Objects
|
||||
this._originalPlaylist(); |
||||
}, |
||||
_originalPlaylist: function() { |
||||
var self = this; |
||||
this.playlist = []; |
||||
// Make both arrays point to the same object elements. Gives us 2 different arrays, each pointing to the same actual object. ie., Not copies of the object.
|
||||
$.each(this.original, function(i,v) { |
||||
self.playlist[i] = self.original[i]; |
||||
}); |
||||
}, |
||||
_refresh: function(instant) { |
||||
/* instant: Can be undefined, true or a function. |
||||
* undefined -> use animation timings |
||||
* true -> no animation |
||||
* function -> use animation timings and excute function at half way point. |
||||
*/ |
||||
var self = this; |
||||
|
||||
if(instant && !$.isFunction(instant)) { |
||||
$(this.cssSelector.playlist + " ul").empty(); |
||||
$.each(this.playlist, function(i,v) { |
||||
$(self.cssSelector.playlist + " ul").append(self._createListItem(self.playlist[i])); |
||||
}); |
||||
this._updateControls(); |
||||
} else { |
||||
var displayTime = $(this.cssSelector.playlist + " ul").children().length ? this.options.playlistOptions.displayTime : 0; |
||||
|
||||
$(this.cssSelector.playlist + " ul").slideUp(displayTime, function() { |
||||
var $this = $(this); |
||||
$(this).empty(); |
||||
|
||||
$.each(self.playlist, function(i,v) { |
||||
$this.append(self._createListItem(self.playlist[i])); |
||||
}); |
||||
self._updateControls(); |
||||
if($.isFunction(instant)) { |
||||
instant(); |
||||
} |
||||
if(self.playlist.length) { |
||||
$(this).slideDown(self.options.playlistOptions.displayTime); |
||||
} else { |
||||
$(this).show(); |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
_createListItem: function(media) { |
||||
var self = this; |
||||
|
||||
// Wrap the <li> contents in a <div>
|
||||
var listItem = "<li><div>"; |
||||
|
||||
// Create remove control
|
||||
listItem += "<a href='javascript:;' class='" + this.options.playlistOptions.removeItemClass + "'>×</a>"; |
||||
|
||||
// Create links to free media
|
||||
if(media.free) { |
||||
var first = true; |
||||
listItem += "<span class='" + this.options.playlistOptions.freeGroupClass + "'>("; |
||||
$.each(media, function(property,value) { |
||||
if($.jPlayer.prototype.format[property]) { // Check property is a media format.
|
||||
if(first) { |
||||
first = false; |
||||
} else { |
||||
listItem += " | "; |
||||
} |
||||
listItem += "<a class='" + self.options.playlistOptions.freeItemClass + "' href='" + value + "' tabindex='1'>" + property + "</a>"; |
||||
} |
||||
}); |
||||
listItem += ")</span>"; |
||||
} |
||||
|
||||
// The title is given next in the HTML otherwise the float:right on the free media corrupts in IE6/7
|
||||
listItem += "<a href='javascript:;' class='" + this.options.playlistOptions.itemClass + "' tabindex='1'>" + media.title + (media.artist ? " <span class='jp-artist'>by " + media.artist + "</span>" : "") + "</a>"; |
||||
listItem += "</div></li>"; |
||||
|
||||
return listItem; |
||||
}, |
||||
_createItemHandlers: function() { |
||||
var self = this; |
||||
// Create .live() handlers for the playlist items
|
||||
$(this.cssSelector.playlist + " a." + this.options.playlistOptions.itemClass).die("click").live("click", function() { |
||||
var index = $(this).parent().parent().index(); |
||||
if(self.current !== index) { |
||||
self.play(index); |
||||
} else { |
||||
$(self.cssSelector.jPlayer).jPlayer("play"); |
||||
} |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
|
||||
// Create .live() handlers that disable free media links to force access via right click
|
||||
$(self.cssSelector.playlist + " a." + this.options.playlistOptions.freeItemClass).die("click").live("click", function() { |
||||
$(this).parent().parent().find("." + self.options.playlistOptions.itemClass).click(); |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
|
||||
// Create .live() handlers for the remove controls
|
||||
$(self.cssSelector.playlist + " a." + this.options.playlistOptions.removeItemClass).die("click").live("click", function() { |
||||
var index = $(this).parent().parent().index(); |
||||
self.remove(index); |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
}, |
||||
_updateControls: function() { |
||||
if(this.options.playlistOptions.enableRemoveControls) { |
||||
$(this.cssSelector.playlist + " ." + this.options.playlistOptions.removeItemClass).show(); |
||||
} else { |
||||
$(this.cssSelector.playlist + " ." + this.options.playlistOptions.removeItemClass).hide(); |
||||
} |
||||
if(this.shuffled) { |
||||
$(this.cssSelector.shuffleOff).show(); |
||||
$(this.cssSelector.shuffle).hide(); |
||||
} else { |
||||
$(this.cssSelector.shuffleOff).hide(); |
||||
$(this.cssSelector.shuffle).show(); |
||||
} |
||||
}, |
||||
_highlight: function(index) { |
||||
if(this.playlist.length && index !== undefined) { |
||||
$(this.cssSelector.playlist + " .jp-playlist-current").removeClass("jp-playlist-current"); |
||||
$(this.cssSelector.playlist + " li:nth-child(" + (index + 1) + ")").addClass("jp-playlist-current").find(".jp-playlist-item").addClass("jp-playlist-current"); |
||||
$(this.cssSelector.title + " li").html(this.playlist[index].title + (this.playlist[index].artist ? " <span class='jp-artist'>by " + this.playlist[index].artist + "</span>" : "")); |
||||
} |
||||
}, |
||||
setPlaylist: function(playlist) { |
||||
this._initPlaylist(playlist); |
||||
this._init(); |
||||
}, |
||||
add: function(media, playNow) { |
||||
$(this.cssSelector.playlist + " ul").append(this._createListItem(media)).find("li:last-child").hide().slideDown(this.options.playlistOptions.addTime); |
||||
this._updateControls(); |
||||
this.original.push(media); |
||||
this.playlist.push(media); // Both array elements share the same object pointer. Comforms with _initPlaylist(p) system.
|
||||
|
||||
if(playNow) { |
||||
this.play(this.playlist.length - 1); |
||||
} else { |
||||
if(this.original.length === 1) { |
||||
this.select(0); |
||||
} |
||||
} |
||||
}, |
||||
remove: function(index) { |
||||
var self = this; |
||||
|
||||
if(index === undefined) { |
||||
this._initPlaylist([]); |
||||
this._refresh(function() { |
||||
$(self.cssSelector.jPlayer).jPlayer("clearMedia"); |
||||
}); |
||||
return true; |
||||
} else { |
||||
|
||||
if(this.removing) { |
||||
return false; |
||||
} else { |
||||
index = (index < 0) ? self.original.length + index : index; // Negative index relates to end of array.
|
||||
if(0 <= index && index < this.playlist.length) { |
||||
this.removing = true; |
||||
|
||||
$(this.cssSelector.playlist + " li:nth-child(" + (index + 1) + ")").slideUp(this.options.playlistOptions.removeTime, function() { |
||||
$(this).remove(); |
||||
|
||||
if(self.shuffled) { |
||||
var item = self.playlist[index]; |
||||
$.each(self.original, function(i,v) { |
||||
if(self.original[i] === item) { |
||||
self.original.splice(i, 1); |
||||
return false; // Exit $.each
|
||||
} |
||||
}); |
||||
self.playlist.splice(index, 1); |
||||
} else { |
||||
self.original.splice(index, 1); |
||||
self.playlist.splice(index, 1); |
||||
} |
||||
|
||||
if(self.original.length) { |
||||
if(index === self.current) { |
||||
self.current = (index < self.original.length) ? self.current : self.original.length - 1; // To cope when last element being selected when it was removed
|
||||
self.select(self.current); |
||||
} else if(index < self.current) { |
||||
self.current--; |
||||
} |
||||
} else { |
||||
$(self.cssSelector.jPlayer).jPlayer("clearMedia"); |
||||
self.current = 0; |
||||
self.shuffled = false; |
||||
self._updateControls(); |
||||
} |
||||
|
||||
self.removing = false; |
||||
}); |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
}, |
||||
select: function(index) { |
||||
index = (index < 0) ? this.original.length + index : index; // Negative index relates to end of array.
|
||||
if(0 <= index && index < this.playlist.length) { |
||||
this.current = index; |
||||
this._highlight(index); |
||||
$(this.cssSelector.jPlayer).jPlayer("setMedia", this.playlist[this.current]); |
||||
} else { |
||||
this.current = 0; |
||||
} |
||||
}, |
||||
play: function(index) { |
||||
index = (index < 0) ? this.original.length + index : index; // Negative index relates to end of array.
|
||||
if(0 <= index && index < this.playlist.length) { |
||||
if(this.playlist.length) { |
||||
this.select(index); |
||||
$(this.cssSelector.jPlayer).jPlayer("play"); |
||||
} |
||||
} else if(index === undefined) { |
||||
$(this.cssSelector.jPlayer).jPlayer("play"); |
||||
} |
||||
}, |
||||
pause: function() { |
||||
$(this.cssSelector.jPlayer).jPlayer("pause"); |
||||
}, |
||||
next: function() { |
||||
var index = (this.current + 1 < this.playlist.length) ? this.current + 1 : 0; |
||||
|
||||
if(this.loop) { |
||||
// See if we need to shuffle before looping to start, and only shuffle if more than 1 item.
|
||||
if(index === 0 && this.shuffled && this.options.playlistOptions.shuffleOnLoop && this.playlist.length > 1) { |
||||
this.shuffle(true, true); // playNow
|
||||
} else { |
||||
this.play(index); |
||||
} |
||||
} else { |
||||
// The index will be zero if it just looped round
|
||||
if(index > 0) { |
||||
this.play(index); |
||||
} |
||||
} |
||||
}, |
||||
previous: function() { |
||||
var index = (this.current - 1 >= 0) ? this.current - 1 : this.playlist.length - 1; |
||||
|
||||
if(this.loop && this.options.playlistOptions.loopOnPrevious || index < this.playlist.length - 1) { |
||||
this.play(index); |
||||
} |
||||
}, |
||||
shuffle: function(shuffled, playNow) { |
||||
var self = this; |
||||
|
||||
if(shuffled === undefined) { |
||||
shuffled = !this.shuffled; |
||||
} |
||||
|
||||
if(shuffled || shuffled !== this.shuffled) { |
||||
|
||||
$(this.cssSelector.playlist + " ul").slideUp(this.options.playlistOptions.shuffleTime, function() { |
||||
self.shuffled = shuffled; |
||||
if(shuffled) { |
||||
self.playlist.sort(function() { |
||||
return 0.5 - Math.random(); |
||||
}); |
||||
} else { |
||||
self._originalPlaylist(); |
||||
} |
||||
self._refresh(true); // Instant
|
||||
|
||||
if(playNow || !$(self.cssSelector.jPlayer).data("jPlayer").status.paused) { |
||||
self.play(0); |
||||
} else { |
||||
self.select(0); |
||||
} |
||||
|
||||
$(this).slideDown(self.options.playlistOptions.shuffleTime); |
||||
}); |
||||
} |
||||
} |
||||
}; |
||||
})(jQuery); |
||||
@ -0,0 +1,331 @@ |
||||
/* |
||||
* jPlayerInspector Plugin for jPlayer (2.0.0+) Plugin for jQuery JavaScript Library |
||||
* http://www.happyworm.com/jquery/jplayer
|
||||
* |
||||
* Copyright (c) 2009 - 2011 Happyworm Ltd |
||||
* Dual licensed under the MIT and GPL licenses. |
||||
* - http://www.opensource.org/licenses/mit-license.php
|
||||
* - http://www.gnu.org/copyleft/gpl.html
|
||||
* |
||||
* Author: Mark J Panaghiston |
||||
* Version: 1.0.3 |
||||
* Date: 7th August 2011 |
||||
* |
||||
* For use with jPlayer Version: 2.0.29 |
||||
* |
||||
* Note: Declare inspector instances after jPlayer instances. ie., Otherwise the jPlayer instance is nonsense. |
||||
*/ |
||||
|
||||
(function($, undefined) { |
||||
$.jPlayerInspector = {}; |
||||
$.jPlayerInspector.i = 0; |
||||
$.jPlayerInspector.defaults = { |
||||
jPlayer: undefined, // The jQuery selector of the jPlayer instance to inspect.
|
||||
idPrefix: "jplayer_inspector_", |
||||
visible: false |
||||
}; |
||||
|
||||
var methods = { |
||||
init: function(options) { |
||||
var self = this; |
||||
var $this = $(this); |
||||
|
||||
var config = $.extend({}, $.jPlayerInspector.defaults, options); |
||||
$(this).data("jPlayerInspector", config); |
||||
|
||||
config.id = $(this).attr("id"); |
||||
config.jPlayerId = config.jPlayer.attr("id"); |
||||
|
||||
config.windowId = config.idPrefix + "window_" + $.jPlayerInspector.i; |
||||
config.statusId = config.idPrefix + "status_" + $.jPlayerInspector.i; |
||||
config.configId = config.idPrefix + "config_" + $.jPlayerInspector.i; |
||||
config.toggleId = config.idPrefix + "toggle_" + $.jPlayerInspector.i; |
||||
config.eventResetId = config.idPrefix + "event_reset_" + $.jPlayerInspector.i; |
||||
config.updateId = config.idPrefix + "update_" + $.jPlayerInspector.i; |
||||
config.eventWindowId = config.idPrefix + "event_window_" + $.jPlayerInspector.i; |
||||
|
||||
config.eventId = {}; |
||||
config.eventJq = {}; |
||||
config.eventTimeout = {}; |
||||
config.eventOccurrence = {}; |
||||
|
||||
$.each($.jPlayer.event, function(eventName,eventType) { |
||||
config.eventId[eventType] = config.idPrefix + "event_" + eventName + "_" + $.jPlayerInspector.i; |
||||
config.eventOccurrence[eventType] = 0; |
||||
}); |
||||
|
||||
var structure =
|
||||
'<p><a href="#" id="' + config.toggleId + '">' + (config.visible ? "Hide" : "Show") + '</a> jPlayer Inspector</p>'
|
||||
+ '<div id="' + config.windowId + '">' |
||||
+ '<div id="' + config.statusId + '"></div>' |
||||
+ '<div id="' + config.eventWindowId + '" style="padding:5px 5px 0 5px;background-color:#eee;border:1px dotted #000;">' |
||||
+ '<p style="margin:0 0 10px 0;"><strong>jPlayer events that have occurred over the past 1 second:</strong>' |
||||
+ '<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>'; |
||||
|
||||
// MJP: Would use the next 3 lines for ease, but the events are just slapped on the page.
|
||||
// $.each($.jPlayer.event, function(eventName,eventType) {
|
||||
// structure += '<div id="' + config.eventId[eventType] + '" style="float:left;">' + eventName + '</div>';
|
||||
// });
|
||||
|
||||
var eventStyle = "float:left;margin:0 5px 5px 0;padding:0 5px;border:1px dotted #000;"; |
||||
// MJP: Doing it longhand so order and layout easier to control.
|
||||
structure += |
||||
'<div id="' + config.eventId[$.jPlayer.event.ready] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.flashreset] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.resize] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.repeat] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.click] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.error] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.warning] + '" style="' + eventStyle + '"></div>' |
||||
|
||||
+ '<div id="' + config.eventId[$.jPlayer.event.loadstart] + '" style="clear:left;' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.progress] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.timeupdate] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.volumechange] + '" style="' + eventStyle + '"></div>' |
||||
|
||||
+ '<div id="' + config.eventId[$.jPlayer.event.play] + '" style="clear:left;' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.pause] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.waiting] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.playing] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.seeking] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.seeked] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.ended] + '" style="' + eventStyle + '"></div>' |
||||
|
||||
+ '<div id="' + config.eventId[$.jPlayer.event.loadeddata] + '" style="clear:left;' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.loadedmetadata] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.canplay] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.canplaythrough] + '" style="' + eventStyle + '"></div>' |
||||
|
||||
+ '<div id="' + config.eventId[$.jPlayer.event.suspend] + '" style="clear:left;' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.abort] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.emptied] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.stalled] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.ratechange] + '" style="' + eventStyle + '"></div>' |
||||
+ '<div id="' + config.eventId[$.jPlayer.event.durationchange] + '" style="' + eventStyle + '"></div>' |
||||
|
||||
+ '<div style="clear:both"></div>'; |
||||
|
||||
// MJP: Would like a check here in case we missed an event.
|
||||
|
||||
// MJP: Check fails, since it is not on the page yet.
|
||||
/* $.each($.jPlayer.event, function(eventName,eventType) { |
||||
if($("#" + config.eventId[eventType])[0] === undefined) { |
||||
structure += '<div id="' + config.eventId[eventType] + '" style="clear:left;' + eventStyle + '">' + eventName + '</div>'; |
||||
} |
||||
}); |
||||
*/ |
||||
structure += |
||||
'</div>' |
||||
+ '<p><a href="#" id="' + config.updateId + '">Update</a> jPlayer Inspector</p>' |
||||
+ '<div id="' + config.configId + '"></div>' |
||||
+ '</div>'; |
||||
$(this).html(structure); |
||||
|
||||
config.windowJq = $("#" + config.windowId); |
||||
config.statusJq = $("#" + config.statusId); |
||||
config.configJq = $("#" + config.configId); |
||||
config.toggleJq = $("#" + config.toggleId); |
||||
config.eventResetJq = $("#" + config.eventResetId); |
||||
config.updateJq = $("#" + config.updateId); |
||||
|
||||
$.each($.jPlayer.event, function(eventName,eventType) { |
||||
config.eventJq[eventType] = $("#" + config.eventId[eventType]); |
||||
config.eventJq[eventType].text(eventName + " (" + config.eventOccurrence[eventType] + ")"); // Sets the text to the event name and (0);
|
||||
|
||||
config.jPlayer.bind(eventType + ".jPlayerInspector", function(e) { |
||||
config.eventOccurrence[e.type]++; |
||||
if(config.eventOccurrence[e.type] > 1) { |
||||
config.eventJq[e.type].css("background-color","#ff9"); |
||||
} else { |
||||
config.eventJq[e.type].css("background-color","#9f9"); |
||||
} |
||||
config.eventJq[e.type].text(eventName + " (" + config.eventOccurrence[e.type] + ")"); |
||||
// The timer to handle the color
|
||||
clearTimeout(config.eventTimeout[e.type]); |
||||
config.eventTimeout[e.type] = setTimeout(function() { |
||||
config.eventJq[e.type].css("background-color","#fff"); |
||||
}, 1000); |
||||
// The timer to handle the occurences.
|
||||
setTimeout(function() { |
||||
config.eventOccurrence[e.type]--; |
||||
config.eventJq[e.type].text(eventName + " (" + config.eventOccurrence[e.type] + ")"); |
||||
}, 1000); |
||||
if(config.visible) { // Update the status, if inspector open.
|
||||
$this.jPlayerInspector("updateStatus"); |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
config.jPlayer.bind($.jPlayer.event.ready + ".jPlayerInspector", function(e) { |
||||
$this.jPlayerInspector("updateConfig"); |
||||
}); |
||||
|
||||
config.toggleJq.click(function() { |
||||
if(config.visible) { |
||||
$(this).text("Show"); |
||||
config.windowJq.hide(); |
||||
config.statusJq.empty(); |
||||
config.configJq.empty(); |
||||
} else { |
||||
$(this).text("Hide"); |
||||
config.windowJq.show(); |
||||
config.updateJq.click(); |
||||
} |
||||
config.visible = !config.visible; |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
|
||||
config.eventResetJq.click(function() { |
||||
$.each($.jPlayer.event, function(eventName,eventType) { |
||||
config.eventJq[eventType].css("background-color","#eee"); |
||||
}); |
||||
$(this).blur(); |
||||
return false; |
||||
}); |
||||
|
||||
config.updateJq.click(function() { |
||||
$this.jPlayerInspector("updateStatus"); |
||||
$this.jPlayerInspector("updateConfig"); |
||||
return false; |
||||
}); |
||||
|
||||
if(!config.visible) { |
||||
config.windowJq.hide(); |
||||
} else { |
||||
// config.updateJq.click();
|
||||
} |
||||
|
||||
$.jPlayerInspector.i++; |
||||
|
||||
return this; |
||||
}, |
||||
destroy: function() { |
||||
$(this).data("jPlayerInspector") && $(this).data("jPlayerInspector").jPlayer.unbind(".jPlayerInspector"); |
||||
$(this).empty(); |
||||
}, |
||||
updateConfig: function() { // This displays information about jPlayer's configuration in inspector
|
||||
|
||||
var jPlayerInfo = "<p>This jPlayer instance is running in your browser where:<br />" |
||||
|
||||
for(i = 0; i < $(this).data("jPlayerInspector").jPlayer.data("jPlayer").solutions.length; i++) { |
||||
var solution = $(this).data("jPlayerInspector").jPlayer.data("jPlayer").solutions[i]; |
||||
jPlayerInfo += " jPlayer's <strong>" + solution + "</strong> solution is";
|
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].used) { |
||||
jPlayerInfo += " being <strong>used</strong> and will support:<strong>"; |
||||
for(format in $(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].support) { |
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].support[format]) { |
||||
jPlayerInfo += " " + format; |
||||
} |
||||
} |
||||
jPlayerInfo += "</strong><br />"; |
||||
} else { |
||||
jPlayerInfo += " <strong>not required</strong><br />"; |
||||
} |
||||
} |
||||
jPlayerInfo += "</p>"; |
||||
|
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.active) { |
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").flash.active) { |
||||
jPlayerInfo += "<strong>Problem with jPlayer since both HTML5 and Flash are active.</strong>"; |
||||
} else { |
||||
jPlayerInfo += "The <strong>HTML5 is active</strong>."; |
||||
} |
||||
} else { |
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").flash.active) { |
||||
jPlayerInfo += "The <strong>Flash is active</strong>."; |
||||
} else { |
||||
jPlayerInfo += "No solution is currently active. jPlayer needs a setMedia()."; |
||||
} |
||||
} |
||||
jPlayerInfo += "</p>"; |
||||
|
||||
var formatType = $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.formatType; |
||||
jPlayerInfo += "<p><code>status.formatType = '" + formatType + "'</code><br />"; |
||||
if(formatType) { |
||||
jPlayerInfo += "<code>Browser canPlay('" + $.jPlayer.prototype.format[formatType].codec + "')</code>"; |
||||
} else { |
||||
jPlayerInfo += "</p>"; |
||||
} |
||||
|
||||
jPlayerInfo += "<p><code>status.src = '" + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.src + "'</code></p>"; |
||||
|
||||
jPlayerInfo += "<p><code>status.media = {<br />"; |
||||
for(prop in $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.media) { |
||||
jPlayerInfo += " " + prop + ": " + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.media[prop] + "<br />"; // Some are strings
|
||||
} |
||||
jPlayerInfo += "};</code></p>" |
||||
|
||||
+ "<p>Raw browser test for HTML5 support. Should equal a function if HTML5 is available.<br />"; |
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.audio.available) { |
||||
jPlayerInfo += "<code>htmlElement.audio.canPlayType = " + (typeof $(this).data("jPlayerInspector").jPlayer.data("jPlayer").htmlElement.audio.canPlayType) +"</code><br />" |
||||
} |
||||
if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.video.available) { |
||||
jPlayerInfo += "<code>htmlElement.video.canPlayType = " + (typeof $(this).data("jPlayerInspector").jPlayer.data("jPlayer").htmlElement.video.canPlayType) +"</code>"; |
||||
} |
||||
jPlayerInfo += "</p>"; |
||||
|
||||
jPlayerInfo += "<p>This instance is using the constructor options:<br />" |
||||
+ "<code>$('#" + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").internal.self.id + "').jPlayer({<br />" |
||||
|
||||
+ " swfPath: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "swfPath") + "',<br />" |
||||
|
||||
+ " solution: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "solution") + "',<br />" |
||||
|
||||
+ " supplied: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "supplied") + "',<br />" |
||||
|
||||
+ " preload: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "preload") + "',<br />" |
||||
|
||||
+ " volume: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "volume") + ",<br />" |
||||
|
||||
+ " muted: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "muted") + ",<br />" |
||||
|
||||
+ " backgroundColor: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "backgroundColor") + "',<br />" |
||||
|
||||
+ " cssSelectorAncestor: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelectorAncestor") + "',<br />" |
||||
|
||||
+ " cssSelector: {"; |
||||
|
||||
var cssSelector = $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelector"); |
||||
for(prop in cssSelector) { |
||||
|
||||
// jPlayerInfo += "<br /> " + prop + ": '" + cssSelector[prop] + "'," // This works too of course, but want to use option method for deep keys.
|
||||
jPlayerInfo += "<br /> " + prop + ": '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelector." + prop) + "'," |
||||
} |
||||
|
||||
jPlayerInfo = jPlayerInfo.slice(0, -1); // Because the sloppy comma was bugging me.
|
||||
|
||||
jPlayerInfo += "<br /> },<br />" |
||||
|
||||
+ " errorAlerts: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "errorAlerts") + ",<br />" |
||||
|
||||
+ " warningAlerts: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "warningAlerts") + "<br />" |
||||
|
||||
+ "});</code></p>"; |
||||
$(this).data("jPlayerInspector").configJq.html(jPlayerInfo); |
||||
return this; |
||||
}, |
||||
updateStatus: function() { // This displays information about jPlayer's status in the inspector
|
||||
$(this).data("jPlayerInspector").statusJq.html( |
||||
"<p>jPlayer is " + |
||||
($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.paused ? "paused" : "playing") + |
||||
" at time: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentTime*10)/10 + "s." + |
||||
" (d: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.duration*10)/10 + "s" + |
||||
", sp: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.seekPercent) + "%" + |
||||
", cpr: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentPercentRelative) + "%" + |
||||
", cpa: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentPercentAbsolute) + "%)</p>" |
||||
); |
||||
return this; |
||||
} |
||||
}; |
||||
$.fn.jPlayerInspector = function( method ) { |
||||
// Method calling logic
|
||||
if ( methods[method] ) { |
||||
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); |
||||
} else if ( typeof method === 'object' || ! method ) { |
||||
return methods.init.apply( this, arguments ); |
||||
} else { |
||||
$.error( 'Method ' + method + ' does not exist on jQuery.jPlayerInspector' ); |
||||
}
|
||||
}; |
||||
})(jQuery); |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,140 @@ |
||||
/* |
||||
* In-Field Label jQuery Plugin |
||||
* http://fuelyourcoding.com/scripts/infield.html
|
||||
* |
||||
* Copyright (c) 2009 Doug Neiner |
||||
* Dual licensed under the MIT and GPL licenses. |
||||
* Uses the same license as jQuery, see: |
||||
* http://docs.jquery.com/License
|
||||
* |
||||
* @version 0.1 |
||||
*/ |
||||
(function($){ |
||||
|
||||
$.InFieldLabels = function(label,field, options){ |
||||
// To avoid scope issues, use 'base' instead of 'this'
|
||||
// to reference this class from internal events and functions.
|
||||
var base = this; |
||||
|
||||
// Access to jQuery and DOM versions of each element
|
||||
base.$label = $(label); |
||||
base.label = label; |
||||
|
||||
base.$field = $(field); |
||||
base.field = field; |
||||
|
||||
base.$label.data("InFieldLabels", base); |
||||
base.showing = true; |
||||
|
||||
base.init = function(){ |
||||
// Merge supplied options with default options
|
||||
base.options = $.extend({},$.InFieldLabels.defaultOptions, options); |
||||
|
||||
// Check if the field is already filled in
|
||||
if(base.$field.val() != ""){ |
||||
base.$label.hide(); |
||||
base.showing = false; |
||||
}; |
||||
|
||||
base.$field.focus(function(){ |
||||
base.fadeOnFocus(); |
||||
}).blur(function(){ |
||||
base.checkForEmpty(true); |
||||
}).bind('keydown.infieldlabel',function(e){ |
||||
// Use of a namespace (.infieldlabel) allows us to
|
||||
// unbind just this method later
|
||||
base.hideOnChange(e); |
||||
}).change(function(e){ |
||||
base.checkForEmpty(); |
||||
}).bind('onPropertyChange', function(){ |
||||
base.checkForEmpty(); |
||||
}); |
||||
}; |
||||
|
||||
// If the label is currently showing
|
||||
// then fade it down to the amount
|
||||
// specified in the settings
|
||||
base.fadeOnFocus = function(){ |
||||
if(base.showing){ |
||||
base.setOpacity(base.options.fadeOpacity); |
||||
}; |
||||
}; |
||||
|
||||
base.setOpacity = function(opacity){ |
||||
base.$label.stop().animate({ opacity: opacity }, base.options.fadeDuration); |
||||
base.showing = (opacity > 0.0); |
||||
}; |
||||
|
||||
// Checks for empty as a fail safe
|
||||
// set blur to true when passing from
|
||||
// the blur event
|
||||
base.checkForEmpty = function(blur){ |
||||
if(base.$field.val() == ""){ |
||||
base.prepForShow(); |
||||
base.setOpacity( blur ? 1.0 : base.options.fadeOpacity ); |
||||
} else { |
||||
base.setOpacity(0.0); |
||||
}; |
||||
}; |
||||
|
||||
base.prepForShow = function(e){ |
||||
if(!base.showing) { |
||||
// Prepare for a animate in...
|
||||
base.$label.css({opacity: 0.0}).show(); |
||||
|
||||
// Reattach the keydown event
|
||||
base.$field.bind('keydown.infieldlabel',function(e){ |
||||
base.hideOnChange(e); |
||||
}); |
||||
}; |
||||
}; |
||||
|
||||
base.hideOnChange = function(e){ |
||||
if( |
||||
(e.keyCode == 16) || // Skip Shift
|
||||
(e.keyCode == 9) // Skip Tab
|
||||
) return;
|
||||
|
||||
if(base.showing){ |
||||
base.$label.hide(); |
||||
base.showing = false; |
||||
}; |
||||
|
||||
// Remove keydown event to save on CPU processing
|
||||
base.$field.unbind('keydown.infieldlabel'); |
||||
}; |
||||
|
||||
// Run the initialization method
|
||||
base.init(); |
||||
}; |
||||
|
||||
$.InFieldLabels.defaultOptions = { |
||||
fadeOpacity: 0.5, // Once a field has focus, how transparent should the label be
|
||||
fadeDuration: 300 // How long should it take to animate from 1.0 opacity to the fadeOpacity
|
||||
}; |
||||
|
||||
|
||||
$.fn.inFieldLabels = function(options){ |
||||
return this.each(function(){ |
||||
// Find input or textarea based on for= attribute
|
||||
// The for attribute on the label must contain the ID
|
||||
// of the input or textarea element
|
||||
var for_attr = $(this).attr('for'); |
||||
if( !for_attr ) return; // Nothing to attach, since the for field wasn't used
|
||||
|
||||
|
||||
// Find the referenced input or textarea element
|
||||
var $field = $( |
||||
"input#" + for_attr + "[type='text']," +
|
||||
"input#" + for_attr + "[type='password']," +
|
||||
"textarea#" + for_attr |
||||
); |
||||
|
||||
if( $field.length == 0) return; // Again, nothing to attach
|
||||
|
||||
// Only create object for input[text], input[password], or textarea
|
||||
(new $.InFieldLabels(this, $field[0], options)); |
||||
}); |
||||
}; |
||||
|
||||
})(jQuery); |
||||
Loading…
Reference in new issue