From 3e1079c5b094bf20c385b407e1cc60b361d1c746 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Wed, 8 Oct 2014 21:37:49 -0400 Subject: [PATCH] More tests --- dist/videojs-transcript.js | 16 ++------ dist/videojs-transcript.min.js | 2 +- src/scroller.js | 8 ++-- test/modules.html | 12 +++++- test/modules.test.js | 74 ++++++++++++++++++++++------------ 5 files changed, 68 insertions(+), 44 deletions(-) diff --git a/dist/videojs-transcript.js b/dist/videojs-transcript.js index 05128aa..918d7bb 100644 --- a/dist/videojs-transcript.js +++ b/dist/videojs-transcript.js @@ -146,21 +146,11 @@ var eventEmitter = { h[2].apply(); } }); - }, - delegate: function (obj) { - obj.on = function (event, callback) { - eventEmitter.on(obj, event, callback); - }; - obj.trigger = function (obj) { - eventEmitter.trigget(obj, event); - }; - return obj; } }; var scrollerProto = function(plugin) { - var initHandlers = function (el) { var self = this; // The scroll event. We want to keep track of when the user is scrolling the transcript. @@ -201,7 +191,9 @@ var scrollerProto = function(plugin) { var init = function (element, plugin) { this.element = element; this.userIsScrolling = false; - this.mouseIsOverTranscript = false; + + //default to true in case user isn't using a mouse; + this.mouseIsOverTranscript = true; this.isAutoScrolling = true; initHandlers.call(this, this.element); return this; @@ -242,7 +234,7 @@ var scrollerProto = function(plugin) { var parent = element.parentElement; var parentOffsetBottom = parent.offsetTop + parent.clientHeight; var elementOffsetBottom = element.offsetTop + element.clientHeight; - var relPos = (element.offsetTop + element.clientHeight) - parent.offsetTop; + var relPos = element.offsetTop - parent.offsetTop; var newPos; // If the line is above the top of the parent view, were scrolling up, diff --git a/dist/videojs-transcript.min.js b/dist/videojs-transcript.min.js index ffa7af2..d5c88dc 100644 --- a/dist/videojs-transcript.min.js +++ b/dist/videojs-transcript.min.js @@ -1,3 +1,3 @@ /*! videojs-transcript - v0.0.0 - 2014-10-08 * Copyright (c) 2014 Matthew Walsh; Licensed MIT */ -!function(a,b){"use strict";!function(){for(var b=0,c=["ms","moz","webkit","o"],d=0;d1)throw Error("Second argument not supported");if("object"!=typeof b)throw TypeError("Argument must be an object");a.prototype=b;var c=new a;return a.prototype=null,c}}()),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c,d;if(null==this)throw new TypeError(" this is null or not defined");var e=Object(this),f=e.length>>>0;if("function"!=typeof a)throw new TypeError(a+" is not a function");for(arguments.length>1&&(c=b),d=0;f>d;){var g;d in e&&(g=e[d],a.call(c,g,d,e)),d++}});var c={};c.settings={},c.prefix="transcript",c.player=this;var d={autoscroll:!0,clickArea:"line"},e=function(a){return{secondsToTime:function(a){var b=Math.floor(a/3600),c=Math.floor(a%3600/60),d=Math.floor(a%60);return d=10>d?"0"+d:d,c=b>0&&10>c?"0"+c:c,b>0?b+":"+c+":"+d:c+":"+d},localize:function(a){return a},createEl:function(b,c){c=c||"";var d=document.createElement(b);return d.className=a.prefix+c,d},extend:function(a){var b=typeof a;if(!("function"===b||"object"===b&&a))return a;for(var c,d,e=1,f=arguments.length;f>e;e++){c=arguments[e];for(d in c)a[d]=c[d]}return a}}}(c),f={handlers_:[],on:function(a,b,c){if("function"!=typeof c)throw new TypeError("Callback is not a function.");this.handlers_.push([a,b,c])},trigger:function(a,b){this.handlers_.forEach(function(c){c[0]===a&&c[1]===b&&c[2].apply()})},delegate:function(a){return a.on=function(b,c){f.on(a,b,c)},a.trigger=function(a){f.trigget(a,event)},a}},g=function(){var a=function(a){var b=this;a.addEventListener("scroll",function(){b.isAutoScrolling?b.isAutoScrolling=!1:(b.userIsScrolling=!0,a.classList.add("is-inuse"))}),a.addEventListener("mouseenter",function(){b.mouseIsOverTranscript=!0}),a.addEventListener("mouseleave",function(){b.mouseIsOverTranscript=!1,setTimeout(function(){b.mouseIsOverTranscript||(b.userIsScrolling=!1,a.classList.remove("is-inuse"))},1e3)})},b=function(b){return this.element=b,this.userIsScrolling=!1,this.mouseIsOverTranscript=!1,this.isAutoScrolling=!0,a.call(this,this.element),this},c=function(a,b,c,d){return b+c*Math.sin(Math.min(1,a/d)*(Math.PI/2))},d=function(a,b,d){var e=Date.now(),f=a.scrollTop,g=this;b=Math.max(0,b),b=Math.min(a.scrollHeight-a.clientHeight,b);var h=b-f,i=function(){var j=Date.now(),k=j-e;g.isAutoScrolling=!0,a.scrollTop=c(k,f,h,d),a.scrollTop!==b&&requestAnimationFrame(i,a)};requestAnimationFrame(i,a)},e=function(a){if(this.canScroll()){var b,c=a.parentElement,e=c.offsetTop+c.clientHeight,f=a.offsetTop+a.clientHeight,g=a.offsetTop+a.clientHeight-c.offsetTop;gc.scrollTop+c.clientHeight&&(b=f-e),void 0!==b&&c.scrollTop!==b&&d.call(this,c,b,400)}},f=function(){var a=this.element;return a.scrollHeight>a.offsetHeight},g=function(){return this.userIsScrolling};return{init:b,to:e,canScroll:f,inUse:g}}(c),h=function(a){return Object.create(g).init(a)},i=function(){var a;return{get:function(){var a=[];return c.tracks=c.player.textTracks(),c.tracks.forEach(function(b){("captions"===b.kind()||"subtitles"===b.kind())&&a.push(b)}),a},active:function(b){return b.forEach(function(b){return 2===b.mode()?(a=b,b):void 0}),a||b[0]}}}(c),j=function(a){var b={};b.element={},b.body={};var c=function(a,b){f.on(this,a,b)},d=function(a){f.trigger(this,a)},g=function(){var a=e.createEl("header","-header");return a.textContent=e.localize("Transcript"),a},i=function(){var b=e.createEl("select","-selector");return a.validTracks.forEach(function(a,c){var d=document.createElement("option");d.value=c,d.textContent=a.label()+" ("+a.language()+")",b.appendChild(d)}),b.addEventListener("change",function(){n(document.querySelector("#"+a.prefix+"-"+a.player.id()+" option:checked").value),d("trackchanged")}),b},j=function(b){var c=b.target.classList,d=b.target.getAttribute("data-begin")||b.target.parentElement.getAttribute("data-begin");void 0!==d&&null!==d&&("line"===a.settings.clickArea||"timestamp"===a.settings.clickArea&&c.contains(myPrefix+"-timestamp")||"text"===a.settings.clickArea&&c.contains(myPrefix+"-text"))&&a.player.currentTime(d)},k=function(a){var b=e.createEl("div","-line"),c=e.createEl("span","-timestamp"),d=e.createEl("span","-text");return b.setAttribute("data-begin",a.startTime),c.textContent=e.secondsToTime(a.startTime),d.innerHTML=a.text,b.appendChild(c),b.appendChild(d),b},l=function(b){"object"!=typeof b&&(b=a.player.textTracks()[b]);var c,d,f=e.createEl("div","-body"),g=document.createDocumentFragment(),i=function(){var a=b.cues();for(d=0;df&&g>c?e.classList.contains("is-active")||(e.classList.add("is-active"),a.settings.autoscroll&&!b.body.scroll.inUse()&&b.body.scroll.to(e)):e.classList.remove("is-active")},p=function(){return b.element};return{create:m,setTrack:n,setCue:o,el:p,on:c,trigger:d}}(c),k=function(a){c.player=this,c.validTracks=i.get(),c.currentTrack=i.active(c.validTracks),c.settings=b.util.mergeOptions(d,a),c.widget=j.create();var e=function(){c.widget.setCue(c.player.currentTime())},f=function(){c.currentTrack=i.active(c.validTracks),c.widget.setTrack(c.currentTrack)};if(!(c.validTracks.length>0))throw new Error("videojs-transcript: No tracks found!");return f(),c.player.on("timeupdate",e),c.player.on("captionstrackchange",f),c.player.on("subtitlestrackchange",f),{el:function(){return c.widget.el()},setTrack:c.widget.setTrack}};b.plugin("transcript",k)}(window,videojs); \ No newline at end of file +!function(a,b){"use strict";!function(){for(var b=0,c=["ms","moz","webkit","o"],d=0;d1)throw Error("Second argument not supported");if("object"!=typeof b)throw TypeError("Argument must be an object");a.prototype=b;var c=new a;return a.prototype=null,c}}()),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c,d;if(null==this)throw new TypeError(" this is null or not defined");var e=Object(this),f=e.length>>>0;if("function"!=typeof a)throw new TypeError(a+" is not a function");for(arguments.length>1&&(c=b),d=0;f>d;){var g;d in e&&(g=e[d],a.call(c,g,d,e)),d++}});var c={};c.settings={},c.prefix="transcript",c.player=this;var d={autoscroll:!0,clickArea:"line"},e=function(a){return{secondsToTime:function(a){var b=Math.floor(a/3600),c=Math.floor(a%3600/60),d=Math.floor(a%60);return d=10>d?"0"+d:d,c=b>0&&10>c?"0"+c:c,b>0?b+":"+c+":"+d:c+":"+d},localize:function(a){return a},createEl:function(b,c){c=c||"";var d=document.createElement(b);return d.className=a.prefix+c,d},extend:function(a){var b=typeof a;if(!("function"===b||"object"===b&&a))return a;for(var c,d,e=1,f=arguments.length;f>e;e++){c=arguments[e];for(d in c)a[d]=c[d]}return a}}}(c),f={handlers_:[],on:function(a,b,c){if("function"!=typeof c)throw new TypeError("Callback is not a function.");this.handlers_.push([a,b,c])},trigger:function(a,b){this.handlers_.forEach(function(c){c[0]===a&&c[1]===b&&c[2].apply()})}},g=function(){var a=function(a){var b=this;a.addEventListener("scroll",function(){b.isAutoScrolling?b.isAutoScrolling=!1:(b.userIsScrolling=!0,a.classList.add("is-inuse"))}),a.addEventListener("mouseenter",function(){b.mouseIsOverTranscript=!0}),a.addEventListener("mouseleave",function(){b.mouseIsOverTranscript=!1,setTimeout(function(){b.mouseIsOverTranscript||(b.userIsScrolling=!1,a.classList.remove("is-inuse"))},1e3)})},b=function(b){return this.element=b,this.userIsScrolling=!1,this.mouseIsOverTranscript=!0,this.isAutoScrolling=!0,a.call(this,this.element),this},c=function(a,b,c,d){return b+c*Math.sin(Math.min(1,a/d)*(Math.PI/2))},d=function(a,b,d){var e=Date.now(),f=a.scrollTop,g=this;b=Math.max(0,b),b=Math.min(a.scrollHeight-a.clientHeight,b);var h=b-f,i=function(){var j=Date.now(),k=j-e;g.isAutoScrolling=!0,a.scrollTop=c(k,f,h,d),a.scrollTop!==b&&requestAnimationFrame(i,a)};requestAnimationFrame(i,a)},e=function(a){if(this.canScroll()){var b,c=a.parentElement,e=c.offsetTop+c.clientHeight,f=a.offsetTop+a.clientHeight,g=a.offsetTop-c.offsetTop;gc.scrollTop+c.clientHeight&&(b=f-e),void 0!==b&&c.scrollTop!==b&&d.call(this,c,b,400)}},f=function(){var a=this.element;return a.scrollHeight>a.offsetHeight},g=function(){return this.userIsScrolling};return{init:b,to:e,canScroll:f,inUse:g}}(c),h=function(a){return Object.create(g).init(a)},i=function(){var a;return{get:function(){var a=[];return c.tracks=c.player.textTracks(),c.tracks.forEach(function(b){("captions"===b.kind()||"subtitles"===b.kind())&&a.push(b)}),a},active:function(b){return b.forEach(function(b){return 2===b.mode()?(a=b,b):void 0}),a||b[0]}}}(c),j=function(a){var b={};b.element={},b.body={};var c=function(a,b){f.on(this,a,b)},d=function(a){f.trigger(this,a)},g=function(){var a=e.createEl("header","-header");return a.textContent=e.localize("Transcript"),a},i=function(){var b=e.createEl("select","-selector");return a.validTracks.forEach(function(a,c){var d=document.createElement("option");d.value=c,d.textContent=a.label()+" ("+a.language()+")",b.appendChild(d)}),b.addEventListener("change",function(){n(document.querySelector("#"+a.prefix+"-"+a.player.id()+" option:checked").value),d("trackchanged")}),b},j=function(b){var c=b.target.classList,d=b.target.getAttribute("data-begin")||b.target.parentElement.getAttribute("data-begin");void 0!==d&&null!==d&&("line"===a.settings.clickArea||"timestamp"===a.settings.clickArea&&c.contains(myPrefix+"-timestamp")||"text"===a.settings.clickArea&&c.contains(myPrefix+"-text"))&&a.player.currentTime(d)},k=function(a){var b=e.createEl("div","-line"),c=e.createEl("span","-timestamp"),d=e.createEl("span","-text");return b.setAttribute("data-begin",a.startTime),c.textContent=e.secondsToTime(a.startTime),d.innerHTML=a.text,b.appendChild(c),b.appendChild(d),b},l=function(b){"object"!=typeof b&&(b=a.player.textTracks()[b]);var c,d,f=e.createEl("div","-body"),g=document.createDocumentFragment(),i=function(){var a=b.cues();for(d=0;df&&g>c?e.classList.contains("is-active")||(e.classList.add("is-active"),a.settings.autoscroll&&!b.body.scroll.inUse()&&b.body.scroll.to(e)):e.classList.remove("is-active")},p=function(){return b.element};return{create:m,setTrack:n,setCue:o,el:p,on:c,trigger:d}}(c),k=function(a){c.player=this,c.validTracks=i.get(),c.currentTrack=i.active(c.validTracks),c.settings=b.util.mergeOptions(d,a),c.widget=j.create();var e=function(){c.widget.setCue(c.player.currentTime())},f=function(){c.currentTrack=i.active(c.validTracks),c.widget.setTrack(c.currentTrack)};if(!(c.validTracks.length>0))throw new Error("videojs-transcript: No tracks found!");return f(),c.player.on("timeupdate",e),c.player.on("captionstrackchange",f),c.player.on("subtitlestrackchange",f),{el:function(){return c.widget.el()},setTrack:c.widget.setTrack}};b.plugin("transcript",k)}(window,videojs); \ No newline at end of file diff --git a/src/scroller.js b/src/scroller.js index dead0db..14081a9 100644 --- a/src/scroller.js +++ b/src/scroller.js @@ -1,10 +1,8 @@ /* * Scroller object to handle scrolling. */ - var scrollerProto = function(plugin) { - var initHandlers = function (el) { var self = this; // The scroll event. We want to keep track of when the user is scrolling the transcript. @@ -45,7 +43,9 @@ var scrollerProto = function(plugin) { var init = function (element, plugin) { this.element = element; this.userIsScrolling = false; - this.mouseIsOverTranscript = false; + + //default to true in case user isn't using a mouse; + this.mouseIsOverTranscript = true; this.isAutoScrolling = true; initHandlers.call(this, this.element); return this; @@ -86,7 +86,7 @@ var scrollerProto = function(plugin) { var parent = element.parentElement; var parentOffsetBottom = parent.offsetTop + parent.clientHeight; var elementOffsetBottom = element.offsetTop + element.clientHeight; - var relPos = (element.offsetTop + element.clientHeight) - parent.offsetTop; + var relPos = element.offsetTop - parent.offsetTop; var newPos; // If the line is above the top of the parent view, were scrolling up, diff --git a/test/modules.html b/test/modules.html index f4a41dc..4338e57 100644 --- a/test/modules.html +++ b/test/modules.html @@ -7,7 +7,16 @@
-
+
+
+
1
+
2
+
3
+
4
+
+
+ +
+ diff --git a/test/modules.test.js b/test/modules.test.js index 7de3e32..ae84db7 100644 --- a/test/modules.test.js +++ b/test/modules.test.js @@ -1,6 +1,7 @@ /*! videojs-transcript - v0.0.0 - 2014-9-8 * Copyright (c) 2014 Matthew Walsh * Licensed under the MIT license. */ + /*global my, defaults, eventEmitter, trackList, scroller, widget*/ (function (window, videojs, qunit) { 'use strict'; @@ -25,33 +26,14 @@ // notEqual(actual, expected, [message]) notEqual = qunit.notEqual, // throws(block, [expected], [message]) - throws = qunit.throws; + throws = qunit.throws, + expect = qunit.expect, + asyncTest = qunit.asyncTest; /******************** * test events.js ********************/ - module('events', { - setup: function() { - // force HTML support so the tests run in a reasonable - // environment under phantomjs - realIsHtmlSupported = videojs.Html5.isSupported; - videojs.Html5.isSupported = function () { - return true; - }; - - // create a video element - var video = document.createElement('video'); - document.querySelector('#qunit-fixture').appendChild(video); - - // create a video.js player - player = videojs(video); - - my.player = player; - }, - teardown: function() { - videojs.Html5.isSupported = realIsHtmlSupported; - } - }); + module('events'); test('Register and trigger event', function(assert) { expect(1); @@ -102,19 +84,59 @@ } }); - test('getTracks() returns list of tracks.', function(assert) { + test('getTracks() returns list of tracks.', function (assert) { assert.equal(trackList.get().length, videojs.players['test-video'].textTracks().length, 'Tracklist length is correct'); }); - test('active() returns the default track.', function(assert) { + test('active() returns the default track.', function (assert) { var tracks = trackList.get(); assert.equal(trackList.active(tracks).label(), 'English', 'Active track is defined'); }); - test('active() returns active track after track change.', function(assert) { + test('active() returns active track after track change.', function (assert) { var tracks = trackList.get(); videojs.players['test-video'].textTracks()[1].show(); assert.equal(trackList.active(tracks).label(), 'Swedish', 'Active track returns current track after track change.'); }); + /******************** + * test scroller.js + ********************/ + module('scroller'); + + test('scroller() returns an object.', function (assert) { + var container = document.querySelector('#scrollable-container'); + assert.notEqual(scroller(container), undefined, 'scroller is not undefined.'); + }); + + test('canScroll() returns true when scrollable', function (assert) { + var container = document.querySelector('#scrollable-container'); + container.scroll = scroller(container); + assert.equal(container.scroll.canScroll(), true, 'canScroll returns true on scrollable container.'); + }); + + test('canScroll() returns false when non-scrollable ', function (assert) { + var container = document.querySelector('#non-scrollable-container'); + container.scroll = scroller(container); + assert.equal(container.scroll.canScroll(), false, 'canScroll returns false on non-scrollable container.'); + }); + + asyncTest('to() scrolls to correct location', function (assert) { + expect(2); + var container = document.querySelector('#scrollable-container'); + var item2 = document.querySelector('#item2'); + var item4 = document.querySelector('#item4'); + var initialScrollTop = container.scrollTop; + container.scroll = scroller(container); + container.scroll.to(item4); + setTimeout(function () { + assert.equal(container.scrollTop, initialScrollTop + 100, 'Container scrolls up by 100 pixels to reveal item4' ); + container.scroll.to(item2); + setTimeout(function () { + assert.equal(container.scrollTop, initialScrollTop + 50, 'Container scrolls down by 50 pixels to reveal item2' ); + qunit.start(); + },500); + }, 500); + }); + }(window, window.videojs, window.QUnit));