--- 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
--- 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") {
--- 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;
--- 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"]);
}
--- 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 :-(
*/
--- 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, '<span class="Ldt-AnnotationsList-highlight">$1</span>'))
- })
- } */
-};
-
-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, '<span class="Ldt-AnnotationsList-highlight">$1</span>'))
})
- });
-
- 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, '<span class="Ldt-AnnotationsList-highlight">$1</span>'))
- })
+ }
}
+ if (this.ajax_url && this.ajax_granularity) {
+ if (Math.abs(_currentTime - this.lastAjaxQuery) > this.ajax_granularity / 2) {
+ this.ajaxSource();
+ }
+ }
return _list.length;
}
--- /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('<div>');
+ 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('<div>')
+ .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('<div>')
+ .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('<div>')
+ .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"
+ })
+}
--- 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"
}
]
--- 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() {