Re-write Popcorn.removeTrackEvent, Fix ByEnd removal bug [#911]

This commit is contained in:
Christopher De Cairos 2012-02-23 15:14:15 -05:00
Родитель 7cbc7f8128 ae8bbf80a5
Коммит d79edc924b
2 изменённых файлов: 190 добавлений и 36 удалений

Просмотреть файл

@ -929,55 +929,83 @@
return obj;
};
Popcorn.removeTrackEvent = function( obj, trackId ) {
Popcorn.removeTrackEvent = function( obj, removeId ) {
var historyLen = obj.data.history.length,
var start, end, animate,
historyLen = obj.data.history.length,
length = obj.data.trackEvents.byStart.length,
index = 0,
indexWasAt = 0,
byStart = [],
byEnd = [],
animating = [],
history = [];
Popcorn.forEach( obj.data.trackEvents.byStart, function( o, i, context ) {
// Preserve the original start/end trackEvents
if ( !o._id ) {
byStart.push( obj.data.trackEvents.byStart[i] );
byEnd.push( obj.data.trackEvents.byEnd[i] );
while ( --length > -1 ) {
start = obj.data.trackEvents.byStart[ index ];
end = obj.data.trackEvents.byEnd[ index ];
// Padding events will not have _id properties.
// These should be safely pushed onto the front and back of the
// track event array
if ( !start._id ) {
byStart.push( start );
byEnd.push( end );
}
// Filter for user track events (vs system track events)
if ( o._id ) {
if ( start._id ) {
// Filter for the trackevent to remove
if ( o._id !== trackId ) {
byStart.push( obj.data.trackEvents.byStart[i] );
byEnd.push( obj.data.trackEvents.byEnd[i] );
// If not a matching start event for removal
if ( start._id !== removeId ) {
byStart.push( start );
}
// Capture the position of the track being removed.
if ( o._id === trackId ) {
indexWasAt = i;
o._natives._teardown && o._natives._teardown.call( obj, o );
}
}
});
if ( obj.data.trackEvents.animating.length ) {
Popcorn.forEach( obj.data.trackEvents.animating, function( o, i, context ) {
// Preserve the original start/end trackEvents
if ( !o._id ) {
animating.push( obj.data.trackEvents.animating[i] );
// If not a matching end event for removal
if ( end._id !== removeId ) {
byEnd.push( end );
}
// Filter for user track events (vs system track events)
if ( o._id ) {
// Filter for the trackevent to remove
if ( o._id !== trackId ) {
animating.push( obj.data.trackEvents.animating[i] );
// If the _id is matched, capture the current index
if ( start._id === removeId ) {
indexWasAt = index;
// If a _teardown function was defined,
// enforce for track event removals
if ( start._natives._teardown ) {
start._natives._teardown.call( obj, start );
}
}
});
}
// Increment the track index
index++;
}
// Reset length to be used by the condition below to determine
// if animating track events should also be filtered for removal.
// Reset index below to be used by the reverse while as an
// incrementing counter
length = obj.data.trackEvents.animating.length;
index = 0;
if ( length ) {
while ( --length > -1 ) {
animate = obj.data.trackEvents.animating[ index ];
// Padding events will not have _id properties.
// These should be safely pushed onto the front and back of the
// track event array
if ( !animate._id ) {
animating.push( animate );
}
// If not a matching animate event for removal
if ( animate._id && animate._id !== removeId ) {
animating.push( animate );
}
// Increment the track index
index++;
}
}
// Update
@ -994,7 +1022,7 @@
obj.data.trackEvents.animating = animating;
for ( var i = 0; i < historyLen; i++ ) {
if ( obj.data.history[ i ] !== trackId ) {
if ( obj.data.history[ i ] !== removeId ) {
history.push( obj.data.history[ i ] );
}
}
@ -1003,12 +1031,12 @@
obj.data.history = history;
// Update track event references
Popcorn.removeTrackEvent.ref( obj, trackId );
Popcorn.removeTrackEvent.ref( obj, removeId );
};
// Internal Only - Removes track event references from instance object's trackRefs hash table
Popcorn.removeTrackEvent.ref = function( obj, trackId ) {
delete obj.data.trackRefs[ trackId ];
Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
delete obj.data.trackRefs[ removeId ];
return obj;
};

Просмотреть файл

@ -183,6 +183,132 @@ test( "Popcorn.getTrackEvent", function() {
});
test( "Popcorn.removeTrackEvent", function() {
var pop = Popcorn( "#video" ),
count = 0,
aId, bId, cId, dId, byStart, byEnd;
expect( 5 );
Popcorn.plugin( "a", {
_setup: function( options ) {},
start: function( event, options ) {},
end: function( event, options ) {},
_teardown: function( options ) {}
});
Popcorn.plugin( "b", {
_setup: function( options ) {},
start: function( event, options ) {},
end: function( event, options ) {},
_teardown: function( options ) {}
});
Popcorn.plugin( "c", {
_setup: function( options ) {},
start: function( event, options ) {},
end: function( event, options ) {},
_teardown: function( options ) {}
});
Popcorn.plugin( "d", {
_setup: function( options ) {},
start: function( event, options ) {},
end: function( event, options ) {},
_teardown: function( options ) {}
});
pop.a({
start: 1,
end: 5
});
// Store track event id for "plugin a"
aId = pop.getLastTrackEventId();
pop.b({
start: 3,
end: 4
});
// Store track event id for "plugin b"
bId = pop.getLastTrackEventId();
pop.c({
start: 0,
end: 3
});
// Store track event id for "plugin c"
cId = pop.getLastTrackEventId();
pop.d({
start: 1,
end: 2
});
// Store track event id for "plugin d"
dId = pop.getLastTrackEventId();
// Capture the pre-removal track event count
count = pop.data.trackEvents.byStart.length;
// Remove the first track event for "plugin a"
pop.removeTrackEvent( aId );
// Shorthand references
byStart = pop.data.trackEvents.byStart;
byEnd = pop.data.trackEvents.byEnd;
equal( byStart.length, count - 1, "One less track event" );
// Iterate all byStart track events to prove that _only_ track events
// created by "plugin b" have survived
Popcorn.forEach( byStart, function( start ) {
if ( start._id ) {
// This condition should NEVER evaluate to true
if ( start._id === aId ) {
ok( false, "No byStart track events with " + aId + " should exist" );
}
// This condition should ALWAYS evaluate to true
if ( start._id === bId ) {
ok( true, "Only byStart track events with " + bId + " should exist" );
}
}
});
// Iterate all byEnd track events to prove that _only_ track events
// created by "plugin b" have survived
Popcorn.forEach( byEnd, function( end ) {
if ( end._id ) {
// This condition should NEVER evaluate to true
if ( end._id === aId ) {
ok( false, "No byEnd track events with " + aId + " should exist" );
}
// This condition should ALWAYS evaluate to true
if ( end._id === bId ) {
ok( true, "Only byEnd track events with " + bId + " should exist" );
}
}
});
// after the removal, byStart's first element is c
// console.log( byStart );
// after the removal, byEnd's first element should be d (if c, then broken)
// console.log( byEnd );
// Test to ensure order was preserved
equal( byStart[1]._id, cId, "byStart[1]._id matches cId" );
equal( byEnd[1]._id, dId, "byEnd[1]._id matches dId" );
Popcorn.forEach([ "a", "b", "c", "d" ], function( name ) {
Popcorn.removePlugin( name );
});
});
test( "Popcorn.forEach", function() {
expect( 3 );