src/js/widgets-container/widget.js
changeset 1068 7623f9af9272
parent 1049 4e8b3df6e5be
child 1072 ac1eacb3aa33
equal deleted inserted replaced
1067:539c9bee5372 1068:7623f9af9272
    15  * @param config - configuration options for the widget
    15  * @param config - configuration options for the widget
    16  */
    16  */
    17 
    17 
    18 
    18 
    19 IriSP.Widgets.Widget = function(player, config) {
    19 IriSP.Widgets.Widget = function(player, config) {
    20     
    20 
    21     if( typeof player === "undefined") {
    21     if( typeof player === "undefined") {
    22         /* Probably an abstract call of the class when
    22         /* Probably an abstract call of the class when
    23          * individual widgets set their prototype */
    23          * individual widgets set their prototype */
    24         return;
    24         return;
    25     }
    25     }
    26     
    26 
    27     this.__subwidgets = [];
    27     this.__subwidgets = [];
    28     
    28 
    29     /* Setting all the configuration options */
    29     /* Setting all the configuration options */
    30     var _type = config.type || "(unknown)",
    30     var _type = config.type || "(unknown)",
    31         _config = IriSP._.defaults({}, config, (player && player.config ? player.config.default_options : {}), this.defaults),
    31         _config = IriSP._.defaults({}, config, (player && player.config ? player.config.default_options : {}), this.defaults),
    32         _this = this;
    32         _this = this;
    33     
    33 
    34     IriSP._(_config).forEach(function(_value, _key) {
    34     IriSP._(_config).forEach(function(_value, _key) {
    35        _this[_key] = _value;
    35        _this[_key] = _value;
    36     });
    36     });
    37     
    37 
    38     this.$ = IriSP.jQuery('#' + this.container);
    38     this.$ = IriSP.jQuery('#' + this.container);
    39     
    39 
    40     if (typeof this.width === "undefined") {
    40     if (typeof this.width === "undefined") {
    41         this.width = this.$.width();
    41         this.width = this.$.width();
    42     } else {
    42     } else {
    43         this.$.css("width", this.width);
    43         this.$.css("width", this.width);
    44     }
    44     }
    45     
    45 
    46     if (typeof this.height !== "undefined") {
    46     if (typeof this.height !== "undefined") {
    47         this.$.css("height", this.height);
    47         this.$.css("height", this.height);
    48     }
    48     }
    49     
    49 
    50     /* Setting this.player at the end in case it's been overriden
    50     /* Setting this.player at the end in case it's been overriden
    51      * by a configuration option of the same name :-(
    51      * by a configuration option of the same name :-(
    52      */
    52      */
    53     this.player = player || new IriSP.FakeClass(["on","trigger","off","loadWidget","loadMetadata"]);
    53     this.player = player || new IriSP.FakeClass(["on","trigger","off","loadWidget","loadMetadata"]);
    54     
    54 
    55     /* Adding classes and html attributes */
    55     /* Adding classes and html attributes */
    56     this.$.addClass("Ldt-TraceMe Ldt-Widget").attr("widget-type", _type);
    56     this.$.addClass("Ldt-TraceMe Ldt-Widget").attr("widget-type", _type);
    57     
    57 
    58     this.l10n = (
    58     this.l10n = (
    59         typeof this.messages[IriSP.language] !== "undefined"
    59         typeof this.messages[IriSP.language] !== "undefined"
    60         ? this.messages[IriSP.language]
    60         ? this.messages[IriSP.language]
    61         : (
    61         : (
    62             IriSP.language.length > 2 && typeof this.messages[IriSP.language.substr(0,2)] !== "undefined"
    62             IriSP.language.length > 2 && typeof this.messages[IriSP.language.substr(0,2)] !== "undefined"
    63             ? this.messages[IriSP.language.substr(0,2)]
    63             ? this.messages[IriSP.language.substr(0,2)]
    64             : this.messages["en"]
    64             : this.messages["en"]
    65         )
    65         )
    66     );
    66     );
    67     
    67 
    68     /* Loading Metadata if required */
    68     /* Loading Metadata if required */
    69    
    69 
    70     function onsourceloaded() {
    70     function onsourceloaded() {
       
    71         if (_this.localannotations) {
       
    72             _this.localsource = player.loadLocalAnnotations(_this.localannotations);
       
    73             _this.source.merge(_this.localsource);
       
    74         }
    71         if (_this.media_id) {
    75         if (_this.media_id) {
    72                 _this.media = this.getElement(_this.media_id);
    76                 _this.media = this.getElement(_this.media_id);
    73             } else {
    77             } else {
    74                 var _mediaopts = {
    78                 var _mediaopts = {
    75                     is_mashup: _this.is_mashup || false
    79                     is_mashup: _this.is_mashup || false
    76                 };
    80                 };
    77                 _this.media = _this.source.getCurrentMedia(_mediaopts);
    81                 _this.media = _this.source.getCurrentMedia(_mediaopts);
    78             }
    82             }
    79             
       
    80 
       
    81         if (_this.pre_draw_callback){
    83         if (_this.pre_draw_callback){
    82             IriSP.jQuery.when(_this.pre_draw_callback()).done(_this.draw());
    84             IriSP.jQuery.when(_this.pre_draw_callback()).done(_this.draw());
    83         }
    85         }
    84         else {
    86         else {
    85             _this.draw();
    87             _this.draw();
    86         }
    88         }
    87         _this.player.trigger("widget-loaded");
    89         _this.player.trigger("widget-loaded");
    88     }
    90     }
    89     
    91 
    90     if (this.metadata) {
    92     if (this.metadata) {
    91         /* Getting metadata */
    93         /* Getting metadata */
    92         this.source = player.loadMetadata(this.metadata);
    94         this.source = player.loadMetadata(this.metadata);
    93         
       
    94         /* Call draw when loaded */
    95         /* Call draw when loaded */
    95         this.source.onLoad(onsourceloaded);
    96         this.source.onLoad(onsourceloaded);
    96     } else {
    97     } else {
    97         if (this.source) {
    98         if (this.source) {
    98             onsourceloaded();
    99             onsourceloaded();
    99         }
   100         }
   100     }
   101     }
   101     
   102 
   102     
   103 
   103 };
   104 };
   104 
   105 
   105 IriSP.Widgets.Widget.prototype.defaults = {};
   106 IriSP.Widgets.Widget.prototype.defaults = {};
   106 
   107 
   107 IriSP.Widgets.Widget.prototype.template = '';
   108 IriSP.Widgets.Widget.prototype.template = '';
   215  */
   216  */
   216 IriSP.Widgets.Widget.prototype.navigate = function(offset) {
   217 IriSP.Widgets.Widget.prototype.navigate = function(offset) {
   217     // offset is normally either -1 (previous slide) or +1 (next slide)
   218     // offset is normally either -1 (previous slide) or +1 (next slide)
   218     var _this = this;
   219     var _this = this;
   219     var currentTime = _this.media.getCurrentTime();
   220     var currentTime = _this.media.getCurrentTime();
   220     var annotations = _this.source.getAnnotations().sortBy(function(_annotation) {
   221     var annotations = _this.getWidgetAnnotations().sortBy(function(_annotation) {
   221         return _annotation.begin;
   222         return _annotation.begin;
   222     });
   223     });
   223     for (var i = 0; i < annotations.length; i++) {
   224     for (var i = 0; i < annotations.length; i++) {
   224         if (annotations[i].begin <= currentTime && currentTime < annotations[i].end) {
   225         if (annotations[i].begin <= currentTime && currentTime < annotations[i].end) {
   225             // Found a current annotation - clamp i+offset value to [0, length - 1]
   226             // Found a current annotation - clamp i+offset value to [0, length - 1]
   228             break;
   229             break;
   229         }
   230         }
   230     };
   231     };
   231 };
   232 };
   232 
   233 
       
   234 /*
       
   235  * Propose an export of the widget's annotations
       
   236  *
       
   237  * Parameter: a list of annotations. If not specified, the widget's annotations will be exported.
       
   238  */
       
   239 IriSP.Widgets.Widget.prototype.exportAnnotations = function(annotations) {
       
   240     var widget = this;
       
   241     if (annotations === undefined)
       
   242         annotations = this.getWidgetAnnotations();
       
   243     var $ = IriSP.jQuery;
       
   244 
       
   245     // FIXME: this should belong to a proper serialize/deserialize component?
       
   246     var content = Mustache.to_html("[video:{{url}}]\n", {url: widget.media.url}) + annotations.map( function(a) { return Mustache.to_html("[{{ a.begin }}]{{ a.title }} {{ a.description }}[{{ a.end }}]", { a: a }); }).join("\n");
       
   247 
       
   248     var el = $("<pre>")
       
   249             .addClass("exportContainer")
       
   250             .text(content)
       
   251             .dialog({
       
   252                 title: "Annotation export",
       
   253                 open: function( event, ui ) {
       
   254                     // Select text
       
   255                     var range;
       
   256                     if (document.selection) {
       
   257 		                range = document.body.createTextRange();
       
   258                         range.moveToElementText(this[0]);
       
   259 		                range.select();
       
   260 		            } else if (window.getSelection) {
       
   261 		                range = document.createRange();
       
   262 		                range.selectNode(this[0]);
       
   263 		                window.getSelection().addRange(range);
       
   264 		            }
       
   265                 },
       
   266                 autoOpen: true,
       
   267                 width: '80%',
       
   268                 minHeight: '400',
       
   269                 height: 400,
       
   270                 buttons: [ { text: "Close", click: function() { $( this ).dialog( "close" ); } },
       
   271                            { text: "Download", click: function () {
       
   272                                a = document.createElement('a');
       
   273                                a.setAttribute('href', 'data:text/plain;base64,' + btoa(content));
       
   274                                a.setAttribute('download', 'Annotations - ' + widget.media.title.replace(/[^ \w]/g, '') + '.txt');
       
   275                                a.click();
       
   276                            } } ]
       
   277             });
       
   278 };
   233 
   279 
   234 /**
   280 /**
   235  * This method responsible of drawing a widget on screen.
   281  * This method responsible of drawing a widget on screen.
   236  */
   282  */
   237 IriSP.Widgets.Widget.prototype.draw = function() {
   283 IriSP.Widgets.Widget.prototype.draw = function() {