Lots of changes popcorn-port
authorveltr
Thu, 08 Mar 2012 18:38:46 +0100
branchpopcorn-port
changeset 830 18ca612e9ff0
parent 829 ae16691d183d
child 831 0dd21c298380
Lots of changes
src/js/header.js
src/js/site.js.templ
src/js/utils.js
src/js/widgets.js
src/js/widgets/createAnnotationWidget.js
src/js/widgets/playerWidget.js
src/js/widgets/polemicWidget.js
src/js/widgets/stackGraphWidget.js
src/js/widgets/tagCloudWidget.js
src/js/widgets/tooltipWidget.js
src/js/widgets/traceWidget.js
src/templates/annotation.html
src/templates/annotationWidget.html
src/templates/annotationsListWidget.html
src/templates/createAnnotationWidget.html
src/templates/player.html
src/templates/sliderWidget.html
src/templates/tweetWidget.html
test/integration/allocine_dossier_independant/polemic-allocine.htm
test/integration/polemic.htm
--- a/src/js/header.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/header.js	Thu Mar 08 18:38:46 2012 +0100
@@ -1,7 +1,7 @@
 /* 
  * 	
  *	Copyright 2010-2012 Institut de recherche et d'innovation 
- *	contributor(s) : Karim Hamidou, Samuel Huron 
+ *	contributor(s) : Karim Hamidou, Samuel Huron, Raphael Velt, Thibaut Cavalie
  *	 
  *	contact@iri.centrepompidou.fr
  *	http://www.iri.centrepompidou.fr 
--- a/src/js/site.js.templ	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/site.js.templ	Thu Mar 08 18:38:46 2012 +0100
@@ -82,13 +82,14 @@
            Ldt-createAnnotation-polemic-plusplus for plusplus
            Ldt-createAnnotation-polemic-equalequal for equalequal, etc.
         */
-        polemics: {"++" : "positive", "--" : "negative", "==" : "reference", "??" : "question"}, 
+        polemics: [ { "className" : "positive", "keyword" : "++" }, { "className" : "negative", "keyword" : "--" }, { "className" : "reference", "keyword" : "==" }, { "className" : "question", "keyword" : "??" } ],
         cinecast_version: true, /* put to false to enable the platform version, true for the festival cinecast one. */
         
         /* where does the widget PUT the annotations - this is a mustache template. id refers to the id of the media ans is filled
            by the widget. 
         */
-        api_endpoint_template: platform_url + "/ldtplatform/api/ldt/annotations/{{id}}.json"
+        api_endpoint_template: platform_url + "/ldtplatform/api/ldt/annotations/{{id}}.json",
+        api_method: "PUT"
     },
     "SparklineWidget" : {
         column_width: 10 // the width of a column in pixels.
--- a/src/js/utils.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/utils.js	Thu Mar 08 18:38:46 2012 +0100
@@ -192,3 +192,8 @@
    }
 }
 */
+
+/* Creates regexps from text */
+IriSP.regexpFromText = function(_text) {
+    return new RegExp('(' + _text.replace(/(\W)/gim,'\\$1') + ')','gim');
+}
--- a/src/js/widgets.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets.js	Thu Mar 08 18:38:46 2012 +0100
@@ -50,29 +50,32 @@
   } 
 
   if (config.hasOwnProperty("layoutManager")) {
-     this.layoutManager = config.layoutManager;     
+     this.layoutManager = config.layoutManager;
   }
-  if (typeof this.selector != "undefined" && typeof Popcorn != "undefined") {
-      var _id = this._id;
-      this.selector.bind("click mouseover mouseout dragstart dragstop", function(_e) {
-            var _data = {
-                "type": _e.type,
-                "x": _e.clientX,
-                "y": _e.clientY,
-                "widget": _id,
-                "target_name": _e.target.localName,
-                "target_id": _e.target.id,
-                "target_class": _e.target.className,
-                "text": _e.target.textContent.trim(),
-                "title": _e.target.title,
-                "value": _e.target.value
-            };
-            Popcorn.trigger('IriSP.Widget.MouseEvents', _data);
-      })
+  if (typeof this.selector != "undefined") {
+      this.selector.addClass("Ldt-TraceMe").addClass("Ldt-Widget");
   }
   
 };
 
+// This functions checks for configuration options
+
+IriSP.Widget.prototype.checkOption = function(_name, _default) {
+    this[_name] = (
+        typeof this._config[_name] != "undefined"
+        ? this._config[_name]
+        : (
+            (typeof IriSP.widgetsDefaults[this._config.type] != "undefined" && IriSP.widgetsDefaults[this._config.type][_name] != "undefined")
+            ? IriSP.widgetsDefaults[this._config.type][_name]
+            : (
+                typeof _default != "undefined"
+                ? _default
+                : null
+            )
+        )
+    )
+}
+
 /**
   * This method responsible of drawing a widget on screen.
   */
--- a/src/js/widgets/createAnnotationWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/createAnnotationWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -1,15 +1,23 @@
 IriSP.createAnnotationWidget = function(Popcorn, config, Serializer) {
   IriSP.Widget.call(this, Popcorn, config, Serializer);
   this._hidden = true;
-  this.keywords = IriSP.widgetsDefaults["createAnnotationWidget"].keywords;
   
-  this.polemic_mode = IriSP.widgetsDefaults["createAnnotationWidget"].polemic_mode;
-  this.polemics = IriSP.widgetsDefaults["createAnnotationWidget"].polemics;
-  
-  this.cinecast_version = IriSP.widgetsDefaults["createAnnotationWidget"].cinecast_version;
-  this.api_endpoint_template = IriSP.widgetsDefaults["createAnnotationWidget"].api_endpoint_template;
-  
-  this.ids = {}; /* a dictionnary linking buttons ids to keywords */
+  this.checkOption("keywords");
+  this.checkOption("polemic_mode", true);
+  this.checkOption("polemics");
+  this.checkOption("cinecast_version", false);
+  this.checkOption("api_endpoint_template");
+  this.checkOption("show_from_field", true);
+  this.checkOption("api_method");
+                         
+  if (!IriSP.null_or_undefined(IriSP.user)) {
+      if (!IriSP.null_or_undefined(IriSP.user.avatar)) {
+        this.user_avatar = IriSP.user.avatar;
+      }
+      if (!IriSP.null_or_undefined(IriSP.user.name)) {
+        this.user_name = IriSP.user.name;
+      }
+  }
   
   /* variables to save the current position of the slicer */
   if (this.cinecast_version) {
@@ -29,14 +37,9 @@
 
 IriSP.createAnnotationWidget.prototype.draw = function() {
   var _this = this;
-  var template_params = {cinecast_version: this.cinecast_version, 
-                         polemic_mode: this.polemic_mode};
-                         
-  if (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.avatar))
-    template_params["user_avatar"] = IriSP.user.avatar;
   
   var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template, 
-                                           template_params);
+                                           this);
   
 	this.selector.append(annotationMarkup);
   
@@ -45,70 +48,12 @@
   else {
     this.showStartScreen();
   }
+
+  // Add onclick event to both polemic and keywords buttons
   
-  // add the keywords.
-  for (var i = 0; i < this.keywords.length; i++) {
-    var keyword = this.keywords[i];
-    var id = IriSP.guid("button_");
-    var templ = IriSP.templToHTML("<button id={{id}} class='Ldt-createAnnotation-absent-keyword'>{{keyword}}</button>", 
-                                  {keyword: keyword, id: id});
-                                  
-    this.ids[keyword] = id; // save it for the function that handle textarea changes.
-    
-    this.selector.find(".Ldt-createAnnotation-keywords").append(templ);
-    this.selector.find("#" + id).click(function(keyword) { return function() {
-      var contents = _this.selector.find(".Ldt-createAnnotation-Description").val();
-      if (contents.indexOf(keyword) != -1) {
-        var newVal = contents.replace(" " + keyword, "");
-        if (newVal == contents)
-          newVal = contents.replace(keyword, "");
-      } else {
-        if (contents === "")
-          var newVal = keyword;
-        else
-          var newVal = contents + " " + keyword;      
-      }
-      
-      _this.selector.find(".Ldt-createAnnotation-Description").val(newVal);
-      // we use a custom event because there's no simple way to test for a js
-      // change in a textfield.
-      _this.selector.find(".Ldt-createAnnotation-Description").trigger("js_mod");
-      // also call our update function.
-      //_this.handleTextChanges();
-    }
-   }(keyword));
-  }
-
-  // add the polemic buttons.
-  if(this.polemic_mode)
-    for (var polemic in this.polemics) {
-
-      var classname = IriSP.templToHTML("Ldt-createAnnotation-polemic-{{classname}}", {classname : this.polemics[polemic]});
-
-      var templ = IriSP.templToHTML("<button class='{{classname}} Ldt-createAnnotation-polemic-button'>{{polemic}}</button>",
-                  {classname: classname, polemic: polemic});
-                  
-      this.selector.find(".Ldt-createAnnotation-polemics").append(templ);
-      this.selector.find("." + classname).click(function(polemic) { return function() {
-          var contents = _this.selector.find(".Ldt-createAnnotation-Description").val();
-          if (contents.indexOf(polemic) != -1) {
-            var newVal = contents.replace(" " + polemic, "");
-            if (newVal == contents)
-              newVal = contents.replace(polemic, "");
-          } else {
-            if (contents === "")
-              var newVal = polemic;
-            else
-              var newVal = contents + " " + polemic;      
-          }
-          
-          _this.selector.find(".Ldt-createAnnotation-Description").val(newVal);
-          
-          // also call our update function.
-          _this.handleTextChanges();
-        }
-       }(polemic));
-      }    
+  this.selector.find(".Ldt-createAnnotation-keywords button, .Ldt-createAnnotation-polemics button").click(function() {
+      _this.addKeyword(IriSP.jQuery(this).text());
+  });
   
   // js_mod is a custom event because there's no simple way to test for a js
   // change in a textfield.                    
@@ -178,6 +123,19 @@
   }
 };
 
+/* Handles adding keywords and polemics */
+IriSP.createAnnotationWidget.prototype.addKeyword = function(_keyword) {
+    var _field = this.selector.find(".Ldt-createAnnotation-Description"),
+        _rx = IriSP.regexpFromText(_keyword),
+        _contents = _field.val();
+    _contents = ( _rx.test(_contents)
+        ? _contents.replace(_rx,"").replace("  "," ").trim()
+        : _contents.trim() + " " + _keyword
+    );
+    _field.val(_contents);
+    _field.trigger("js_mod");
+}
+
 /** handles clicks on the annotate button. Works only for the non-cinecast version */
 IriSP.createAnnotationWidget.prototype.handleAnnotateSignal = function() {
   
@@ -237,24 +195,25 @@
 IriSP.createAnnotationWidget.prototype.handleTextChanges = function(event) {
   var contents = this.selector.find(".Ldt-createAnnotation-Description").val();
 
-  for(var keyword in this.ids) {
-  
-    var id = this.ids[keyword];
+  this.selector.find(".Ldt-createAnnotation-keywords button").each(function() {
+      var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text());
+      if (_rx.test(contents)) {
+          IriSP.jQuery(this).removeClass("Ldt-createAnnotation-absent-keyword")
+            .addClass("Ldt-createAnnotation-present-keyword");
+      } else {
+          IriSP.jQuery(this).addClass("Ldt-createAnnotation-absent-keyword")
+            .removeClass("Ldt-createAnnotation-present-keyword");
+      }
+  });
 
-    if (contents.indexOf(keyword) != -1) {
-      /* the word is present in the textarea but the button is not toggled */
-      if (this.selector.find("#" + id).hasClass("Ldt-createAnnotation-absent-keyword"))
-          this.selector.find("#" + id).removeClass("Ldt-createAnnotation-absent-keyword")
-                                      .addClass("Ldt-createAnnotation-present-keyword");      
-    } else {
-      /* the word is absent from the textarea but the button is toggled */
-      if (this.selector.find("#" + id).hasClass("Ldt-createAnnotation-present-keyword")) {
-          this.selector.find("#" + id).removeClass("Ldt-createAnnotation-present-keyword")
-                                      .addClass("Ldt-createAnnotation-absent-keyword");
+  this.selector.find(".Ldt-createAnnotation-polemics button").each(function() {
+      var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text());
+      if (_rx.test(contents)) {
+          IriSP.jQuery(this).addClass("Ldt-createAnnotation-polemic-active");
+      } else {
+          IriSP.jQuery(this).removeClass("Ldt-createAnnotation-polemic-active");
       }
-    }
-  }
-  
+  });
   if (this.polemic_mode) {
     /* Also go through the polemics to highlight the buttons */
     for (var polemic in this.polemics) {
@@ -327,7 +286,7 @@
   var _this = this;
   var textfield = this.selector.find(".Ldt-createAnnotation-Description");
   var contents = textfield.val();
-
+  
   if (contents === "") {  
     if (this.selector.find(".Ldt-createAnnotation-errorMessage").length === 0) {
       this.selector.find(".Ldt-createAnnotation-Container")
@@ -407,20 +366,23 @@
   annotation.content["data"] = contents;
   
   var meta = apiJson["meta"];
-  if (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name))
-    meta.creator = IriSP.user.name;    
-  else 
-    meta.creator = "An User";
+  
+  
+  var _username = this.selector.find(".Ldt-createAnnotation-userName").val();
+  meta.creator = (
+      (_username && _username.length)
+      ? _username
+      : (
+          (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name))
+          ? IriSP.user.name
+          : "Anonymous user"
+      )
+  );
   
   meta.created = Date().toString();
   
-  annotation["tags"] = [];
-  
-  for (var i = 0; i < this.keywords.length; i++) {
-    var keyword = this.keywords[i];
-    if (contents.indexOf(keyword) != -1)
-      annotation["tags"].push(keyword);
-  }
+  // All #hashtags are added to tags
+  annotation.tags = contents.match(/(#[\S]*)/g);
   
   var jsonString = JSON.stringify(apiJson);
   var project_id = this._serializer._data.meta.id;
@@ -431,7 +393,7 @@
                           
   IriSP.jQuery.ajax({
       url: url,
-      type: 'PUT',
+      type: this.api_method,
       contentType: 'application/json',
       data: jsonString,               
       //dataType: 'json',
--- a/src/js/widgets/playerWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/playerWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -58,9 +58,9 @@
 /* Update the elasped time div */
 IriSP.PlayerWidget.prototype.timeDisplayUpdater = function() {
   
-  if (this._previousSecond === undefined)
+  if (this._previousSecond === undefined) {
     this._previousSecond = this._Popcorn.roundTime();
-  
+  }
   else {
     /* we're still in the same second, so it's not necessary to update time */
     if (this._Popcorn.roundTime() == this._previousSecond)
--- a/src/js/widgets/polemicWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/polemicWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -54,7 +54,7 @@
     var duration      = this._serializer.getDuration();      // timescale width 
     var frameLength   = lineSize / frameSize;    // frame timescale  
     var timeline;
-    var colors  = new Array("","#1D973D","#C5A62D","#CE0A15","#036AAE","#585858");
+    var colors  = new Array("","#1D973D","#036AAE","#CE0A15","#C5A62D","#585858");
     
     // array 
     //var tweets  = new Array();
@@ -322,9 +322,16 @@
                   e.id = frames[i].mytweetsID[k].cinecast_id;
                   this.svgElements[e.id] = e;
                   
-                  IriSP.jQuery(e.node).mouseenter(function(element) { return function () {                    
+                  IriSP.jQuery(e.node).mouseenter(function(element) { return function (_e) {                    
                         self.TooltipWidget.show.call(self.TooltipWidget, element.title, element.attr("fill"), element.attrs.x + element.attrs.width / 2, element.attrs.y - 2);
                         element.displayed = true;
+                        self._Popcorn.trigger("IriSP.TraceWidget.MouseEvents", {
+                            "widget" : "StackGraphWidget",
+                            "type": "mousemove",
+                            "x": _e.pageX,
+                            "y": _e.pageY,
+                            "annotation_id": element.id
+                        });
                   }}(e)).mousedown(function(element) { return function () {                    
                     self._Popcorn.currentTime(element.time/1000);
                     self._Popcorn.trigger("IriSP.PolemicTweet.click", element.id); 
--- a/src/js/widgets/stackGraphWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/stackGraphWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -158,14 +158,19 @@
     var _this = this;
     this.selector
         .click(IriSP.wrap(this, this.clickHandler))
-        .mousemove(function(event) {
-            _this.updateTooltip(event);
-            
-            // Also tell the world where the mouse is hovering.
-            var relX = event.pageX - _this.selector.offset().left;
-            var duration = _this._serializer.getDuration();
-            var Time = ((relX / _this.width) * duration).toFixed(2);
-            _this._Popcorn.trigger("IriSP.StackGraphWidget.mouseOver", Time);
+        .mousemove(function(_e) {
+            _this.updateTooltip(_e);
+            // Trace
+            var relX = _e.pageX - _this.selector.offset().left;
+            var _duration = _this._serializer.getDuration();
+            var _time = parseInt((relX / _this.width) * _duration);
+            _this._Popcorn.trigger("IriSP.TraceWidget.MouseEvents", {
+                "widget" : "StackGraphWidget",
+                "type": "mousemove",
+                "x": _e.pageX,
+                "y": _e.pageY,
+                "time": _time
+            });
 
         })
         .mouseout(function() {
@@ -198,7 +203,7 @@
 };
 
 IriSP.StackGraphWidget.prototype.updateTooltip = function(event) {
-    var _segment = Math.floor(this.sliceCount * (event.pageX - this.selector.offset().left)/this.width),
+    var _segment = Math.max(0,Math.min(this.groups.length - 1, Math.floor(this.sliceCount * (event.pageX - this.selector.offset().left)/this.width))),
         _valeurs = this.groups[_segment],
         _width = this.width / this.sliceCount,
         _html = '<ul style="list-style: none; margin: 0; padding: 0;">' + IriSP._(this.tagconf).map(function(_tag, _i) {
--- a/src/js/widgets/tagCloudWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/tagCloudWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -8,9 +8,9 @@
     
     var _urlRegExp = /https?:\/\/[0-9a-zA-Z\.%\/-_]+/g,
         _stopWords = [
-            'aussi', 'and', 'avec', 'aux', 'bien', 'car', 'cette', 'comme', 'dans', 'donc', 'des', 'elle', 'encore', 'est',
+            'aussi', 'and', 'avec', 'aux', 'bien', 'car', 'cette', 'comme', 'dans', 'donc', 'des', 'elle', 'encore', 'entre', 'est',
             'être', 'eux', 'faire', 'fait', 'http', 'ici', 'ils', 'les', 'leur', 'leurs', 'mais', 'mes', 'même', 'mon', 'notre',
-            'non', 'nos', 'nous', 'ont', 'par', 'pas', 'peu', 'peut', 'plus', 'pour', 'que', 'qui', 'ses' ,'son', 'sont', 'sur',
+            'non', 'nos', 'nous', 'ont', 'par', 'pas', 'peu', 'peut', 'plus', 'pour', 'que', 'qui', 'sans', 'ses' ,'son', 'sont', 'sur',
             'tes', 'très', 'the', 'ton', 'tous', 'tout', 'une', 'votre', 'vos', 'vous' ],
         _regexpword = /[^\s\.&;,'"!\?\d\(\)\+\[\]\\\…\-«»:\/]{3,}/g,
         _words = {},
@@ -61,7 +61,7 @@
                 .shuffle()
                 .map(function(_word) {
                     var _size = 10 + _scale * Math.sqrt(_word.count - _min);
-                    return '<li style="font-size:'
+                    return '<li class="Ldt-TraceMe" style="font-size:'
                         + _size
                         + 'px;">'
                         + _word.word
@@ -81,7 +81,7 @@
         var _rgxp = new RegExp("(" + searchString.replace(/(\W)/g,'\\$1') + ")","gi");
         this.selector.find("li").each(function(_i, _e) {
             _e.innerHTML = searchString.length ?
-                _e.textContent.replace(_rgxp,'<span class="Ldt-TagCloud-actif">$1</span>')
+                _e.textContent.replace(_rgxp,'<span class="Ldt-TagCloud-actif Ldt-TraceMe">$1</span>')
                 : _e.textContent;
         });
     }));
--- a/src/js/widgets/tooltipWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/tooltipWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -21,6 +21,10 @@
       "position": "relative"
   });
   this.selector.append(templ);
+  var _this = this;
+  this.selector.mouseover(function() {
+      _this.hide();
+  });
   this.hide();
 
 };
--- a/src/js/widgets/traceWidget.js	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/js/widgets/traceWidget.js	Thu Mar 08 18:38:46 2012 +0100
@@ -12,23 +12,14 @@
         "IriSP.SliceWidget.show",
         "IriSP.SliceWidget.hide",
         "IriSP.createAnnotationWidget.addedAnnotation",
-//        "IriSP.PlayerWidget.AnnotateButton.clicked",
-//        "IriSP.PlayerWidget.MouseOver",
-//        "IriSP.PlayerWidget.MouseOut",
         "IriSP.search.open",
         "IriSP.search.closed",
         "IriSP.search",
         "IriSP.search.cleared",
-//        "IriSP.PolemicTweet.click",
         "IriSP.search.matchFound",
         "IriSP.search.noMatchFound",
-//        "IriSP.SegmentsWidget.click",
-        "IriSP.SliceWidget.zoneChange",
-//        "IriSP.SparklineWidget.clicked",
-//        "IriSP.StackGraphWidget.mouseOver",
-//        "IriSP.StackGraphWidget.clicked",
         "IriSP.search.triggeredSearch",
-        "IriSP.Widget.MouseEvents",
+        "IriSP.TraceWidget.MouseEvents",
         "play",
         "pause",
         "volumechange",
@@ -38,8 +29,8 @@
         "pause"
     ];
     IriSP._(_listeners).each(function(_listener) {
-      _this._Popcorn.listen(_listener, function() {
-          _this.eventHandler(_listener, arguments);
+      _this._Popcorn.listen(_listener, function(_arg) {
+          _this.eventHandler(_listener, _arg);
       });
     });
   
@@ -48,55 +39,89 @@
 IriSP.TraceWidget.prototype = new IriSP.Widget();
 
 IriSP.TraceWidget.prototype.draw = function() {
+    this.mouseLocation = '';
+    var _this = this;
+    IriSP.jQuery(".Ldt-Widget").bind("click mouseover mouseout dragstart dragstop", function(_e) {
+        var _widget = this.id.match('LdtPlayer_widget_([^_]+)')[1],
+            _class = _e.target.className;
+        var _data = {
+            "type": _e.type,
+            "x": _e.clientX,
+            "y": _e.clientY,
+            "widget": _widget
+        }
+        if (typeof _class == "string" && _class.indexOf('Ldt-TraceMe') != -1) {
+            var _name = _e.target.localName,
+                _id = _e.target.id,
+                _text = _e.target.textContent.trim(),
+                _title = _e.target.title,
+                _value = _e.target.value;
+            _data.target = _name + (_id.length ? '#' + _id : '') + (_class.length ? '.' + _class.replace(/\s/g,'.').replace(/\.Ldt-(Widget|TraceMe)/g,'') : '');
+            if (typeof _title == "string" && _title.length && _title.length < 140) {
+                _data.title = _title;
+            }
+            if (typeof _text == "string" && _text.length && _text.length < 140) {
+                _data.text = _text;
+            }
+            if (typeof _value == "string" && _value.length) {
+                _data.value = _value;
+            }
+            _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+        } else {
+            //console.log(_e.type+','+_this.mouseLocation+','+_widget);
+            if (_e.type == "mouseover") {
+                if (_this.mouseLocation != _widget) {
+                    _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+                } else {
+                    if (typeof _this.moTimeout != "undefined") {
+                        clearTimeout(_this.moTimeout);
+                        delete _this.moTimeout;
+                    }
+                }
+            }
+            if (_e.type == "click") {
+                _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+            }
+            if (_e.type == "mouseout") {
+                if (typeof _this.moTimeout != "undefined") {
+                    clearTimeout(_this.moTimeout);
+                }
+                _this.moTimeout = setTimeout(function() {
+                   if (_data.widget != _this.mouseLocation) {
+                       _this._Popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
+                   }
+                },100);
+            }
+        }
+        _this.mouseLocation = _widget;
+    });
 }
 
-IriSP.TraceWidget.prototype.eventHandler = function(_listener, _args) {
-    var _traceName = 'Mdp_',
-        _data = {};
-        
-    function packArgs() {
-        for (var _i = 0; _i < _args.length; _i++) {
-            _data[_i] = _args[_i];
-        }
+IriSP.TraceWidget.prototype.eventHandler = function(_listener, _arg) {
+    var _traceName = 'Mdp_';
+    if (typeof _arg == "string" || typeof _arg == "number") {
+        _arg = { "value" : _arg }
     }
-    
+    if (typeof _arg == "undefined") {
+        _arg = {}
+    }
     switch(_listener) {
-        case 'IriSP.Widget.MouseEvents':
-            var _type = _args[0].type,
-                _name = _args[0].target_name,
-                _class = _args[0].target_class,
-                _id = _args[0].target_id,
-                _widget = _args[0].widget.match(/[^_]+widget/i)[0];
-            _traceName += _widget + '_' + _type;
-            _data.x = _args[0].x;
-            _data.y = _args[0].y;
-            _data.target = _name + (_id.length ? '#' + _id : '') + (_class.length ? '.' + _class.replace(/\s/g,'.') : '');
-            if (typeof _args[0].value == "string" && _args[0].value.length) {
-                _data.value = _args[0].value;
-            }
-            if ((_name == "button" || /button/.test(_class)) && typeof _args[0].text == "string" && _args[0].text.length) {
-                _data.text = _args[0].text;
-            }
-            if (typeof _args[0].title == "string" && _args[0].title.length) {
-                _data.title = _args[0].title;
-            }
-            // Filtrer les événements mouseover quand on se déplace vers des éléments non pertinents
-            if (!_id.length && !_class.length && ( _type == 'mouseover' || _type == 'mouseout' ) && this.lastEvent.search('Mdp_' + _widget) == 0) {
-                return;
-            }
+        case 'IriSP.TraceWidget.MouseEvents':
+            _traceName += _arg.widget + '_' + _arg.type;
+            delete _arg.widget;
+            delete _arg.type;
         break;
+        case 'timeupdate':
         case 'play':
         case 'pause':
+            _arg.time = this._Popcorn.currentTime() * 1000;
         case 'seeked':
-        case 'timeupdate':
         case 'volumechange':
-            _traceName += 'Popcorn' + _listener;
-            packArgs();
+            _traceName += 'Popcorn_' + _listener;
         break;
         default:
             _traceName += _listener.replace('IriSP.','').replace('.','_');
-            packArgs();
     }
     this.lastEvent = _traceName;
-    console.log("trace('" + _traceName + "', " + JSON.stringify(_data) + ");");
+    console.log("trace('" + _traceName + "', " + JSON.stringify(_arg) + ");");
 }
--- a/src/templates/annotation.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/annotation.html	Thu Mar 08 18:38:46 2012 +0100
@@ -1,6 +1,6 @@
 {{! template for an annotation displayed in a segmentWidget }}
 <div title='{{divTitle}}' id='{{id}}'
-	class='Ldt-iri-chapter' 
+	class='Ldt-iri-chapter Ldt-TraceMe' 
 	style='left: {{startPixel}}px; 
          width: {{pxWidth}}px; 
          background-color:#{{hexa_color}};' 
--- a/src/templates/annotationWidget.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/annotationWidget.html	Thu Mar 08 18:38:46 2012 +0100
@@ -5,9 +5,9 @@
   
     <div class='Ldt-AnnotationContent'>  
         <div class='Ldt-AnnotationShareIcons'>
-         <a target='_blank' class='Ldt-fbShare' title='share on facebook'></a>
-         <a target='_blank' class='Ldt-TwShare' title='share on twitter'></a>
-         <a target='_blank'  class='Ldt-GplusShare' title='share on google+'></a>
+         <a target='_blank' class='Ldt-fbShare Ldt-TraceMe' title='share on facebook'></a>
+         <a target='_blank' class='Ldt-TwShare Ldt-TraceMe' title='share on twitter'></a>
+         <a target='_blank'  class='Ldt-GplusShare Ldt-TraceMe' title='share on google+'></a>
         </div>
 
         <div class='Ldt-SaTitle'></div>
--- a/src/templates/annotationsListWidget.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/annotationsListWidget.html	Thu Mar 08 18:38:46 2012 +0100
@@ -4,7 +4,7 @@
   <div class='Ldt-Annotation-DoubleBorder'>
     <ul>
     {{#annotations}}
-      <li>
+      <li id='Ldt-Annotation-li-{{id}}' class='Ldt-TraceMe'>
         {{! if the url is not present, it means that the annotation exists 
             in the current project }}
         {{^url}}
--- a/src/templates/createAnnotationWidget.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/createAnnotationWidget.html	Thu Mar 08 18:38:46 2012 +0100
@@ -1,61 +1,67 @@
 {{! template for the annotation creation widget }}
 <div class='Ldt-createAnnotationWidget'>
-  <!-- ugly div because we want to have a double border -->
-  <div class='Ldt-createAnnotation-DoubleBorder'>
-    <div class='Ldt-createAnnotation-startScreen'>
-      <div style='margin-bottom: 7px; overflow: auto;'>
-        <div class='Ldt-createAnnotation-Title'></div>
-        <div class='Ldt-createAnnotation-TimeFrame'></div>
-        {{^cinecast_version}}
-          <div class='Ldt-createAnnotation-Minimize' title='Cancel'></div>
-        {{/cinecast_version}}
-      </div>
-      
-      <div class='Ldt-createAnnotation-Container'>
-        <textarea class='Ldt-createAnnotation-Description'></textarea>
-        <div class='Ldt-createAnnotation-profileArrow'>          
-        </div>
-        <div class='Ldt-createAnnotation-userAvatar'>
-        {{^user_avatar}}
-          <img src='https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png'></img>
-        {{/user_avatar}}
-        {{#user_avatar}}
-          <img src='{{ user_avatar }}'></img>
-        {{/user_avatar}}
+    <!-- ugly div because we want to have a double border -->
+    <div class='Ldt-createAnnotation-DoubleBorder'>
+        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-startScreen'>
+            <div style='margin-bottom: 7px; overflow: auto;'>
+                <div class='Ldt-createAnnotation-Title'></div>
+                <div class='Ldt-createAnnotation-TimeFrame'></div>
+                {{^cinecast_version}} <div class='Ldt-createAnnotation-Minimize Ldt-TraceMe' title='Cancel'></div>
+                {{/cinecast_version}}
+            </div>
+            <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-Container'>
+                {{#show_from_field}}
+                <label>Your name&nbsp;: </label><input class='Ldt-createAnnotation-userName Ldt-TraceMe' value='{{user_name}}' />
+                {{/show_from_field}}
+                <textarea class='Ldt-createAnnotation-Description Ldt-TraceMe'></textarea>
+                <div class='Ldt-createAnnotation-profileArrow'></div>
+                <div class='Ldt-createAnnotation-userAvatar Ldt-TraceMe'>
+                    {{^user_avatar}} <img src='https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png'></img>
+                    {{/user_avatar}}
+                    {{#user_avatar}} <img src='{{ user_avatar }}'></img>
+                    {{/user_avatar}}
+                </div>
+            </div>
+            <div class='Ldt-createAnnotation-submitButton Ldt-TraceMe'>
+                <div style='position: absolute; bottom: 5px; right: 5px;'>
+                    Submit
+                </div>
+            </div>
+            {{#keywords.length}}
+            <div class='Ldt-createAnnotation-keywords'>
+                Add keywords :
+                {{#keywords}}
+                    <button class='Ldt-createAnnotation-absent-keyword Ldt-TraceMe'>{{.}}</button>
+                {{/keywords}}
+            </div>
+            {{/keywords.length}}
+            {{#polemic_mode}}
+            <div class='Ldt-createAnnotation-polemics'>
+                Add polemic keywords :
+                {{#polemics}}
+                    <button class='Ldt-createAnnotation-polemic-{{className}} Ldt-createAnnotation-polemic-button Ldt-TraceMe'>{{keyword}}</button>
+                {{/polemics}}
+            </div>
+            {{/polemic_mode}}
         </div>
-      </div>
-      <div class='Ldt-createAnnotation-submitButton'>
-        <div style='position: absolute; bottom: 5px; right: 5px;'>Submit</div>
-      </div>
-      <div class='Ldt-createAnnotation-keywords'>
-        Add keywords :       
-      </div>
-      {{#polemic_mode}}
-      <div class='Ldt-createAnnotation-polemics'>
-        Add polemic keywords     
-      </div>
-      {{/polemic_mode}}
-
-    </div>
-    <div class='Ldt-createAnnotation-waitScreen' style='display: none; text-align: center'>
-      <div class='Ldt-createAnnotation-spinner'></div>
-      Please wait while your request is being processed...
+        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-waitScreen' style='display: none; text-align: center'>
+            <div class='Ldt-createAnnotation-spinner'></div>
+            Please wait while your request is being processed...
+        </div>
+        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-errorScreen' style='display: none; text-align: center'>
+            <div class='Ldt-createAnnotation-Minimize' title='Hide'></div>
+            An error happened while contacting the server. Your annotation has not been saved.
+        </div>
+        <div class='Ldt-createAnnotation-screen Ldt-createAnnotation-endScreen' style='display: none'>
+            <div class='Ldt-createAnnotation-Minimize' title='Hide'></div>
+            Thank you, your annotation has been saved.
+            <br>
+            Would you like to share it on social networks ?
+            <div style='margin-top: 12px; text-align: center;'>
+                <a target='_blank' class='Ldt-createAnnotation-endScreen-TweetLink Ldt-TraceMe'></a>
+                <a target='_blank' class='Ldt-createAnnotation-endScreen-FbLink Ldt-TraceMe'></a>
+                <a target='_blank' class='Ldt-createAnnotation-endScreen-GplusLink Ldt-TraceMe'></a>
+            </div>
+        </div>
     </div>
-
-    <div class='Ldt-createAnnotation-errorScreen' style='display: none; text-align: center'>
-      <div class='Ldt-createAnnotation-Minimize' title='Hide'></div>
-      An error happened while contacting the server. Your annotation has not been saved.
-    </div>
-    
-    <div class='Ldt-createAnnotation-endScreen' style='display: none'>
-      <div class='Ldt-createAnnotation-Minimize' title='Hide'></div>
-      Thank you, your annotation has been saved.<br>
-      Would you like to share it on social networks ?
-      <div style='margin-top: 12px; text-align: center;'>
-          <a target='_blank' class='Ldt-createAnnotation-endScreen-TweetLink'></a>
-          <a target='_blank' class='Ldt-createAnnotation-endScreen-FbLink'></a>
-          <a target='_blank' class='Ldt-createAnnotation-endScreen-GplusLink'></a>                    
-      </div>
-    </div>
-  </div>
 </div>
--- a/src/templates/player.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/player.html	Thu Mar 08 18:38:46 2012 +0100
@@ -1,11 +1,11 @@
 {{! template for the radio player }}
-<div class='Ldt-controler demo'>
+<div class='Ldt-controler'>
 	<div class='Ldt-LeftPlayerControls'>
-    <div class='Ldt-button Ldt-CtrlPlay Ldt-CtrlPlay-PlayState' title='Play/Pause'></div>
-		<div class='Ldt-button Ldt-CtrlAnnotate' title='Annotate'></div>
-    <div class='Ldt-button Ldt-CtrlSearch' title='Search'></div>
+    <div class='Ldt-button Ldt-CtrlPlay Ldt-CtrlPlay-PlayState Ldt-TraceMe' title='Play/Pause'></div>
+		<div class='Ldt-button Ldt-CtrlAnnotate Ldt-TraceMe' title='Annotate'></div>
+    <div class='Ldt-button Ldt-CtrlSearch Ldt-TraceMe' title='Search'></div>
     <div class='LdtSearch'>
-      <input class='LdtSearchInput' style='margin-top: 2px; margin-bottom: 2px;'></input>
+      <input class='LdtSearchInput Ldt-TraceMe' style='margin-top: 2px; margin-bottom: 2px;'></input>
     </div>
     
 	</div>
@@ -15,6 +15,6 @@
       <div class='Ldt-TimeSeparator'>/</div>
       <div class='Ldt-TotalTime' title='Total time'>00:00</div>
     </div>
-		<div class='Ldt-button Ldt-CtrlSound Ldt-CtrlSound-MuteState' title='Mute/Unmute'></div>
+		<div class='Ldt-button Ldt-CtrlSound Ldt-CtrlSound-MuteState Ldt-TraceMe' title='Mute/Unmute'></div>
 	</div>
 </div>
--- a/src/templates/sliderWidget.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/sliderWidget.html	Thu Mar 08 18:38:46 2012 +0100
@@ -2,4 +2,4 @@
     of the other }}
 <div class='Ldt-sliderBackground'></div>
 <div class='Ldt-sliderForeground'></div>
-<div class='Ldt-sliderPositionMarker'></div>
+<div class='Ldt-sliderPositionMarker Ldt-TraceMe'></div>
--- a/src/templates/tweetWidget.html	Tue Mar 06 13:26:51 2012 +0100
+++ b/src/templates/tweetWidget.html	Thu Mar 08 18:38:46 2012 +0100
@@ -2,13 +2,13 @@
 <div class='Ldt-tweetWidget'>
   <div class='Ldt-tweet-DoubleBorder'>
 
-      <div class='Ldt-tweetWidgetKeepOpen' title='dont minimize automatically'></div>
-      <div class='Ldt-tweetWidgetMinimize' title='minimize window'></div>
+      <div class='Ldt-tweetWidgetKeepOpen Ldt-TraceMe' title='dont minimize automatically'></div>
+      <div class='Ldt-tweetWidgetMinimize Ldt-TraceMe' title='minimize window'></div>
       <div class='Ldt-tweetAvatar'></div>
       <div class='Ldt-tweetAvatar-profileArrow'></div>
       <div class='Ldt-tweetContents'></div>
-      <a href='' target='_blank' class='Ldt-Retweet'><div class='Ldt-RetweetIcon'></div> - Retweet </a>
-      <a href='' target='_blank' class='Ldt-TweetReply'><div class='Ldt-TweetReplyIcon'></div> - Reply</a>
+      <a href='' target='_blank' class='Ldt-Retweet Ldt-TraceMe'><div class='Ldt-RetweetIcon'></div> - Retweet </a>
+      <a href='' target='_blank' class='Ldt-TweetReply Ldt-TraceMe'><div class='Ldt-TweetReplyIcon'></div> - Reply</a>
 
   </div>
 </div>
--- a/test/integration/allocine_dossier_independant/polemic-allocine.htm	Tue Mar 06 13:26:51 2012 +0100
+++ b/test/integration/allocine_dossier_independant/polemic-allocine.htm	Thu Mar 08 18:38:46 2012 +0100
@@ -25,11 +25,6 @@
     
     IriSP.user = {name: 'awesome_user_name', avatar: 'allocine_test/avatar.png'};
     IriSP.libdir = "js/libs/";
-    IriSP.widgetsDefaults["createAnnotationWidget"] = {};
-    IriSP.widgetsDefaults["createAnnotationWidget"].cinecast_version = true;
-    IriSP.widgetsDefaults["createAnnotationWidget"].polemic_mode = false;
-    IriSP.widgetsDefaults["createAnnotationWidget"].keywords = ["#allocine", "#vodkaster", "#universcine"];
-    IriSP.widgetsDefaults["createAnnotationWidget"].api_endpoint_template = "coucou/{{id}}.json";
     IriSP.defaults.user = function(){ return IriSP.user; };
     
     var config = {            
@@ -57,13 +52,17 @@
             },            
             {type: "AnnotationsListWidget",
              container: "AnnotationsListContainer"},
-            {type: "SliderWidget"},        
+            {type: "SliderWidget"},
             {type: "PlayerWidget", // please note that type refers directly to the constructor of the widget.
              mode: "radio"},                     
             {type: "ArrowWidget"},
             {type: "TweetsWidget"},
-            {type: "createAnnotationWidget"},
-            {type: "TraceWidget"}
+            {type: "createAnnotationWidget",
+            polemic_mode: false,
+            cinecast_version: true,
+            keywords: ['#vodkaster', '#allocine', '#universcine'],
+            api_endpoint_template : "coucou/{{id}}.json",
+            api_method: 'POST'}
             ]
         },
       player:{
--- a/test/integration/polemic.htm	Tue Mar 06 13:26:51 2012 +0100
+++ b/test/integration/polemic.htm	Thu Mar 08 18:38:46 2012 +0100
@@ -21,6 +21,7 @@
   <div id="LdtPlayer"></div>
   
   <script  type="text/javascript">
+IriSP.jwplayer_swf_path = "../libs/player.swf";
     var file = "polemic_fr.json";
     var config = {            
         gui:{
@@ -46,7 +47,8 @@
             },
             {type: "StackGraphWidget",
              width: 640, /* required for this widget */
-             height: 50,              
+             height: 50,
+            streamgraph: true,         
              requires: [{
               type: "TooltipWidget",
               width: 180,
@@ -71,7 +73,9 @@
             {type: "TweetsWidget"},
             {type: "createAnnotationWidget"},
             {type: "TagCloudWidget",
-            excludeWords: ['#museoweb']}
+            excludeWords: ['#museoweb']},
+            {type: "AnnotationsListWidget"},
+            {type: "TraceWidget"}
             ]
         },
       player:{