1 IriSP.createAnnotationWidget = function(Popcorn, config, Serializer) { |
1 IriSP.createAnnotationWidget = function(Popcorn, config, Serializer) { |
2 IriSP.Widget.call(this, Popcorn, config, Serializer); |
2 IriSP.Widget.call(this, Popcorn, config, Serializer); |
3 this._hidden = true; |
3 this._hidden = true; |
4 this.keywords = IriSP.widgetsDefaults["createAnnotationWidget"].keywords; |
4 |
5 |
5 this.checkOption("keywords"); |
6 this.polemic_mode = IriSP.widgetsDefaults["createAnnotationWidget"].polemic_mode; |
6 this.checkOption("polemic_mode", true); |
7 this.polemics = IriSP.widgetsDefaults["createAnnotationWidget"].polemics; |
7 this.checkOption("polemics"); |
8 |
8 this.checkOption("cinecast_version", false); |
9 this.cinecast_version = IriSP.widgetsDefaults["createAnnotationWidget"].cinecast_version; |
9 this.checkOption("api_endpoint_template"); |
10 this.api_endpoint_template = IriSP.widgetsDefaults["createAnnotationWidget"].api_endpoint_template; |
10 this.checkOption("show_from_field", true); |
11 |
11 this.checkOption("api_method"); |
12 this.ids = {}; /* a dictionnary linking buttons ids to keywords */ |
12 |
|
13 if (!IriSP.null_or_undefined(IriSP.user)) { |
|
14 if (!IriSP.null_or_undefined(IriSP.user.avatar)) { |
|
15 this.user_avatar = IriSP.user.avatar; |
|
16 } |
|
17 if (!IriSP.null_or_undefined(IriSP.user.name)) { |
|
18 this.user_name = IriSP.user.name; |
|
19 } |
|
20 } |
13 |
21 |
14 /* variables to save the current position of the slicer */ |
22 /* variables to save the current position of the slicer */ |
15 if (this.cinecast_version) { |
23 if (this.cinecast_version) { |
16 this.sliceLeft = 0; |
24 this.sliceLeft = 0; |
17 this.sliceWidth = 0; |
25 this.sliceWidth = 0; |
27 this.selector.find(".Ldt-SaKeywordText").text(""); |
35 this.selector.find(".Ldt-SaKeywordText").text(""); |
28 }; |
36 }; |
29 |
37 |
30 IriSP.createAnnotationWidget.prototype.draw = function() { |
38 IriSP.createAnnotationWidget.prototype.draw = function() { |
31 var _this = this; |
39 var _this = this; |
32 var template_params = {cinecast_version: this.cinecast_version, |
|
33 polemic_mode: this.polemic_mode}; |
|
34 |
|
35 if (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.avatar)) |
|
36 template_params["user_avatar"] = IriSP.user.avatar; |
|
37 |
40 |
38 var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template, |
41 var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template, |
39 template_params); |
42 this); |
40 |
43 |
41 this.selector.append(annotationMarkup); |
44 this.selector.append(annotationMarkup); |
42 |
45 |
43 if (!this.cinecast_version) |
46 if (!this.cinecast_version) |
44 this.selector.hide(); |
47 this.selector.hide(); |
45 else { |
48 else { |
46 this.showStartScreen(); |
49 this.showStartScreen(); |
47 } |
50 } |
48 |
51 |
49 // add the keywords. |
52 // Add onclick event to both polemic and keywords buttons |
50 for (var i = 0; i < this.keywords.length; i++) { |
53 |
51 var keyword = this.keywords[i]; |
54 this.selector.find(".Ldt-createAnnotation-keywords button, .Ldt-createAnnotation-polemics button").click(function() { |
52 var id = IriSP.guid("button_"); |
55 _this.addKeyword(IriSP.jQuery(this).text()); |
53 var templ = IriSP.templToHTML("<button id={{id}} class='Ldt-createAnnotation-absent-keyword'>{{keyword}}</button>", |
56 }); |
54 {keyword: keyword, id: id}); |
|
55 |
|
56 this.ids[keyword] = id; // save it for the function that handle textarea changes. |
|
57 |
|
58 this.selector.find(".Ldt-createAnnotation-keywords").append(templ); |
|
59 this.selector.find("#" + id).click(function(keyword) { return function() { |
|
60 var contents = _this.selector.find(".Ldt-createAnnotation-Description").val(); |
|
61 if (contents.indexOf(keyword) != -1) { |
|
62 var newVal = contents.replace(" " + keyword, ""); |
|
63 if (newVal == contents) |
|
64 newVal = contents.replace(keyword, ""); |
|
65 } else { |
|
66 if (contents === "") |
|
67 var newVal = keyword; |
|
68 else |
|
69 var newVal = contents + " " + keyword; |
|
70 } |
|
71 |
|
72 _this.selector.find(".Ldt-createAnnotation-Description").val(newVal); |
|
73 // we use a custom event because there's no simple way to test for a js |
|
74 // change in a textfield. |
|
75 _this.selector.find(".Ldt-createAnnotation-Description").trigger("js_mod"); |
|
76 // also call our update function. |
|
77 //_this.handleTextChanges(); |
|
78 } |
|
79 }(keyword)); |
|
80 } |
|
81 |
|
82 // add the polemic buttons. |
|
83 if(this.polemic_mode) |
|
84 for (var polemic in this.polemics) { |
|
85 |
|
86 var classname = IriSP.templToHTML("Ldt-createAnnotation-polemic-{{classname}}", {classname : this.polemics[polemic]}); |
|
87 |
|
88 var templ = IriSP.templToHTML("<button class='{{classname}} Ldt-createAnnotation-polemic-button'>{{polemic}}</button>", |
|
89 {classname: classname, polemic: polemic}); |
|
90 |
|
91 this.selector.find(".Ldt-createAnnotation-polemics").append(templ); |
|
92 this.selector.find("." + classname).click(function(polemic) { return function() { |
|
93 var contents = _this.selector.find(".Ldt-createAnnotation-Description").val(); |
|
94 if (contents.indexOf(polemic) != -1) { |
|
95 var newVal = contents.replace(" " + polemic, ""); |
|
96 if (newVal == contents) |
|
97 newVal = contents.replace(polemic, ""); |
|
98 } else { |
|
99 if (contents === "") |
|
100 var newVal = polemic; |
|
101 else |
|
102 var newVal = contents + " " + polemic; |
|
103 } |
|
104 |
|
105 _this.selector.find(".Ldt-createAnnotation-Description").val(newVal); |
|
106 |
|
107 // also call our update function. |
|
108 _this.handleTextChanges(); |
|
109 } |
|
110 }(polemic)); |
|
111 } |
|
112 |
57 |
113 // js_mod is a custom event because there's no simple way to test for a js |
58 // js_mod is a custom event because there's no simple way to test for a js |
114 // change in a textfield. |
59 // change in a textfield. |
115 this.selector.find(".Ldt-createAnnotation-Description") |
60 this.selector.find(".Ldt-createAnnotation-Description") |
116 .bind("propertychange keyup input paste js_mod", IriSP.wrap(this, this.handleTextChanges)); |
61 .bind("propertychange keyup input paste js_mod", IriSP.wrap(this, this.handleTextChanges)); |
176 } |
121 } |
177 )); |
122 )); |
178 } |
123 } |
179 }; |
124 }; |
180 |
125 |
|
126 /* Handles adding keywords and polemics */ |
|
127 IriSP.createAnnotationWidget.prototype.addKeyword = function(_keyword) { |
|
128 var _field = this.selector.find(".Ldt-createAnnotation-Description"), |
|
129 _rx = IriSP.regexpFromText(_keyword), |
|
130 _contents = _field.val(); |
|
131 _contents = ( _rx.test(_contents) |
|
132 ? _contents.replace(_rx,"").replace(" "," ").trim() |
|
133 : _contents.trim() + " " + _keyword |
|
134 ); |
|
135 _field.val(_contents); |
|
136 _field.trigger("js_mod"); |
|
137 } |
|
138 |
181 /** handles clicks on the annotate button. Works only for the non-cinecast version */ |
139 /** handles clicks on the annotate button. Works only for the non-cinecast version */ |
182 IriSP.createAnnotationWidget.prototype.handleAnnotateSignal = function() { |
140 IriSP.createAnnotationWidget.prototype.handleAnnotateSignal = function() { |
183 |
141 |
184 if (this._hidden == false && this._state == 'startScreen') { |
142 if (this._hidden == false && this._state == 'startScreen') { |
185 this.selector.hide(); |
143 this.selector.hide(); |
235 |
193 |
236 /** watch for changes in the textfield and change the buttons accordingly */ |
194 /** watch for changes in the textfield and change the buttons accordingly */ |
237 IriSP.createAnnotationWidget.prototype.handleTextChanges = function(event) { |
195 IriSP.createAnnotationWidget.prototype.handleTextChanges = function(event) { |
238 var contents = this.selector.find(".Ldt-createAnnotation-Description").val(); |
196 var contents = this.selector.find(".Ldt-createAnnotation-Description").val(); |
239 |
197 |
240 for(var keyword in this.ids) { |
198 this.selector.find(".Ldt-createAnnotation-keywords button").each(function() { |
241 |
199 var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text()); |
242 var id = this.ids[keyword]; |
200 if (_rx.test(contents)) { |
243 |
201 IriSP.jQuery(this).removeClass("Ldt-createAnnotation-absent-keyword") |
244 if (contents.indexOf(keyword) != -1) { |
202 .addClass("Ldt-createAnnotation-present-keyword"); |
245 /* the word is present in the textarea but the button is not toggled */ |
203 } else { |
246 if (this.selector.find("#" + id).hasClass("Ldt-createAnnotation-absent-keyword")) |
204 IriSP.jQuery(this).addClass("Ldt-createAnnotation-absent-keyword") |
247 this.selector.find("#" + id).removeClass("Ldt-createAnnotation-absent-keyword") |
205 .removeClass("Ldt-createAnnotation-present-keyword"); |
248 .addClass("Ldt-createAnnotation-present-keyword"); |
206 } |
249 } else { |
207 }); |
250 /* the word is absent from the textarea but the button is toggled */ |
208 |
251 if (this.selector.find("#" + id).hasClass("Ldt-createAnnotation-present-keyword")) { |
209 this.selector.find(".Ldt-createAnnotation-polemics button").each(function() { |
252 this.selector.find("#" + id).removeClass("Ldt-createAnnotation-present-keyword") |
210 var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text()); |
253 .addClass("Ldt-createAnnotation-absent-keyword"); |
211 if (_rx.test(contents)) { |
254 } |
212 IriSP.jQuery(this).addClass("Ldt-createAnnotation-polemic-active"); |
255 } |
213 } else { |
256 } |
214 IriSP.jQuery(this).removeClass("Ldt-createAnnotation-polemic-active"); |
257 |
215 } |
|
216 }); |
258 if (this.polemic_mode) { |
217 if (this.polemic_mode) { |
259 /* Also go through the polemics to highlight the buttons */ |
218 /* Also go through the polemics to highlight the buttons */ |
260 for (var polemic in this.polemics) { |
219 for (var polemic in this.polemics) { |
261 /* Add the active class to the button */ |
220 /* Add the active class to the button */ |
262 var classname = "Ldt-createAnnotation-polemic-" + this.polemics[polemic]; |
221 var classname = "Ldt-createAnnotation-polemic-" + this.polemics[polemic]; |
325 /** handle clicks on "send annotation" button */ |
284 /** handle clicks on "send annotation" button */ |
326 IriSP.createAnnotationWidget.prototype.handleButtonClick = function(event) { |
285 IriSP.createAnnotationWidget.prototype.handleButtonClick = function(event) { |
327 var _this = this; |
286 var _this = this; |
328 var textfield = this.selector.find(".Ldt-createAnnotation-Description"); |
287 var textfield = this.selector.find(".Ldt-createAnnotation-Description"); |
329 var contents = textfield.val(); |
288 var contents = textfield.val(); |
330 |
289 |
331 if (contents === "") { |
290 if (contents === "") { |
332 if (this.selector.find(".Ldt-createAnnotation-errorMessage").length === 0) { |
291 if (this.selector.find(".Ldt-createAnnotation-errorMessage").length === 0) { |
333 this.selector.find(".Ldt-createAnnotation-Container") |
292 this.selector.find(".Ldt-createAnnotation-Container") |
334 .after(IriSP.templToHTML(IriSP.createAnnotation_errorMessage_template)); |
293 .after(IriSP.templToHTML(IriSP.createAnnotation_errorMessage_template)); |
335 textfield.css("background-color", "#d93c71"); |
294 textfield.css("background-color", "#d93c71"); |
405 annotation["type_title"] = "Contributions"; |
364 annotation["type_title"] = "Contributions"; |
406 annotation.content = {}; |
365 annotation.content = {}; |
407 annotation.content["data"] = contents; |
366 annotation.content["data"] = contents; |
408 |
367 |
409 var meta = apiJson["meta"]; |
368 var meta = apiJson["meta"]; |
410 if (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name)) |
369 |
411 meta.creator = IriSP.user.name; |
370 |
412 else |
371 var _username = this.selector.find(".Ldt-createAnnotation-userName").val(); |
413 meta.creator = "An User"; |
372 meta.creator = ( |
|
373 (_username && _username.length) |
|
374 ? _username |
|
375 : ( |
|
376 (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name)) |
|
377 ? IriSP.user.name |
|
378 : "Anonymous user" |
|
379 ) |
|
380 ); |
414 |
381 |
415 meta.created = Date().toString(); |
382 meta.created = Date().toString(); |
416 |
383 |
417 annotation["tags"] = []; |
384 // All #hashtags are added to tags |
418 |
385 annotation.tags = contents.match(/(#[\S]*)/g); |
419 for (var i = 0; i < this.keywords.length; i++) { |
|
420 var keyword = this.keywords[i]; |
|
421 if (contents.indexOf(keyword) != -1) |
|
422 annotation["tags"].push(keyword); |
|
423 } |
|
424 |
386 |
425 var jsonString = JSON.stringify(apiJson); |
387 var jsonString = JSON.stringify(apiJson); |
426 var project_id = this._serializer._data.meta.id; |
388 var project_id = this._serializer._data.meta.id; |
427 |
389 |
428 //TODO: extract magic url |
390 //TODO: extract magic url |
429 var url = Mustache.to_html(this.api_endpoint_template, |
391 var url = Mustache.to_html(this.api_endpoint_template, |
430 {id: project_id}); |
392 {id: project_id}); |
431 |
393 |
432 IriSP.jQuery.ajax({ |
394 IriSP.jQuery.ajax({ |
433 url: url, |
395 url: url, |
434 type: 'PUT', |
396 type: this.api_method, |
435 contentType: 'application/json', |
397 contentType: 'application/json', |
436 data: jsonString, |
398 data: jsonString, |
437 //dataType: 'json', |
399 //dataType: 'json', |
438 success: IriSP.wrap(this, function(json, textStatus, XMLHttpRequest) { |
400 success: IriSP.wrap(this, function(json, textStatus, XMLHttpRequest) { |
439 /* add the annotation to the annotation and tell the world */ |
401 /* add the annotation to the annotation and tell the world */ |