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.
- data/.gitignore +0 -0
- data/Gemfile +0 -0
- data/README.md +10 -4
- data/Rakefile +0 -0
- data/lib/popcornjs-rails/version.rb +1 -1
- data/lib/popcornjs-rails.rb +0 -0
- data/popcornjs-rails.gemspec +0 -0
- data/vendor/assets/javascripts/popcorn-complete.js +1512 -910
- data/vendor/assets/javascripts/popcorn-complete.min.js +188 -178
- data/vendor/assets/javascripts/popcorn-ie8.js +2849 -0
- data/vendor/assets/javascripts/popcorn-ie8.min.js +64 -0
- data/vendor/assets/javascripts/popcorn.js +207 -511
- data/vendor/assets/javascripts/popcorn.min.js +37 -42
- metadata +5 -3
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* popcorn.js version 1.
|
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 = ( "
|
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
|
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.
|
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 === "
|
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
|
-
//
|
255
|
-
var isReady = function(
|
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
|
-
|
260
|
-
|
261
|
-
|
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
|
-
|
264
|
-
|
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
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
285
|
+
Popcorn.addTrackEvent( self, {
|
286
|
+
start: videoDurationPlus,
|
287
|
+
end: videoDurationPlus
|
288
|
+
});
|
271
289
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
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
|
-
|
297
|
+
Popcorn.timeUpdate( self, {} );
|
280
298
|
|
281
|
-
|
299
|
+
self.emit( "timeupdate" );
|
282
300
|
|
283
|
-
|
284
|
-
|
301
|
+
!self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
|
302
|
+
};
|
285
303
|
|
286
|
-
|
304
|
+
!self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
|
287
305
|
|
288
|
-
|
306
|
+
} else {
|
289
307
|
|
290
|
-
|
291
|
-
|
292
|
-
|
308
|
+
self.data.timeUpdate = function( event ) {
|
309
|
+
Popcorn.timeUpdate( self, event );
|
310
|
+
};
|
293
311
|
|
294
|
-
|
295
|
-
|
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
|
-
|
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: "
|
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.
|
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
|
-
|
825
|
-
|
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,
|
941
|
+
Popcorn.removeTrackEvent = function( obj, removeId ) {
|
922
942
|
|
923
|
-
var
|
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
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
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 (
|
966
|
+
if ( start._id ) {
|
939
967
|
|
940
|
-
//
|
941
|
-
if (
|
942
|
-
byStart.push(
|
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
|
-
//
|
947
|
-
if (
|
948
|
-
|
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
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
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
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
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 ] !==
|
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,
|
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,
|
1000
|
-
delete obj.data.trackRefs[
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
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 ( !
|
1396
|
-
options.end = options[ "out" ] ||
|
1440
|
+
if ( !options.end && options.end !== 0 ) {
|
1441
|
+
options.end = options[ "out" ] || Number.MAX_VALUE;
|
1397
1442
|
}
|
1398
1443
|
|
1399
|
-
//
|
1400
|
-
|
1401
|
-
|
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 ( !
|
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
|
-
|
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,
|
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(
|
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.
|
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
|
-
|
1443
|
-
|
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.
|
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 (
|
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.
|
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:
|
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
|
|