98 lines
3.4 KiB
Plaintext
98 lines
3.4 KiB
Plaintext
|
|
App.VideoPlayer = {
|
||
|
|
init: function(videoElement) {
|
||
|
|
// The source path for the video
|
||
|
|
var videoUrl = $(videoElement).attr("src");
|
||
|
|
|
||
|
|
// Replace the standard <video> element with the Clappr player
|
||
|
|
$(videoElement).replaceWith($("<div>", { id: "player" }));
|
||
|
|
var player = new Clappr.Player({
|
||
|
|
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
|
||
|
|
source: videoUrl, parentId: "#player", width: "100%",
|
||
|
|
focusElement: NotTypingSelectiveListenerElement(document), // Allows keyboard shortcuts to work even if the player itself isn't in focus
|
||
|
|
plugins: {
|
||
|
|
core: [ClapprMarkersPlugin, PlaybackRatePlugin]
|
||
|
|
},
|
||
|
|
markersPlugin: { markers: [] }
|
||
|
|
});
|
||
|
|
|
||
|
|
return player;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$(document).on("turbolinks:load", function() {
|
||
|
|
$("[data-behavior=video-player]").each(function(index, element) {
|
||
|
|
App.VideoPlayer.init(element);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// An implementation of SelectiveListenerElement which only listens when text areas are not in focus
|
||
|
|
var NotTypingSelectiveListenerElement = function(element) {
|
||
|
|
var inputInFocus = function() { return $('input:focus, textarea:focus, video:focus').length > 0; }
|
||
|
|
var noInputInFocus = function() { return !inputInFocus(); }
|
||
|
|
|
||
|
|
return new SelectiveListenerElement(element, noInputInFocus);
|
||
|
|
}
|
||
|
|
|
||
|
|
// A helper class that maintains a collection of handlers for a given event and callback
|
||
|
|
var HandlerCollection = function() {
|
||
|
|
this.handlers = [];
|
||
|
|
|
||
|
|
// Stores a handler for a given event and callback
|
||
|
|
this.store = function(eventName, originalCallback, handler) {
|
||
|
|
var item = {
|
||
|
|
eventName: eventName,
|
||
|
|
callback: originalCallback,
|
||
|
|
handler: handler,
|
||
|
|
}
|
||
|
|
this.handlers.push(item);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Finds a handler for a given event and callback
|
||
|
|
this.find = function(eventName, callback) {
|
||
|
|
var handler = null;
|
||
|
|
for (var i = 0; i < this.handlers.length; i++) {
|
||
|
|
var item = this.handlers[i];
|
||
|
|
|
||
|
|
if (item.eventName == eventName && item.callback == callback) {
|
||
|
|
handler = item.handler;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return handler;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// A helper class to allow a DOM element to be wrapped and selectively ignore events that are triggered on it
|
||
|
|
var SelectiveListenerElement = function(element, shouldListenFn) {
|
||
|
|
// The element we are proxying
|
||
|
|
this.element = element;
|
||
|
|
// A function that determines if we should run any event callbacks or not
|
||
|
|
this.shouldRunCallbacks = shouldListenFn;
|
||
|
|
// Stores the functions to be called when an event listener needs to be removed
|
||
|
|
this.removeHandlers = new HandlerCollection();
|
||
|
|
|
||
|
|
this.addEventListener = function(eventName, callback, useCapture) {
|
||
|
|
// Create a new callback function that conditionally calls the original
|
||
|
|
var conditionalCallback = function() {
|
||
|
|
if (this.shouldRunCallbacks()) {
|
||
|
|
callback();
|
||
|
|
}
|
||
|
|
}.bind(this);
|
||
|
|
|
||
|
|
// Store the function to be called when removing the event listener
|
||
|
|
this.removeHandlers.store(eventName, callback, function() {
|
||
|
|
this.element.removeEventListener(eventName, conditionalCallback, useCapture);
|
||
|
|
}.bind(this));
|
||
|
|
|
||
|
|
// Attach an event listener to the same event with the conditional callback function
|
||
|
|
this.element.addEventListener(eventName, conditionalCallback, useCapture);
|
||
|
|
}
|
||
|
|
|
||
|
|
this.removeEventListener = function(eventName, callback, useCapture) {
|
||
|
|
var removeHandler = this.removeHandlers.find(eventName, callback);
|
||
|
|
|
||
|
|
if (removeHandler != null) {
|
||
|
|
removeHandler();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|