popcornjs-rails 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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