# HG changeset patch # User veltr # Date 1334856041 -7200 # Node ID d777d05a16e41621f6ca5382ebc67e4e009a82db # Parent 2c025db10a104a0d1d2a22c27db4e1f3a29fd3aa finished AnnotationsList and started New PolemicWidget diff -r 2c025db10a10 -r d777d05a16e4 src/js/defaults.js --- a/src/js/defaults.js Wed Apr 18 18:58:44 2012 +0200 +++ b/src/js/defaults.js Thu Apr 19 19:20:41 2012 +0200 @@ -104,20 +104,25 @@ implementers. Note that the player has to replace the variables between {{ and }} by its own values. */ - ajax_url : false, //platform_url + "/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}", + ajax_url : false, + /* URL when the annotations are to be reloaded from an LDT-like segment API + * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=? + */ ajax_granularity : 300000, /* how much ms should we look before and after the current timecode */ default_thumbnail : "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png", - project_url : "", //platform_url + "/ldtplatform/ldt/front/player/" - /* the beginning of a link to the new front */ + foreign_url : "", + /* URL when the annotation is not in the current project, + * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}} + */ cinecast_version : false, annotation_type : false, - refresh_interval : 300000, + refresh_interval : 0, limit_count : 10, newest_first : false }, "StackGraphWidget" : { - defaultcolor : "#585858", - tags : [ + defaultcolor : "#585858", + tags : [ { "keywords" : [ "++" ], "description" : "positif", @@ -140,5 +145,34 @@ } ], streamgraph : false + }, + "PolemicNewWidget" : { + element_width : 5, + element_height : 5, + annotation_type : "tweet", + defaultcolor : "#585858", + foundcolor : "#fc00ff", + tags : [ + { + "keywords" : [ "++" ], + "description" : "positif", + "color" : "#1D973D" + }, + { + "keywords" : [ "--" ], + "description" : "negatif", + "color" : "#CE0A15" + }, + { + "keywords" : [ "==" ], + "description" : "reference", + "color" : "#C5A62D" + }, + { + "keywords" : [ "??" ], + "description" : "question", + "color" : "#036AAE" + } + ] } } \ No newline at end of file diff -r 2c025db10a10 -r d777d05a16e4 src/js/model.js --- a/src/js/model.js Wed Apr 18 18:58:44 2012 +0200 +++ b/src/js/model.js Thu Apr 19 19:20:41 2012 +0200 @@ -8,6 +8,20 @@ getUID : function() { return "autoid-" + (++this._ID_AUTO_INCREMENT); }, + regexpFromTextOrArray : function(_textOrArray) { + function escapeText(_text) { + return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1'); + } + return new RegExp( '(' + + ( + typeof _textOrArray === "string" + ? escapeText(_textOrArray) + : IriSP._(_textOrArray).map(escapeText).join("|") + ) + + ')', + 'gim' + ); + }, isoToDate : function(_str) { // http://delete.me.uk/2005/03/iso8601.html var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"; @@ -52,7 +66,7 @@ this.directory = _directory; this.idIndex = []; if (typeof _directory == "undefined") { - throw("Error : new IriSP.Model.List(directory): directory is undefined"); + throw "Error : new IriSP.Model.List(directory): directory is undefined"; } } @@ -107,6 +121,13 @@ return _res; } +IriSP.Model.List.prototype.splice = function(_start, _end) { + var _res = new IriSP.Model.List(this.directory); + _res.addElements(Array.prototype.splice.call(this, _start, _end)); + this.idIndex.splice(_start, _end); + return _res; +} + /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy * and won't return a new IriSP.Model.List */ @@ -123,21 +144,21 @@ * here we can search by these criteria */ IriSP.Model.List.prototype.searchByTitle = function(_text) { - var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim'); + var _rgxp = IriSP.Model.regexpFromTextOrArray(_text); return this.filter(function(_element) { return _rgxp.test(_element.title); }); } IriSP.Model.List.prototype.searchByDescription = function(_text) { - var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim'); + var _rgxp = IriSP.Model.regexpFromTextOrArray(_text); return this.filter(function(_element) { return _rgxp.test(_element.description); }); } IriSP.Model.List.prototype.searchByTextFields = function(_text) { - var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim'); + var _rgxp = IriSP.Model.regexpFromTextOrArray(_text); return this.filter(function(_element) { return _rgxp.test(_element.description) || _rgxp.test(_element.title); }); @@ -158,8 +179,8 @@ } IriSP.Model.List.prototype.push = function(_el) { - if (typeof this.directory.getElement(_el.id) === "undefined") { - this.directory.addElement(_el); + if (typeof _el === "undefined") { + return; } var _index = (IriSP._(this.idIndex).indexOf(_el.id)); if (_index === -1) { @@ -185,6 +206,31 @@ }); } +IriSP.Model.List.prototype.removeId = function(_id) { + var _index = (IriSP._(this.idIndex).indexOf(_id)); + if (_index !== -1) { + this.splice(_index,1); + } +} + +IriSP.Model.List.prototype.removeElement = function(_el) { + this.removeId(_el.id); +} + +IriSP.Model.List.prototype.removeIds = function(_list) { + var _this = this; + IriSP._(_list).forEach(function(_id) { + _this.removeId(_id); + }); +} + +IriSP.Model.List.prototype.removeElements = function(_list) { + var _this = this; + IriSP._(_list).forEach(function(_el) { + _this.removeElement(_el); + }); +} + /* A simple time management object, that helps converting millisecs to seconds and strings, * without the clumsiness of the original Date object. */ @@ -210,6 +256,10 @@ } } +IriSP.Model.Time.prototype.valueOf = function() { + return this.milliseconds; +} + IriSP.Model.Time.prototype.toString = function() { function pad(_n) { var _res = _n.toString(); @@ -234,13 +284,38 @@ this.source = _source; if (typeof _idRef === "object") { this.isList = true; - this.contents = new IriSP.Model.List(this.source.directory); - this.contents.addIds(IriSP._(_idRef).map(function(_id) { + this.id = IriSP._(_idRef).map(function(_id) { return _source.getNamespaced(_id).fullname; - })); + }); } else { this.isList = false; - this.contents = this.source.directory.getElement(_source.getNamespaced(_idRef).fullname); + this.id = _source.getNamespaced(_idRef).fullname; + } + this.refresh(); +} + +IriSP.Model.Reference.prototype.refresh = function() { + if (this.isList) { + this.contents = new IriSP.Model.List(this.source.directory); + this.contents.addIds(this.id); + } else { + this.contents = this.source.directory.getElement(this.id); + } + +} + +IriSP.Model.Reference.prototype.getContents = function() { + if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) { + this.refresh(); + } + return this.contents; +} + +IriSP.Model.Reference.prototype.isOrHasId = function(_idRef) { + if (this.isList) { + return (IriSP._(this.id).indexOf(_idRef) !== -1) + } else { + return (this.id == _idRef); } } @@ -248,17 +323,18 @@ IriSP.Model.Element = function(_id, _source) { this.elementType = 'element'; - if (typeof _source !== "undefined") { - if (typeof _id === "undefined" || !_id) { - _id = IriSP.Model.getUID(); - } - this.source = _source; - this.namespacedId = _source.getNamespaced(_id) - this.id = this.namespacedId.fullname; - this.title = ""; - this.description = ""; - this.source.directory.addElement(this); + if (typeof _source === "undefined") { + return; + } + if (typeof _id === "undefined" || !_id) { + _id = IriSP.Model.getUID(); } + this.source = _source; + this.namespacedId = _source.getNamespaced(_id) + this.id = this.namespacedId.fullname; + this.title = ""; + this.description = ""; + this.source.directory.addElement(this); } IriSP.Model.Element.prototype.toString = function() { @@ -271,20 +347,16 @@ IriSP.Model.Element.prototype.getReference = function(_elementType) { if (typeof this[_elementType] !== "undefined") { - return this[_elementType].contents; + return this[_elementType].getContents(); } } -IriSP.Model.Element.prototype.getRelated = function(_elementType) { +IriSP.Model.Element.prototype.getRelated = function(_elementType, _global) { + _global = (typeof _global !== "undefined" && _global); var _this = this; - return this.source.getList(_elementType).filter(function(_el) { + return this.source.getList(_elementType, _global).filter(function(_el) { var _ref = _el[_this.elementType]; - if (_ref.isList) { - return _ref.contents.hasId(_this.id); - } - else { - return _ref.contents.id === _this.id; - } + return _ref.isOrHasId(_this.id); }); } @@ -393,12 +465,26 @@ this.callbackQueue = []; this.contents = {}; if (typeof this.namespace === "undefined") { - this.namespace = IriSP.Model.getUID(); + this.namespace = "metadataplayer"; + } else { + if (typeof this.namespaceUrl === "undefined" && typeof this.url !== "undefined") { + var _matches = this.url.match(/(^[^?&]+|[^?&][a-zA-Z0-9_%=?]+)/g), + _url = _matches[0]; + if (_matches.length > 1) { + _matches = IriSP._(_matches.slice(1)).reject(function(_txt) { + return /\?$/.test(_txt); + }); + } + if (_matches.length > 0) { + _url += '?' + _matches.join('&'); + } + this.namespaceUrl = _url; + } } if (typeof this.namespaceUrl === "undefined") { - this.namespaceUrl = (typeof this.url !== "undefined" ? this.url : this.namespaceUrl); + this.namespaceUrl = "http://ldt.iri.centrepompidou.fr/"; } - this.directory.namespaces[this.namespace] = this.namespaceUrl; + this.directory.addNamespace(this.namespace, this.namespaceUrl); this.get(); } } @@ -421,7 +507,9 @@ } IriSP.Model.Source.prototype.unNamespace = function(_id) { - return _id.replace(this.namespace + ':', ''); + if (typeof _id !== "undefined") { + return _id.replace(this.namespace + ':', ''); + } } IriSP.Model.Source.prototype.addList = function(_listId, _contents) { @@ -431,10 +519,11 @@ this.contents[_listId].addElements(_contents); } -IriSP.Model.Source.prototype.getList = function(_listId) { - if (typeof this.contents[_listId] === "undefined") { +IriSP.Model.Source.prototype.getList = function(_listId, _global) { + _global = (typeof _global !== "undefined" && _global); + if (_global || typeof this.contents[_listId] === "undefined") { return this.directory.getGlobalList().filter(function(_e) { - return (_e.elType === _listId); + return (_e.elementType === _listId); }); } else { return this.contents[_listId]; @@ -515,30 +604,29 @@ this.serializer.deSerialize(_data, this); } -IriSP.Model.Source.prototype.getAnnotations = function() { - return this.getList("annotation"); +IriSP.Model.Source.prototype.getAnnotations = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("annotation", _global); } -IriSP.Model.Source.prototype.getMedias = function() { - return this.getList("media"); -} - -IriSP.Model.Source.prototype.getAnnotationTypes = function() { - return this.getList("annotationType"); +IriSP.Model.Source.prototype.getMedias = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("media", _global); } -IriSP.Model.Source.prototype.getAnnotationTypeByTitle = function(_title) { - var _res = this.getAnnotationTypes().searchByTitle(_title); - if (_res.length) { - return _res[0]; - } +IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("annotationType", _global); } -IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title) { - var _annType = this.getAnnotationTypeByTitle(_title); - if (typeof _annType !== "undefined") { - return _annType.getAnnotations(); - } +IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) { + _global = (typeof _global !== "undefined" && _global); + var _res = new IriSP.Model.List(this.directory), + _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title); + _annTypes.forEach(function(_annType) { + _res.addElements(_annType.getAnnotations(_global)); + }) + return _res; } IriSP.Model.Source.prototype.getDuration = function() { @@ -559,7 +647,7 @@ IriSP.Model.RemoteSource.prototype.get = function() { this.status = IriSP.Model._SOURCE_STATUS_WAITING; var _this = this; - IriSP.jQuery.getJSON(this.url, function(_result) { + this.serializer.loadData(this.url, function(_result) { _this.deSerialize(_result); _this.handleCallbacks(); }); @@ -573,6 +661,10 @@ this.namespaces = {}; } +IriSP.Model.Directory.prototype.addNamespace = function(_namespace, _url) { + this.namespaces[_namespace] = _url; +} + IriSP.Model.Directory.prototype.remoteSource = function(_properties) { var _config = IriSP._({ directory: this }).extend(_properties); if (typeof this.remoteSources[_properties.url] === "undefined") { diff -r 2c025db10a10 -r d777d05a16e4 src/js/serializers/CinecastSerializer.js --- a/src/js/serializers/CinecastSerializer.js Wed Apr 18 18:58:44 2012 +0200 +++ b/src/js/serializers/CinecastSerializer.js Thu Apr 19 19:20:41 2012 +0200 @@ -116,15 +116,15 @@ }, begin : _data.begin.milliseconds, end : _data.begin.milliseconds, - media : _source.unNamespace(_data.media.contents), - type : _source.unNamespace(_data.annotationType.contents), + media : _source.unNamespace(_data.media.id), + type : _source.unNamespace(_data.annotationType.id), meta : { created : IriSP.Model.dateToIso(_data.created), creator : _data.creator, creator_name : _data.title }, - tags : _data.getTags().map(function(_el) { - return _source.unNamespace(_el.id) + tags : _data.tag.id.map(function(_id) { + return _source.unNamespace(_id) }) } } @@ -154,7 +154,13 @@ }); return _res; }, + loadData : function(_url, _callback) { + IriSP.jQuery.getJSON(_url, _callback) + }, deSerialize : function(_data, _source) { + if (typeof _data !== "object" && _data === null) { + return; + } if (typeof _data.imports !== "undefined") { IriSP._(_data.imports).forEach(function(_import) { _source.directory.namespaces[_import.id] = _import.url; diff -r 2c025db10a10 -r d777d05a16e4 src/js/serializers/PlatformSerializer.js --- a/src/js/serializers/PlatformSerializer.js Wed Apr 18 18:58:44 2012 +0200 +++ b/src/js/serializers/PlatformSerializer.js Thu Apr 19 19:20:41 2012 +0200 @@ -77,8 +77,8 @@ serialized_name : "annotations", deserializer : function(_data, _source) { var _res = new IriSP.Model.Annotation(_data.id, _source); - _res.title = _data.content.title; - _res.description = _data.content.description; + _res.title = _data.content.title || ""; + _res.description = _data.content.description || ""; _res.created = IriSP.Model.isoToDate(_data.meta["dc:created"]); var _c = parseInt(_data.color).toString(16); while (_c.length < 6) { @@ -91,6 +91,7 @@ _res.setBegin(_data.begin); _res.setEnd(_data.end); _res.creator = _data.meta["dc:creator"]; + _res.project = _data.meta.project; return _res; }, serializer : function(_data, _source) { @@ -100,13 +101,14 @@ title : _data.title, description : _data.description }, - media : _source.unNamespace(_data.media.contents), + media : _source.unNamespace(_data.media.id), meta : { - "id-ref" : _source.unNamespace(_data.annotationType.contents), + "id-ref" : _source.unNamespace(_data.annotationType.id), "dc:created" : IriSP.Model.dateToIso(_data.created), - "dc:creator" : _data.creator + "dc:creator" : _data.creator, + project : _source.projectId }, - tags : _data.getTags().map(function(_el, _id) { + tags : IriSP._(_data.tag.id).map(function(_d) { return { "id-ref" : _source.unNamespace(_id) } @@ -127,7 +129,13 @@ }); return _res; }, + loadData : function(_url, _callback) { + IriSP.jQuery.getJSON(_url, _callback) + }, deSerialize : function(_data, _source) { + if (typeof _data !== "object" && _data === null) { + return; + } IriSP._(this.types).forEach(function(_type, _typename) { var _listdata = _data[_type.serialized_name]; if (typeof _listdata !== "undefined") { @@ -144,6 +152,10 @@ } }); + if (typeof _data.meta !== "undefined") { + _source.projectId = _data.meta.id; + } + if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") { _source.setCurrentMediaId(_data.meta.main_media["id-ref"]); } diff -r 2c025db10a10 -r d777d05a16e4 src/js/widgets.js --- a/src/js/widgets.js Wed Apr 18 18:58:44 2012 +0200 +++ b/src/js/widgets.js Thu Apr 19 19:20:41 2012 +0200 @@ -34,6 +34,10 @@ _this[_key] = _value; }); + if (typeof this.width === "undefined") { + this.width = player.config.gui.width; + } + /* Setting this.player at the end in case it's been overriden * by a configuration option of the same name :-( */ diff -r 2c025db10a10 -r d777d05a16e4 src/js/widgets/annotationsListWidget.js --- a/src/js/widgets/annotationsListWidget.js Wed Apr 18 18:58:44 2012 +0200 +++ b/src/js/widgets/annotationsListWidget.js Thu Apr 19 19:20:41 2012 +0200 @@ -30,198 +30,38 @@ } } } -/** effectively redraw the widget - called by drawList */ -IriSP.AnnotationsListWidget.prototype.do_redraw = function(list) { -/* var _html = IriSP.templToHTML(IriSP.annotationsListWidget_template, { - annotations : list - }), _this = this; - this.selector.html(_html); - - this.selector.find('.Ldt-AnnotationsList-Tag-Li').click(function() { - _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().trim()); - }) - if(this.searchRe !== null) { - this.selector.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() { - var _$ = IriSP.jQuery(this); - _$.html(_$.text().trim().replace(_this.searchRe, '$1')) - }) - } */ -}; - -IriSP.AnnotationsListWidget.prototype.transformAnnotation = function(a) { -/* var _this = this; - return { - "id" : a.id, - "title" : this.cinecast_version ? IriSP.get_aliased(a.meta, ['creator_name', 'creator']) : a.content.title, - "desc" : this.cinecast_version ? a.content.data : a.content.description, - "begin" : IriSP.msToTime(a.begin), - "end" : IriSP.msToTime(a.end), - "thumbnail" : ( typeof a.meta == "object" && typeof a.meta.thumbnail == "string") ? a.meta.thumbnail : this.default_thumbnail, - "url" : ( typeof a.meta == "object" && typeof a.meta.url == "string") ? a.meta.url : null, - "created_at" : ( typeof a.meta == "object" && typeof a.meta.created == "string") ? Date.parse(a.meta.created.replace(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}\:\d{2}\:\d{2}).*$/, "$2/$3/$1 $4 UTC+0000")) : null, - "tags" : typeof a.tags == "object" ? IriSP.underscore(a.tags).chain().map(function(_t) { - if( typeof _t == "string") { - return _t.replace(/^.*:/, '#'); - } else { - if( typeof _t['id-ref'] != "undefined") { - var _f = IriSP.underscore.find(_this._serializer._data.tags, function(_tag) { - return _tag.id == _t['id-ref']; - }); - if( typeof _f != "undefined") { - return IriSP.get_aliased(_f.meta, ['dc:title', 'title']); - } - } - } - return null; - }).filter(function(_t) { - return _t !== null && _t !== "" - }).value() : [] - } */ -} -/** draw the annotation list */ -IriSP.AnnotationsListWidget.prototype.drawList = function(force_redraw) { -/* var _this = this; - - // var view_type = this._serializer.getContributions(); - var annotations = this._serializer._data.annotations; - var currentTime = this.player.popcorn.currentTime(); - var list = []; - - for( i = 0; i < annotations.length; i++) { - var obj = this.transformAnnotation(annotations[i]); - obj.iterator = i; - obj.distance = Math.abs((annotations[i].end + annotations[i].begin) / 2000 - currentTime); - if(!this.cinecast_version || annotations[i].type == "cinecast:UserAnnotation") { - list.push(obj); - } - - } - - if(this.searchRe !== null) { - list = list.filter(function(_a) { - return (_this.searchRe.test(_a.desc) || _this.searchRe.test(_a.title)); - }); - if(list.length) { - this.player.popcorn.trigger("IriSP.search.matchFound"); - } else { - this.player.popcorn.trigger("IriSP.search.noMatchFound"); - } - } - list = IriSP.underscore(list).chain().sortBy(function(_o) { - return _o.distance; - }).first(10).sortBy(function(_o) { - return (_this.cinecast_version ? -_o.created_at : _o.iterator); - }).value(); - var idList = IriSP.underscore.pluck(list, "id").sort(); - - if(!IriSP.underscore.isEqual(this.__oldList, idList) || this.lastSearch !== this.searchRe || typeof (force_redraw) !== "undefined") { - this.do_redraw(list); - this.__oldList = idList; - this.lastSearch = this.searchRe; - } - /* save for next call */ - -}; - -IriSP.AnnotationsListWidget.prototype.ajaxRedraw = function(timecode) { - - /* the seeked signal sometimes passes an argument - depending on if we're using - our popcorn lookalike or the real thing - if it's the case, use it as it's - more precise than currentTime which sometimes contains the place we where at */ - if(IriSP.null_or_undefined(timecode) || typeof (timecode) != "number") { - var tcode = this.player.popcorn.currentTime(); - } else { - var tcode = timecode; - } - - /* the platform gives us a special url - of the type : http://path/{{media}}/{{begin}}/{{end}} - we double the braces using regexps and we feed it to mustache to build the correct url - we have to do that because the platform only knows at run time what view it's displaying. - */ - - var media_id = this.currentMedia()["id"]; - var duration = this.getDuration(); - - var begin_timecode = (Math.floor(tcode) - 300) * 1000; - if(begin_timecode < 0) - begin_timecode = 0; - - var end_timecode = (Math.floor(tcode) + 300) * 1000; - if(end_timecode > duration) - end_timecode = duration; - - var templ = Mustache.to_html(this.ajax_url, { - media : media_id, - begin : begin_timecode, - end : end_timecode - }); - - /* we create on the fly a serializer to get the ajax */ - var serializer = new IriSP.JSONSerializer(IriSP.__dataloader, templ); - serializer.sync(IriSP.wrap(this, function(json) { - this.processJson(json, serializer) - })); -}; -/** process the received json - it's a bit hackish */ -IriSP.AnnotationsListWidget.prototype.processJson = function(json, serializer) { - /* FIXME: DRY the whole thing */ -/* var annotations = serializer._data.annotations; - if(IriSP.null_or_undefined(annotations)) - return; - - /* - commented in case we wanted to discriminate against some annotation types. - var view_types = serializer.getIds("Contributions"); - */ - var l = []; - - var media = this.currentMedia()["id"]; - - for( i = 0; i < annotations.length; i++) { - var obj = this.transformAnnotation(annotations[i]) - if( typeof obj.url == "undefined" || !obj.url) { - /* only if the annotation isn't present in the document create an - external link */ - if(this.annotations_ids.indexOf(obj.id.toLowerCase()) == -1) { - // braindead url; jacques didn't want to create a new one in the platform, - // so we append the cutting id to the url. - obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; - - // obj.url = document.location.href.split("#")[0] + "/" + annotation.meta.project; - } - } - l.push(obj); - } - this._ajax_cache = l; - this.do_redraw(l); -}; +//obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; IriSP.AnnotationsListWidget.prototype.ajaxSource = function() { + var _currentTime = this.player.popcorn.currentTime(), + _duration = this.source.getDuration(); + if (typeof _currentTime == "undefined") { + _currentTime = 0; + } + this.lastAjaxQuery = _currentTime; + _currentTime = Math.floor(1000 * _currentTime); var _url = Mustache.to_html(this.ajax_url, { media : this.source.currentMedia.namespacedId.name, - begin : 0, - end : 0 + begin : Math.max(0, _currentTime - this.ajax_granularity), + end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity) }); - console.log(_url); + this.currentSource = this.player.loadMetadata(IriSP._.defaults({ + "url" : _url + }, this.metadata)); } IriSP.AnnotationsListWidget.prototype.refresh = function(_forceRedraw) { + _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw); if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) { return 0; } var _this = this, - _list = undefined, _currentTime = this.player.popcorn.currentTime(); if (typeof _currentTime == "undefined") { _currentTime = 0; } - if (this.annotation_type) { - _list = this.currentSource.getAnnotationsByTypeTitle(this.annotation_type); - } - if (typeof _list === "undefined") { - _list = this.currentSource.getAnnotations(); - } + var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type, true) : this.currentSource.getAnnotations(); if (this.searchString) { _list = _list.searchByTextFields(this.searchString); } @@ -236,49 +76,71 @@ }); } else { _list = _list.sortBy(function(_annotation) { - return _annotation.begin.milliseconds; + return _annotation.begin; }); } - var _ids = _list.idIndex; - if (!_forceRedraw && IriSP._.isEqual(_ids, this.lastIds)) { - return _list.length; - } - /* This part only gets executed if the list needs updating */ - this.lastIds = _ids; - - var _html = IriSP.templToHTML( - IriSP.annotationsListWidget_template, - { - annotations : _list.map(function(_annotation) { - var _res = { - id : _annotation.id, - title : _annotation.title.replace(_annotation.description,''), - description : _annotation.description, - begin : _annotation.begin.toString(), - end : _annotation.end.toString(), - thumbnail : typeof _annotation.thumbnail !== "undefined" ? _annotation.thumbnail : _this.default_thumbnail, - url : typeof _annotation.url !== "undefined" ? _annotation.thumbnail : '#' + _annotation.namespacedId.name, - tags : _annotation.getTagTexts() - } - return _res; + var _ids = _list.idIndex; + + if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds)) { + /* This part only gets executed if the list needs updating */ + this.lastIds = _ids; + + var _html = IriSP.templToHTML( + IriSP.annotationsListWidget_template, + { + annotations : _list.map(function(_annotation) { + var _url = ( + ( typeof _annotation.url !== "undefined" ) + ? _annotation.url + : ( + ( typeof _this.source.projectId !== "undefined" && typeof _annotation.project !== "undefined" && _this.source.projectId !== _annotation.project ) + ? Mustache.to_html( + this.foreign_url, + { + project : _annotation.project, + media : _annotation.media.id.replace(/^.*:/,''), + annotation : _annotation.namespacedId.name, + annotationType : _annotation.annotationType.id.replace(/^.*:/,'') + } + ) + : '#id=' + _annotation.namespacedId.name + ) + ); + var _res = { + id : _annotation.id, + title : _annotation.title.replace(_annotation.description,''), + description : _annotation.description, + begin : _annotation.begin.toString(), + end : _annotation.end.toString(), + thumbnail : typeof _annotation.thumbnail !== "undefined" ? _annotation.thumbnail : _this.default_thumbnail, + url : _url, + tags : _annotation.getTagTexts() + } + return _res; + }) + }); + + this.$.html(_html); + + this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() { + _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); + }) + + if(this.searchString) { + var _searchRe = new RegExp('(' + this.searchString.replace(/(\W)/gm,'\\$1') + ')','gim'); + this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() { + var _$ = IriSP.jQuery(this); + _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '$1')) }) - }); - - this.$.html(_html); - - this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() { - _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); - }) - - if(this.searchString) { - var _searchRe = new RegExp('(' + this.searchString.replace(/(\W)/gm,'\\$1') + ')','gim'); - this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() { - var _$ = IriSP.jQuery(this); - _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '$1')) - }) + } } + if (this.ajax_url && this.ajax_granularity) { + if (Math.abs(_currentTime - this.lastAjaxQuery) > this.ajax_granularity / 2) { + this.ajaxSource(); + } + } return _list.length; } diff -r 2c025db10a10 -r d777d05a16e4 src/js/widgets/polemicNewWidget.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/js/widgets/polemicNewWidget.js Thu Apr 19 19:20:41 2012 +0200 @@ -0,0 +1,174 @@ +IriSP.PolemicNewWidget = function(player, config) { + IriSP.Widget.call(this, player, config); + this.bindPopcorn("IriSP.search", "searchHandler"); + this.bindPopcorn("IriSP.search.closed", "searchHandler"); + this.bindPopcorn("IriSP.search.cleared", "searchHandler"); + this.bindPopcorn("timeupdate", "onTimeupdate"); + this.sliceCount = Math.floor( this.width / this.element_width ); + this.$zone = IriSP.jQuery('
'); + this.$.append(this.$zone); +}; + +IriSP.PolemicNewWidget.prototype = new IriSP.Widget(); + +IriSP.PolemicNewWidget.prototype.searchHandler = function(searchString) { + this.searchString = typeof searchString !== "undefined" ? searchString : ''; + var _found = 0, + _re = IriSP.Model.regexpFromTextOrArray(searchString) + _this = this; + this.$tweets.each(function() { + var _el = IriSP.jQuery(this); + if (_this.searchString) { + if (_re.test(_el.attr("title"))) { + _el.css({ + "background" : _this.foundcolor, + "opacity" : 1 + }); + _found++; + } else { + _el.css({ + "background" : _el.attr("polemic-color"), + "opacity" : .6 + }); + } + } else { + _el.css({ + "background" : _el.attr("polemic-color"), + "opacity" : 1 + }); + } + }); + if (this.searchString) { + if (_found) { + this.player.popcorn.trigger("IriSP.search.matchFound"); + } else { + this.player.popcorn.trigger("IriSP.search.noMatchFound"); + } + } +} + +IriSP.PolemicNewWidget.prototype.draw = function() { + var _slices = [], + _duration = this.source.getDuration(), + _max = 0, + _list = this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations(); + + for (var _i = 0; _i < this.sliceCount; _i++) { + var _begin = new IriSP.Model.Time(_i*_duration/this.sliceCount), + _end = new IriSP.Model.Time((_i+1)*_duration/this.sliceCount), + _count = 0, + _res = { + annotations : _list.filter(function(_annotation) { + return _annotation.begin >= _begin && _annotation.end < _end; + }), + polemicStacks : [] + } + + for (var _j = 0; _j < this.tags.length; _j++) { + var _polemic = _res.annotations.searchByDescription(this.tags[_j].keywords); + _count += _polemic.length; + _res.polemicStacks.push(_polemic); + } + for (var _j = 0; _j < this.tags.length; _j++) { + _res.annotations.removeElements(_res.polemicStacks[_j]); + } + _count += _res.annotations.length; + _max = Math.max(_max, _count); + _slices.push(_res); + } + this.height = (_max ? (_max + 2) * this.element_height : 0); + console.log(this.height); + this.$zone.css({ + width: this.width + "px", + height: this.height + "px", + position: "relative" + }); + + this.$elapsed = IriSP.jQuery('
') + .css({ + background: '#cccccc', + position: "absolute", + top: 0, + left: 0, + width: 0, + height: "100%" + }); + + this.$zone.append(this.$elapsed); + + var _x = 0, + _this = this; + + function displayElement(_x, _y, _color, _id, _title) { + var _el = IriSP.jQuery('
') + .attr({ + title : _title, + "pos-x" : _x, + "pos-y" : _y, + "polemic-color" : _color, + "annotation-id" : _id + }) + .css({ + position: "absolute", + width: (_this.element_width-1) + "px", + height: _this.element_height + "px", + left: _x + "px", + top: _y + "px", + background: _color + }) + .addClass("Ldt-Polemic-TweetDiv"); + _this.$zone.append(_el); + return _el; + } + + IriSP._(_slices).forEach(function(_slice) { + var _y = _this.height; + _slice.annotations.forEach(function(_annotation) { + _y -= _this.element_height; + displayElement(_x, _y, _this.defaultcolor, _annotation.namespacedId.name, _annotation.title); + }); + IriSP._(_slice.polemicStacks).forEach(function(_annotations, _j) { + var _color = _this.tags[_j].color; + _annotations.forEach(function(_annotation) { + _y -= _this.element_height; + displayElement(_x, _y, _color, _annotation.namespacedId.name, _annotation.title); + }); + }); + _x += _this.element_width; + }); + + this.$tweets = this.$.find(".Ldt-Polemic-TweetDiv"); + + this.$position = IriSP.jQuery('
') + .css({ + background: '#fc00ff', + position: "absolute", + top: 0, + left: "-1px", + width: "2px", + height: "100%" + }); + + this.$zone.append(this.$position); + + this.$tweets.click(function(_e) { + //TODO: Display Tweet in Tweet Widget + }); + + //TODO: Mouseover a tweet to display tooltip + + this.$zone.click(function(_e) { + var _x = _e.pageX - _this.$zone.offset().left; + _this.player.popcorn.currentTime(_this.source.getDuration().getSeconds() * _x / _this.width); + }); +} + +IriSP.PolemicNewWidget.prototype.onTimeupdate = function() { + var _x = Math.floor( this.width * this.player.popcorn.currentTime() / this.source.getDuration().getSeconds()); + this.$elapsed.css({ + width: _x + "px" + }); + this.$position.css({ + left: (_x - 1) + "px" + }) +} diff -r 2c025db10a10 -r d777d05a16e4 test/integration/polemic.htm --- a/test/integration/polemic.htm Wed Apr 18 18:58:44 2012 +0200 +++ b/test/integration/polemic.htm Thu Apr 19 19:20:41 2012 +0200 @@ -29,7 +29,7 @@ }; var _config = { gui: { - width:640, + width:640, height:800, container:'LdtPlayer', default_options: { @@ -78,11 +78,16 @@ type: "PlayerWidget" }, { + type: "PolemicNewWidget" + }, + { type: "HelloWorldWidget" }, { type: "AnnotationsListWidget", - /* ajax_url : "http://ldt.iri.centrepompidou.fr/ldt/api/ldt/segments/{{media}}/{{begin}}/{{end}}", */ + ajax_url : "http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=?", + foreign_url : "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}", + annotation_type : "tweet", container: "AnnotationsListContainer" } ] diff -r 2c025db10a10 -r d777d05a16e4 test/model/test.html --- a/test/model/test.html Wed Apr 18 18:58:44 2012 +0200 +++ b/test/model/test.html Thu Apr 19 19:20:41 2012 +0200 @@ -19,7 +19,7 @@ var _source = _directory.remoteSource({ //url: "../integration/polemic_fr.json", url : '../integration/allocine_dossier_independant/json_examples/movie32.json', - namespace: "metadataplayer", + namespace: "cinecast", serializer: IriSP.serializers.cinecast }); function showExport() {