Merge pull request #46 from humphd/t1011

Text plugin
This commit is contained in:
Christopher De Cairos 2012-05-22 09:46:51 -07:00
Родитель 1db19133ea ac11003a96
Коммит 7a83050e64
8 изменённых файлов: 493 добавлений и 93 удалений

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

@ -32,7 +32,7 @@
<p> A footnote displaying 'Visit webmademovies.org for more details' will appear at 20 seconds and disappear at 45 seconds.</p>
<div>
<video id="video"
controls
controls
width="250px"
poster="../../test/poster.png">

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

@ -15,59 +15,58 @@
* @param {Object} options
*
* Example:
var p = Popcorn('#video')
.footnote({
start: 5, // seconds
end: 15, // seconds
text: 'This video made exclusively for drumbeat.org',
target: 'footnotediv'
} )
*
*/
* var p = Popcorn('#video')
* .footnote({
* start: 5, // seconds
* end: 15, // seconds
* text: 'This video made exclusively for drumbeat.org',
* target: 'footnotediv'
* });
**/
Popcorn.forEach( [ "footnote", "text" ], function( name ) {
Popcorn.plugin( "footnote", {
Popcorn.plugin( name , {
manifest: {
about: {
name: "Popcorn " + name + " Plugin",
version: "0.2",
author: "@annasob, @rwaldron",
website: "annasob.wordpress.com"
},
options: {
start: {
elem: "input",
type: "text",
label: "In"
},
end: {
elem: "input",
type: "text",
label: "Out"
},
text: {
elem: "input",
type: "text",
label: "Text"
},
target: name + "-container"
}
manifest: {
about: {
name: "Popcorn Footnote Plugin",
version: "0.2",
author: "@annasob, @rwaldron",
website: "annasob.wordpress.com"
},
options: {
start: {
elem: "input",
type: "text",
label: "In"
},
end: {
elem: "input",
type: "text",
label: "Out"
},
text: {
elem: "input",
type: "text",
label: "Text"
},
target: "footnote-container"
}
},
_setup: function( options ) {
var target = document.getElementById( options.target );
var target = Popcorn.dom.find( options.target );
options._container = document.createElement( "div" );
options._container.style.display = "none";
options._container.innerHTML = options.text;
if ( !target && Popcorn.plugin.debug ) {
if ( !target ) {
throw new Error( "target container doesn't exist" );
}
target && target.appendChild( options._container );
target.appendChild( options._container );
},
/**
* @member footnote
* The start function will be executed when the currentTime
@ -77,6 +76,7 @@
start: function( event, options ){
options._container.style.display = "inline";
},
/**
* @member footnote
* The end function will be executed when the currentTime
@ -86,10 +86,13 @@
end: function( event, options ){
options._container.style.display = "none";
},
_teardown: function( options ) {
document.getElementById( options.target ) && document.getElementById( options.target ).removeChild( options._container );
}
});
});
_teardown: function( options ) {
var target = Popcorn.dom.find( options.target );
if ( target ) {
target.removeChild( options._container );
}
}
});
})( Popcorn );

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

@ -1,17 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Popcorn API</title>
<title>Popcorn Footnote Plugin</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.footnote.js"></script>
<script src="popcorn.footnote.unit.js"></script>
<script src="../../test/inject.js"></script>
</head>
@ -24,7 +18,7 @@
<div id="qunit-fixture"> </div>
<video id="video"
controls
controls
width="250px"
poster="../../test/poster.png">
@ -35,7 +29,7 @@
<source id="ogv"
src="../../test/trailer.ogv"
type='video/ogg; codecs="theora, vorbis"'>
<source id='webm'
src="../../test/trailer.webm"
type='video/webm; codecs="vp8, vorbis"'>

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

@ -62,41 +62,3 @@ test( "Popcorn Footnote Plugin", function() {
popped.play().volume( 0 );
});
test( "Popcorn Text Plugin", function() {
var popped = Popcorn( "#video" ),
expects = 2,
count = 0,
setupId,
textdiv = document.getElementById( "textdiv" );
expect( expects );
function plus() {
if ( ++count===expects ) {
start();
}
}
ok( "text" in popped, "text is a method of the popped instance" );
plus();
popped.text({
start: 5,
end: 6,
text: "I am an alias",
target: "textdiv"
});
stop();
popped.exec( 5, function() {
equal( textdiv.children[ 0 ].innerHTML, "I am an alias", "I am an alias set by Popcorn.p.text" );
plus();
popped.pause();
}).currentTime( 5 ).play();
});

87
plugins/text/popcorn.text.html Executable file
Просмотреть файл

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html>
<head>
<title>Popcorn text Plug-in Demo</title>
<script src="../../popcorn.js"></script>
<script src="popcorn.text.js"></script>
<script>
Popcorn( function () {
var p = Popcorn( "#video" )
// Simple text
.text( {
start: 1,
end: 5,
text: 'This video made exclusively for drumbeat.org',
target: 'textdiv'
} )
// HTML text, rendered as HTML
.text( {
start: 5,
end: 10,
text: '<p>This video made <em>exclusively</em> for drumbeat.org</p>',
target: 'textdiv'
} )
// HTML text, escaped and rendered as plain text
.text( {
start: 10,
end: 15,
text: 'This is an HTML p element: <p>paragraph</p>',
escape: true,
target: 'textdiv'
} )
// Multi-Line HTML text, escaped and rendered as plain text without breaks
.text( {
start: 15,
end: 20,
text: 'This is an HTML p element: <p>paragraph</p>\nThis is an HTML b element: <b>bold</b>',
escape: true,
target: 'textdiv'
} )
// Multi-Line HTML text, escaped and rendered as plain text with breaks
.text( {
start: 20,
end: 25,
text: 'This is an HTML p element: <p>paragraph</p>\nThis is an HTML b element: <b>bold</b>',
escape: true,
multiline: true,
target: 'textdiv'
} )
.play().volume( 0 );
} );
</script>
</head>
<body>
<h1 id="qunit-header">Popcorn Footnote Plug-in Demo</h1>
<p> Text displaying "This video made exclusively for drumbeat.org" will appear from 1 to 5.</p>
<p> Text displaying "This video made exclusively for drumbeat.org", with <em>exclusively</em> emphasized (e.g., inline html) will appear from 5 to 10.</p>
<p> Text displaying "This is an HTML p element: &lt;p&gt;paragraph&lt;/p&gt;" (e.g., escaped html) will appear from 10 to 15.</p>
<div>
<video id="video"
controls
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>
</div>
<div id="textdiv" width="50%" height="50%">
</div>
</body>
</html>

167
plugins/text/popcorn.text.js Executable file
Просмотреть файл

@ -0,0 +1,167 @@
// PLUGIN: Text
(function ( Popcorn ) {
/**
* Text Popcorn plug-in
*
* Places text in an element on the page. Plugin options include:
* Options parameter will need a start, end, 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
* Text: is the text that you want to appear in the target
* Escape: {true|false} whether to escape the text (e.g., html strings)
* Multiline: {true|false} whether newlines should be turned into <br>s
* Target: is the ID of the element where the text should be placed.
*
* @param {Object} options
*
* Example:
* var p = Popcorn('#video')
*
* // Simple text
* .text({
* start: 5, // seconds
* end: 15, // seconds
* text: 'This video made exclusively for drumbeat.org',
* target: 'textdiv'
* })
*
* // HTML text, rendered as HTML
* .text({
* start: 15, // seconds
* end: 20, // seconds
* text: '<p>This video made <em>exclusively</em> for drumbeat.org</p>',
* target: 'textdiv'
* })
*
* // HTML text, escaped and rendered as plain text
* .text({
* start: 20, // seconds
* end: 25, // seconds
* text: 'This is an HTML p element: <p>paragraph</p>',
* escape: true,
* target: 'textdiv'
* })
*
* // Multi-Line HTML text, escaped and rendered as plain text
* .text({
* start: 25, // seconds
* end: 30, // seconds
* text: 'This is an HTML p element: <p>paragraph</p>\nThis is an HTML b element: <b>bold</b>',
* escape: true,
* multiline: true,
* target: 'textdiv'
* });
**/
/**
* HTML escape code from mustache.js, used under MIT Licence
* https://github.com/janl/mustache.js/blob/master/mustache.js
**/
var escapeMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': '&quot;',
"'": '&#39;'
};
function escapeHTML( string, multiline ) {
return String( string ).replace( /&(?!\w+;)|[<>"']/g, function ( s ) {
return escapeMap[ s ] || s;
});
}
function newlineToBreak( string ) {
// Deal with both \r\n and \n
return string.replace( /\r?\n/gm, "<br>" );
}
Popcorn.plugin( "text", {
manifest: {
about: {
name: "Popcorn Text Plugin",
version: "0.1",
author: "@humphd"
},
options: {
start: {
elem: "input",
type: "text",
label: "In"
},
end: {
elem: "input",
type: "text",
label: "Out"
},
text: {
elem: "input",
type: "text",
label: "Text"
},
escape: {
elem: "input",
type: "checkbox",
label: "Escape"
},
multiline: {
elem: "input",
type: "checkbox",
label: "Multiline"
},
target: "text-container"
}
},
_setup: function( options ) {
var target = Popcorn.dom.find( options.target );
var container = options._container = document.createElement( "div" );
container.style.display = "none";
// Escape HTML text if requested
var text = !!options.escape ? escapeHTML( options.text ) :
options.text;
// Swap newline for <br> if requested
text = !!options.multiline ? newlineToBreak ( text ) : text;
container.innerHTML = text;
if ( !target ) {
throw new Error( "target container doesn't exist" );
}
target.appendChild( container );
},
/**
* @member text
* The start function will be executed when the currentTime
* of the video reaches the start time provided by the
* options variable
*/
start: function( event, options ) {
options._container.style.display = "inline";
},
/**
* @member text
* The end function will be executed when the currentTime
* of the video reaches the end time provided by the
* options variable
*/
end: function( event, options ) {
options._container.style.display = "none";
},
_teardown: function( options ) {
var target = document.getElementById( options.target );
if ( target ) {
target.removeChild( options._container );
}
}
});
})( Popcorn );

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

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<title>Popcorn Text Plugin</title>
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
<script src="../../test/qunit/qunit.js"></script>
<script src="../../popcorn.js"></script>
<script src="popcorn.text.js"></script>
<script src="popcorn.text.unit.js"></script>
<script src="../../test/inject.js"></script>
</head>
<body>
<h1 id="qunit-header">Popcorn Text 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
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"'>
<source id='webm'
src="../../test/trailer.webm"
type='video/webm; codecs="vp8, vorbis"'>
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
<div id="textdiv"></div>
</body>
</html>

144
plugins/text/popcorn.text.unit.js Executable file
Просмотреть файл

@ -0,0 +1,144 @@
test( "Popcorn text Plugin", function() {
var popped = Popcorn( "#video" ),
expects = 10,
count = 0,
setupId,
textdiv = document.getElementById( "textdiv" ),
childElem;
var strings = {
PLAIN: "This is plain text",
HTML: "<p>This is <em>HTML</em> text</p>",
ESCAPED: "&lt;p&gt;This is &lt;em&gt;HTML&lt;/em&gt; text&lt;/p&gt;",
MULTILINE_NO_BREAKS: "a\nb\r\nc",
MULTILINE_BREAKS: "a<br>b<br>c"
};
expect( expects );
function plus() {
if ( ++count===expects ) {
start();
}
}
function injectString( s ) {
var elem = document.createElement( "div" );
elem.innerHTML = s;
return elem.innerHTML;
}
stop();
ok( "text" in popped, "text is a mehtod of the popped instance" );
plus();
equal( textdiv.childElementCount, 0, "initially, there is nothing inside textdiv" );
plus();
// Simple text
popped.text( {
start: 1,
end: 3,
text: strings.PLAIN,
target: 'textdiv'
} )
.cue( 2, function() {
equal( textdiv.childElementCount, 1, "textdiv now has two inner elements" );
plus();
childElem = textdiv.children[ 0 ];
equal( childElem.innerHTML, strings.PLAIN, "textdiv correctly displaying plain text" );
plus();
equal( childElem.style.display, "inline", "textdiv is visible on the page" );
plus();
} )
.cue( 4, function() {
equal( childElem && childElem.style.display, "none", "textdiv is hidden again" );
plus();
popped.pause();
} )
// Setup the rest of events (first tests only want 1 text event)
.on( "pause", function secondarySetup() {
popped.off( "pause", secondarySetup )
// HTML text, rendered as HTML
.text( {
start: 5,
end: 7,
text: strings.HTML,
target: 'textdiv'
} )
.cue( 6, function() {
equal(
textdiv.children[ 1 ].innerHTML,
injectString( strings.HTML ),
"textdiv correctly displaying HTML text"
);
plus();
} )
// HTML text, escaped and rendered as plain text
.text( {
start: 8,
end: 10,
text: strings.HTML,
escape: true,
target: 'textdiv'
} )
.cue( 9, function() {
equal(
textdiv.children[ 2 ].innerHTML,
injectString( strings.ESCAPED ),
"textdiv correctly displaying escaped HTML text"
);
plus();
} )
// Multi-Line HTML text, escaped and rendered as plain text without breaks
.text( {
start: 11,
end: 13,
text: strings.MULTILINE_NO_BREAKS,
target: 'textdiv'
} )
.cue( 12, function() {
equal(
textdiv.children[ 3 ].innerHTML,
injectString( strings.MULTILINE_NO_BREAKS ),
"textdiv correctly displaying multiline with no breaks"
);
plus();
} )
// Multi-Line HTML text, escaped and rendered as plain text with breaks
.text( {
start: 14,
end: 16,
text: strings.MULTILINE_NO_BREAKS,
multiline: true,
target: 'textdiv'
} )
.cue( 15, function() {
equal(
textdiv.children[ 4 ].innerHTML,
injectString( strings.MULTILINE_BREAKS ),
"textdiv correctly displaying multiline with breaks"
);
plus();
// Test is done
popped.pause();
} );
// Continue tests
popped.play();
} );
// Start tests
popped.play().volume( 0 );
});