# HG changeset patch # User hamidouk # Date 1324633567 -3600 # Node ID 97599ff4307210c2635e216ab9150654dc5156b0 # Parent b1e442d9a1bc2cd7fda271e5880b9739f99895ff# Parent fe8c9f4791cb28ae2b1b91b23596bb87fd520b94 Merge with calage-segmentsWidget diff -r b1e442d9a1bc -r 97599ff43072 sbin/build/client.xml --- a/sbin/build/client.xml Wed Dec 21 16:06:41 2011 +0100 +++ b/sbin/build/client.xml Fri Dec 23 10:46:07 2011 +0100 @@ -50,7 +50,7 @@ + files="lab.js mustache.js underscore.js"/> diff -r b1e442d9a1bc -r 97599ff43072 src/css/LdtPlayer.css --- a/src/css/LdtPlayer.css Wed Dec 21 16:06:41 2011 +0100 +++ b/src/css/LdtPlayer.css Fri Dec 23 10:46:07 2011 +0100 @@ -23,8 +23,8 @@ padding-bottom: 8px; /* FIXME: only a temporary fix. This should be put into the layout manager. */ } - .Ldt-iri-chapter{ - float: left; + .Ldt-iri-chapter { + position: absolute; height: 10px; border-right: 1px solid white; } diff -r b1e442d9a1bc -r 97599ff43072 src/js/libs/underscore.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/js/libs/underscore.js Fri Dec 23 10:46:07 2011 +0100 @@ -0,0 +1,30 @@ +// Underscore.js 1.2.3 +// (c) 2009-2011 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore +(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== +c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c, +h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.concat,H=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,I=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&& +define.amd?define("underscore",function(){return b}):s._=b;b.VERSION="1.2.3";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g, +c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,c,b){var e;D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c, +b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});return e};var D=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a, +d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex= +function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after= +function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=I||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments, +1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a=== +Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)== +"[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){J(c, +b[c]=a[c])})};var K=0;b.uniqueId=function(a){var b=K++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g, +"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},J=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);H.call(a,this._wrapped);return u(c.apply(b, +a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this); diff -r b1e442d9a1bc -r 97599ff43072 src/js/main.js --- a/src/js/main.js Wed Dec 21 16:06:41 2011 +0100 +++ b/src/js/main.js Fri Dec 23 10:46:07 2011 +0100 @@ -43,6 +43,8 @@ $L.wait(function() { IriSP.jQuery = window.jQuery.noConflict( true ); + IriSP._ = window._.noConflict(); + IriSP.underscore = IriSP._; var css_link_jquery = IriSP.jQuery( "", { rel: "stylesheet", diff -r b1e442d9a1bc -r 97599ff43072 src/js/serializers/JSONSerializer.js --- a/src/js/serializers/JSONSerializer.js Wed Dec 21 16:06:41 2011 +0100 +++ b/src/js/serializers/JSONSerializer.js Fri Dec 23 10:46:07 2011 +0100 @@ -242,3 +242,34 @@ return ret_array; }; + + +/* this function returns a list of ids of tweet lines */ +IriSP.JSONSerializer.prototype.getTweetIds = function() { + if (typeof(this._data.lists) === "undefined" || this._data.lists === null) + return []; + + var tweetsId = []; + + /* first get the list containing the tweets */ + var tweets = IriSP.underscore.filter(this._data.lists, function(entry) { return entry.id.indexOf("tweet") !== -1 }); + + // FIXME: collect tweets from multiple sources ? + tweetsId = IriSP.underscore.pluck(tweets[0].items, "id-ref"); + + return tweetsId; +}; + +/* this function returns a list of lines which are not tweet lines */ +IriSP.JSONSerializer.prototype.getNonTweetIds = function() { + if (typeof(this._data.lists) === "undefined" || this._data.lists === null) + return []; + + /* get all the ids */ + var ids = IriSP.underscore.map(this._data.lists, function(entry) { + return IriSP.underscore.pluck(entry.items, "id-ref"); }); + + var illegal_values = this.getTweetIds(); + return IriSP.underscore.difference(ids, illegal_values); + +}; diff -r b1e442d9a1bc -r 97599ff43072 src/js/widgets/segmentsWidget.js --- a/src/js/widgets/segmentsWidget.js Wed Dec 21 16:06:41 2011 +0100 +++ b/src/js/widgets/segmentsWidget.js Fri Dec 23 10:46:07 2011 +0100 @@ -12,29 +12,41 @@ IriSP.SegmentsWidget.prototype = new IriSP.Widget(); +/* Get the width of a segment, in pixels. */ +IriSP.SegmentsWidget.prototype.segmentToPixel = function(annotation) { + var begin = Math.round((+ annotation.begin) / 1000); + var end = Math.round((+ annotation.end) / 1000); + var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000; + + var startPourcent = IriSP.timeToPourcent(begin, duration); + var startPixel = Math.floor(this.selector.parent().width() * (startPourcent / 100)); + + var endPourcent = Math.floor(IriSP.timeToPourcent(end, duration) - startPourcent); + var endPixel = Math.floor(this.selector.parent().width() * (endPourcent / 100)); + + return endPixel; +}; + +/* compute the total length of a group of segments */ +IriSP.SegmentsWidget.prototype.segmentsLength = function(segmentsList) { + var self = this; + var total = 0; + + for (var i = 0; i < segmentsList.length; i++) + total += self.segmentToPixel(segmentsList[i].annotation); + + return total; +}; + IriSP.SegmentsWidget.prototype.draw = function() { var self = this; var annotations = this._serializer._data.annotations; this.selector.addClass("Ldt-SegmentsWidget"); - - /* in case we have different types of annotations, we want to display only the first type */ - /* the next two lines are a bit verbose because for some test data, _serializer.data.view is either - null or undefined. - */ - var view; - - if (typeof(this._serializer._data.views) !== "undefined" && this._serializer._data.views !== null) - view = this._serializer._data.views[0]; - - var view_type = ""; - - if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) { - view_type = view.annotation_types[0]; - } - this.selector.append(Mustache.to_html(IriSP.overlay_marker_template)); + + var view_type = this._serializer.getNonTweetIds()[0]; this.positionMarker = this.selector.children(":first"); @@ -42,9 +54,9 @@ var i = 0; - var totalWidth = this.selector.width(); - var onePxPercent = 100 / totalWidth; /* the value of a pixel, in percents */ - + + var segments_annotations = []; + for (i = 0; i < annotations.length; i++) { var annotation = annotations[i]; @@ -54,23 +66,30 @@ continue; } - var begin = Math.round((+ annotation.begin) / 1000); - var end = Math.round((+ annotation.end) / 1000); - var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000; - var id = annotation.id; - var startPourcent = IriSP.timeToPourcent(begin, duration); + segments_annotations.push(annotation); + } - /* surprisingly, the following code doesn't work on webkit - for some reason, most of the - boxes are 3 pixels smaller. - */ - var endPourcent = Math.floor(IriSP.timeToPourcent(end, duration) - startPourcent); - var endPixel = Math.floor(this.selector.parent().width() * (endPourcent / 100)) - 2; + var totalWidth = this.selector.width() - segments_annotations.length; + var lastSegment = IriSP.underscore.max(segments_annotations, function(annotation) { return annotation.end; }); + + for (i = 0; i < segments_annotations.length; i++) { + + var annotation = segments_annotations[i]; + var begin = (+ annotation.begin); + var end = (+ annotation.end); + var duration = this._serializer.currentMedia().meta["dc:duration"]; + var id = annotation.id; - if (i == 0) { + var startPixel = Math.floor(this.selector.parent().width() * (begin / duration)); - endPourcent -= onePxPercent; - } + var endPixel = Math.floor(this.selector.parent().width() * (end / duration)); + if (annotation.id !== lastSegment.id) + var pxWidth = endPixel - startPixel -1; + else + /* the last segment has no segment following it */ + var pxWidth = endPixel - startPixel; + var divTitle = (annotation.content.title + " - " + annotation.content.description).substr(0,55); if (typeof(annotation.content.color) !== "undefined") @@ -86,13 +105,18 @@ hexa_color = hexa_color + '00'; var annotationTemplate = Mustache.to_html(IriSP.annotation_template, - {"divTitle" : divTitle, "id" : id, "startPourcent" : startPourcent, - "endPixel" : endPixel, "hexa_color" : hexa_color, + {"divTitle" : divTitle, "id" : id, "startPixel" : startPixel, + "pxWidth" : pxWidth, "hexa_color" : hexa_color, "seekPlace" : Math.round(begin/1000)}); + this.selector.append(annotationTemplate); - -// IriSP.jQuery("#" + id).tooltip({ effect: 'slide'}); + + /* add a special class to the last segment and change its border */ + if (annotation.id === lastSegment.id) { + this.selector.find("#" + id).addClass("Ldt-lastSegment"); + this.selector.find(".Ldt-lastSegment").css("border-color", "#" + hexa_color); + } IriSP.jQuery("#" + id).fadeTo(0, 0.3); @@ -126,7 +150,7 @@ /* restores the view after a search */ IriSP.SegmentsWidget.prototype.clear = function() { - this.selector.children(".Ldt-iri-chapter").css('border','none').animate({opacity:0.3}, 100); + this.selector.children(".Ldt-iri-chapter").animate({opacity:0.3}, 100); }; IriSP.SegmentsWidget.prototype.clickHandler = function(annotation) { @@ -155,7 +179,6 @@ for (var id in matches) { var factor = 0.5 + matches[id] * 0.2; this.selector.find("#"+id).dequeue(); - this.selector.find("#"+id).css('border','1px red'); this.selector.find("#"+id).animate({opacity:factor}, 200); } diff -r b1e442d9a1bc -r 97599ff43072 src/templates/annotation.html --- a/src/templates/annotation.html Wed Dec 21 16:06:41 2011 +0100 +++ b/src/templates/annotation.html Fri Dec 23 10:46:07 2011 +0100 @@ -1,8 +1,8 @@ {{! template for an annotation displayed in a segmentWidget }}
diff -r b1e442d9a1bc -r 97599ff43072 test/integration/polemic-jsonp.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/integration/polemic-jsonp.htm Fri Dec 23 10:46:07 2011 +0100 @@ -0,0 +1,111 @@ + + + + +Metadataplayer - Polemic tweet integration test + + + + +
+

MetaDataPlayer

+ Polemic tweet integration test - loading an outside ressource using JSONP. +
+ + + + + + +
+
+ + + + + +
+