Merge commit 'origin/0.4' into 358

Conflicts:
	plugins/wikipedia/popcorn.wikipedia.js
	plugins/wikipedia/popcorn.wikipedia.unit.js
This commit is contained in:
Anna Sobiepanek 2011-03-10 14:46:42 -05:00
Родитель 88b2526bf7 02a9c1f1be
Коммит 43f14ad0ee
23 изменённых файлов: 670 добавлений и 193 удалений

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

@ -36,8 +36,8 @@
</head> </head>
<body> <body>
<h1 id="qunit-header">Popcorn Attribution Plug-in Demo</h1> <h1 id="qunit-header">Popcorn Attribution Plug-in Demo</h1>
<p> A attribution displaying This video made exclusively for drumbeat.org' will appear at 0 seconds and disappear at 10 seconds.</p> <p> A attribution displaying 'A Shared Culture, Jesse Dylan, license: CC-BY-N6' will appear at 0 seconds and disappear at 10 seconds.</p>
<p> A attribution displaying 'Visit webmademovies.org for more details' will appear at 5 seconds and disappear at 15 seconds.</p> <p> A attribution displaying 'Internet, The Computer Chronicles' will appear at 5 seconds and disappear at 15 seconds.</p>
<div> <div>
<video id='video' <video id='video'
controls preload='none' controls preload='none'

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

@ -87,7 +87,6 @@
uri += "lang=en-us&format=json&jsoncallback=flickr"; uri += "lang=en-us&format=json&jsoncallback=flickr";
Popcorn.xhr.getJSONP( uri, function( data ) { Popcorn.xhr.getJSONP( uri, function( data ) {
//$.getJSON( uri, function( data ) {
options.container.innerHTML = "<p style='padding:" + padding + ";'>" + data.title + "<p/>"; options.container.innerHTML = "<p style='padding:" + padding + ";'>" + data.title + "<p/>";
Popcorn.forEach( data.items, function ( item, i ) { Popcorn.forEach( data.items, function ( item, i ) {

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

@ -32,7 +32,10 @@ var googleCallback;
* *
*/ */
var newdiv, i = 1, _mapFired = false, _mapLoaded = false; var newdiv,
i = 1,
_mapFired = false,
_mapLoaded = false;
// callback function fires when the script is run // callback function fires when the script is run
googleCallback = function() { googleCallback = function() {
@ -41,23 +44,19 @@ var googleCallback;
// insert google api script once // insert google api script once
if (!_mapFired) { if (!_mapFired) {
_mapFired = true; _mapFired = true;
var loadScriptTime = (new Date).getTime(); Popcorn.getScript("http://maps.google.com/maps/api/js?sensor=false&callback=googleCallback");
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=googleCallback";
script.type = "text/javascript";
head.insertBefore( script, head.firstChild );
} }
Popcorn.plugin( "googlemap" , function( options ) { Popcorn.plugin( "googlemap" , function( options ) {
var newdiv, map, location; var newdiv,
map,
location;
// create a new div this way anything in the target div // create a new div this way anything in the target div
// this is later passed on to the maps api // this is later passed on to the maps api
newdiv = document.createElement("div"); newdiv = document.createElement("div");
newdiv.id = "actualmap"+i; newdiv.id = "actualmap" + i;
newdiv.style.width = "100%"; newdiv.style.width = "100%";
newdiv.style.height = "100%"; newdiv.style.height = "100%";
i++; i++;

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

@ -5,9 +5,6 @@
<script src="../../popcorn.js"></script> <script src="../../popcorn.js"></script>
<script src="http://google.com/jsapi"></script>
<script>google.load("elements", "1", {packages : ["newsshow"]});</script>
<script src="popcorn.googlenews.js"></script> <script src="popcorn.googlenews.js"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {

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

@ -1,8 +1,34 @@
// PLUGIN: Google News // PLUGIN: Google News
(function (Popcorn) { (function (Popcorn) {
var scriptLoaded = false;
Popcorn.getScript( "http://www.google.com/jsapi", function() {
google.load("elements", "1", {packages : ["newsshow"], callback: function() {scriptLoaded = true;}});
});
/** /**
* Google News popcorn plug-in
* Displays Google News information on a topic in a targeted div.
* Options parameter will need a start, end and target.
* Optional parameters are topic. topic defaults to "top stories"
* Start is the time that you want this plug-in to execute
* End is the time that you want this plug-in to stop executing
* Target is the id of the document element that the content is
* appended to, this target element must exist on the DOM
* Topic is the topic of news articles you want to display.
*
* @param {Object} options
*
* Example:
var p = Popcorn('#video')
.footnote({
start: 5, // seconds, mandatory
end: 15, // seconds, mandatory
topic: 'oil spill', // optional
target: 'newsdiv' // mandatory
} )
*
*/ */
Popcorn.plugin( "googlenews" , { Popcorn.plugin( "googlenews" , {
@ -26,12 +52,22 @@
if ( document.getElementById( options.target ) ) { if ( document.getElementById( options.target ) ) {
document.getElementById( options.target ).appendChild( options.container ); document.getElementById( options.target ).appendChild( options.container );
} }
var newsShow = new google.elements.NewsShow( options.container, {
format : "300x250", var readyCheck = setInterval(function() {
queryList : [ if ( !scriptLoaded ) {
{ q: options.topic || "Top Stories" } return;
] }
} ); clearInterval(readyCheck);
var newsShow = new google.elements.NewsShow( options.container, {
format : "300x250",
queryList : [
{ q: options.topic || "Top Stories" }
]
} );
}, 5);
options.container.style.display = "none"; options.container.style.display = "none";
}, },

68
plugins/index.html Normal file
Просмотреть файл

@ -0,0 +1,68 @@
<!DOCTYPE>
<html>
<head>
<title>Popcorn Plug-in Unit Tests</title>
</head>
<body onload="runAllTests();">
<div style="position:absolute;top:0px;left:0px;width:150px;height:100%">
<h1>Popcorn Plug-in Unit Tests</h1>
<button type="button" onclick="runAllTests();">Run all Tests</button>
<ul id="menuItems">
<li><a onclick="clearEvents();" target="out" href="attribution/popcorn.attribution.unit.html">attribution</a></li>
<li><a onclick="clearEvents();" target="out" href="code/popcorn.code.unit.html">code</a></li>
<li><a onclick="clearEvents();" target="out" href="flickr/popcorn.flickr.unit.html">flickr</a></li>
<li><a onclick="clearEvents();" target="out" href="footnote/popcorn.footnote.unit.html">footnote</a></li>
<li><a onclick="clearEvents();" target="out" href="googlemap/popcorn.googlemap.unit.html">googlemap</a></li>
<li><a onclick="clearEvents();" target="out" href="googlenews/popcorn.googlenews.unit.html">googlenews</a></li>
<li><a onclick="clearEvents();" target="out" href="image/popcorn.image.unit.html">image</a></li>
<li><a onclick="clearEvents();" target="out" href="lastfm/popcorn.lastfm.unit.html">lastfm</a></li>
<li><a onclick="clearEvents();" target="out" href="lowerthird/popcorn.lowerthird.unit.html">lowerthird</a></li>
<li><a onclick="clearEvents();" target="out" href="mustache/popcorn.mustache.unit.html">mustache</a></li>
<li><a onclick="clearEvents();" target="out" href="subtitle/popcorn.subtitle.unit.html">subtitle</a></li>
<li><a onclick="clearEvents();" target="out" href="tagthisperson/popcorn.tagthisperson.unit.html">tagthisperson</a></li>
<li><a onclick="clearEvents();" target="out" href="twitter/popcorn.twitter.unit.html">twitter</a></li>
<li><a onclick="clearEvents();" target="out" href="webpage/popcorn.webpage.unit.html">webpage</a></li>
<li><a onclick="clearEvents();" target="out" href="wikipedia/popcorn.wikipedia.unit.html">wikipedia</a></li>
</ul>
</div>
<iframe id="out" name="out" style="position:absolute;top:0px;left:150px;height:100%;width:100%"></iframe>
<script>
var eventList = [];
function runAllTests(){
var testUrl = [ "attribution", "code", "flickr", "footnote", "googlemap",
"googlenews", "image", "lastfm", "lowerthird", "mustache",
"subtitle", "tagthisperson", "twitter", "webpage", "wikipedia" ];
//googlenews and lowerthird tests do not exist, therefore their test time is set to 0
var testDur = [ 17000, 20000, 10000, 20000, 11000,
0, 10000, 10000, 0, 15000,
25000, 21000, 10000, 21000, 21000 ];
var setTest = function( index ) {
var url = function( str ) {
return str + "/popcorn." + str + ".unit.html";
};
document.getElementById('out').src = url( testUrl[ index ] );
};
for ( var i = 0, delay = 0; i < testUrl.length; delay += testDur[i], i++ ) {
(function ( j ) {
var event = setTimeout(function() {
setTest( j );
}, delay);
eventList.push(event);
})( i );
}
}
function clearEvents(){
var len = eventList.length;
for( var i = 0; i < len; i++ ) {
clearTimeout( eventList[i] );
}
for( var i = 0; i < len; i++ ) {
eventList.pop();
}
}
</script>
</body>
</html>

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

@ -1,5 +1,28 @@
// PLUGIN: LASTFM // PLUGIN: LASTFM
var lastFMcallback; var _artists = [],
lastFMcallback = function(data){
if (data.artist) {
var htmlString = '<h3>'+data.artist.name+'</h3>';
htmlString += '<a href="'+data.artist.url+'" target="_blank" style="float:left;margin:0 10px 0 0;"><img src="'+ data.artist.image[2]['#text'] +'" alt=""></a>';
htmlString += '<p>'+ data.artist.bio.summary +'</p>';
htmlString += '<hr /><p><h4>Tags</h4><ul>';
Popcorn.forEach( data.artist.tags.tag, function( val, i) {
htmlString += '<li><a href="'+ val.url +'">'+ val.name +'</a></li>';
});
htmlString += '</ul></p>';
htmlString += '<hr /><p><h4>Similar</h4><ul>';
Popcorn.forEach( data.artist.similar.artist, function( val, i) {
htmlString += '<li><a href="'+ val.url +'">'+ val.name +'</a></li>';
});
htmlString += '</ul></p>';
_artists[data.artist.name.toLowerCase()] = htmlString;
}
};
(function (Popcorn) { (function (Popcorn) {
@ -29,7 +52,6 @@ var lastFMcallback;
*/ */
Popcorn.plugin( "lastfm" , (function(){ Popcorn.plugin( "lastfm" , (function(){
var _artists = [];
return { return {
manifest: { manifest: {
@ -59,40 +81,12 @@ var lastFMcallback;
} }
if(!_artists[options.artist]) { if(!_artists[options.artist]) {
var loadScriptTime = (new Date).getTime();
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist="+ options.artist +"&api_key="+options.apikey+"&format=json&callback=lastFMcallback";
script.type = "text/javascript";
head.insertBefore( script, head.firstChild );
_artists[options.artist] = "Unknown Artist"; _artists[options.artist] = "Unknown Artist";
Popcorn.getScript("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist="+ options.artist +"&api_key="+options.apikey+"&format=json&callback=lastFMcallback");
} }
lastFMcallback = function(data){
if (data.artist) {
var htmlString = '<h3>'+data.artist.name+'</h3>';
htmlString += '<a href="'+data.artist.url+'" target="_blank" style="float:left;margin:0 10px 0 0;"><img src="'+ data.artist.image[2]['#text'] +'" alt=""></a>';
htmlString += '<p>'+ data.artist.bio.summary +'</p>';
htmlString += '<hr /><p><h4>Tags</h4><ul>';
Popcorn.forEach( data.artist.tags.tag, function( val, i) {
htmlString += '<li><a href="'+ val.url +'">'+ val.name +'</a></li>';
});
htmlString += '</ul></p>';
htmlString += '<hr /><p><h4>Similar</h4><ul>';
Popcorn.forEach( data.artist.similar.artist, function( val, i) {
htmlString += '<li><a href="'+ val.url +'">'+ val.name +'</a></li>';
});
htmlString += '</ul></p>';
_artists[data.artist.name.toLowerCase()] = htmlString;
}
};
}, },
/** /**
* @member LastFM * @member LastFM

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

@ -3,7 +3,32 @@
(function (Popcorn) { (function (Popcorn) {
/** /**
*/ * Lower Third popcorn plug-in
* Displays information about a speaker over the video, or in the target div
* Options parameter will need a start, and end.
* Optional parameters are target, salutation, name and role.
* Start is the time that you want this plug-in to execute
* End is the time that you want this plug-in to stop executing
* Target is the id of the document element that the content is
* appended to, this target element must exist on the DOM
* salutation is the speaker's Mr. Ms. Dr. etc.
* name is the speaker's name.
* role is information about the speaker, example Engineer.
*
* @param {Object} options
*
* Example:
var p = Popcorn('#video')
.footnote({
start: 5, // seconds, mandatory
end: 15, // seconds, mandatory
salutation: 'Mr', // optional
name: 'Scott Downe', // optional
role: 'Programmer', // optional
target: 'subtitlediv' // optional
} )
*
*/
// just a little tool function // just a little tool function
// calculates the top and left position of an element // calculates the top and left position of an element

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

@ -2,17 +2,7 @@
(function (Popcorn) { (function (Popcorn) {
// TODO: swap to getScript() Popcorn.getScript('https://github.com/janl/mustache.js/raw/master/mustache.js');
(function() {
var mustacheUrl = 'https://github.com/janl/mustache.js/raw/master/mustache.js';
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = mustacheUrl;
head.insertBefore( script, head.firstChild );
})();
/** /**
* Mustache Popcorn Plug-in * Mustache Popcorn Plug-in

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

@ -62,7 +62,7 @@ test('Popcorn Mustache Plugin', function () {
video.addEventListener('timeupdate', function() { video.addEventListener('timeupdate', function() {
function pass(a, b) { function pass(a, b) {
equals( '<h1>mustache - test ' + a + '/' + b + '<\/h1>', mustacheDiv.innerHTML, 'Mustache template rendered' ); equals( mustacheDiv.innerHTML, '<h1>mustache - test ' + a + '/' + b + '<\/h1>','Mustache template rendered' );
plus(); plus();
} }

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

@ -4,8 +4,6 @@
<title>Popcorn Subtitle Plug-in Demo</title> <title>Popcorn Subtitle Plug-in Demo</title>
<script src="../../popcorn.js"></script> <script src="../../popcorn.js"></script>
<script src="http://google.com/jsapi"></script>
<script>google.load("language", "1");</script>
<script src="popcorn.subtitle.js"></script> <script src="popcorn.subtitle.js"></script>
<script> <script>

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

@ -2,7 +2,59 @@
(function (Popcorn) { (function (Popcorn) {
var scriptLoaded = false;
Popcorn.getScript( "http://www.google.com/jsapi", function() {
google.load("language", "1", {callback: function() {scriptLoaded = true;}});
});
/** /**
* Subtitle popcorn plug-in
* Displays a subtitle over the video, or in the target div
* Options parameter will need a start, and end.
* Optional parameters are target and text.
* Start is the time that you want this plug-in to execute
* End is the time that you want this plug-in to stop executing
* Target is the id of the document element that the content is
* appended to, this target element must exist on the DOM
* Text is the text of the subtitle you want to display.
*
* Language is the expected language the subtitle text is in
* Languagesrc is the target id of the element that contains
* the language value ("en", "fr", etc.) to translate the text into
* example:
* <select id="language">
* <option value="zh" selected="selected">Chinese</option>
* <option value="en">English</option>
* <option value="fr">French</option>
* <option value="de">German</option>
* <option value="it">Italian</option>
* <option value="ja">Japanese</option>
* <option value="ko">Korean</option>
* <option value="fa">Persian</option>
* <option value="pl">Polish</option>
* <option value="pt">Portuguese</option>
* <option value="es">Spanish</option>
* </select>
* Accessibilitysrc is the target id of a checkbox element
* checked means show all subtitles regardless of language and languagesrc
* not checked means only translate if language and languagesrc are different
* if no accessibilitysrc exists, default is to display all subtitles regardless
*
* @param {Object} options
*
* Example:
var p = Popcorn('#video')
.footnote({
start: 5, // seconds, mandatory
end: 15, // seconds, mandatory
text: 'Hellow world', // optional
target: 'subtitlediv', // optional
language: 'en', // optional
languagesrc: 'language', // optional
accessibilitysrc: 'accessibility' // optional
} )
*
*/ */
// just a little tool function // just a little tool function
@ -34,17 +86,6 @@
} ); } );
}; };
/*
// Find element offset
if (element.offsetParent) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
*/
Popcorn.plugin( "subtitle" , { Popcorn.plugin( "subtitle" , {
manifest: { manifest: {
@ -67,7 +108,7 @@
// Creates a div for all subtitles to use // Creates a div for all subtitles to use
if ( !this.container ) { if ( !this.container ) {
this.container = document.createElement('div'); this.container = document.createElement('div');
this.container.id = "subtitlediv";
this.container.style.position = "absolute"; this.container.style.position = "absolute";
this.container.style.color = "white"; this.container.style.color = "white";
this.container.style.textShadow = "black 2px 2px 6px"; this.container.style.textShadow = "black 2px 2px 6px";
@ -80,7 +121,7 @@
this.container.style.top = offset( this.video ).top + this.video.offsetHeight - 65 + "px"; this.container.style.top = offset( this.video ).top + this.video.offsetHeight - 65 + "px";
this.container.style.left = offset( this.video ).left + "px"; this.container.style.left = offset( this.video ).left + "px";
this.video.parentNode.appendChild( this.container ); document.body.appendChild( this.container );
} }
// if a target is specified, use that // if a target is specified, use that
@ -99,58 +140,65 @@
options.toggleSubtitles = function() {}; options.toggleSubtitles = function() {};
options.that = this; options.that = this;
var readyCheck = setInterval(function() {
if ( options.languagesrc ) { if ( !scriptLoaded ) {
options.showSubtitle = translate; return;
options.languageSrc = document.getElementById( options.languagesrc );
options.selectedLanguage = options.languageSrc.options[ options.languageSrc.selectedIndex ].value;
if ( !this.languageSources ) {
this.languageSources = {};
} }
clearInterval(readyCheck);
if ( options.languagesrc ) {
options.showSubtitle = translate;
if ( !this.languageSources[ options.languagesrc ] ) { options.languageSrc = document.getElementById( options.languagesrc );
this.languageSources[ options.languagesrc ] = {};
}
if ( !this.languageSources[ options.languagesrc ][ options.target ] ) {
this.languageSources[ options.languagesrc ][ options.target ] = true;
options.languageSrc.addEventListener( "change", function() {
options.toggleSubtitles();
options.showSubtitle( options, options.container.innerHTML );
}, false );
}
}
if ( accessibility ) {
options.accessibility = accessibility;
options.toggleSubtitles = function() {
options.selectedLanguage = options.languageSrc.options[ options.languageSrc.selectedIndex ].value; options.selectedLanguage = options.languageSrc.options[ options.languageSrc.selectedIndex ].value;
if ( options.accessibility.checked || options.selectedLanguage !== ( options.language || "") ) {
options.display = "inline"; if ( !this.languageSources ) {
options.container.style.display = options.display; this.languageSources = {};
} else if ( options.selectedLanguage === ( options.language || "") ) {
options.display = "none";
options.container.style.display = options.display;
} }
}; if ( !this.languageSources[ options.languagesrc ] ) {
this.languageSources[ options.languagesrc ] = {};
}
if ( !this.languageSources[ options.languagesrc ][ options.target ] ) {
this.languageSources[ options.languagesrc ][ options.target ] = true;
options.languageSrc.addEventListener( "change", function() {
options.toggleSubtitles();
options.showSubtitle( options, options.container.innerHTML );
}, false );
}
}
if ( accessibility ) {
options.accessibility = accessibility;
options.toggleSubtitles = function() {
options.selectedLanguage = options.languageSrc.options[ options.languageSrc.selectedIndex ].value;
if ( options.accessibility.checked || options.selectedLanguage !== ( options.language || "") ) {
options.display = "inline";
options.container.style.display = options.display;
} else if ( options.selectedLanguage === ( options.language || "") ) {
options.display = "none";
options.container.style.display = options.display;
}
};
options.accessibility.addEventListener( "change", options.toggleSubtitles, false );
// initiate it once to set starting state
options.toggleSubtitles();
}
}, 5);
options.accessibility.addEventListener( "change", options.toggleSubtitles, false );
// initiate it once to set starting state
options.toggleSubtitles();
}
}, },
/** /**

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

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>Popcorn Subtitle Plug-in Test</title>
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
<script src="../../test/qunit/qunit.js"></script>
<!--
do not move - this must be called immediately prior to
popcorn-api-draft.js
-->
<script src="../../popcorn.js"></script>
<script src="popcorn.subtitle.js"></script>
<script src="popcorn.subtitle.unit.js"></script>
</head>
<body>
<h1 id="qunit-header">Popcorn Subtitle Plugin</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"> </div>
<video id='video'
controls preload='none'
width= '250px'
poster="../../test/poster.png">
<source id='mp4'
src="../../test/trailer.mp4"
type='video/mp4; codecs="avc1, mp4a"'>
<source id='ogv'
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
<h2>Choose your language</h2>
<select id="language">
<option value="en" selected="selected">English</option>
</select>
<div>
with help from <a href="http://google.com/translate">Google Translate</a><br />
<input type="checkbox" id="accessibility" checked="checked" />All subtitles (accessibility)
</div>
</body>
</html>

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

@ -0,0 +1,83 @@
test("Popcorn Subtitle Plugin", function () {
var popped = Popcorn("#video"),
expects = 5,
count = 0,
interval,
interval2,
interval3,
interval4,
subtitlediv;
expect(expects);
function plus() {
if ( ++count===expects) {
start();
}
}
stop();
ok ('subtitle' in popped, "subtitle is a method of the popped instance");
plus();
popped.subtitle({
start: 3,
text: 'this is the first subtitle of 2011',
language: "en",
languagesrc: "language",
accessibilitysrc: "accessibility"
} )
.subtitle({
start: 10,
end: 15,
text: 'this is the second subtitle of 2011',
language: "en",
languagesrc: "language",
accessibilitysrc: "accessibility"
} )
.subtitle({
start: 20,
text: 'this is the third subtitle of 2011',
language: "en",
languagesrc: "language",
accessibilitysrc: "accessibility"
} )
.volume(0)
.play();
interval = setInterval( function() {
if( popped.currentTime() >= 3 && popped.currentTime() < 10 ) {
subtitlediv = document.getElementById('subtitlediv'); // this div has only now been created
equals (subtitlediv.innerHTML, "this is the first subtitle of 2011", "subtitle displaying correct information" );
plus();
clearInterval( interval );
}
}, 500);
interval2 = setInterval( function() {
if( popped.currentTime() >= 10 && popped.currentTime() < 15 ) {
equals (subtitlediv.innerHTML, "this is the second subtitle of 2011", "subtitle displaying correct information" );
plus();
clearInterval( interval2 );
}
}, 500);
interval3 = setInterval( function() {
if( popped.currentTime() >= 15 && popped.currentTime() < 20 ) {
equals (subtitlediv.innerHTML, "" );
plus();
clearInterval( interval3 );
}
}, 500);
interval4 = setInterval( function() {
if( popped.currentTime() > 20) {
equals (subtitlediv.innerHTML, "this is the third subtitle of 2011", "subtitle displaying correct information" );
plus();
clearInterval( interval4 );
}
}, 500);
});

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

@ -15,18 +15,20 @@
end: 10, // seconds end: 10, // seconds
person: 'Anna Sob', person: 'Anna Sob',
image: 'http://newshour.s3.amazonaws.com/photos%2Fspeeches%2Fguests%2FRichardNSmith_thumbnail.jpg', image: 'http://newshour.s3.amazonaws.com/photos%2Fspeeches%2Fguests%2FRichardNSmith_thumbnail.jpg',
href: 'http://annasob.wordpress.com',
target: 'tagdiv' target: 'tagdiv'
} ) } )
.tagthisperson({ .tagthisperson({
start: 5, // seconds start: 5, // seconds
end: 15, // seconds end: 15, // seconds
person: 'Scott', person: 'Scott',
href: 'http://scottdowne.wordpress.com/',
target: 'tagdiv' target: 'tagdiv'
} ) } )
.tagthisperson({ .tagthisperson({
start: 0, // seconds start: 0, // seconds
end: 15, // seconds end: 15, // seconds
person: 'Scott', person: 'Mike',
target: 'tagdiv2' target: 'tagdiv2'
} ) } )
}, false); }, false);
@ -35,8 +37,9 @@
</head> </head>
<body> <body>
<h1 id="qunit-header">Popcorn tagthisperson Plug-in Demo</h1> <h1 id="qunit-header">Popcorn tagthisperson Plug-in Demo</h1>
<p> A tag displaying Scott will appear at 0 seconds and disappear at 15 seconds.</p> <p> A tag displaying Mike will appear at 0 seconds and disappear at 15 seconds.</p>
<p> A separate tag displaying Anna Sob with an image will appear at 0 seconds and disappear at 10 seconds. At 5 seconds Scott will be appended to this tag.</p> <p> A separate tag displaying Anna Sob with an image and a URL attached will appear at 0 seconds and disappear at 10 seconds.</p>
<p> At 5 seconds Scott with a URL attached will be appended to this tag and disappear at 15 seconds.</p>
<div> <div>
<video id='video' <video id='video'
controls preload='none' controls preload='none'

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

@ -10,6 +10,7 @@
* End is the time that you want this plug-in to stop executing * End is the time that you want this plug-in to stop executing
* Person is the name of the person who you want to tag * Person is the name of the person who you want to tag
* Image is the url to the image of the person - optional * Image is the url to the image of the person - optional
* href is the url to the webpage of the person - optional
* Target is the id of the document element that the text needs to be * Target is the id of the document element that the text needs to be
* attached to, this target element must exist on the DOM * attached to, this target element must exist on the DOM
* *
@ -21,6 +22,8 @@
start: 5, // seconds start: 5, // seconds
end: 15, // seconds end: 15, // seconds
person: '@annasob', person: '@annasob',
image: 'http://newshour.s3.amazonaws.com/photos%2Fspeeches%2Fguests%2FRichardNSmith_thumbnail.jpg',
href: 'http://annasob.wordpress.com',
target: 'tagdiv' target: 'tagdiv'
} ) } )
* *
@ -56,14 +59,15 @@
end : {elem:'input', type:'text', label:'Out'}, end : {elem:'input', type:'text', label:'Out'},
target : 'tag-container', target : 'tag-container',
person : {elem:'input', type:'text', label:'Name'}, person : {elem:'input', type:'text', label:'Name'},
image : {elem:'input', type:'text', label:'Image Src'} image : {elem:'input', type:'text', label:'Image Src'},
href : {elem:'input', type:'text', label:'URL'}
} }
}, },
_setup: function( options ) { _setup: function( options ) {
var exists = false; var exists = false;
// loop through the existing objects to ensure no duplicates // loop through the existing objects to ensure no duplicates
// the idea here is to have one object per unique options.target // the idea here is to have one object per unique options.target
for ( var i = 0; i< peopleArray.length; i++ ) { for ( var i = 0; i < peopleArray.length; i++ ) {
if ( peopleArray[ i ].name === options.target ) { if ( peopleArray[ i ].name === options.target ) {
options._p = peopleArray[ i ]; options._p = peopleArray[ i ];
exists = true; exists = true;
@ -83,14 +87,11 @@
* options variable * options variable
*/ */
start: function( event, options ){ start: function( event, options ){
if ( options.image ) { options._p.contains[ options.person ] = ( options.image ) ? "<img src='" + options.image + "'/> " : "" ;
options._p.contains[ options.person ] = " <img src='" + options.image + "'/> " + options.person; options._p.contains[ options.person ] += ( options.href ) ? "<a href='" + options.href + "' target='_blank'> " + options.person + "</a>" : options.person ;
} else {
options._p.contains[ options.person ] = options.person;
}
//options._p.contains[options.person] = options.person;
if ( document.getElementById( options.target ) ) { if ( document.getElementById( options.target ) ) {
document.getElementById( options.target ).innerHTML = options._p.toString(); document.getElementById( options.target ).innerHTML = options._p.toString();
} }
}, },
/** /**
@ -99,10 +100,10 @@
* of the video reaches the end time provided by the * of the video reaches the end time provided by the
* options variable * options variable
*/ */
end: function(event, options){ end: function( event, options ){
delete options._p.contains[ options.person ]; delete options._p.contains[ options.person ];
if ( document.getElementById( options.target ) ) { if ( document.getElementById( options.target ) ) {
document.getElementById( options.target ).innerHTML = options._p.toString(); document.getElementById( options.target ).innerHTML = options._p.toString();
} }
} }
}; };

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

@ -39,5 +39,6 @@
</video> </video>
<div id="tagdiv"></div> <div id="tagdiv"></div>
<div id="tagdiv2"></div>
</body> </body>
</html> </html>

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

@ -1,17 +1,18 @@
test("Popcorn tagthisperson Plugin", function () { test("Popcorn tagthisperson Plugin", function () {
var popped = Popcorn( "#video" ), var popped = Popcorn( "#video" ),
expects = 7, expects = 8,
count = 0, count = 0,
interval, interval,
interval2, interval2,
interval3, interval3,
tagdiv = document.getElementById( 'tagdiv' ); tagdiv = document.getElementById( 'tagdiv' );
tagdiv2 = document.getElementById( 'tagdiv2' );
expect(expects); expect(expects);
function plus() { function plus() {
if ( ++count===expects ) { if ( ++count === expects ) {
start(); start();
} }
} }
@ -29,21 +30,35 @@ test("Popcorn tagthisperson Plugin", function () {
end: 5, // seconds end: 5, // seconds
person: 'Anna Sob', person: 'Anna Sob',
image: 'http://newshour.s3.amazonaws.com/photos%2Fspeeches%2Fguests%2FRichardNSmith_thumbnail.jpg', image: 'http://newshour.s3.amazonaws.com/photos%2Fspeeches%2Fguests%2FRichardNSmith_thumbnail.jpg',
href: 'http://annasob.wordpress.com',
target: 'tagdiv' target: 'tagdiv'
} ) } )
.tagthisperson({ .tagthisperson({
start: 3, // seconds start: 3, // seconds
end: 10, // seconds end: 10, // seconds
person: 'Scott', person: 'Scott',
href: 'http://scottdowne.wordpress.com/',
target: 'tagdiv' target: 'tagdiv'
} ) } )
.tagthisperson({
start: 6, // seconds
end: 10, // seconds
person: 'Mike',
target: 'tagdiv2'
} )
.tagthisperson({
start: 7, // seconds
end: 12, // seconds
person: 'Daniel',
target: 'tagdiv2'
} )
.volume(0) .volume(0)
.play(); .play();
interval = setInterval( function() { interval = setInterval( function() {
if( popped.currentTime() > 0 && popped.currentTime() <= 5 ) { if( popped.currentTime() > 0 && popped.currentTime() <= 5 ) {
equals ( tagdiv.childElementCount, 1, "tagdiv now contains one child elements" ); equals ( tagdiv.childElementCount, 2, "tagdiv now contains two child elements" );
plus(); plus();
equals ( tagdiv.textContent.trim() , "Anna Sob" ,"tagdiv shows the first tag" ); equals ( tagdiv.textContent.trim() , "Anna Sob" ,"tagdiv shows the first tag" );
plus(); plus();
@ -52,25 +67,23 @@ test("Popcorn tagthisperson Plugin", function () {
}, 2000); }, 2000);
interval2 = setInterval( function() { interval2 = setInterval( function() {
if( popped.currentTime() > 3 && popped.currentTime() < 5 ) { if( popped.currentTime() > 5 ) {
equals ( tagdiv.textContent.trim() , "Anna Sob, Scott", "tagdiv shows the first & second tag" ); equals ( tagdiv.innerHTML.search( "<a href" ) , 1 ,"second tag in tagdiv has a url" );
plus();
equals ( tagdiv2.textContent.trim(), "Mike, Daniel" ,"tagdiv2 shows the first & second tag" );
plus(); plus();
clearInterval( interval2 ); clearInterval( interval2 );
} }
}, 2000); }, 4000);
interval3 = setInterval( function() { interval3 = setInterval( function() {
if( popped.currentTime() > 5 ) { if( popped.currentTime() > 12 ) {
equals ( tagdiv.innerHTML.trim() , "Scott" ,"tagdiv shows the second tag only" ); equals ( tagdiv.innerHTML , "" ,"tagdiv is now cleared" );
plus();
equals ( tagdiv2.innerHTML , "" ,"tagdiv2 is now cleared" );
plus(); plus();
clearInterval( interval3 ); clearInterval( interval3 );
} }
}, 5000);
interval4 = setInterval( function() {
if( popped.currentTime() > 10 ) {
equals ( tagdiv.innerHTML , "" ,"tagdiv is now cleared" );
plus();
clearInterval( interval4 );
}
}, 4000); }, 4000);
}); });

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

@ -31,12 +31,7 @@
*/ */
if ( !window.TWTR ) { if ( !window.TWTR ) {
var head = document.getElementsByTagName("head")[0] || document.documentElement, Popcorn.getScript("http://widgets.twimg.com/j/2/widget.js");
script = document.createElement("script");
script.src = "http://widgets.twimg.com/j/2/widget.js";
head.insertBefore( script, head.firstChild );
} }
Popcorn.plugin( "twitter" , { Popcorn.plugin( "twitter" , {

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

@ -87,11 +87,8 @@ var wikiCallback;
options._fired = true; options._fired = true;
}; };
var head = document.getElementsByTagName( "head" )[0]; Popcorn.getScript("http://" + options.lang + ".wikipedia.org/w/api.php?action=parse&props=text&page=" + ( options.title || options.src.slice( options.src.lastIndexOf("/")+1) ) + "&format=json&callback=wikiCallback" + _guid);
var script = document.createElement( "script" );
script.src = "http://" + options.lang + ".wikipedia.org/w/api.php?action=parse&props=text&page=" + ( options.src.slice( options.src.lastIndexOf("/")+1) ) + "&format=json&callback=wikiCallback" + _guid;
head.insertBefore( script, head.firstChild );
}, },
/** /**
* @member wikipedia * @member wikipedia

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

@ -61,5 +61,4 @@ test("Popcorn wikipedia Plugin", function () {
equals (theArticle.childElement[1].innerHTML, "São Paulo is the largest city in Brazil, the largest city in the southern hemisphere, and the world's 7th largest metropolitan area. The city is the capital of the state of São Paulo, the most populou ...", "wikidiv has the right content" ); equals (theArticle.childElement[1].innerHTML, "São Paulo is the largest city in Brazil, the largest city in the southern hemisphere, and the world's 7th largest metropolitan area. The city is the capital of the state of São Paulo, the most populou ...", "wikidiv has the right content" );
plus(); plus();
}); });
}); });

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

@ -22,6 +22,59 @@
return new Popcorn.p.init( entity ); return new Popcorn.p.init( entity );
}; };
// Instance caching
Popcorn.instances = [];
Popcorn.instanceIds = {};
Popcorn.removeInstance = function( instance ) {
// If called prior to any instances being created
// Return early to avoid splicing on nothing
if ( !Popcorn.instances.length ) {
return;
}
// Remove instance from Popcorn.instances
Popcorn.instances.splice( Popcorn.instanceIds[ instance.id ], 1 );
// Delete the instance id key
delete Popcorn.instanceIds[ instance.id ];
// Return current modified instances
return Popcorn.instances;
};
// Addes a Popcorn instance to the Popcorn instance array
Popcorn.addInstance = function( instance ) {
var instanceLen = Popcorn.instances.length,
instanceId = instance.video.id && instance.video.id;
// If the video element has its own `id` use it, otherwise provide one
// Ensure that instances have unique ids and unique entries
// Uses `in` operator to avoid false positives on 0
instance.id = !( instanceId in Popcorn.instanceIds ) && instanceId ||
"__popcorn" + instanceLen;
// Create a reference entry for this instance
Popcorn.instanceIds[ instance.id ] = instanceLen;
// Add this instance to the cache
Popcorn.instances.push( instance );
// Return the current modified instances
return Popcorn.instances;
};
// Request Popcorn object instance by id
Popcorn.getInstanceById = function( id ) {
return Popcorn.instances[ Popcorn.instanceIds[ id ] ];
};
// Remove Popcorn object instance by id
Popcorn.removeInstanceById = function( id ) {
return Popcorn.removeInstance( Popcorn.instances[ Popcorn.instanceIds[ id ] ] );
};
// Declare a shortcut (Popcorn.p) to and a definition of // Declare a shortcut (Popcorn.p) to and a definition of
// the new prototype for our Popcorn constructor // the new prototype for our Popcorn constructor
Popcorn.p = Popcorn.prototype = { Popcorn.p = Popcorn.prototype = {
@ -87,6 +140,8 @@
this.video = elem ? elem : null; this.video = elem ? elem : null;
Popcorn.addInstance(this);
this.data = { this.data = {
history: [], history: [],
events: {}, events: {},
@ -335,6 +390,7 @@
_running: false, _running: false,
_natives: { _natives: {
start: fn || Popcorn.nop, start: fn || Popcorn.nop,
end: Popcorn.nop,
type: "exec" type: "exec"
} }
}); });
@ -484,6 +540,9 @@
// Push track event ids into the history // Push track event ids into the history
obj.data.history.push( track._id ); obj.data.history.push( track._id );
track._natives.start = track._natives.start || Popcorn.nop;
track._natives.end = track._natives.end || Popcorn.nop;
} }
// Store this definition in an array sorted by times // Store this definition in an array sorted by times
@ -902,7 +961,7 @@
settings.ajax.open( settings.type, settings.url, settings.async ); settings.ajax.open( settings.type, settings.url, settings.async );
settings.ajax.send( settings.data = null ? null : settings.data ); settings.ajax.send( settings.data || null );
return Popcorn.xhr.httpData( settings ); return Popcorn.xhr.httpData( settings );
} }

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

@ -67,6 +67,63 @@ test("Utility", function () {
}); });
test("Instances", function() {
var expects = 11,
count = 0,
instance;
expect(expects);
function plus(){
if ( ++count == expects ) {
start();
}
}
stop();
ok( typeof Popcorn.addInstance === "function" , "Popcorn.addInstance is a provided utility function");
plus();
ok( typeof Popcorn.removeInstance === "function" , "Popcorn.removeInstance is a provided utility function");
plus();
ok( typeof Popcorn.getInstanceById === "function" , "Popcorn.getInstanceById is a provided utility function");
plus();
ok( typeof Popcorn.removeInstanceById === "function" , "Popcorn.removeInstanceById is a provided utility function");
plus();
ok( typeof Popcorn.instanceIds === "object" , "Popcorn.instanceIds is a provided cache object");
plus();
ok( "length" in Popcorn.instances && "join" in Popcorn.instances, "Popcorn.instances is a provided cache array");
plus();
instance = Popcorn.getInstanceById("video");
ok( instance.video, "Stored instance as a `video` property" );
plus();
ok( instance.data, "Stored instance as a `data` property" );
plus();
ok( instance instanceof Popcorn, "Instance instanceof Popcorn" );
plus();
equal( Popcorn.instances.length, 1, "There are the correct number of Popcorn instances" );
plus();
// Create another instance
Popcorn("#video");
// Get a reference to remove
var remove = Popcorn.instances[1];
// Remove and check the length of the currently cached instances
equal( Popcorn.removeInstanceById( remove.id ).length, 1, "Removing an instance by id: 1 instance remains" );
plus();
});
test("guid", function () { test("guid", function () {
@ -578,27 +635,21 @@ test("Plugin Factory", function () {
QUnit.reset(); QUnit.reset();
// needs expectation
var popped = Popcorn("#video"), var popped = Popcorn("#video"),
methods = "load play pause currentTime mute volume roundTime exec removePlugin", methods = "load play pause currentTime mute volume roundTime exec removePlugin",
expects = 48, expects = 34,
count = 0; count = 0;
//expect(expects);
function plus() { function plus() {
if ( ++count == expects ) { if ( ++count == expects ) {
Popcorn.removePlugin("breaker");
Popcorn.removePlugin("executor"); Popcorn.removePlugin("executor");
Popcorn.removePlugin("complicator"); Popcorn.removePlugin("complicator");
Popcorn.removePlugin("closure");
start(); start();
} }
} }
expect( expects );
stop( 10000 ); stop( 10000 );
expect(expects);
Popcorn.plugin("executor", function () { Popcorn.plugin("executor", function () {
@ -639,7 +690,7 @@ test("Plugin Factory", function () {
ok( "executor" in popped, "executor plugin is now available to instance" ); ok( "executor" in popped, "executor plugin is now available to instance" );
plus(); plus();
ok( Popcorn.registry.length === 1, "One item in the registry"); equals( Popcorn.registry.length, 1, "One item in the registry");
plus(); plus();
@ -649,7 +700,6 @@ test("Plugin Factory", function () {
end: 2 end: 2
}); });
Popcorn.plugin("complicator", { Popcorn.plugin("complicator", {
start: function ( event ) { start: function ( event ) {
@ -688,10 +738,9 @@ test("Plugin Factory", function () {
} }
}); });
ok( "complicator" in popped, "complicator plugin is now available to instance" ); ok( "complicator" in popped, "complicator plugin is now available to instance" );
plus(); plus();
ok( Popcorn.registry.length === 2, "Two items in the registry"); equals( Popcorn.registry.length, 2, "Two items in the registry");
plus(); plus();
popped.complicator({ popped.complicator({
@ -699,6 +748,27 @@ test("Plugin Factory", function () {
end: 4 end: 4
}); });
popped.currentTime(0).play();
});
test("Plugin Breaker", function () {
QUnit.reset();
var popped = Popcorn("#video"),
expects = 6,
count = 0;
function plus() {
if ( ++count == expects ) {
Popcorn.removePlugin("breaker");
start();
}
}
expect( expects );
stop( 10000 );
var breaker = { var breaker = {
@ -735,7 +805,7 @@ test("Plugin Factory", function () {
ok( "breaker" in popped, "breaker plugin is now available to instance" ); ok( "breaker" in popped, "breaker plugin is now available to instance" );
plus(); plus();
ok( Popcorn.registry.length === 3, "Three items in the registry"); equals( Popcorn.registry.length, 1, "Three items in the registry");
plus(); plus();
popped.breaker({ popped.breaker({
@ -743,6 +813,61 @@ test("Plugin Factory", function () {
end: 2 end: 2
}); });
popped.currentTime(0).play();
});
test("Plugin Empty", function () {
QUnit.reset();
var popped = Popcorn("#video"),
expects = 2,
testObj = {},
count = 0;
function plus() {
if ( ++count == expects ) {
Popcorn.removePlugin("empty");
start();
}
}
expect( expects );
stop( 10000 );
Popcorn.plugin("empty", testObj);
popped.empty({});
ok( testObj.start, "default start function is generated" );
plus();
ok( testObj.end, "default end function is generated" );
plus();
popped.currentTime(0).play();
});
test("Plugin Closure", function () {
QUnit.reset();
var popped = Popcorn("#video"),
methods = "load play pause currentTime mute volume roundTime exec removePlugin",
expects = 8,
count = 0;
function plus() {
if ( ++count == expects ) {
Popcorn.removePlugin("closure");
start();
}
}
expect( expects );
stop( 10000 );
Popcorn.plugin("closure", function() { Popcorn.plugin("closure", function() {
var startCount = 0; var startCount = 0;
@ -781,7 +906,7 @@ test("Plugin Factory", function () {
nick: "second closure track" nick: "second closure track"
}); });
popped.currentTime(0).play(); popped.currentTime(5).play();
}); });
@ -1652,9 +1777,6 @@ test("Parsing Handler - References unavailable plugin", function () {
}); });
module("Popcorn Test Runner End"); module("Popcorn Test Runner End");
test("Last Check", function () { test("Last Check", function () {