From feed5be6b08f75d2651d2066d71009eead133ce1 Mon Sep 17 00:00:00 2001 From: Rick Waldron Date: Wed, 6 Jun 2012 12:07:52 -0400 Subject: [PATCH] [#1084] Modify cue/track event after it's been set. Signed-off-by: Rick Waldron --- popcorn.js | 96 +++++++++++++++++++++++++++++++++++++++++-- test/popcorn.unit.js | 97 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 189 insertions(+), 4 deletions(-) diff --git a/popcorn.js b/popcorn.js index 1c624e4c..d570b793 100644 --- a/popcorn.js +++ b/popcorn.js @@ -545,10 +545,50 @@ }, // Attach an event to a single point in time - exec: function( time, fn ) { + exec: function( id, time, fn ) { + var length = arguments.length, + trackEvent; + + // Shift arguments based on use case + // + // Back compat for: + // p.cue( time, fn ); + if ( typeof id === "number" && length === 2 ) { + fn = time; + time = id; + id = Popcorn.guid( "cue" ); + } else { + // Support for new forms + + // Get the trackEvent that matches the given id. + trackEvent = this.getTrackEvent( id ); + + if ( trackEvent ) { + // p.cue( "my-id", 12 ); + // p.cue( "my-id", function() { ... }); + if ( typeof id === "string" && length === 2 ) { + + // p.cue( "my-id", 12 ); + // The path will update the cue time. + if ( typeof time === "number" ) { + // Re-use existing trackEvent start callback + fn = trackEvent._natives.start; + } + + // p.cue( "my-id", function() { ... }); + // The path will update the cue function + if ( typeof time === "function" ) { + fn = time; + // Re-use existing trackEvent start time + time = trackEvent.start; + } + } + } + } // Creating a one second track event with an empty end Popcorn.addTrackEvent( this, { + id: id, start: time, end: time + 1, _running: false, @@ -849,6 +889,22 @@ // Internal Only - Adds track events to the instance object Popcorn.addTrackEvent = function( obj, track ) { + var trackEvent; + + // Do a lookup for existing trackevents with this id + if ( track.id ) { + trackEvent = obj.getTrackEvent( track.id ); + } + + // If a track event by this id currently exists, modify it + if ( trackEvent ) { + // Create a new object with the existing trackEvent + // Extend with new track properties + track = Popcorn.extend( {}, trackEvent, track ); + + // Remove the existing track from the instance + obj.removeTrackEvent( track.id ); + } // Determine if this track has default options set for it // If so, apply them to the track object @@ -1491,12 +1547,46 @@ // Extend Popcorn.p with new named definition // Assign new named definition - Popcorn.p[ name ] = plugin[ name ] = function( options ) { + Popcorn.p[ name ] = plugin[ name ] = function( id, options ) { + var length = arguments.length, + trackEvent, defaults; + + // Shift arguments based on use case + // + // Back compat for: + // p.plugin( options ); + if ( id && !options ) { + options = id; + id = null; + } else { + + // Get the trackEvent that matches the given id. + trackEvent = this.getTrackEvent( id ); + + // If the track event does not exist, ensure that the options + // object has a proper id + if ( !trackEvent ) { + options.id = id; + + // If the track event does exist, merge the updated properties + } else { + + options = Popcorn.extend( {}, trackEvent, options ); + + // Remove existing track event to make room for + // newly updated track event + this.removeTrackEvent( id ); + + Popcorn.addTrackEvent( this, options ); + + return this; + } + } this.data.running[ name ] = this.data.running[ name ] || []; // Merge with defaults if they exist, make sure per call is prioritized - var defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {}, + defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {}, mergedSetupOpts = Popcorn.extend( {}, defaults, options ); return pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition, diff --git a/test/popcorn.unit.js b/test/popcorn.unit.js index a13ff718..f6d8f671 100644 --- a/test/popcorn.unit.js +++ b/test/popcorn.unit.js @@ -932,7 +932,7 @@ test( "exec", function() { }).currentTime( 3 ).play(); }); -test( "cue (alias of exec)", function() { +test( "cue: alias of exec", function() { expect( 2 ); ok( Popcorn.p.cue, "Popcorn.p.cue exists" ); equal( typeof Popcorn.p.cue, "function", "Popcorn.p.cue is a function" ); @@ -4297,6 +4297,101 @@ asyncTest( "Plug-ins with a `once` attribute should be removed after `end` is fi $pop.play( 0 ); }); +asyncTest( "Modify cue or track event after creation", 6, function() { + var p = Popcorn("#video"), + passed = 0; + + Popcorn.plugin( "modifyMe", { + start: function( event, options ) { + var floor = Math.floor( this.currentTime() ); + + // This test will fail the unit if it is run + if ( floor === 10 ) { + ok( false, "Plugin track start at 10 seconds should never fire because it is changed to 11 seconds" ); + } + + if ( floor === 11 ) { + ok( true, "Plugin track start at 11 seconds fired, it was changed from 10 to 11" ); + passed++; + + equal( options.content, "Hola!", "Plugin track content property was updated" ); + passed++; + } + + // This is the passing test for the unchanged plugin call + if ( floor === 12 ) { + ok( true, "Plugin track start at 12 seconds fired (unchanged)" ); + passed++; + } + }, + end: function() { + var floor = Math.floor( this.currentTime() ); + + // This test will fail the unit if it is run + if ( floor === 11 ) { + ok( false, "Plugin track end at 11 seconds should never fire because it is changed to 12 seconds" ); + } + + if ( floor === 12 ) { + ok( true, "Plugin track end at 12 seconds fired, it was changed from 11 to 12" ); + passed++; + } + + if ( passed === 4 ) { + start(); + } + } + }); + + p.on( "canplayall", function() { + + // traditional, unchanging cue + p.cue( 11, function() { + ok( true, "Cue at 11 seconds fired (unchanged)" ); + }); + + // set a cue at 10 seconds + p.cue( "cue-id", 10, function() { + ok( false, "Cue at 10 seconds should never fire, because it is changed to 12 seconds" ); + }); + + // now I want to change that cue to 12: + p.cue( "cue-id", 12 ); + + // now change the function... + p.cue( "cue-id", function() { + ok( true, "Cue at 12 seconds fired, it was changed from 10 to 12" ); + }); + + // traditional, unchanging plugin call + p.modifyMe({ + start: 12, + end: 13 + }); + + // set up a new changeable trackevent + p.modifyMe( "plugin-id", { + start: 10, + end: 11, + content: "Hi!" + }); + + // change it to start at 11 + p.modifyMe( "plugin-id", { + start: 11, + content: "Hola!" + }); + + // change it to end at 12 + p.modifyMe( "plugin-id", { + end: 12 + }); + + p.play(9); + }); +}); + + module( "Popcorn XHR" ); test( "Basic", function() {