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 = ''; |
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() { |