popcornjs-rails 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * popcorn.js version 1.1.2
2
+ * popcorn.js version 1.2
3
3
  * http://popcornjs.org
4
4
  *
5
5
  * Copyright 2011, Mozilla Foundation
@@ -14,9 +14,10 @@
14
14
  isSupported: false
15
15
  };
16
16
 
17
- var methods = ( "forEach extend effects error guid sizeOf isArray nop position disable enable destroy " +
17
+ var methods = ( "removeInstance addInstance getInstanceById removeInstanceById " +
18
+ "forEach extend effects error guid sizeOf isArray nop position disable enable destroy" +
18
19
  "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
19
- "timeUpdate plugin removePlugin compose effect parser xhr getJSONP getScript" ).split(/\s+/);
20
+ "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/);
20
21
 
21
22
  while ( methods.length ) {
22
23
  global.Popcorn[ methods.shift() ] = function() {};
@@ -66,6 +67,21 @@
66
67
  };
67
68
  }()),
68
69
 
70
+ // Non-public `getKeys`, return an object's keys as an array
71
+ getKeys = function( obj ) {
72
+ return Object.keys ? Object.keys( obj ) : (function( obj ) {
73
+ var item,
74
+ list = [];
75
+
76
+ for ( item in obj ) {
77
+ if ( hasOwn.call( obj, item ) ) {
78
+ list.push( item );
79
+ }
80
+ }
81
+ return list;
82
+ })( obj );
83
+ },
84
+
69
85
  refresh = function( obj ) {
70
86
  var currentTime = obj.media.currentTime,
71
87
  animation = obj.options.frameAnimation,
@@ -129,7 +145,7 @@
129
145
  };
130
146
 
131
147
  // Popcorn API version, automatically inserted via build system.
132
- Popcorn.version = "1.1.2";
148
+ Popcorn.version = "1.2";
133
149
 
134
150
  // Boolean flag allowing a client to determine if Popcorn can be supported
135
151
  Popcorn.isSupported = true;
@@ -143,7 +159,8 @@
143
159
 
144
160
  init: function( entity, options ) {
145
161
 
146
- var matches;
162
+ var matches,
163
+ self = this;
147
164
 
148
165
  // Supports Popcorn(function () { /../ })
149
166
  // Originally proposed by Daniel Brooks
@@ -151,7 +168,7 @@
151
168
  if ( typeof entity === "function" ) {
152
169
 
153
170
  // If document ready has already fired
154
- if ( document.readyState === "interactive" || document.readyState === "complete" ) {
171
+ if ( document.readyState === "complete" ) {
155
172
 
156
173
  entity( document, Popcorn );
157
174
 
@@ -251,58 +268,60 @@
251
268
  }
252
269
  };
253
270
 
254
- // Wrap true ready check
255
- var isReady = function( that ) {
271
+ // function to fire when video is ready
272
+ var isReady = function() {
273
+
274
+ self.media.removeEventListener( "loadeddata", isReady, false );
256
275
 
257
276
  var duration, videoDurationPlus;
258
277
 
259
- if ( that.media.readyState >= 2 ) {
260
- // Adding padding to the front and end of the arrays
261
- // this is so we do not fall off either end
278
+ // Adding padding to the front and end of the arrays
279
+ // this is so we do not fall off either end
280
+ duration = self.media.duration;
262
281
 
263
- duration = that.media.duration;
264
- // Check for no duration info (NaN)
265
- videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
282
+ // Check for no duration info (NaN)
283
+ videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
266
284
 
267
- Popcorn.addTrackEvent( that, {
268
- start: videoDurationPlus,
269
- end: videoDurationPlus
270
- });
285
+ Popcorn.addTrackEvent( self, {
286
+ start: videoDurationPlus,
287
+ end: videoDurationPlus
288
+ });
271
289
 
272
- if ( that.options.frameAnimation ) {
273
- // if Popcorn is created with frameAnimation option set to true,
274
- // requestAnimFrame is used instead of "timeupdate" media event.
275
- // This is for greater frame time accuracy, theoretically up to
276
- // 60 frames per second as opposed to ~4 ( ~every 15-250ms)
277
- that.data.timeUpdate = function () {
290
+ if ( self.options.frameAnimation ) {
291
+ // if Popcorn is created with frameAnimation option set to true,
292
+ // requestAnimFrame is used instead of "timeupdate" media event.
293
+ // This is for greater frame time accuracy, theoretically up to
294
+ // 60 frames per second as opposed to ~4 ( ~every 15-250ms)
295
+ self.data.timeUpdate = function () {
278
296
 
279
- Popcorn.timeUpdate( that, {} );
297
+ Popcorn.timeUpdate( self, {} );
280
298
 
281
- that.trigger( "timeupdate" );
299
+ self.emit( "timeupdate" );
282
300
 
283
- !that.isDestroyed && requestAnimFrame( that.data.timeUpdate );
284
- };
301
+ !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
302
+ };
285
303
 
286
- !that.isDestroyed && requestAnimFrame( that.data.timeUpdate );
304
+ !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
287
305
 
288
- } else {
306
+ } else {
289
307
 
290
- that.data.timeUpdate = function( event ) {
291
- Popcorn.timeUpdate( that, event );
292
- };
308
+ self.data.timeUpdate = function( event ) {
309
+ Popcorn.timeUpdate( self, event );
310
+ };
293
311
 
294
- if ( !that.isDestroyed ) {
295
- that.media.addEventListener( "timeupdate", that.data.timeUpdate, false );
296
- }
312
+ if ( !self.isDestroyed ) {
313
+ self.media.addEventListener( "timeupdate", self.data.timeUpdate, false );
297
314
  }
298
- } else {
299
- global.setTimeout(function() {
300
- isReady( that );
301
- }, 1 );
302
315
  }
303
316
  };
304
317
 
305
- isReady( this );
318
+ if ( self.media.readyState >= 2 ) {
319
+
320
+ isReady();
321
+ } else {
322
+
323
+ self.media.addEventListener( "loadeddata", isReady, false );
324
+ }
306
325
 
307
326
  return this;
308
327
  }
@@ -534,7 +553,7 @@
534
553
  _natives: {
535
554
  start: fn || Popcorn.nop,
536
555
  end: Popcorn.nop,
537
- type: "exec"
556
+ type: "cue"
538
557
  }
539
558
  });
540
559
 
@@ -561,7 +580,7 @@
561
580
  }
562
581
 
563
582
  // Trigger either muted|unmuted event
564
- this.trigger( event );
583
+ this.emit( event );
565
584
 
566
585
  return this;
567
586
  },
@@ -821,8 +840,9 @@
821
840
  };
822
841
 
823
842
  // Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
824
- Popcorn.forEach( [ "trigger", "listen", "unlisten" ], function( key ) {
825
- Popcorn.p[ key ] = Popcorn.events.fn[ key ];
843
+ // Extend aliases (on, off, emit)
844
+ Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) {
845
+ Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
826
846
  });
827
847
 
828
848
  // Internal Only - Adds track events to the instance object
@@ -918,55 +938,83 @@
918
938
  return obj;
919
939
  };
920
940
 
921
- Popcorn.removeTrackEvent = function( obj, trackId ) {
941
+ Popcorn.removeTrackEvent = function( obj, removeId ) {
922
942
 
923
- var historyLen = obj.data.history.length,
943
+ var start, end, animate,
944
+ historyLen = obj.data.history.length,
945
+ length = obj.data.trackEvents.byStart.length,
946
+ index = 0,
924
947
  indexWasAt = 0,
925
948
  byStart = [],
926
949
  byEnd = [],
927
950
  animating = [],
928
951
  history = [];
929
952
 
930
- Popcorn.forEach( obj.data.trackEvents.byStart, function( o, i, context ) {
931
- // Preserve the original start/end trackEvents
932
- if ( !o._id ) {
933
- byStart.push( obj.data.trackEvents.byStart[i] );
934
- byEnd.push( obj.data.trackEvents.byEnd[i] );
953
+ while ( --length > -1 ) {
954
+ start = obj.data.trackEvents.byStart[ index ];
955
+ end = obj.data.trackEvents.byEnd[ index ];
956
+
957
+ // Padding events will not have _id properties.
958
+ // These should be safely pushed onto the front and back of the
959
+ // track event array
960
+ if ( !start._id ) {
961
+ byStart.push( start );
962
+ byEnd.push( end );
935
963
  }
936
964
 
937
965
  // Filter for user track events (vs system track events)
938
- if ( o._id ) {
966
+ if ( start._id ) {
939
967
 
940
- // Filter for the trackevent to remove
941
- if ( o._id !== trackId ) {
942
- byStart.push( obj.data.trackEvents.byStart[i] );
943
- byEnd.push( obj.data.trackEvents.byEnd[i] );
968
+ // If not a matching start event for removal
969
+ if ( start._id !== removeId ) {
970
+ byStart.push( start );
944
971
  }
945
972
 
946
- // Capture the position of the track being removed.
947
- if ( o._id === trackId ) {
948
- indexWasAt = i;
949
- o._natives._teardown && o._natives._teardown.call( obj, o );
973
+ // If not a matching end event for removal
974
+ if ( end._id !== removeId ) {
975
+ byEnd.push( end );
950
976
  }
951
- }
952
977
 
953
- });
978
+ // If the _id is matched, capture the current index
979
+ if ( start._id === removeId ) {
980
+ indexWasAt = index;
954
981
 
955
- if ( obj.data.trackEvents.animating.length ) {
956
- Popcorn.forEach( obj.data.trackEvents.animating, function( o, i, context ) {
957
- // Preserve the original start/end trackEvents
958
- if ( !o._id ) {
959
- animating.push( obj.data.trackEvents.animating[i] );
982
+ // If a _teardown function was defined,
983
+ // enforce for track event removals
984
+ if ( start._natives._teardown ) {
985
+ start._natives._teardown.call( obj, start );
986
+ }
960
987
  }
988
+ }
989
+ // Increment the track index
990
+ index++;
991
+ }
961
992
 
962
- // Filter for user track events (vs system track events)
963
- if ( o._id ) {
964
- // Filter for the trackevent to remove
965
- if ( o._id !== trackId ) {
966
- animating.push( obj.data.trackEvents.animating[i] );
967
- }
993
+ // Reset length to be used by the condition below to determine
994
+ // if animating track events should also be filtered for removal.
995
+ // Reset index below to be used by the reverse while as an
996
+ // incrementing counter
997
+ length = obj.data.trackEvents.animating.length;
998
+ index = 0;
999
+
1000
+ if ( length ) {
1001
+ while ( --length > -1 ) {
1002
+ animate = obj.data.trackEvents.animating[ index ];
1003
+
1004
+ // Padding events will not have _id properties.
1005
+ // These should be safely pushed onto the front and back of the
1006
+ // track event array
1007
+ if ( !animate._id ) {
1008
+ animating.push( animate );
968
1009
  }
969
- });
1010
+
1011
+ // If not a matching animate event for removal
1012
+ if ( animate._id && animate._id !== removeId ) {
1013
+ animating.push( animate );
1014
+ }
1015
+ // Increment the track index
1016
+ index++;
1017
+ }
970
1018
  }
971
1019
 
972
1020
  // Update
@@ -983,7 +1031,7 @@
983
1031
  obj.data.trackEvents.animating = animating;
984
1032
 
985
1033
  for ( var i = 0; i < historyLen; i++ ) {
986
- if ( obj.data.history[ i ] !== trackId ) {
1034
+ if ( obj.data.history[ i ] !== removeId ) {
987
1035
  history.push( obj.data.history[ i ] );
988
1036
  }
989
1037
  }
@@ -992,12 +1040,12 @@
992
1040
  obj.data.history = history;
993
1041
 
994
1042
  // Update track event references
995
- Popcorn.removeTrackEvent.ref( obj, trackId );
1043
+ Popcorn.removeTrackEvent.ref( obj, removeId );
996
1044
  };
997
1045
 
998
1046
  // Internal Only - Removes track event references from instance object's trackRefs hash table
999
- Popcorn.removeTrackEvent.ref = function( obj, trackId ) {
1000
- delete obj.data.trackRefs[ trackId ];
1047
+ Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
1048
+ delete obj.data.trackRefs[ removeId ];
1001
1049
 
1002
1050
  return obj;
1003
1051
  };
@@ -1076,7 +1124,7 @@
1076
1124
  byEnd._running = false;
1077
1125
  natives.end.call( obj, event, byEnd );
1078
1126
 
1079
- obj.trigger( trackend,
1127
+ obj.emit( trackend,
1080
1128
  Popcorn.extend({}, byEnd, {
1081
1129
  plugin: type,
1082
1130
  type: trackend
@@ -1110,7 +1158,7 @@
1110
1158
  byStart._running = true;
1111
1159
  natives.start.call( obj, event, byStart );
1112
1160
 
1113
- obj.trigger( trackstart,
1161
+ obj.emit( trackstart,
1114
1162
  Popcorn.extend({}, byStart, {
1115
1163
  plugin: type,
1116
1164
  type: trackstart
@@ -1167,7 +1215,7 @@
1167
1215
  byStart._running = false;
1168
1216
  natives.end.call( obj, event, byStart );
1169
1217
 
1170
- obj.trigger( trackend,
1218
+ obj.emit( trackend,
1171
1219
  Popcorn.extend({}, byEnd, {
1172
1220
  plugin: type,
1173
1221
  type: trackend
@@ -1200,7 +1248,7 @@
1200
1248
  byEnd._running = true;
1201
1249
  natives.start.call( obj, event, byEnd );
1202
1250
 
1203
- obj.trigger( trackstart,
1251
+ obj.emit( trackstart,
1204
1252
  Popcorn.extend({}, byStart, {
1205
1253
  plugin: type,
1206
1254
  type: trackstart
@@ -1339,7 +1387,7 @@
1339
1387
  // Storing the plugin natives
1340
1388
  var natives = options._natives = {},
1341
1389
  compose = "",
1342
- defaults, originalOpts, manifestOpts, mergedSetupOpts;
1390
+ originalOpts, manifestOpts;
1343
1391
 
1344
1392
  Popcorn.extend( natives, setup );
1345
1393
 
@@ -1362,9 +1410,6 @@
1362
1410
  args[ 1 ]._running && natives.end.apply( this, args );
1363
1411
  }, natives._teardown );
1364
1412
 
1365
- // Check for previously set default options
1366
- defaults = this.options.defaults && this.options.defaults[ options._natives && options._natives.type ];
1367
-
1368
1413
  // default to an empty string if no effect exists
1369
1414
  // split string into an array of effects
1370
1415
  options.compose = options.compose && options.compose.split( " " ) || [];
@@ -1392,29 +1437,44 @@
1392
1437
  options.start = options[ "in" ] || 0;
1393
1438
  }
1394
1439
 
1395
- if ( !( "end" in options ) ) {
1396
- options.end = options[ "out" ] || this.duration() || Number.MAX_VALUE;
1440
+ if ( !options.end && options.end !== 0 ) {
1441
+ options.end = options[ "out" ] || Number.MAX_VALUE;
1397
1442
  }
1398
1443
 
1399
- // Merge with defaults if they exist, make sure per call is prioritized
1400
- mergedSetupOpts = defaults ? Popcorn.extend( {}, defaults, options ) :
1401
- options;
1444
+ // Use hasOwn to detect non-inherited toString, since all
1445
+ // objects will receive a toString - its otherwise undetectable
1446
+ if ( !hasOwn.call( options, "toString" ) ) {
1447
+ options.toString = function() {
1448
+ var props = [
1449
+ "start: " + options.start,
1450
+ "end: " + options.end,
1451
+ "id: " + (options.id || options._id)
1452
+ ];
1453
+
1454
+ // Matches null and undefined, allows: false, 0, "" and truthy
1455
+ if ( options.target != null ) {
1456
+ props.push( "target: " + options.target );
1457
+ }
1458
+
1459
+ return name + " ( " + props.join(", ") + " )";
1460
+ };
1461
+ }
1402
1462
 
1403
1463
  // Resolves 239, 241, 242
1404
- if ( !mergedSetupOpts.target ) {
1464
+ if ( !options.target ) {
1405
1465
 
1406
1466
  // Sometimes the manifest may be missing entirely
1407
1467
  // or it has an options object that doesn't have a `target` property
1408
1468
  manifestOpts = "options" in manifest && manifest.options;
1409
1469
 
1410
- mergedSetupOpts.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
1470
+ options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
1411
1471
  }
1412
1472
 
1413
1473
  // Trigger _setup method if exists
1414
- options._natives._setup && options._natives._setup.call( this, mergedSetupOpts );
1474
+ options._natives._setup && options._natives._setup.call( this, options );
1415
1475
 
1416
1476
  // Create new track event for this instance
1417
- Popcorn.addTrackEvent( this, Popcorn.extend( mergedSetupOpts, options ) );
1477
+ Popcorn.addTrackEvent( this, Popcorn.extend( options, options ) );
1418
1478
 
1419
1479
  // Future support for plugin event definitions
1420
1480
  // for all of the native events
@@ -1424,7 +1484,7 @@
1424
1484
 
1425
1485
  if ( reserved.indexOf( type ) === -1 ) {
1426
1486
 
1427
- this.listen( type, callback );
1487
+ this.on( type, callback );
1428
1488
  }
1429
1489
  }
1430
1490
 
@@ -1433,14 +1493,17 @@
1433
1493
  return this;
1434
1494
  };
1435
1495
 
1496
+ // Extend Popcorn.p with new named definition
1436
1497
  // Assign new named definition
1437
- plugin[ name ] = function( options ) {
1438
- return pluginFn.call( this, isfn ? definition.call( this, options ) : definition,
1439
- options );
1440
- };
1498
+ Popcorn.p[ name ] = plugin[ name ] = function( options ) {
1441
1499
 
1442
- // Extend Popcorn.p with new named definition
1443
- Popcorn.extend( Popcorn.p, plugin );
1500
+ // Merge with defaults if they exist, make sure per call is prioritized
1501
+ var defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {},
1502
+ mergedSetupOpts = Popcorn.extend( {}, defaults, options );
1503
+
1504
+ return pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
1505
+ mergedSetupOpts );
1506
+ };
1444
1507
 
1445
1508
  // Push into the registry
1446
1509
  var entry = {
@@ -1485,7 +1548,7 @@
1485
1548
 
1486
1549
  // Trigger an error that the instance can listen for
1487
1550
  // and react to
1488
- this.trigger( "error", Popcorn.plugin.errors );
1551
+ this.emit( "error", Popcorn.plugin.errors );
1489
1552
  }
1490
1553
  };
1491
1554
  }
@@ -1537,13 +1600,11 @@
1537
1600
  // remove all trackEvents
1538
1601
  for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
1539
1602
 
1540
- if ( ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) &&
1541
- ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) ) {
1603
+ if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) {
1542
1604
 
1543
1605
  byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
1544
1606
 
1545
1607
  byStart.splice( idx, 1 );
1546
- byEnd.splice( idx, 1 );
1547
1608
 
1548
1609
  // update for loop if something removed, but keep checking
1549
1610
  idx--; sl--;
@@ -1552,6 +1613,13 @@
1552
1613
  obj.data.trackEvents.endIndex--;
1553
1614
  }
1554
1615
  }
1616
+
1617
+ // clean any remaining references in the end index
1618
+ // we do this seperate from the above check because they might not be in the same order
1619
+ if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) {
1620
+
1621
+ byEnd.splice( idx, 1 );
1622
+ }
1555
1623
  }
1556
1624
 
1557
1625
  //remove all animating events
@@ -1583,325 +1651,6 @@
1583
1651
 
1584
1652
  Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
1585
1653
 
1586
- // stores parsers keyed on filetype
1587
- Popcorn.parsers = {};
1588
-
1589
- // An interface for extending Popcorn
1590
- // with parser functionality
1591
- Popcorn.parser = function( name, type, definition ) {
1592
-
1593
- if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
1594
- Popcorn.error( "'" + name + "' is a protected function name" );
1595
- return;
1596
- }
1597
-
1598
- // fixes parameters for overloaded function call
1599
- if ( typeof type === "function" && !definition ) {
1600
- definition = type;
1601
- type = "";
1602
- }
1603
-
1604
- if ( typeof definition !== "function" || typeof type !== "string" ) {
1605
- return;
1606
- }
1607
-
1608
- // Provides some sugar, but ultimately extends
1609
- // the definition into Popcorn.p
1610
-
1611
- var natives = Popcorn.events.all,
1612
- parseFn,
1613
- parser = {};
1614
-
1615
- parseFn = function( filename, callback ) {
1616
-
1617
- if ( !filename ) {
1618
- return this;
1619
- }
1620
-
1621
- var that = this;
1622
-
1623
- Popcorn.xhr({
1624
- url: filename,
1625
- dataType: type,
1626
- success: function( data ) {
1627
-
1628
- var tracksObject = definition( data ),
1629
- tracksData,
1630
- tracksDataLen,
1631
- tracksDef,
1632
- idx = 0;
1633
-
1634
- tracksData = tracksObject.data || [];
1635
- tracksDataLen = tracksData.length;
1636
- tracksDef = null;
1637
-
1638
- // If no tracks to process, return immediately
1639
- if ( !tracksDataLen ) {
1640
- return;
1641
- }
1642
-
1643
- // Create tracks out of parsed object
1644
- for ( ; idx < tracksDataLen; idx++ ) {
1645
-
1646
- tracksDef = tracksData[ idx ];
1647
-
1648
- for ( var key in tracksDef ) {
1649
-
1650
- if ( hasOwn.call( tracksDef, key ) && !!that[ key ] ) {
1651
-
1652
- that[ key ]( tracksDef[ key ] );
1653
- }
1654
- }
1655
- }
1656
- if ( callback ) {
1657
- callback();
1658
- }
1659
- }
1660
- });
1661
-
1662
- return this;
1663
- };
1664
-
1665
- // Assign new named definition
1666
- parser[ name ] = parseFn;
1667
-
1668
- // Extend Popcorn.p with new named definition
1669
- Popcorn.extend( Popcorn.p, parser );
1670
-
1671
- // keys the function name by filetype extension
1672
- //Popcorn.parsers[ name ] = true;
1673
-
1674
- return parser;
1675
- };
1676
-
1677
- Popcorn.player = function( name, player ) {
1678
-
1679
- player = player || {};
1680
-
1681
- var playerFn = function( target, src, options ) {
1682
-
1683
- options = options || {};
1684
-
1685
- // List of events
1686
- var date = new Date() / 1000,
1687
- baselineTime = date,
1688
- currentTime = 0,
1689
- volume = 1,
1690
- muted = false,
1691
- events = {},
1692
-
1693
- // The container div of the resource
1694
- container = document.getElementById( rIdExp.exec( target ) && rIdExp.exec( target )[ 2 ] ) ||
1695
- document.getElementById( target ) ||
1696
- target,
1697
- basePlayer = {},
1698
- timeout,
1699
- popcorn;
1700
-
1701
- // copies a div into the media object
1702
- for( var val in container ) {
1703
-
1704
- if ( typeof container[ val ] === "object" ) {
1705
-
1706
- basePlayer[ val ] = container[ val ];
1707
- } else if ( typeof container[ val ] === "function" ) {
1708
-
1709
- basePlayer[ val ] = (function( value ) {
1710
-
1711
- // this is a stupid ugly kludgy hack in honour of Safari
1712
- // in Safari a NodeList is a function, not an object
1713
- if ( "length" in container[ value ] && !container[ value ].call ) {
1714
-
1715
- return container[ value ];
1716
- } else {
1717
-
1718
- return function() {
1719
-
1720
- return container[ value ].apply( container, arguments );
1721
- };
1722
- }
1723
- }( val ));
1724
- } else {
1725
-
1726
- Popcorn.player.defineProperty( basePlayer, val, {
1727
- get: (function( value ) {
1728
-
1729
- return function() {
1730
-
1731
- return container[ value ];
1732
- };
1733
- }( val )),
1734
- set: Popcorn.nop,
1735
- configurable: true
1736
- });
1737
- }
1738
- }
1739
-
1740
- var timeupdate = function() {
1741
-
1742
- date = new Date() / 1000;
1743
-
1744
- if ( !basePlayer.paused ) {
1745
-
1746
- basePlayer.currentTime = basePlayer.currentTime + ( date - baselineTime );
1747
- basePlayer.dispatchEvent( "timeupdate" );
1748
- timeout = setTimeout( timeupdate, 10 );
1749
- }
1750
-
1751
- baselineTime = date;
1752
- };
1753
-
1754
- basePlayer.play = function() {
1755
-
1756
- this.paused = false;
1757
-
1758
- if ( basePlayer.readyState >= 4 ) {
1759
-
1760
- baselineTime = new Date() / 1000;
1761
- basePlayer.dispatchEvent( "play" );
1762
- timeupdate();
1763
- }
1764
- };
1765
-
1766
- basePlayer.pause = function() {
1767
-
1768
- this.paused = true;
1769
- basePlayer.dispatchEvent( "pause" );
1770
- };
1771
-
1772
- Popcorn.player.defineProperty( basePlayer, "currentTime", {
1773
- get: function() {
1774
-
1775
- return currentTime;
1776
- },
1777
- set: function( val ) {
1778
-
1779
- // make sure val is a number
1780
- currentTime = +val;
1781
- basePlayer.dispatchEvent( "timeupdate" );
1782
- return currentTime;
1783
- },
1784
- configurable: true
1785
- });
1786
-
1787
- Popcorn.player.defineProperty( basePlayer, "volume", {
1788
- get: function() {
1789
-
1790
- return volume;
1791
- },
1792
- set: function( val ) {
1793
-
1794
- // make sure val is a number
1795
- volume = +val;
1796
- basePlayer.dispatchEvent( "volumechange" );
1797
- return volume;
1798
- },
1799
- configurable: true
1800
- });
1801
-
1802
- Popcorn.player.defineProperty( basePlayer, "muted", {
1803
- get: function() {
1804
-
1805
- return muted;
1806
- },
1807
- set: function( val ) {
1808
-
1809
- // make sure val is a number
1810
- muted = +val;
1811
- basePlayer.dispatchEvent( "volumechange" );
1812
- return muted;
1813
- },
1814
- configurable: true
1815
- });
1816
-
1817
- // Adds an event listener to the object
1818
- basePlayer.addEventListener = function( evtName, fn ) {
1819
-
1820
- if ( !events[ evtName ] ) {
1821
-
1822
- events[ evtName ] = [];
1823
- }
1824
-
1825
- events[ evtName ].push( fn );
1826
- return fn;
1827
- };
1828
-
1829
- // Can take event object or simple string
1830
- basePlayer.dispatchEvent = function( oEvent ) {
1831
-
1832
- var evt,
1833
- self = this,
1834
- eventInterface,
1835
- eventName = oEvent.type;
1836
-
1837
- // A string was passed, create event object
1838
- if ( !eventName ) {
1839
-
1840
- eventName = oEvent;
1841
- eventInterface = Popcorn.events.getInterface( eventName );
1842
-
1843
- if ( eventInterface ) {
1844
-
1845
- evt = document.createEvent( eventInterface );
1846
- evt.initEvent( eventName, true, true, window, 1 );
1847
- }
1848
- }
1849
-
1850
- Popcorn.forEach( events[ eventName ], function( val ) {
1851
-
1852
- val.call( self, evt, self );
1853
- });
1854
- };
1855
-
1856
- // Attempt to get src from playerFn parameter
1857
- basePlayer.src = src || "";
1858
- basePlayer.readyState = 0;
1859
- basePlayer.duration = 0;
1860
- basePlayer.paused = true;
1861
- basePlayer.ended = 0;
1862
-
1863
- if ( player._setup ) {
1864
-
1865
- player._setup.call( basePlayer, options );
1866
- } else {
1867
-
1868
- // there is no setup, which means there is nothing to load
1869
- basePlayer.readyState = 4;
1870
- basePlayer.dispatchEvent( "load" );
1871
- basePlayer.dispatchEvent( "loadeddata" );
1872
- }
1873
-
1874
- // when a custom player is loaded, load basePlayer state into custom player
1875
- basePlayer.addEventListener( "load", function() {
1876
-
1877
- // if a player is not ready before currentTime is called, this will set it after it is ready
1878
- basePlayer.currentTime = currentTime;
1879
-
1880
- // same as above with volume and muted
1881
- basePlayer.volume = volume;
1882
- basePlayer.muted = muted;
1883
- });
1884
-
1885
- basePlayer.addEventListener( "loadeddata", function() {
1886
-
1887
- // if play was called before player ready, start playing video
1888
- !basePlayer.paused && basePlayer.play();
1889
- });
1890
-
1891
- popcorn = new Popcorn.p.init( basePlayer, options );
1892
-
1893
- return popcorn;
1894
- };
1895
-
1896
- Popcorn[ name ] = Popcorn[ name ] || playerFn;
1897
- };
1898
-
1899
- Popcorn.player.defineProperty = Object.defineProperty || function( object, description, options ) {
1900
-
1901
- object.__defineGetter__( description, options.get || Popcorn.nop );
1902
- object.__defineSetter__( description, options.set || Popcorn.nop );
1903
- };
1904
-
1905
1654
  // Cache references to reused RegExps
1906
1655
  var rparams = /\?/,
1907
1656
  // XHR Setup object
@@ -2049,7 +1798,7 @@
2049
1798
  url = url.replace( parts.join( "=" ), parts[ 0 ] + "=" + callback );
2050
1799
  }
2051
1800
 
2052
- script.onload = function() {
1801
+ script.addEventListener( "load", function() {
2053
1802
 
2054
1803
  // Handling remote script loading callbacks
2055
1804
  if ( isScript ) {
@@ -2064,7 +1813,7 @@
2064
1813
  }
2065
1814
  // Garbage collect the script resource
2066
1815
  head.removeChild( script );
2067
- };
1816
+ }, false );
2068
1817
 
2069
1818
  script.src = url;
2070
1819
 
@@ -2138,96 +1887,43 @@
2138
1887
  }
2139
1888
  };
2140
1889
 
2141
-
2142
- // Initialize locale data
2143
- // Based on http://en.wikipedia.org/wiki/Language_localisation#Language_tags_and_codes
2144
- function initLocale( arg ) {
2145
-
2146
- var locale = typeof arg === "string" ? arg : [ arg.language, arg.region ].join( "-" ),
2147
- parts = locale.split( "-" );
2148
-
2149
- // Setup locale data table
2150
- return {
2151
- iso6391: locale,
2152
- language: parts[ 0 ] || "",
2153
- region: parts[ 1 ] || ""
2154
- };
2155
- }
2156
-
2157
- // Declare locale data table
2158
- var localeData = initLocale( global.navigator.userLanguage || global.navigator.language );
2159
-
2160
- Popcorn.locale = {
2161
-
2162
- // Popcorn.locale.get()
2163
- // returns reference to privately
2164
- // defined localeData
2165
- get: function() {
2166
- return localeData;
2167
- },
2168
-
2169
- // Popcorn.locale.set( string|object );
2170
- set: function( arg ) {
2171
-
2172
- localeData = initLocale( arg );
2173
-
2174
- Popcorn.locale.broadcast();
2175
-
2176
- return localeData;
2177
- },
2178
-
2179
- // Popcorn.locale.broadcast( type )
2180
- // Sends events to all popcorn media instances that are
2181
- // listening for locale events
2182
- broadcast: function( type ) {
2183
-
2184
- var instances = Popcorn.instances,
2185
- length = instances.length,
2186
- idx = 0,
2187
- instance;
2188
-
2189
- type = type || "locale:changed";
2190
-
2191
- // Iterate all current instances
2192
- for ( ; idx < length; idx++ ) {
2193
- instance = instances[ idx ];
2194
-
2195
- // For those instances with locale event listeners,
2196
- // trigger a locale change event
2197
- if ( type in instance.data.events ) {
2198
- instance.trigger( type );
2199
- }
2200
- }
2201
- }
2202
- };
2203
-
2204
1890
  // alias for exec function
2205
1891
  Popcorn.p.cue = Popcorn.p.exec;
2206
1892
 
2207
- function getItems() {
2208
-
2209
- var item,
2210
- list = [];
2211
-
2212
- if ( Object.keys ) {
2213
- list = Object.keys( Popcorn.p );
2214
- } else {
2215
-
2216
- for ( item in Popcorn.p ) {
2217
- if ( hasOwn.call( Popcorn.p, item ) ) {
2218
- list.push( item );
2219
- }
2220
- }
2221
- }
2222
-
2223
- return list.join( "," ).toLowerCase().split( ",");
2224
- }
2225
-
2226
1893
  // Protected API methods
2227
1894
  Popcorn.protect = {
2228
- natives: getItems()
1895
+ natives: getKeys( Popcorn.p ).map(function( val ) {
1896
+ return val.toLowerCase();
1897
+ })
2229
1898
  };
2230
1899
 
1900
+ // Setup logging for deprecated methods
1901
+ Popcorn.forEach({
1902
+ // Deprecated: Recommended
1903
+ "listen": "on",
1904
+ "unlisten": "off",
1905
+ "trigger": "emit",
1906
+ "exec": "cue"
1907
+
1908
+ }, function( recommend, api ) {
1909
+ var original = Popcorn.p[ api ];
1910
+ // Override the deprecated api method with a method of the same name
1911
+ // that logs a warning and defers to the new recommended method
1912
+ Popcorn.p[ api ] = function() {
1913
+ if ( typeof console !== "undefined" && console.warn ) {
1914
+ console.warn(
1915
+ "Deprecated method '" + api + "', " +
1916
+ (recommend == null ? "do not use." : "use '" + recommend + "' instead." )
1917
+ );
1918
+
1919
+ // Restore api after first warning
1920
+ Popcorn.p[ api ] = original;
1921
+ }
1922
+ return Popcorn.p[ recommend ].apply( this, [].slice.call( arguments ) );
1923
+ };
1924
+ });
1925
+
1926
+
2231
1927
  // Exposes Popcorn to global context
2232
1928
  global.Popcorn = Popcorn;
2233
1929