Commit 20e0d95087581895c6cce5083d713fce6af3a353
Rename files
- Rename imganno.js to img_swtr.js
- Rename swtmaker.js to main.js
- swtr/static/js/img_swtr.js 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- swtr/static/js/imganno.js 228 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- swtr/static/js/main.js 772 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- swtr/static/js/swtmaker.js 772 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- swtr/templates/index.html 4 --++
| | | | | | 1 | (function(swtr) { |
---|
| | 2 | swtr.ImgAnnoView = Backbone.View.extend({ |
---|
| | 3 | el: $("#img-annotation-wrapper"), |
---|
| | 4 | events: { |
---|
| | 5 | 'change #custom-dropdown ': 'getFormValue', |
---|
| | 6 | 'click #setbox': 'showHide' |
---|
| | 7 | }, |
---|
| | 8 | initialize: function(options) { |
---|
| | 9 | this.listenTo(this.collection, 'add', this.render); |
---|
| | 10 | // attach event handlers to the anno object |
---|
| | 11 | anno.addHandler('onAnnotationCreated', this.showSwtHelp); |
---|
| | 12 | anno.addHandler('onAnnotationCreated', this.updateNewAnno); |
---|
| | 13 | anno.addHandler('onAnnotationUpdated', this.showSwtHelp); |
---|
| | 14 | anno.addHandler('onSelectionStarted', function(annotation) { |
---|
| | 15 | anno.hideAnnotations(); |
---|
| | 16 | }); |
---|
| | 17 | anno.addHandler('onSelectionCompleted', function(annotation) { |
---|
| | 18 | anno.showAnnotations(); |
---|
| | 19 | }); |
---|
| | 20 | anno.addPlugin('CustomFields', {}); |
---|
| | 21 | anno.addHandler('onSelectionCompleted', this.hideOriginalEditor); |
---|
| | 22 | if(options.img) { |
---|
| | 23 | this.img = options.img; |
---|
| | 24 | this.$img = options.$img; |
---|
| | 25 | options.$img.on('load', this, this.imageLoaded); |
---|
| | 26 | options.$img.on('error', this, this.onImageLoadError); |
---|
| | 27 | this.setImage(options.url); |
---|
| | 28 | } |
---|
| | 29 | }, |
---|
| | 30 | render: function(model) { |
---|
| | 31 | var swt = model.toJSON(); |
---|
| | 32 | swt.how['editable'] = false; |
---|
| | 33 | swt.how.text = swtr.imgAnnoView.createPopupText(swt.how); |
---|
| | 34 | swt.how.text += '\n - by ' + swt.who; |
---|
| | 35 | anno.addAnnotation(swt.how); |
---|
| | 36 | }, |
---|
| | 37 | renderWith: function() { |
---|
| | 38 | _.each(this.collection, this.render); |
---|
| | 39 | }, |
---|
| | 40 | showSwtHelp: function(annotation) { |
---|
| | 41 | var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback |
---|
| | 42 | swtr.appView.helpview.step(3); |
---|
| | 43 | $('#sweet').show(); |
---|
| | 44 | }, |
---|
| | 45 | updateNewAnno: function(annotation) { |
---|
| | 46 | console.log('updateNewAnno()'); |
---|
| | 47 | var self = swtr.imgAnnoView; |
---|
| | 48 | // get the final value/input from the editor |
---|
| | 49 | var selected = $('select option:selected').text().toLowerCase(); |
---|
| | 50 | var text_input = $('.annotorious-editor-text').val(); |
---|
| | 51 | if( selected === "tags") { |
---|
| | 52 | self.new_anno[selected] = $('#tags-input').tags().getTags(); |
---|
| | 53 | } |
---|
| | 54 | else { |
---|
| | 55 | // update it in our annotation object |
---|
| | 56 | self.new_anno[selected] = text_input; |
---|
| | 57 | } |
---|
| | 58 | // prepare the text field |
---|
| | 59 | self.new_anno.text = self.createPopupText(self.new_anno); |
---|
| | 60 | // update the annotorious annotation object with the new values |
---|
| | 61 | if(self.new_anno.comment) { |
---|
| | 62 | annotation.comment = self.new_anno.comment; |
---|
| | 63 | } |
---|
| | 64 | if(self.new_anno.link) { |
---|
| | 65 | annotation.link = self.new_anno.link; |
---|
| | 66 | } |
---|
| | 67 | if(self.new_anno.tags) { |
---|
| | 68 | annotation.tags = self.new_anno.tags; |
---|
| | 69 | } |
---|
| | 70 | if(self.new_anno.title) { |
---|
| | 71 | annotation.title = self.new_anno.title; |
---|
| | 72 | } |
---|
| | 73 | annotation.text = self.new_anno.text; |
---|
| | 74 | console.log(self.new_anno, annotation); |
---|
| | 75 | }, |
---|
| | 76 | // hide the original editor window, when user has completed selecting part |
---|
| | 77 | // of the image to annotate.. |
---|
| | 78 | hideOriginalEditor: function(annotation) { |
---|
| | 79 | console.log('hideOriginalEditor()'); |
---|
| | 80 | var self = swtr.imgAnnoView; |
---|
| | 81 | self.new_anno = {}; |
---|
| | 82 | self.getSuggestionsForTags(); |
---|
| | 83 | //$('.annotorious-editor-text').hide(); |
---|
| | 84 | //$('.annotorious-editor').css('width', '100%'); |
---|
| | 85 | }, |
---|
| | 86 | getFormValue: function(event) { |
---|
| | 87 | console.log('getFormValue()'); |
---|
| | 88 | |
---|
| | 89 | var self = swtr.imgAnnoView; |
---|
| | 90 | // show the editor field to input text |
---|
| | 91 | var $anno_form = $('.annotorious-editor-text'); |
---|
| | 92 | //$anno_form.slideDown(); |
---|
| | 93 | // get the previous item entered |
---|
| | 94 | var $selected = $('select option:selected'); |
---|
| | 95 | var text_input = $anno_form.val(); |
---|
| | 96 | |
---|
| | 97 | // if there was a input and it was not tags.. |
---|
| | 98 | if(text_input && $selected.prev().text() !== 'Tags') { |
---|
| | 99 | var field = $selected.prev().text().toLowerCase(); |
---|
| | 100 | // update it in our annotation object |
---|
| | 101 | self.new_anno[field] = text_input; |
---|
| | 102 | } |
---|
| | 103 | // if it was tags.. |
---|
| | 104 | else if ($selected.prev().text() === 'Tags') { |
---|
| | 105 | // directly save it.. |
---|
| | 106 | self.new_anno['tags'] = $('#tags-input').tags().getTags(); |
---|
| | 107 | } |
---|
| | 108 | |
---|
| | 109 | // if the current selected is tags |
---|
| | 110 | if($selected.text() === 'Tags') { |
---|
| | 111 | $('#tags-input').tags({ |
---|
| | 112 | tagSize: 'md', |
---|
| | 113 | promptText: 'Type word (and press enter)..', |
---|
| | 114 | caseInsensitive: true, |
---|
| | 115 | suggestions: self.tags_suggestions |
---|
| | 116 | }); |
---|
| | 117 | $('#tags-input').show(); |
---|
| | 118 | $('.annotorious-editor-text').hide(); |
---|
| | 119 | } |
---|
| | 120 | else { |
---|
| | 121 | $('#tags-input').hide(); |
---|
| | 122 | $('.annotorious-editor-text').show(); |
---|
| | 123 | } |
---|
| | 124 | $anno_form.val(''); |
---|
| | 125 | $anno_form.attr('placeholder', 'Add ' + $selected.text()); |
---|
| | 126 | console.log(self.new_anno); |
---|
| | 127 | }, |
---|
| | 128 | createPopupText: function(annotation) { |
---|
| | 129 | // title |
---|
| | 130 | var text = (annotation.title) ? '<h4>' + annotation.title + '</h4>' : ''; |
---|
| | 131 | |
---|
| | 132 | // comment |
---|
| | 133 | text += (annotation.comment) ? '<p>' + annotation.comment + '</p>' : ''; |
---|
| | 134 | |
---|
| | 135 | // link |
---|
| | 136 | text += (annotation.link) ? '<a target="blank" href="' + |
---|
| | 137 | swtr.utils.linkify(annotation.link) + '">' + annotation.link + |
---|
| | 138 | '</a>' : ''; |
---|
| | 139 | |
---|
| | 140 | // tags |
---|
| | 141 | text += (annotation.tags) ? '<p>' + annotation.tags + '</p>' : ''; |
---|
| | 142 | |
---|
| | 143 | // if older annotation i.e w/o comment,title etc fields |
---|
| | 144 | // add text field as text |
---|
| | 145 | if(!text) { |
---|
| | 146 | text = annotation.text; |
---|
| | 147 | } |
---|
| | 148 | return text; |
---|
| | 149 | }, |
---|
| | 150 | // load the suggestions for the tag spraying.. |
---|
| | 151 | getSuggestionsForTags: function() { |
---|
| | 152 | var self = swtr.imgAnnoView; |
---|
| | 153 | $.ajax({ |
---|
| | 154 | url: '/static/data/tags_suggestions.json', |
---|
| | 155 | success: function(data) { |
---|
| | 156 | self.tags_suggestions = data; |
---|
| | 157 | } |
---|
| | 158 | }); |
---|
| | 159 | }, |
---|
| | 160 | setImage: function(url) { |
---|
| | 161 | this.imgURL = url; |
---|
| | 162 | console.log(url); |
---|
| | 163 | if(this.$img.attr('src') === this.imgURL) { |
---|
| | 164 | return; |
---|
| | 165 | } |
---|
| | 166 | anno.reset(); |
---|
| | 167 | var self = this; |
---|
| | 168 | swtr.appView.$overlay.show(); |
---|
| | 169 | swtr.appView.helpview.step(7); |
---|
| | 170 | this.$img.attr('src', this.imgURL); |
---|
| | 171 | }, |
---|
| | 172 | imageLoaded: function(event) { |
---|
| | 173 | var self = event.data; |
---|
| | 174 | console.log('image loaded', self); |
---|
| | 175 | swtr.appView.$overlay.hide(); |
---|
| | 176 | // reset the collection |
---|
| | 177 | swtr.sweets.reset(); |
---|
| | 178 | anno.makeAnnotatable(swtr.imgAnnoView.img); |
---|
| | 179 | swtr.imgAnnoView.getExistingAnnotations(); |
---|
| | 180 | }, |
---|
| | 181 | // when image fails to load - could be because of broken URL or network |
---|
| | 182 | // issues |
---|
| | 183 | onImageLoadError: function(event) { |
---|
| | 184 | var self = event.data; |
---|
| | 185 | console.log('error while loading image'); |
---|
| | 186 | swtr.appView.$overlay.hide(); |
---|
| | 187 | swtr.appView.helpview.step(8); |
---|
| | 188 | }, |
---|
| | 189 | initImageAnno: function() { |
---|
| | 190 | // img is a jquery object which annotorious doesn't accept; instead it |
---|
| | 191 | // takes the native object returned by a browser API; fortunately, jqeury |
---|
| | 192 | // stores a copy of the native object too! |
---|
| | 193 | |
---|
| | 194 | this.getExistingAnnotations(); |
---|
| | 195 | |
---|
| | 196 | }, |
---|
| | 197 | getExistingAnnotations: function() { |
---|
| | 198 | var self = this; |
---|
| | 199 | swtr.appView.helpview.step(0); |
---|
| | 200 | swtr.appView.$overlay.show(); |
---|
| | 201 | swtr.sweets.getAll({ |
---|
| | 202 | where: this.imgURL, |
---|
| | 203 | success: function(data) { |
---|
| | 204 | if(_.isArray(data)) { |
---|
| | 205 | swtr.sweets.add(data); |
---|
| | 206 | swtr.appView.$overlay.hide(); |
---|
| | 207 | swtr.appView.helpview.step(2); |
---|
| | 208 | } |
---|
| | 209 | }, |
---|
| | 210 | error: function(jqxhr, error, statusText) { |
---|
| | 211 | if(jqxhr.status === 404) { //annotations don't exist for this image |
---|
| | 212 | console.log('annotations don\'t exist for this image. Create one!'); |
---|
| | 213 | } |
---|
| | 214 | swtr.appView.$overlay.hide(); |
---|
| | 215 | swtr.appView.helpview.step(2); |
---|
| | 216 | } |
---|
| | 217 | }); |
---|
| | 218 | }, |
---|
| | 219 | showHide: function() { |
---|
| | 220 | if($("#setbox:checked").length) { |
---|
| | 221 | $('.annotorious-item-unfocus').css("opacity", "0.5"); |
---|
| | 222 | } |
---|
| | 223 | else { |
---|
| | 224 | $('.annotorious-item-unfocus').css("opacity", "0"); |
---|
| | 225 | } |
---|
| | 226 | } |
---|
| | 227 | }); |
---|
| | 228 | })(swtr); |
---|
| | | | 1 | (function(swtr) { | | (function(swtr) { |
---|
2 | swtr.ImgAnnoView = Backbone.View.extend({ | | swtr.ImgAnnoView = Backbone.View.extend({ |
---|
3 | el: $("#img-annotation-wrapper"), | | el: $("#img-annotation-wrapper"), |
---|
4 | events: { | | events: { |
---|
5 | 'change #custom-dropdown ': 'getFormValue', | | 'change #custom-dropdown ': 'getFormValue', |
---|
6 | 'click #setbox': 'showHide' | | 'click #setbox': 'showHide' |
---|
7 | }, | | }, |
---|
8 | initialize: function(options) { | | initialize: function(options) { |
---|
9 | this.listenTo(this.collection, 'add', this.render); | | this.listenTo(this.collection, 'add', this.render); |
---|
10 | // attach event handlers to the anno object | | // attach event handlers to the anno object |
---|
11 | anno.addHandler('onAnnotationCreated', this.showSwtHelp); | | anno.addHandler('onAnnotationCreated', this.showSwtHelp); |
---|
12 | anno.addHandler('onAnnotationCreated', this.updateNewAnno); | | anno.addHandler('onAnnotationCreated', this.updateNewAnno); |
---|
13 | anno.addHandler('onAnnotationUpdated', this.showSwtHelp); | | anno.addHandler('onAnnotationUpdated', this.showSwtHelp); |
---|
14 | anno.addHandler('onSelectionStarted', function(annotation) { | | anno.addHandler('onSelectionStarted', function(annotation) { |
---|
15 | anno.hideAnnotations(); | | anno.hideAnnotations(); |
---|
16 | }); | | }); |
---|
17 | anno.addHandler('onSelectionCompleted', function(annotation) { | | anno.addHandler('onSelectionCompleted', function(annotation) { |
---|
18 | anno.showAnnotations(); | | anno.showAnnotations(); |
---|
19 | }); | | }); |
---|
20 | anno.addPlugin('CustomFields', {}); | | anno.addPlugin('CustomFields', {}); |
---|
21 | anno.addHandler('onSelectionCompleted', this.hideOriginalEditor); | | anno.addHandler('onSelectionCompleted', this.hideOriginalEditor); |
---|
22 | if(options.img) { | | if(options.img) { |
---|
23 | this.img = options.img; | | this.img = options.img; |
---|
24 | this.$img = options.$img; | | this.$img = options.$img; |
---|
25 | options.$img.on('load', this, this.imageLoaded); | | options.$img.on('load', this, this.imageLoaded); |
---|
26 | options.$img.on('error', this, this.onImageLoadError); | | options.$img.on('error', this, this.onImageLoadError); |
---|
27 | this.setImage(options.url); | | this.setImage(options.url); |
---|
28 | } | | } |
---|
29 | }, | | }, |
---|
30 | render: function(model) { | | render: function(model) { |
---|
31 | var swt = model.toJSON(); | | var swt = model.toJSON(); |
---|
32 | swt.how['editable'] = false; | | swt.how['editable'] = false; |
---|
33 | swt.how.text = swtr.imgAnnoView.createPopupText(swt.how); | | swt.how.text = swtr.imgAnnoView.createPopupText(swt.how); |
---|
34 | swt.how.text += '\n - by ' + swt.who; | | swt.how.text += '\n - by ' + swt.who; |
---|
35 | anno.addAnnotation(swt.how); | | anno.addAnnotation(swt.how); |
---|
36 | }, | | }, |
---|
37 | renderWith: function() { | | renderWith: function() { |
---|
38 | _.each(this.collection, this.render); | | _.each(this.collection, this.render); |
---|
39 | }, | | }, |
---|
40 | showSwtHelp: function(annotation) { | | showSwtHelp: function(annotation) { |
---|
41 | var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback | | var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback |
---|
42 | swtr.appView.helpview.step(3); | | swtr.appView.helpview.step(3); |
---|
43 | $('#sweet').show(); | | $('#sweet').show(); |
---|
44 | }, | | }, |
---|
45 | updateNewAnno: function(annotation) { | | updateNewAnno: function(annotation) { |
---|
46 | console.log('updateNewAnno()'); | | console.log('updateNewAnno()'); |
---|
47 | var self = swtr.imgAnnoView; | | var self = swtr.imgAnnoView; |
---|
48 | // get the final value/input from the editor | | // get the final value/input from the editor |
---|
49 | var selected = $('select option:selected').text().toLowerCase(); | | var selected = $('select option:selected').text().toLowerCase(); |
---|
50 | var text_input = $('.annotorious-editor-text').val(); | | var text_input = $('.annotorious-editor-text').val(); |
---|
51 | if( selected === "tags") { | | if( selected === "tags") { |
---|
52 | self.new_anno[selected] = $('#tags-input').tags().getTags(); | | self.new_anno[selected] = $('#tags-input').tags().getTags(); |
---|
53 | } | | } |
---|
54 | else { | | else { |
---|
55 | // update it in our annotation object | | // update it in our annotation object |
---|
56 | self.new_anno[selected] = text_input; | | self.new_anno[selected] = text_input; |
---|
57 | } | | } |
---|
58 | // prepare the text field | | // prepare the text field |
---|
59 | self.new_anno.text = self.createPopupText(self.new_anno); | | self.new_anno.text = self.createPopupText(self.new_anno); |
---|
60 | // update the annotorious annotation object with the new values | | // update the annotorious annotation object with the new values |
---|
61 | if(self.new_anno.comment) { | | if(self.new_anno.comment) { |
---|
62 | annotation.comment = self.new_anno.comment; | | annotation.comment = self.new_anno.comment; |
---|
63 | } | | } |
---|
64 | if(self.new_anno.link) { | | if(self.new_anno.link) { |
---|
65 | annotation.link = self.new_anno.link; | | annotation.link = self.new_anno.link; |
---|
66 | } | | } |
---|
67 | if(self.new_anno.tags) { | | if(self.new_anno.tags) { |
---|
68 | annotation.tags = self.new_anno.tags; | | annotation.tags = self.new_anno.tags; |
---|
69 | } | | } |
---|
70 | if(self.new_anno.title) { | | if(self.new_anno.title) { |
---|
71 | annotation.title = self.new_anno.title; | | annotation.title = self.new_anno.title; |
---|
72 | } | | } |
---|
73 | annotation.text = self.new_anno.text; | | annotation.text = self.new_anno.text; |
---|
74 | console.log(self.new_anno, annotation); | | console.log(self.new_anno, annotation); |
---|
75 | }, | | }, |
---|
76 | // hide the original editor window, when user has completed selecting part | | // hide the original editor window, when user has completed selecting part |
---|
77 | // of the image to annotate.. | | // of the image to annotate.. |
---|
78 | hideOriginalEditor: function(annotation) { | | hideOriginalEditor: function(annotation) { |
---|
79 | console.log('hideOriginalEditor()'); | | console.log('hideOriginalEditor()'); |
---|
80 | var self = swtr.imgAnnoView; | | var self = swtr.imgAnnoView; |
---|
81 | self.new_anno = {}; | | self.new_anno = {}; |
---|
82 | self.getSuggestionsForTags(); | | self.getSuggestionsForTags(); |
---|
83 | //$('.annotorious-editor-text').hide(); | | //$('.annotorious-editor-text').hide(); |
---|
84 | //$('.annotorious-editor').css('width', '100%'); | | //$('.annotorious-editor').css('width', '100%'); |
---|
85 | }, | | }, |
---|
86 | getFormValue: function(event) { | | getFormValue: function(event) { |
---|
87 | console.log('getFormValue()'); | | console.log('getFormValue()'); |
---|
88 | | | |
---|
89 | var self = swtr.imgAnnoView; | | var self = swtr.imgAnnoView; |
---|
90 | // show the editor field to input text | | // show the editor field to input text |
---|
91 | var $anno_form = $('.annotorious-editor-text'); | | var $anno_form = $('.annotorious-editor-text'); |
---|
92 | //$anno_form.slideDown(); | | //$anno_form.slideDown(); |
---|
93 | // get the previous item entered | | // get the previous item entered |
---|
94 | var $selected = $('select option:selected'); | | var $selected = $('select option:selected'); |
---|
95 | var text_input = $anno_form.val(); | | var text_input = $anno_form.val(); |
---|
96 | | | |
---|
97 | // if there was a input and it was not tags.. | | // if there was a input and it was not tags.. |
---|
98 | if(text_input && $selected.prev().text() !== 'Tags') { | | if(text_input && $selected.prev().text() !== 'Tags') { |
---|
99 | var field = $selected.prev().text().toLowerCase(); | | var field = $selected.prev().text().toLowerCase(); |
---|
100 | // update it in our annotation object | | // update it in our annotation object |
---|
101 | self.new_anno[field] = text_input; | | self.new_anno[field] = text_input; |
---|
102 | } | | } |
---|
103 | // if it was tags.. | | // if it was tags.. |
---|
104 | else if ($selected.prev().text() === 'Tags') { | | else if ($selected.prev().text() === 'Tags') { |
---|
105 | // directly save it.. | | // directly save it.. |
---|
106 | self.new_anno['tags'] = $('#tags-input').tags().getTags(); | | self.new_anno['tags'] = $('#tags-input').tags().getTags(); |
---|
107 | } | | } |
---|
108 | | | |
---|
109 | // if the current selected is tags | | // if the current selected is tags |
---|
110 | if($selected.text() === 'Tags') { | | if($selected.text() === 'Tags') { |
---|
111 | $('#tags-input').tags({ | | $('#tags-input').tags({ |
---|
112 | tagSize: 'md', | | tagSize: 'md', |
---|
113 | promptText: 'Type word (and press enter)..', | | promptText: 'Type word (and press enter)..', |
---|
114 | caseInsensitive: true, | | caseInsensitive: true, |
---|
115 | suggestions: self.tags_suggestions | | suggestions: self.tags_suggestions |
---|
116 | }); | | }); |
---|
117 | $('#tags-input').show(); | | $('#tags-input').show(); |
---|
118 | $('.annotorious-editor-text').hide(); | | $('.annotorious-editor-text').hide(); |
---|
119 | } | | } |
---|
120 | else { | | else { |
---|
121 | $('#tags-input').hide(); | | $('#tags-input').hide(); |
---|
122 | $('.annotorious-editor-text').show(); | | $('.annotorious-editor-text').show(); |
---|
123 | } | | } |
---|
124 | $anno_form.val(''); | | $anno_form.val(''); |
---|
125 | $anno_form.attr('placeholder', 'Add ' + $selected.text()); | | $anno_form.attr('placeholder', 'Add ' + $selected.text()); |
---|
126 | console.log(self.new_anno); | | console.log(self.new_anno); |
---|
127 | }, | | }, |
---|
128 | createPopupText: function(annotation) { | | createPopupText: function(annotation) { |
---|
129 | // title | | // title |
---|
130 | var text = (annotation.title) ? '<h4>' + annotation.title + '</h4>' : ''; | | var text = (annotation.title) ? '<h4>' + annotation.title + '</h4>' : ''; |
---|
131 | | | |
---|
132 | // comment | | // comment |
---|
133 | text += (annotation.comment) ? '<p>' + annotation.comment + '</p>' : ''; | | text += (annotation.comment) ? '<p>' + annotation.comment + '</p>' : ''; |
---|
134 | | | |
---|
135 | // link | | // link |
---|
136 | text += (annotation.link) ? '<a target="blank" href="' + | | text += (annotation.link) ? '<a target="blank" href="' + |
---|
137 | swtr.utils.linkify(annotation.link) + '">' + annotation.link + | | swtr.utils.linkify(annotation.link) + '">' + annotation.link + |
---|
138 | '</a>' : ''; | | '</a>' : ''; |
---|
139 | | | |
---|
140 | // tags | | // tags |
---|
141 | text += (annotation.tags) ? '<p>' + annotation.tags + '</p>' : ''; | | text += (annotation.tags) ? '<p>' + annotation.tags + '</p>' : ''; |
---|
142 | | | |
---|
143 | // if older annotation i.e w/o comment,title etc fields | | // if older annotation i.e w/o comment,title etc fields |
---|
144 | // add text field as text | | // add text field as text |
---|
145 | if(!text) { | | if(!text) { |
---|
146 | text = annotation.text; | | text = annotation.text; |
---|
147 | } | | } |
---|
148 | return text; | | return text; |
---|
149 | }, | | }, |
---|
150 | // load the suggestions for the tag spraying.. | | // load the suggestions for the tag spraying.. |
---|
151 | getSuggestionsForTags: function() { | | getSuggestionsForTags: function() { |
---|
152 | var self = swtr.imgAnnoView; | | var self = swtr.imgAnnoView; |
---|
153 | $.ajax({ | | $.ajax({ |
---|
154 | url: '/static/data/tags_suggestions.json', | | url: '/static/data/tags_suggestions.json', |
---|
155 | success: function(data) { | | success: function(data) { |
---|
156 | self.tags_suggestions = data; | | self.tags_suggestions = data; |
---|
157 | } | | } |
---|
158 | }); | | }); |
---|
159 | }, | | }, |
---|
160 | setImage: function(url) { | | setImage: function(url) { |
---|
161 | this.imgURL = url; | | this.imgURL = url; |
---|
162 | console.log(url); | | console.log(url); |
---|
163 | if(this.$img.attr('src') === this.imgURL) { | | if(this.$img.attr('src') === this.imgURL) { |
---|
164 | return; | | return; |
---|
165 | } | | } |
---|
166 | anno.reset(); | | anno.reset(); |
---|
167 | var self = this; | | var self = this; |
---|
168 | swtr.appView.$overlay.show(); | | swtr.appView.$overlay.show(); |
---|
169 | swtr.appView.helpview.step(7); | | swtr.appView.helpview.step(7); |
---|
170 | this.$img.attr('src', this.imgURL); | | this.$img.attr('src', this.imgURL); |
---|
171 | }, | | }, |
---|
172 | imageLoaded: function(event) { | | imageLoaded: function(event) { |
---|
173 | var self = event.data; | | var self = event.data; |
---|
174 | console.log('image loaded', self); | | console.log('image loaded', self); |
---|
175 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
176 | // reset the collection | | // reset the collection |
---|
177 | swtr.sweets.reset(); | | swtr.sweets.reset(); |
---|
178 | anno.makeAnnotatable(swtr.imgAnnoView.img); | | anno.makeAnnotatable(swtr.imgAnnoView.img); |
---|
179 | swtr.imgAnnoView.getExistingAnnotations(); | | swtr.imgAnnoView.getExistingAnnotations(); |
---|
180 | }, | | }, |
---|
181 | // when image fails to load - could be because of broken URL or network | | // when image fails to load - could be because of broken URL or network |
---|
182 | // issues | | // issues |
---|
183 | onImageLoadError: function(event) { | | onImageLoadError: function(event) { |
---|
184 | var self = event.data; | | var self = event.data; |
---|
185 | console.log('error while loading image'); | | console.log('error while loading image'); |
---|
186 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
187 | swtr.appView.helpview.step(8); | | swtr.appView.helpview.step(8); |
---|
188 | }, | | }, |
---|
189 | initImageAnno: function() { | | initImageAnno: function() { |
---|
190 | // img is a jquery object which annotorious doesn't accept; instead it | | // img is a jquery object which annotorious doesn't accept; instead it |
---|
191 | // takes the native object returned by a browser API; fortunately, jqeury | | // takes the native object returned by a browser API; fortunately, jqeury |
---|
192 | // stores a copy of the native object too! | | // stores a copy of the native object too! |
---|
193 | | | |
---|
194 | this.getExistingAnnotations(); | | this.getExistingAnnotations(); |
---|
195 | | | |
---|
196 | }, | | }, |
---|
197 | getExistingAnnotations: function() { | | getExistingAnnotations: function() { |
---|
198 | var self = this; | | var self = this; |
---|
199 | swtr.appView.helpview.step(0); | | swtr.appView.helpview.step(0); |
---|
200 | swtr.appView.$overlay.show(); | | swtr.appView.$overlay.show(); |
---|
201 | swtr.sweets.getAll({ | | swtr.sweets.getAll({ |
---|
202 | where: this.imgURL, | | where: this.imgURL, |
---|
203 | success: function(data) { | | success: function(data) { |
---|
204 | if(_.isArray(data)) { | | if(_.isArray(data)) { |
---|
205 | swtr.sweets.add(data); | | swtr.sweets.add(data); |
---|
206 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
207 | swtr.appView.helpview.step(2); | | swtr.appView.helpview.step(2); |
---|
208 | } | | } |
---|
209 | }, | | }, |
---|
210 | error: function(jqxhr, error, statusText) { | | error: function(jqxhr, error, statusText) { |
---|
211 | if(jqxhr.status === 404) { //annotations don't exist for this image | | if(jqxhr.status === 404) { //annotations don't exist for this image |
---|
212 | console.log('annotations don\'t exist for this image. Create one!'); | | console.log('annotations don\'t exist for this image. Create one!'); |
---|
213 | } | | } |
---|
214 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
215 | swtr.appView.helpview.step(2); | | swtr.appView.helpview.step(2); |
---|
216 | } | | } |
---|
217 | }); | | }); |
---|
218 | }, | | }, |
---|
219 | showHide: function() { | | showHide: function() { |
---|
220 | if($("#setbox:checked").length) { | | if($("#setbox:checked").length) { |
---|
221 | $('.annotorious-item-unfocus').css("opacity", "0.5"); | | $('.annotorious-item-unfocus').css("opacity", "0.5"); |
---|
222 | } | | } |
---|
223 | else { | | else { |
---|
224 | $('.annotorious-item-unfocus').css("opacity", "0"); | | $('.annotorious-item-unfocus').css("opacity", "0"); |
---|
225 | } | | } |
---|
226 | } | | } |
---|
227 | }); | | }); |
---|
228 | })(swtr); | | })(swtr); |
---|
| | | | | | 1 | (function(swtr) { |
---|
| | 2 | |
---|
| | 3 | //TODO: find a better way to init. |
---|
| | 4 | //Find a better way to do closure |
---|
| | 5 | //Remove script code from the HTML page |
---|
| | 6 | swtr.init = function() { |
---|
| | 7 | this.sweets = new ImgAnnoSwts(); |
---|
| | 8 | this.appView = new AppView(); |
---|
| | 9 | this.who = 'Guest'; |
---|
| | 10 | |
---|
| | 11 | this.app_router = new AppRouter(); |
---|
| | 12 | Backbone.history.start(); |
---|
| | 13 | this.app_router.navigate('home'); |
---|
| | 14 | |
---|
| | 15 | $.ajaxSetup({ |
---|
| | 16 | xhrFields: { |
---|
| | 17 | // we need this to send cookies to cross-domain requests |
---|
| | 18 | withCredentials: true |
---|
| | 19 | }, |
---|
| | 20 | //some browsers won't make cross-domain ajax until it is explicitly set |
---|
| | 21 | crossDomain: true |
---|
| | 22 | }); |
---|
| | 23 | this.handleOAuth(); |
---|
| | 24 | }; |
---|
| | 25 | |
---|
| | 26 | swtr.handleOAuth = function() { |
---|
| | 27 | if(swtr.access_token) { |
---|
| | 28 | $('#signinview').html('Signing you in..'); |
---|
| | 29 | $.ajax({ |
---|
| | 30 | url: swtr.swtstoreURL()+'/api/users/me?access_token='+ |
---|
| | 31 | swtr.access_token, |
---|
| | 32 | success: function(data) { |
---|
| | 33 | swtr.appView.userLoggedIn(data.username); |
---|
| | 34 | }, |
---|
| | 35 | error: function() { |
---|
| | 36 | $('#signinview').html('Error signing in! Please try again'); |
---|
| | 37 | } |
---|
| | 38 | }); |
---|
| | 39 | } |
---|
| | 40 | }; |
---|
| | 41 | |
---|
| | 42 | /* Model for Image Annotation Sweets */ |
---|
| | 43 | var ImgAnnoSwt = Backbone.Model.extend({ |
---|
| | 44 | defaults: { |
---|
| | 45 | 'who': '', |
---|
| | 46 | 'what': 'img-anno', |
---|
| | 47 | 'where': '', |
---|
| | 48 | 'how': {} |
---|
| | 49 | }, |
---|
| | 50 | initialize: function() { |
---|
| | 51 | } |
---|
| | 52 | }); |
---|
| | 53 | |
---|
| | 54 | /* Collection to hold all multiple ImgAnnoSwt */ |
---|
| | 55 | var ImgAnnoSwts = Backbone.Collection.extend({ |
---|
| | 56 | model: ImgAnnoSwt, |
---|
| | 57 | url: function() { |
---|
| | 58 | return swtr.swtstoreURL() + '/sweets'; |
---|
| | 59 | }, |
---|
| | 60 | // get all sweets/annotations of type #img-anno for a particular URI |
---|
| | 61 | // (where) |
---|
| | 62 | // @options is a javascript object, |
---|
| | 63 | // @options.where : URI of the resource for which swts to be fetched |
---|
| | 64 | // @options.who: optional username to filter sweets |
---|
| | 65 | // @options.success: success callback to call |
---|
| | 66 | // @options.error: error callback to call |
---|
| | 67 | getAll: function(options) { |
---|
| | 68 | // error checking |
---|
| | 69 | if(!options.where) { |
---|
| | 70 | throw Error('"where" option must be passed to get sweets of a URI'); |
---|
| | 71 | return false; |
---|
| | 72 | } |
---|
| | 73 | // setting up params |
---|
| | 74 | var where = options.where, |
---|
| | 75 | who = options.who || null; |
---|
| | 76 | url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' + |
---|
| | 77 | encodeURIComponent(where) + '&access_token=' + swtr.access_token; |
---|
| | 78 | if(who) { |
---|
| | 79 | url += '&who=' + who; |
---|
| | 80 | } |
---|
| | 81 | // get them! |
---|
| | 82 | this.sync('read', this, { |
---|
| | 83 | url: url, |
---|
| | 84 | success: function() { |
---|
| | 85 | if(typeof options.success === 'function') { |
---|
| | 86 | options.success.apply(this, arguments); |
---|
| | 87 | } |
---|
| | 88 | }, |
---|
| | 89 | error: function() { |
---|
| | 90 | if(typeof options.error === 'function') { |
---|
| | 91 | options.error.apply(this, arguments); |
---|
| | 92 | } |
---|
| | 93 | } |
---|
| | 94 | }); |
---|
| | 95 | }, |
---|
| | 96 | // post newly created sweets to a sweet store |
---|
| | 97 | // @options is a javascript object, |
---|
| | 98 | // @options.where : URI of the resource for which swts to be fetched |
---|
| | 99 | // @options.who: optional username to filter sweets |
---|
| | 100 | // @options.success: success callback to call |
---|
| | 101 | // @options.error: error callback to call, |
---|
| | 102 | post: function(options) { |
---|
| | 103 | var new_sweets = this.getNew(); |
---|
| | 104 | var dummy_collection = new Backbone.Collection(new_sweets); |
---|
| | 105 | |
---|
| | 106 | if(!swtr.access_token) { |
---|
| | 107 | throw new Error('Access Token is required to sweet'); |
---|
| | 108 | return; |
---|
| | 109 | } |
---|
| | 110 | |
---|
| | 111 | var url = swtr.swtstoreURL() + swtr.endpoints.post + |
---|
| | 112 | '?access_token=' + swtr.access_token; |
---|
| | 113 | |
---|
| | 114 | this.sync('create', dummy_collection, { |
---|
| | 115 | url: url, |
---|
| | 116 | success: function() { |
---|
| | 117 | if(typeof options.success === 'function') { |
---|
| | 118 | options.success.apply(this, arguments); |
---|
| | 119 | } |
---|
| | 120 | }, |
---|
| | 121 | error: function() { |
---|
| | 122 | if(typeof options.error === 'function') { |
---|
| | 123 | options.error.apply(this, arguments); |
---|
| | 124 | } |
---|
| | 125 | } |
---|
| | 126 | }); |
---|
| | 127 | }, |
---|
| | 128 | // return newly created models from the collection |
---|
| | 129 | getNew: function() { |
---|
| | 130 | var new_models = []; |
---|
| | 131 | this.each(function(model) { |
---|
| | 132 | if(model.isNew()) { |
---|
| | 133 | new_models.push(model); |
---|
| | 134 | } |
---|
| | 135 | }); |
---|
| | 136 | return new_models; |
---|
| | 137 | }, |
---|
| | 138 | // update part of the collection after a save on the server |
---|
| | 139 | update: function() { |
---|
| | 140 | } |
---|
| | 141 | }); |
---|
| | 142 | |
---|
| | 143 | var SweetsView = Backbone.View.extend({ |
---|
| | 144 | el: $('#sweet-list-wrapper'), |
---|
| | 145 | events: { |
---|
| | 146 | 'click #sweet-cancel': 'cancelSweeting', |
---|
| | 147 | 'click #post-sweet': 'postSweets' |
---|
| | 148 | }, |
---|
| | 149 | initialize: function() { |
---|
| | 150 | this.template = _.template($('#sweet-template').html()); |
---|
| | 151 | }, |
---|
| | 152 | render: function() { |
---|
| | 153 | $('#sweet-list').html('<h4>These are your sweet annotations!</h4>'); |
---|
| | 154 | _.each(this.collection.models, function(swt) { |
---|
| | 155 | if(swt.has('id')) { |
---|
| | 156 | return false; |
---|
| | 157 | } |
---|
| | 158 | $('#sweet-list').append(this.template({ |
---|
| | 159 | who: swt.get('who'), |
---|
| | 160 | what: swt.get('what'), |
---|
| | 161 | where: swt.get('where'), |
---|
| | 162 | how: JSON.stringify(this.getHumanReadableParts(swt.get('how'))) |
---|
| | 163 | })); |
---|
| | 164 | }, this); |
---|
| | 165 | $(this.el).fadeIn(300); |
---|
| | 166 | }, |
---|
| | 167 | getHumanReadableParts: function(how) { |
---|
| | 168 | var human_readable_json = {}; |
---|
| | 169 | if(how.comment) { |
---|
| | 170 | human_readable_json['comment'] = how.comment; |
---|
| | 171 | } |
---|
| | 172 | if(how.title) { |
---|
| | 173 | human_readable_json['title'] = how.title; |
---|
| | 174 | } |
---|
| | 175 | if(how.tags) { |
---|
| | 176 | human_readable_json['tags'] = how.tags; |
---|
| | 177 | } |
---|
| | 178 | if(how.link) { |
---|
| | 179 | human_readable_json['link'] = how.link; |
---|
| | 180 | } |
---|
| | 181 | return human_readable_json; |
---|
| | 182 | }, |
---|
| | 183 | cancelSweeting: function() { |
---|
| | 184 | this.removeSwtsNotPosted(); |
---|
| | 185 | this.cleanUp(); |
---|
| | 186 | }, |
---|
| | 187 | removeSwtsNotPosted: function() { |
---|
| | 188 | var notPosted = this.collection.filter(function(model) { |
---|
| | 189 | return !model.has('id'); |
---|
| | 190 | }); |
---|
| | 191 | this.collection.remove(notPosted); |
---|
| | 192 | }, |
---|
| | 193 | postSweets: function() { |
---|
| | 194 | console.log("postSWr"); |
---|
| | 195 | var appView = swtr.appView; |
---|
| | 196 | appView.helpview.step(5); |
---|
| | 197 | appView.$overlay.show(); |
---|
| | 198 | try { |
---|
| | 199 | this.collection.post({ |
---|
| | 200 | success: function(collection, response) { |
---|
| | 201 | console.log(collection, response); |
---|
| | 202 | swtr.sweets.set(collection); |
---|
| | 203 | //TODO: move this to a annotation view or something |
---|
| | 204 | // anno.removeAll(); |
---|
| | 205 | // _.each(swtr.sweets.models, function(swt) { |
---|
| | 206 | // if(!_.has(swt.get('how'), 'editable')) { |
---|
| | 207 | // swt.get('how')['editable'] = false; |
---|
| | 208 | // //console.log(swt.get('how').text.Comment); |
---|
| | 209 | // swt.get('how').text = swtr.imgAnnoView.createPopupText(swt.get('how')); |
---|
| | 210 | // //console.log(swt.get('how')); |
---|
| | 211 | // swt.get('how').text += '\n - by ' + swt.get('who'); |
---|
| | 212 | // } |
---|
| | 213 | // //console.log(swt.get('how')); |
---|
| | 214 | // anno.addAnnotation(swt.get('how')); |
---|
| | 215 | // }); |
---|
| | 216 | //console.log(swtr.sweets.toJSON()); |
---|
| | 217 | swtr.appView.$overlay.hide(); |
---|
| | 218 | swtr.appView.helpview.step(6); |
---|
| | 219 | }, |
---|
| | 220 | error: function(jqxhr, error, text) { |
---|
| | 221 | console.log(jqxhr, error, text); |
---|
| | 222 | swtr.appView.$overlay.hide(); |
---|
| | 223 | swtr.appView.helpview.step(10); |
---|
| | 224 | } |
---|
| | 225 | }); |
---|
| | 226 | } catch(e) { |
---|
| | 227 | if(e.message == 'Access Token is required to sweet') { |
---|
| | 228 | appView.$overlay.hide(); |
---|
| | 229 | appView.helpview.step(9); |
---|
| | 230 | } |
---|
| | 231 | } |
---|
| | 232 | this.cleanUp(); |
---|
| | 233 | return false; |
---|
| | 234 | }, |
---|
| | 235 | cleanUp: function() { |
---|
| | 236 | //console.log('cleaning up'); |
---|
| | 237 | $(this.el).hide(); |
---|
| | 238 | } |
---|
| | 239 | }); |
---|
| | 240 | |
---|
| | 241 | var FilterView = Backbone.View.extend({ |
---|
| | 242 | el: $('#filter-div'), |
---|
| | 243 | events: { |
---|
| | 244 | 'click #filter-user-div input': 'filter', |
---|
| | 245 | 'click #filter-tags-div input': 'filter' |
---|
| | 246 | }, |
---|
| | 247 | initialize: function() { |
---|
| | 248 | this.filter_users_template = _.template($('#filter-users').html()); |
---|
| | 249 | this.filter_tags_template = _.template($('#filter-tags').html()); |
---|
| | 250 | this.render(); |
---|
| | 251 | }, |
---|
| | 252 | render: function() { |
---|
| | 253 | //console.log(this.collection); |
---|
| | 254 | // pluck uniq authors of sweets |
---|
| | 255 | var authors = _.uniq(this.collection.pluck('who')); |
---|
| | 256 | // render them as filter controls |
---|
| | 257 | _.each(authors, function(author) { |
---|
| | 258 | $('#filter-user-div').append(this.filter_users_template({ |
---|
| | 259 | who: author |
---|
| | 260 | })); |
---|
| | 261 | }, this); |
---|
| | 262 | |
---|
| | 263 | // pluck uniq tags of sweets |
---|
| | 264 | var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). |
---|
| | 265 | uniq().value(); |
---|
| | 266 | // render them as filter controls |
---|
| | 267 | _.each(tags, function(tag) { |
---|
| | 268 | if(tag) { |
---|
| | 269 | $('#filter-tags-div').append(this.filter_tags_template({ |
---|
| | 270 | tag: tag |
---|
| | 271 | })); |
---|
| | 272 | } |
---|
| | 273 | }, this); |
---|
| | 274 | |
---|
| | 275 | //this.delegateEvents(); |
---|
| | 276 | }, |
---|
| | 277 | filter: function(event) { |
---|
| | 278 | // get id of div - parent to parent to the clicked input |
---|
| | 279 | var target_id = $(event.currentTarget).parent().parent().attr('id'); |
---|
| | 280 | // find out user/tag div |
---|
| | 281 | var which = target_id.split('-')[1]; |
---|
| | 282 | |
---|
| | 283 | var selected = []; |
---|
| | 284 | $('#'+target_id + ' input:checked').each(function() { |
---|
| | 285 | selected.push($(this).attr('name')); |
---|
| | 286 | }); |
---|
| | 287 | |
---|
| | 288 | if(which === 'user') { |
---|
| | 289 | this.filterUsers(selected); |
---|
| | 290 | } |
---|
| | 291 | else if(which === 'tags') { |
---|
| | 292 | this.filterTags(selected); |
---|
| | 293 | } |
---|
| | 294 | }, |
---|
| | 295 | filterUsers: function(users) { |
---|
| | 296 | if(!users.length) { |
---|
| | 297 | return; |
---|
| | 298 | } |
---|
| | 299 | var filtered_swts = this.collection.filter(function(model) { |
---|
| | 300 | if(_.indexOf(users, model.get('who')) > -1) { |
---|
| | 301 | return model; |
---|
| | 302 | } |
---|
| | 303 | }); |
---|
| | 304 | if(filtered_swts.length) { |
---|
| | 305 | anno.removeAll(); |
---|
| | 306 | _.each(filtered_swts, function(swt) { |
---|
| | 307 | anno.addAnnotation(swt.get('how')); |
---|
| | 308 | }); |
---|
| | 309 | } |
---|
| | 310 | }, |
---|
| | 311 | filterTags: function(tags) { |
---|
| | 312 | if(!tags.length) { |
---|
| | 313 | return; |
---|
| | 314 | } |
---|
| | 315 | var filtered_swts = this.collection.filter(function(model) { |
---|
| | 316 | //TODO: find a better way of doing this.. |
---|
| | 317 | var flag = false; |
---|
| | 318 | _.each(model.get('how').tags, function(tag) { |
---|
| | 319 | if(_.indexOf(tags, tag) > -1) { |
---|
| | 320 | flag = true; |
---|
| | 321 | } |
---|
| | 322 | }); |
---|
| | 323 | if(flag === true) { |
---|
| | 324 | return model; |
---|
| | 325 | } |
---|
| | 326 | }); |
---|
| | 327 | if(filtered_swts.length) { |
---|
| | 328 | anno.removeAll(); |
---|
| | 329 | _.each(filtered_swts, function(swt) { |
---|
| | 330 | anno.addAnnotation(swt.get('how')); |
---|
| | 331 | }); |
---|
| | 332 | } |
---|
| | 333 | }, |
---|
| | 334 | filterSweet: function(event) { |
---|
| | 335 | /*if(!event.currentTarget.checked) { |
---|
| | 336 | var results = this.collection.filter(function(model) { |
---|
| | 337 | if(model.get('who') != event.currentTarget.name) |
---|
| | 338 | return model; |
---|
| | 339 | }); |
---|
| | 340 | if(results.length) { |
---|
| | 341 | _.each(results, function(result) { |
---|
| | 342 | anno.removeAnnotation(result.get('how')); |
---|
| | 343 | }); |
---|
| | 344 | } |
---|
| | 345 | else { // if results is empty then remove all anno. |
---|
| | 346 | anno.removeAll(); |
---|
| | 347 | } |
---|
| | 348 | } |
---|
| | 349 | else { |
---|
| | 350 | results = this.collection.filter(function(model) { |
---|
| | 351 | if(model.get('who') == event.currentTarget.name) |
---|
| | 352 | return model; |
---|
| | 353 | }); |
---|
| | 354 | _.each(results, function(result) { |
---|
| | 355 | anno.addAnnotation(result.get('how')); |
---|
| | 356 | }); |
---|
| | 357 | |
---|
| | 358 | } |
---|
| | 359 | // if(results) { |
---|
| | 360 | // anno.removeAll(); |
---|
| | 361 | // } |
---|
| | 362 | // swtr.annoView.collection = results; |
---|
| | 363 | // swtr.annoView.renderWith();*/ |
---|
| | 364 | } |
---|
| | 365 | }); |
---|
| | 366 | |
---|
| | 367 | var AppView = Backbone.View.extend({ |
---|
| | 368 | el: $('body'), |
---|
| | 369 | events: { |
---|
| | 370 | 'click #user-input-submit': 'submitUserInput', |
---|
| | 371 | 'click #sweet': 'sweet', |
---|
| | 372 | 'click #sign-in': 'signIn', |
---|
| | 373 | 'click #ocd-source': 'sourceChanged' |
---|
| | 374 | //'mouseup .annotorious-editor-button-save': 'addnew_anno' |
---|
| | 375 | }, |
---|
| | 376 | initialize: function() { |
---|
| | 377 | // initialize components |
---|
| | 378 | this.source = 'none'; |
---|
| | 379 | this.helpview = new HelpView(); |
---|
| | 380 | this.sweetsview = new SweetsView({collection: swtr.sweets}); |
---|
| | 381 | |
---|
| | 382 | // cache jquery selected elements which are used frequently |
---|
| | 383 | this.$overlay = $('#app-overlay'); |
---|
| | 384 | this.$img = $('#annotatable-img'); |
---|
| | 385 | |
---|
| | 386 | this.helpview.step(1); |
---|
| | 387 | // initialize the oauth stuff |
---|
| | 388 | this.oauth = new Oauth({ |
---|
| | 389 | app_id: swtr.app_id, |
---|
| | 390 | endpoint: swtr.swtstoreURL() + swtr.endpoints.auth, |
---|
| | 391 | redirect_uri: swtr.oauth_redirect_uri, |
---|
| | 392 | scopes: 'email,sweet' |
---|
| | 393 | }); |
---|
| | 394 | }, |
---|
| | 395 | submitUserInput: function(event) { |
---|
| | 396 | event.preventDefault(); |
---|
| | 397 | var input = $('#user-input').val(); |
---|
| | 398 | if(this.source === 'ocd') { |
---|
| | 399 | this.loadOCDSearch(input); |
---|
| | 400 | } |
---|
| | 401 | else if (this.source === 'none') { |
---|
| | 402 | this.loadURL(input); |
---|
| | 403 | } |
---|
| | 404 | }, |
---|
| | 405 | // load a URL for annotation (can be of image or html resource for now) |
---|
| | 406 | loadURL: function(url, type) { |
---|
| | 407 | //console.log('loadURL()'); |
---|
| | 408 | if(this.source !== 'ocd') { |
---|
| | 409 | $('#ocd-results').hide(); |
---|
| | 410 | } |
---|
| | 411 | $('#img-annotation-wrapper').show(); |
---|
| | 412 | if(!url || !url.match(/http/)) { |
---|
| | 413 | this.helpview.step(13); |
---|
| | 414 | return false; |
---|
| | 415 | } |
---|
| | 416 | // if type is given explicitly; we load it as such. |
---|
| | 417 | if(type === 'image') { |
---|
| | 418 | if(swtr.imgAnnoView) { |
---|
| | 419 | swtr.imgAnnoView.setImage(url); |
---|
| | 420 | } |
---|
| | 421 | else { |
---|
| | 422 | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, |
---|
| | 423 | img: this.$img[0], |
---|
| | 424 | $img: this.$img, |
---|
| | 425 | url: url}); |
---|
| | 426 | } |
---|
| | 427 | return false; |
---|
| | 428 | } |
---|
| | 429 | // else try to find what resource is the URL.. |
---|
| | 430 | // if url has an image extension then load the image annotation |
---|
| | 431 | if(url.match(/.jpg|.jpeg|.png|.gif|.bmp|.svg/)) { |
---|
| | 432 | if(swtr.imgAnnoView) { |
---|
| | 433 | swtr.imgAnnoView.setImage(url); |
---|
| | 434 | } |
---|
| | 435 | else { |
---|
| | 436 | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, |
---|
| | 437 | img: this.$img[0], |
---|
| | 438 | $img: this.$img, |
---|
| | 439 | url: url}); |
---|
| | 440 | } |
---|
| | 441 | |
---|
| | 442 | return false; |
---|
| | 443 | } |
---|
| | 444 | // else check with our /media-type endpoint to see what type of resource |
---|
| | 445 | // it is |
---|
| | 446 | else { |
---|
| | 447 | this.helpview.step(12); |
---|
| | 448 | this.$overlay.show(); |
---|
| | 449 | var self = this; |
---|
| | 450 | $.get('/media-type', {where: url}, function(response) { |
---|
| | 451 | //console.log(response); |
---|
| | 452 | self.$overlay.hide(); |
---|
| | 453 | if(response.type === 'image') { |
---|
| | 454 | if(swtr.imgAnnoView) { |
---|
| | 455 | swtr.imgAnnoView.setImage(url); |
---|
| | 456 | } |
---|
| | 457 | else { |
---|
| | 458 | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, |
---|
| | 459 | img: self.$img[0], |
---|
| | 460 | $img: self.$img, |
---|
| | 461 | url: url}); |
---|
| | 462 | } |
---|
| | 463 | } |
---|
| | 464 | else { |
---|
| | 465 | window.location.href = '/annotate?where=' + url; |
---|
| | 466 | } |
---|
| | 467 | }); |
---|
| | 468 | } |
---|
| | 469 | }, |
---|
| | 470 | getSweets: function() { |
---|
| | 471 | var annos = _.filter(anno.getAnnotations(), function(anno) { |
---|
| | 472 | return (!_.has(anno, 'editable') || anno.editable === true); |
---|
| | 473 | }); |
---|
| | 474 | |
---|
| | 475 | _.each(annos, function(anno) { |
---|
| | 476 | swtr.sweets.add({ |
---|
| | 477 | who: swtr.who, |
---|
| | 478 | where: anno.src, |
---|
| | 479 | // remove the text field; we don't want to store that in the sweets |
---|
| | 480 | how: _.omit(anno, 'text') |
---|
| | 481 | }); |
---|
| | 482 | }); |
---|
| | 483 | }, |
---|
| | 484 | showSweets: function() { |
---|
| | 485 | this.sweetsview.render(); |
---|
| | 486 | }, |
---|
| | 487 | sweet: function() { |
---|
| | 488 | this.getSweets(); |
---|
| | 489 | this.showSweets(); |
---|
| | 490 | return false; |
---|
| | 491 | }, |
---|
| | 492 | signIn: function(event) { |
---|
| | 493 | event.preventDefault(); |
---|
| | 494 | this.oauth.authorize(); |
---|
| | 495 | return false; |
---|
| | 496 | }, |
---|
| | 497 | userLoggedIn: function(username) { |
---|
| | 498 | swtr.who = username; |
---|
| | 499 | var text = 'Signed in as <b>' + swtr.who + '</b>'; |
---|
| | 500 | $('#signinview').html(text); |
---|
| | 501 | }, |
---|
| | 502 | userLoggedOut: function() { |
---|
| | 503 | swtr.who = 'Guest'; |
---|
| | 504 | $('#signinview').html('Logged out'); |
---|
| | 505 | }, |
---|
| | 506 | changeURLInputPlaceholder: function(source) { |
---|
| | 507 | switch (source) { |
---|
| | 508 | case 'ocd' : $('#user-input').attr('placeholder', 'Enter search query'); |
---|
| | 509 | break; |
---|
| | 510 | case 'none' : $('#user-input').attr('placeholder', 'Enter URL of image or web page'); |
---|
| | 511 | break; |
---|
| | 512 | } |
---|
| | 513 | }, |
---|
| | 514 | // function to change the source in the application and update the UI |
---|
| | 515 | changeSource: function(source) { |
---|
| | 516 | switch (source) { |
---|
| | 517 | case 'ocd' : this.source = 'ocd'; |
---|
| | 518 | this.helpview.step(11); |
---|
| | 519 | this.changeURLInputPlaceholder('ocd'); |
---|
| | 520 | break; |
---|
| | 521 | case 'none' : this.source = 'none'; |
---|
| | 522 | this.helpview.step(1); |
---|
| | 523 | this.changeURLInputPlaceholder('none'); |
---|
| | 524 | break; |
---|
| | 525 | } |
---|
| | 526 | }, |
---|
| | 527 | // event handler to capture control panel UI change of source |
---|
| | 528 | sourceChanged: function(event) { |
---|
| | 529 | if($('#ocd-source').is(':checked')) { |
---|
| | 530 | this.changeSource('ocd'); |
---|
| | 531 | } |
---|
| | 532 | else { |
---|
| | 533 | this.changeSource('none'); |
---|
| | 534 | } |
---|
| | 535 | }, |
---|
| | 536 | loadOCDSearch: function(input) { |
---|
| | 537 | var self = this; |
---|
| | 538 | $('#img-annotation-wrapper').hide(); |
---|
| | 539 | $('#ocd-results').show(); |
---|
| | 540 | $('#ocd-results').html('<h4 style="text-align: center;">Loading..</h4>'); |
---|
| | 541 | $.ajax({ |
---|
| | 542 | type: 'GET', |
---|
| | 543 | url: '/search/ocd', |
---|
| | 544 | data: {query: input}, |
---|
| | 545 | success: function(data) { |
---|
| | 546 | self.ocdView = new OCDView({ |
---|
| | 547 | query: input, |
---|
| | 548 | data: data, |
---|
| | 549 | model: data.hits.hits |
---|
| | 550 | }); |
---|
| | 551 | } |
---|
| | 552 | }); |
---|
| | 553 | } |
---|
| | 554 | }); |
---|
| | 555 | |
---|
| | 556 | var OCDView = Backbone.View.extend({ |
---|
| | 557 | el: $('#ocd-view'), |
---|
| | 558 | events: { |
---|
| | 559 | 'click .ocd-item a': 'onImgClick', |
---|
| | 560 | 'click .pager li': 'onPagerClick' |
---|
| | 561 | }, |
---|
| | 562 | initialize: function(opts) { |
---|
| | 563 | this.data = opts.data || {}; |
---|
| | 564 | this.query = opts.query || ''; |
---|
| | 565 | this.size = 9; // num of items per page |
---|
| | 566 | this.page = 0; |
---|
| | 567 | this.item_template = _.template($('#ocd-item-template').html()); |
---|
| | 568 | this.base_template = _.template($('#ocd-view-base-template').html()); |
---|
| | 569 | this.render(); |
---|
| | 570 | }, |
---|
| | 571 | render: function() { |
---|
| | 572 | var $row_el; |
---|
| | 573 | this.$el.html(''); |
---|
| | 574 | if(!this.model.length) { |
---|
| | 575 | this.$el.html('No results could be found from your query.'); |
---|
| | 576 | return; |
---|
| | 577 | } |
---|
| | 578 | this.$el.html(this.base_template()); |
---|
| | 579 | var $el = $('#ocd-results'); |
---|
| | 580 | _.each(this.model, function(item, idx) { |
---|
| | 581 | // put every 3 items in a row |
---|
| | 582 | if(idx % 3 === 0) { |
---|
| | 583 | $row_el = $('<div class="row"></div>'); |
---|
| | 584 | $el.append($row_el); |
---|
| | 585 | } |
---|
| | 586 | $row_el.append(this.item_template({ |
---|
| | 587 | title: item._source.title, |
---|
| | 588 | media_url: item._source.media_urls[0].url, |
---|
| | 589 | authors: item._source.authors |
---|
| | 590 | })); |
---|
| | 591 | }, this); |
---|
| | 592 | this.resolveOCDURLs(); |
---|
| | 593 | this.appendTotal(); |
---|
| | 594 | }, |
---|
| | 595 | appendTotal: function() { |
---|
| | 596 | $('#ocd-total-results').html(this.data.hits.total + ' results found.'); |
---|
| | 597 | }, |
---|
| | 598 | // resolve the OCD media URLs |
---|
| | 599 | resolveOCDURLs: function() { |
---|
| | 600 | var self = this; |
---|
| | 601 | $('.ocd-item').each(function(idx, elem) { |
---|
| | 602 | var temp_arr = self.model[idx]._source.media_urls[0].url.split('/'); |
---|
| | 603 | var media_hash = temp_arr[temp_arr.length - 1]; |
---|
| | 604 | $.get('/resolve-ocd-media', {hash: media_hash}, function(resp) { |
---|
| | 605 | $(elem).find('img').attr('src', resp.url); |
---|
| | 606 | }); |
---|
| | 607 | }); |
---|
| | 608 | }, |
---|
| | 609 | rerender: function(data) { |
---|
| | 610 | this.data = data; |
---|
| | 611 | this.model = data.hits.hits; |
---|
| | 612 | this.render(); |
---|
| | 613 | }, |
---|
| | 614 | onPagerClick: function(event) { |
---|
| | 615 | event.preventDefault(); |
---|
| | 616 | var elem = $(event.currentTarget); |
---|
| | 617 | var self = this; |
---|
| | 618 | if(elem.hasClass('next')) { |
---|
| | 619 | if((this.page + 1) * this.size >= this.data.hits.total) { |
---|
| | 620 | console.log('no next page to go to'); |
---|
| | 621 | return false; |
---|
| | 622 | } |
---|
| | 623 | console.log('clicked next'); |
---|
| | 624 | this.search({ |
---|
| | 625 | query: this.query, |
---|
| | 626 | from: (this.page + 1) * this.size |
---|
| | 627 | }, function(resp) { |
---|
| | 628 | console.log('reached next page'); |
---|
| | 629 | self.page = self.page + 1; |
---|
| | 630 | self.rerender(resp); |
---|
| | 631 | }); |
---|
| | 632 | } |
---|
| | 633 | else if (elem.hasClass('previous')) { |
---|
| | 634 | if(this.page <= 0) { |
---|
| | 635 | console.log('no prev page to go to'); |
---|
| | 636 | return false; |
---|
| | 637 | } |
---|
| | 638 | console.log('clicked prev'); |
---|
| | 639 | this.search({ |
---|
| | 640 | query: this.query, |
---|
| | 641 | from: (this.page - 1) * this.size |
---|
| | 642 | }, function(resp) { |
---|
| | 643 | console.log('reached prev page'); |
---|
| | 644 | self.page = self.page - 1; |
---|
| | 645 | self.rerender(resp); |
---|
| | 646 | }); |
---|
| | 647 | } |
---|
| | 648 | return false; |
---|
| | 649 | }, |
---|
| | 650 | onImgClick: function(event) { |
---|
| | 651 | event.preventDefault(); |
---|
| | 652 | // TODO: init the image anno |
---|
| | 653 | var url = $(event.currentTarget).find('img').attr('src'); |
---|
| | 654 | swtr.appView.loadURL(url, 'image'); |
---|
| | 655 | return false; |
---|
| | 656 | }, |
---|
| | 657 | search: function(data, cb) { |
---|
| | 658 | swtr.appView.$overlay.show(); |
---|
| | 659 | var self = this; |
---|
| | 660 | $.ajax({ |
---|
| | 661 | type: 'GET', |
---|
| | 662 | url: '/search/ocd', |
---|
| | 663 | data: data, |
---|
| | 664 | success: function(resp) { |
---|
| | 665 | swtr.appView.$overlay.hide(); |
---|
| | 666 | cb(resp); |
---|
| | 667 | } |
---|
| | 668 | }); |
---|
| | 669 | } |
---|
| | 670 | }); |
---|
| | 671 | |
---|
| | 672 | var HelpView = Backbone.View.extend({ |
---|
| | 673 | el: $('#helpview'), |
---|
| | 674 | events: { |
---|
| | 675 | }, |
---|
| | 676 | initialize: function() { |
---|
| | 677 | this.$text_el = $('#helpview-text'); |
---|
| | 678 | }, |
---|
| | 679 | //TODO: move from number based steps to something else. number based steps |
---|
| | 680 | //implicitly imply sequential processing..which does not happen in this |
---|
| | 681 | //case.. |
---|
| | 682 | //following helps can be async.. |
---|
| | 683 | step: function(n) { |
---|
| | 684 | var text = ''; |
---|
| | 685 | switch (n) { |
---|
| | 686 | case 0 : text = 'Getting annotations..'; |
---|
| | 687 | break; |
---|
| | 688 | case 1: text = 'Enter URL of an image or web page below, and start annotating!'; |
---|
| | 689 | break; |
---|
| | 690 | case 2: text = 'Annotate the image, or see other annotations'; |
---|
| | 691 | break; |
---|
| | 692 | case 3: text = 'Now you can sweet this annotation, or add more annotations'; |
---|
| | 693 | break; |
---|
| | 694 | case 4: text = 'Click Sweet button to publish these annotations to the Sweet Store'; |
---|
| | 695 | break; |
---|
| | 696 | case 5: text = 'Publishing your sweets'; |
---|
| | 697 | break; |
---|
| | 698 | case 6: text = 'Sweets successfully posted'; |
---|
| | 699 | break; |
---|
| | 700 | case 7: text = 'Fetching your image..'; |
---|
| | 701 | break; |
---|
| | 702 | case 8: text = 'Oops! Seems like the image URL is wrong! Or we couldn\'t fetch the image.'; |
---|
| | 703 | break; |
---|
| | 704 | case 9: text = 'You have to be <i>signed in</i> to sweet store to post sweets'; |
---|
| | 705 | break; |
---|
| | 706 | case 10: text = 'Oops! Something went wrong. We couldn\'t publish the sweets. Try again.' |
---|
| | 707 | break; |
---|
| | 708 | case 11: text = 'Search in <a href="http://www.opencultuurdata.nl/">Open Cuultur Data API</a>'; |
---|
| | 709 | break; |
---|
| | 710 | case 12: text = 'Analyzing the resource type..'; |
---|
| | 711 | break; |
---|
| | 712 | case 13: text = 'This does not seem to be a URL. Please enter a valid URL.'; |
---|
| | 713 | break; |
---|
| | 714 | } |
---|
| | 715 | $(this.$text_el).html(text); |
---|
| | 716 | $(window).scrollTop(0, 0); |
---|
| | 717 | } |
---|
| | 718 | }); |
---|
| | 719 | |
---|
| | 720 | |
---|
| | 721 | // utilities and helper functions to go here |
---|
| | 722 | swtr.utils = { |
---|
| | 723 | linkify: function(link) { |
---|
| | 724 | if(link.match('http')) { |
---|
| | 725 | return link; |
---|
| | 726 | } |
---|
| | 727 | else { |
---|
| | 728 | return 'http://' + link; |
---|
| | 729 | } |
---|
| | 730 | } |
---|
| | 731 | }; |
---|
| | 732 | //swtr.AppView = AppView; |
---|
| | 733 | |
---|
| | 734 | var AppRouter = Backbone.Router.extend({ |
---|
| | 735 | routes: { |
---|
| | 736 | 'home': 'home', |
---|
| | 737 | 'linked-data': 'linkedData', |
---|
| | 738 | 'play': 'play', |
---|
| | 739 | 'search': 'search' |
---|
| | 740 | }, |
---|
| | 741 | home: function() { |
---|
| | 742 | this.hideAll(); |
---|
| | 743 | this.show('home-page'); |
---|
| | 744 | }, |
---|
| | 745 | linkedData: function() { |
---|
| | 746 | this.hideAll(); |
---|
| | 747 | this.show('linked-data-page'); |
---|
| | 748 | }, |
---|
| | 749 | play: function() { |
---|
| | 750 | this.hideAll(); |
---|
| | 751 | this.show('play-page'); |
---|
| | 752 | }, |
---|
| | 753 | search: function() { |
---|
| | 754 | this.hideAll(); |
---|
| | 755 | this.show('search-page'); |
---|
| | 756 | }, |
---|
| | 757 | hideAll: function() { |
---|
| | 758 | $('.page').hide(); |
---|
| | 759 | }, |
---|
| | 760 | show: function(id) { |
---|
| | 761 | $('#' + id).show(); |
---|
| | 762 | this.highlight(id); |
---|
| | 763 | }, |
---|
| | 764 | highlight: function(id) { |
---|
| | 765 | $('#swtr-navbar-collapse li').removeClass('active'); |
---|
| | 766 | var href = id.split('-page')[0]; |
---|
| | 767 | var selector = '#swtr-navbar-collapse a[href="#/' + href + '"]'; |
---|
| | 768 | $(selector).parent('li').addClass('active'); |
---|
| | 769 | } |
---|
| | 770 | }); |
---|
| | 771 | |
---|
| | 772 | })(swtr); |
---|
| | | | 1 | (function(swtr) { | | (function(swtr) { |
---|
2 | | | |
---|
3 | //TODO: find a better way to init. | | //TODO: find a better way to init. |
---|
4 | //Find a better way to do closure | | //Find a better way to do closure |
---|
5 | //Remove script code from the HTML page | | //Remove script code from the HTML page |
---|
6 | swtr.init = function() { | | swtr.init = function() { |
---|
7 | this.sweets = new ImgAnnoSwts(); | | this.sweets = new ImgAnnoSwts(); |
---|
8 | this.appView = new AppView(); | | this.appView = new AppView(); |
---|
9 | this.who = 'Guest'; | | this.who = 'Guest'; |
---|
10 | | | |
---|
11 | this.app_router = new AppRouter(); | | this.app_router = new AppRouter(); |
---|
12 | Backbone.history.start(); | | Backbone.history.start(); |
---|
13 | this.app_router.navigate('home'); | | this.app_router.navigate('home'); |
---|
14 | | | |
---|
15 | $.ajaxSetup({ | | $.ajaxSetup({ |
---|
16 | xhrFields: { | | xhrFields: { |
---|
17 | // we need this to send cookies to cross-domain requests | | // we need this to send cookies to cross-domain requests |
---|
18 | withCredentials: true | | withCredentials: true |
---|
19 | }, | | }, |
---|
20 | //some browsers won't make cross-domain ajax until it is explicitly set | | //some browsers won't make cross-domain ajax until it is explicitly set |
---|
21 | crossDomain: true | | crossDomain: true |
---|
22 | }); | | }); |
---|
23 | this.handleOAuth(); | | this.handleOAuth(); |
---|
24 | }; | | }; |
---|
25 | | | |
---|
26 | swtr.handleOAuth = function() { | | swtr.handleOAuth = function() { |
---|
27 | if(swtr.access_token) { | | if(swtr.access_token) { |
---|
28 | $('#signinview').html('Signing you in..'); | | $('#signinview').html('Signing you in..'); |
---|
29 | $.ajax({ | | $.ajax({ |
---|
30 | url: swtr.swtstoreURL()+'/api/users/me?access_token='+ | | url: swtr.swtstoreURL()+'/api/users/me?access_token='+ |
---|
31 | swtr.access_token, | | swtr.access_token, |
---|
32 | success: function(data) { | | success: function(data) { |
---|
33 | swtr.appView.userLoggedIn(data.username); | | swtr.appView.userLoggedIn(data.username); |
---|
34 | }, | | }, |
---|
35 | error: function() { | | error: function() { |
---|
36 | $('#signinview').html('Error signing in! Please try again'); | | $('#signinview').html('Error signing in! Please try again'); |
---|
37 | } | | } |
---|
38 | }); | | }); |
---|
39 | } | | } |
---|
40 | }; | | }; |
---|
41 | | | |
---|
42 | /* Model for Image Annotation Sweets */ | | /* Model for Image Annotation Sweets */ |
---|
43 | var ImgAnnoSwt = Backbone.Model.extend({ | | var ImgAnnoSwt = Backbone.Model.extend({ |
---|
44 | defaults: { | | defaults: { |
---|
45 | 'who': '', | | 'who': '', |
---|
46 | 'what': 'img-anno', | | 'what': 'img-anno', |
---|
47 | 'where': '', | | 'where': '', |
---|
48 | 'how': {} | | 'how': {} |
---|
49 | }, | | }, |
---|
50 | initialize: function() { | | initialize: function() { |
---|
51 | } | | } |
---|
52 | }); | | }); |
---|
53 | | | |
---|
54 | /* Collection to hold all multiple ImgAnnoSwt */ | | /* Collection to hold all multiple ImgAnnoSwt */ |
---|
55 | var ImgAnnoSwts = Backbone.Collection.extend({ | | var ImgAnnoSwts = Backbone.Collection.extend({ |
---|
56 | model: ImgAnnoSwt, | | model: ImgAnnoSwt, |
---|
57 | url: function() { | | url: function() { |
---|
58 | return swtr.swtstoreURL() + '/sweets'; | | return swtr.swtstoreURL() + '/sweets'; |
---|
59 | }, | | }, |
---|
60 | // get all sweets/annotations of type #img-anno for a particular URI | | // get all sweets/annotations of type #img-anno for a particular URI |
---|
61 | // (where) | | // (where) |
---|
62 | // @options is a javascript object, | | // @options is a javascript object, |
---|
63 | // @options.where : URI of the resource for which swts to be fetched | | // @options.where : URI of the resource for which swts to be fetched |
---|
64 | // @options.who: optional username to filter sweets | | // @options.who: optional username to filter sweets |
---|
65 | // @options.success: success callback to call | | // @options.success: success callback to call |
---|
66 | // @options.error: error callback to call | | // @options.error: error callback to call |
---|
67 | getAll: function(options) { | | getAll: function(options) { |
---|
68 | // error checking | | // error checking |
---|
69 | if(!options.where) { | | if(!options.where) { |
---|
70 | throw Error('"where" option must be passed to get sweets of a URI'); | | throw Error('"where" option must be passed to get sweets of a URI'); |
---|
71 | return false; | | return false; |
---|
72 | } | | } |
---|
73 | // setting up params | | // setting up params |
---|
74 | var where = options.where, | | var where = options.where, |
---|
75 | who = options.who || null; | | who = options.who || null; |
---|
76 | url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' + | | url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' + |
---|
77 | encodeURIComponent(where) + '&access_token=' + swtr.access_token; | | encodeURIComponent(where) + '&access_token=' + swtr.access_token; |
---|
78 | if(who) { | | if(who) { |
---|
79 | url += '&who=' + who; | | url += '&who=' + who; |
---|
80 | } | | } |
---|
81 | // get them! | | // get them! |
---|
82 | this.sync('read', this, { | | this.sync('read', this, { |
---|
83 | url: url, | | url: url, |
---|
84 | success: function() { | | success: function() { |
---|
85 | if(typeof options.success === 'function') { | | if(typeof options.success === 'function') { |
---|
86 | options.success.apply(this, arguments); | | options.success.apply(this, arguments); |
---|
87 | } | | } |
---|
88 | }, | | }, |
---|
89 | error: function() { | | error: function() { |
---|
90 | if(typeof options.error === 'function') { | | if(typeof options.error === 'function') { |
---|
91 | options.error.apply(this, arguments); | | options.error.apply(this, arguments); |
---|
92 | } | | } |
---|
93 | } | | } |
---|
94 | }); | | }); |
---|
95 | }, | | }, |
---|
96 | // post newly created sweets to a sweet store | | // post newly created sweets to a sweet store |
---|
97 | // @options is a javascript object, | | // @options is a javascript object, |
---|
98 | // @options.where : URI of the resource for which swts to be fetched | | // @options.where : URI of the resource for which swts to be fetched |
---|
99 | // @options.who: optional username to filter sweets | | // @options.who: optional username to filter sweets |
---|
100 | // @options.success: success callback to call | | // @options.success: success callback to call |
---|
101 | // @options.error: error callback to call, | | // @options.error: error callback to call, |
---|
102 | post: function(options) { | | post: function(options) { |
---|
103 | var new_sweets = this.getNew(); | | var new_sweets = this.getNew(); |
---|
104 | var dummy_collection = new Backbone.Collection(new_sweets); | | var dummy_collection = new Backbone.Collection(new_sweets); |
---|
105 | | | |
---|
106 | if(!swtr.access_token) { | | if(!swtr.access_token) { |
---|
107 | throw new Error('Access Token is required to sweet'); | | throw new Error('Access Token is required to sweet'); |
---|
108 | return; | | return; |
---|
109 | } | | } |
---|
110 | | | |
---|
111 | var url = swtr.swtstoreURL() + swtr.endpoints.post + | | var url = swtr.swtstoreURL() + swtr.endpoints.post + |
---|
112 | '?access_token=' + swtr.access_token; | | '?access_token=' + swtr.access_token; |
---|
113 | | | |
---|
114 | this.sync('create', dummy_collection, { | | this.sync('create', dummy_collection, { |
---|
115 | url: url, | | url: url, |
---|
116 | success: function() { | | success: function() { |
---|
117 | if(typeof options.success === 'function') { | | if(typeof options.success === 'function') { |
---|
118 | options.success.apply(this, arguments); | | options.success.apply(this, arguments); |
---|
119 | } | | } |
---|
120 | }, | | }, |
---|
121 | error: function() { | | error: function() { |
---|
122 | if(typeof options.error === 'function') { | | if(typeof options.error === 'function') { |
---|
123 | options.error.apply(this, arguments); | | options.error.apply(this, arguments); |
---|
124 | } | | } |
---|
125 | } | | } |
---|
126 | }); | | }); |
---|
127 | }, | | }, |
---|
128 | // return newly created models from the collection | | // return newly created models from the collection |
---|
129 | getNew: function() { | | getNew: function() { |
---|
130 | var new_models = []; | | var new_models = []; |
---|
131 | this.each(function(model) { | | this.each(function(model) { |
---|
132 | if(model.isNew()) { | | if(model.isNew()) { |
---|
133 | new_models.push(model); | | new_models.push(model); |
---|
134 | } | | } |
---|
135 | }); | | }); |
---|
136 | return new_models; | | return new_models; |
---|
137 | }, | | }, |
---|
138 | // update part of the collection after a save on the server | | // update part of the collection after a save on the server |
---|
139 | update: function() { | | update: function() { |
---|
140 | } | | } |
---|
141 | }); | | }); |
---|
142 | | | |
---|
143 | var SweetsView = Backbone.View.extend({ | | var SweetsView = Backbone.View.extend({ |
---|
144 | el: $('#sweet-list-wrapper'), | | el: $('#sweet-list-wrapper'), |
---|
145 | events: { | | events: { |
---|
146 | 'click #sweet-cancel': 'cancelSweeting', | | 'click #sweet-cancel': 'cancelSweeting', |
---|
147 | 'click #post-sweet': 'postSweets' | | 'click #post-sweet': 'postSweets' |
---|
148 | }, | | }, |
---|
149 | initialize: function() { | | initialize: function() { |
---|
150 | this.template = _.template($('#sweet-template').html()); | | this.template = _.template($('#sweet-template').html()); |
---|
151 | }, | | }, |
---|
152 | render: function() { | | render: function() { |
---|
153 | $('#sweet-list').html('<h4>These are your sweet annotations!</h4>'); | | $('#sweet-list').html('<h4>These are your sweet annotations!</h4>'); |
---|
154 | _.each(this.collection.models, function(swt) { | | _.each(this.collection.models, function(swt) { |
---|
155 | if(swt.has('id')) { | | if(swt.has('id')) { |
---|
156 | return false; | | return false; |
---|
157 | } | | } |
---|
158 | $('#sweet-list').append(this.template({ | | $('#sweet-list').append(this.template({ |
---|
159 | who: swt.get('who'), | | who: swt.get('who'), |
---|
160 | what: swt.get('what'), | | what: swt.get('what'), |
---|
161 | where: swt.get('where'), | | where: swt.get('where'), |
---|
162 | how: JSON.stringify(this.getHumanReadableParts(swt.get('how'))) | | how: JSON.stringify(this.getHumanReadableParts(swt.get('how'))) |
---|
163 | })); | | })); |
---|
164 | }, this); | | }, this); |
---|
165 | $(this.el).fadeIn(300); | | $(this.el).fadeIn(300); |
---|
166 | }, | | }, |
---|
167 | getHumanReadableParts: function(how) { | | getHumanReadableParts: function(how) { |
---|
168 | var human_readable_json = {}; | | var human_readable_json = {}; |
---|
169 | if(how.comment) { | | if(how.comment) { |
---|
170 | human_readable_json['comment'] = how.comment; | | human_readable_json['comment'] = how.comment; |
---|
171 | } | | } |
---|
172 | if(how.title) { | | if(how.title) { |
---|
173 | human_readable_json['title'] = how.title; | | human_readable_json['title'] = how.title; |
---|
174 | } | | } |
---|
175 | if(how.tags) { | | if(how.tags) { |
---|
176 | human_readable_json['tags'] = how.tags; | | human_readable_json['tags'] = how.tags; |
---|
177 | } | | } |
---|
178 | if(how.link) { | | if(how.link) { |
---|
179 | human_readable_json['link'] = how.link; | | human_readable_json['link'] = how.link; |
---|
180 | } | | } |
---|
181 | return human_readable_json; | | return human_readable_json; |
---|
182 | }, | | }, |
---|
183 | cancelSweeting: function() { | | cancelSweeting: function() { |
---|
184 | this.removeSwtsNotPosted(); | | this.removeSwtsNotPosted(); |
---|
185 | this.cleanUp(); | | this.cleanUp(); |
---|
186 | }, | | }, |
---|
187 | removeSwtsNotPosted: function() { | | removeSwtsNotPosted: function() { |
---|
188 | var notPosted = this.collection.filter(function(model) { | | var notPosted = this.collection.filter(function(model) { |
---|
189 | return !model.has('id'); | | return !model.has('id'); |
---|
190 | }); | | }); |
---|
191 | this.collection.remove(notPosted); | | this.collection.remove(notPosted); |
---|
192 | }, | | }, |
---|
193 | postSweets: function() { | | postSweets: function() { |
---|
194 | console.log("postSWr"); | | console.log("postSWr"); |
---|
195 | var appView = swtr.appView; | | var appView = swtr.appView; |
---|
196 | appView.helpview.step(5); | | appView.helpview.step(5); |
---|
197 | appView.$overlay.show(); | | appView.$overlay.show(); |
---|
198 | try { | | try { |
---|
199 | this.collection.post({ | | this.collection.post({ |
---|
200 | success: function(collection, response) { | | success: function(collection, response) { |
---|
201 | console.log(collection, response); | | console.log(collection, response); |
---|
202 | swtr.sweets.set(collection); | | swtr.sweets.set(collection); |
---|
203 | //TODO: move this to a annotation view or something | | //TODO: move this to a annotation view or something |
---|
204 | // anno.removeAll(); | | // anno.removeAll(); |
---|
205 | // _.each(swtr.sweets.models, function(swt) { | | // _.each(swtr.sweets.models, function(swt) { |
---|
206 | // if(!_.has(swt.get('how'), 'editable')) { | | // if(!_.has(swt.get('how'), 'editable')) { |
---|
207 | // swt.get('how')['editable'] = false; | | // swt.get('how')['editable'] = false; |
---|
208 | // //console.log(swt.get('how').text.Comment); | | // //console.log(swt.get('how').text.Comment); |
---|
209 | // swt.get('how').text = swtr.imgAnnoView.createPopupText(swt.get('how')); | | // swt.get('how').text = swtr.imgAnnoView.createPopupText(swt.get('how')); |
---|
210 | // //console.log(swt.get('how')); | | // //console.log(swt.get('how')); |
---|
211 | // swt.get('how').text += '\n - by ' + swt.get('who'); | | // swt.get('how').text += '\n - by ' + swt.get('who'); |
---|
212 | // } | | // } |
---|
213 | // //console.log(swt.get('how')); | | // //console.log(swt.get('how')); |
---|
214 | // anno.addAnnotation(swt.get('how')); | | // anno.addAnnotation(swt.get('how')); |
---|
215 | // }); | | // }); |
---|
216 | //console.log(swtr.sweets.toJSON()); | | //console.log(swtr.sweets.toJSON()); |
---|
217 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
218 | swtr.appView.helpview.step(6); | | swtr.appView.helpview.step(6); |
---|
219 | }, | | }, |
---|
220 | error: function(jqxhr, error, text) { | | error: function(jqxhr, error, text) { |
---|
221 | console.log(jqxhr, error, text); | | console.log(jqxhr, error, text); |
---|
222 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
223 | swtr.appView.helpview.step(10); | | swtr.appView.helpview.step(10); |
---|
224 | } | | } |
---|
225 | }); | | }); |
---|
226 | } catch(e) { | | } catch(e) { |
---|
227 | if(e.message == 'Access Token is required to sweet') { | | if(e.message == 'Access Token is required to sweet') { |
---|
228 | appView.$overlay.hide(); | | appView.$overlay.hide(); |
---|
229 | appView.helpview.step(9); | | appView.helpview.step(9); |
---|
230 | } | | } |
---|
231 | } | | } |
---|
232 | this.cleanUp(); | | this.cleanUp(); |
---|
233 | return false; | | return false; |
---|
234 | }, | | }, |
---|
235 | cleanUp: function() { | | cleanUp: function() { |
---|
236 | //console.log('cleaning up'); | | //console.log('cleaning up'); |
---|
237 | $(this.el).hide(); | | $(this.el).hide(); |
---|
238 | } | | } |
---|
239 | }); | | }); |
---|
240 | | | |
---|
241 | var FilterView = Backbone.View.extend({ | | var FilterView = Backbone.View.extend({ |
---|
242 | el: $('#filter-div'), | | el: $('#filter-div'), |
---|
243 | events: { | | events: { |
---|
244 | 'click #filter-user-div input': 'filter', | | 'click #filter-user-div input': 'filter', |
---|
245 | 'click #filter-tags-div input': 'filter' | | 'click #filter-tags-div input': 'filter' |
---|
246 | }, | | }, |
---|
247 | initialize: function() { | | initialize: function() { |
---|
248 | this.filter_users_template = _.template($('#filter-users').html()); | | this.filter_users_template = _.template($('#filter-users').html()); |
---|
249 | this.filter_tags_template = _.template($('#filter-tags').html()); | | this.filter_tags_template = _.template($('#filter-tags').html()); |
---|
250 | this.render(); | | this.render(); |
---|
251 | }, | | }, |
---|
252 | render: function() { | | render: function() { |
---|
253 | //console.log(this.collection); | | //console.log(this.collection); |
---|
254 | // pluck uniq authors of sweets | | // pluck uniq authors of sweets |
---|
255 | var authors = _.uniq(this.collection.pluck('who')); | | var authors = _.uniq(this.collection.pluck('who')); |
---|
256 | // render them as filter controls | | // render them as filter controls |
---|
257 | _.each(authors, function(author) { | | _.each(authors, function(author) { |
---|
258 | $('#filter-user-div').append(this.filter_users_template({ | | $('#filter-user-div').append(this.filter_users_template({ |
---|
259 | who: author | | who: author |
---|
260 | })); | | })); |
---|
261 | }, this); | | }, this); |
---|
262 | | | |
---|
263 | // pluck uniq tags of sweets | | // pluck uniq tags of sweets |
---|
264 | var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). | | var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). |
---|
265 | uniq().value(); | | uniq().value(); |
---|
266 | // render them as filter controls | | // render them as filter controls |
---|
267 | _.each(tags, function(tag) { | | _.each(tags, function(tag) { |
---|
268 | if(tag) { | | if(tag) { |
---|
269 | $('#filter-tags-div').append(this.filter_tags_template({ | | $('#filter-tags-div').append(this.filter_tags_template({ |
---|
270 | tag: tag | | tag: tag |
---|
271 | })); | | })); |
---|
272 | } | | } |
---|
273 | }, this); | | }, this); |
---|
274 | | | |
---|
275 | //this.delegateEvents(); | | //this.delegateEvents(); |
---|
276 | }, | | }, |
---|
277 | filter: function(event) { | | filter: function(event) { |
---|
278 | // get id of div - parent to parent to the clicked input | | // get id of div - parent to parent to the clicked input |
---|
279 | var target_id = $(event.currentTarget).parent().parent().attr('id'); | | var target_id = $(event.currentTarget).parent().parent().attr('id'); |
---|
280 | // find out user/tag div | | // find out user/tag div |
---|
281 | var which = target_id.split('-')[1]; | | var which = target_id.split('-')[1]; |
---|
282 | | | |
---|
283 | var selected = []; | | var selected = []; |
---|
284 | $('#'+target_id + ' input:checked').each(function() { | | $('#'+target_id + ' input:checked').each(function() { |
---|
285 | selected.push($(this).attr('name')); | | selected.push($(this).attr('name')); |
---|
286 | }); | | }); |
---|
287 | | | |
---|
288 | if(which === 'user') { | | if(which === 'user') { |
---|
289 | this.filterUsers(selected); | | this.filterUsers(selected); |
---|
290 | } | | } |
---|
291 | else if(which === 'tags') { | | else if(which === 'tags') { |
---|
292 | this.filterTags(selected); | | this.filterTags(selected); |
---|
293 | } | | } |
---|
294 | }, | | }, |
---|
295 | filterUsers: function(users) { | | filterUsers: function(users) { |
---|
296 | if(!users.length) { | | if(!users.length) { |
---|
297 | return; | | return; |
---|
298 | } | | } |
---|
299 | var filtered_swts = this.collection.filter(function(model) { | | var filtered_swts = this.collection.filter(function(model) { |
---|
300 | if(_.indexOf(users, model.get('who')) > -1) { | | if(_.indexOf(users, model.get('who')) > -1) { |
---|
301 | return model; | | return model; |
---|
302 | } | | } |
---|
303 | }); | | }); |
---|
304 | if(filtered_swts.length) { | | if(filtered_swts.length) { |
---|
305 | anno.removeAll(); | | anno.removeAll(); |
---|
306 | _.each(filtered_swts, function(swt) { | | _.each(filtered_swts, function(swt) { |
---|
307 | anno.addAnnotation(swt.get('how')); | | anno.addAnnotation(swt.get('how')); |
---|
308 | }); | | }); |
---|
309 | } | | } |
---|
310 | }, | | }, |
---|
311 | filterTags: function(tags) { | | filterTags: function(tags) { |
---|
312 | if(!tags.length) { | | if(!tags.length) { |
---|
313 | return; | | return; |
---|
314 | } | | } |
---|
315 | var filtered_swts = this.collection.filter(function(model) { | | var filtered_swts = this.collection.filter(function(model) { |
---|
316 | //TODO: find a better way of doing this.. | | //TODO: find a better way of doing this.. |
---|
317 | var flag = false; | | var flag = false; |
---|
318 | _.each(model.get('how').tags, function(tag) { | | _.each(model.get('how').tags, function(tag) { |
---|
319 | if(_.indexOf(tags, tag) > -1) { | | if(_.indexOf(tags, tag) > -1) { |
---|
320 | flag = true; | | flag = true; |
---|
321 | } | | } |
---|
322 | }); | | }); |
---|
323 | if(flag === true) { | | if(flag === true) { |
---|
324 | return model; | | return model; |
---|
325 | } | | } |
---|
326 | }); | | }); |
---|
327 | if(filtered_swts.length) { | | if(filtered_swts.length) { |
---|
328 | anno.removeAll(); | | anno.removeAll(); |
---|
329 | _.each(filtered_swts, function(swt) { | | _.each(filtered_swts, function(swt) { |
---|
330 | anno.addAnnotation(swt.get('how')); | | anno.addAnnotation(swt.get('how')); |
---|
331 | }); | | }); |
---|
332 | } | | } |
---|
333 | }, | | }, |
---|
334 | filterSweet: function(event) { | | filterSweet: function(event) { |
---|
335 | /*if(!event.currentTarget.checked) { | | /*if(!event.currentTarget.checked) { |
---|
336 | var results = this.collection.filter(function(model) { | | var results = this.collection.filter(function(model) { |
---|
337 | if(model.get('who') != event.currentTarget.name) | | if(model.get('who') != event.currentTarget.name) |
---|
338 | return model; | | return model; |
---|
339 | }); | | }); |
---|
340 | if(results.length) { | | if(results.length) { |
---|
341 | _.each(results, function(result) { | | _.each(results, function(result) { |
---|
342 | anno.removeAnnotation(result.get('how')); | | anno.removeAnnotation(result.get('how')); |
---|
343 | }); | | }); |
---|
344 | } | | } |
---|
345 | else { // if results is empty then remove all anno. | | else { // if results is empty then remove all anno. |
---|
346 | anno.removeAll(); | | anno.removeAll(); |
---|
347 | } | | } |
---|
348 | } | | } |
---|
349 | else { | | else { |
---|
350 | results = this.collection.filter(function(model) { | | results = this.collection.filter(function(model) { |
---|
351 | if(model.get('who') == event.currentTarget.name) | | if(model.get('who') == event.currentTarget.name) |
---|
352 | return model; | | return model; |
---|
353 | }); | | }); |
---|
354 | _.each(results, function(result) { | | _.each(results, function(result) { |
---|
355 | anno.addAnnotation(result.get('how')); | | anno.addAnnotation(result.get('how')); |
---|
356 | }); | | }); |
---|
357 | | | |
---|
358 | } | | } |
---|
359 | // if(results) { | | // if(results) { |
---|
360 | // anno.removeAll(); | | // anno.removeAll(); |
---|
361 | // } | | // } |
---|
362 | // swtr.annoView.collection = results; | | // swtr.annoView.collection = results; |
---|
363 | // swtr.annoView.renderWith();*/ | | // swtr.annoView.renderWith();*/ |
---|
364 | } | | } |
---|
365 | }); | | }); |
---|
366 | | | |
---|
367 | var AppView = Backbone.View.extend({ | | var AppView = Backbone.View.extend({ |
---|
368 | el: $('body'), | | el: $('body'), |
---|
369 | events: { | | events: { |
---|
370 | 'click #user-input-submit': 'submitUserInput', | | 'click #user-input-submit': 'submitUserInput', |
---|
371 | 'click #sweet': 'sweet', | | 'click #sweet': 'sweet', |
---|
372 | 'click #sign-in': 'signIn', | | 'click #sign-in': 'signIn', |
---|
373 | 'click #ocd-source': 'sourceChanged' | | 'click #ocd-source': 'sourceChanged' |
---|
374 | //'mouseup .annotorious-editor-button-save': 'addnew_anno' | | //'mouseup .annotorious-editor-button-save': 'addnew_anno' |
---|
375 | }, | | }, |
---|
376 | initialize: function() { | | initialize: function() { |
---|
377 | // initialize components | | // initialize components |
---|
378 | this.source = 'none'; | | this.source = 'none'; |
---|
379 | this.helpview = new HelpView(); | | this.helpview = new HelpView(); |
---|
380 | this.sweetsview = new SweetsView({collection: swtr.sweets}); | | this.sweetsview = new SweetsView({collection: swtr.sweets}); |
---|
381 | | | |
---|
382 | // cache jquery selected elements which are used frequently | | // cache jquery selected elements which are used frequently |
---|
383 | this.$overlay = $('#app-overlay'); | | this.$overlay = $('#app-overlay'); |
---|
384 | this.$img = $('#annotatable-img'); | | this.$img = $('#annotatable-img'); |
---|
385 | | | |
---|
386 | this.helpview.step(1); | | this.helpview.step(1); |
---|
387 | // initialize the oauth stuff | | // initialize the oauth stuff |
---|
388 | this.oauth = new Oauth({ | | this.oauth = new Oauth({ |
---|
389 | app_id: swtr.app_id, | | app_id: swtr.app_id, |
---|
390 | endpoint: swtr.swtstoreURL() + swtr.endpoints.auth, | | endpoint: swtr.swtstoreURL() + swtr.endpoints.auth, |
---|
391 | redirect_uri: swtr.oauth_redirect_uri, | | redirect_uri: swtr.oauth_redirect_uri, |
---|
392 | scopes: 'email,sweet' | | scopes: 'email,sweet' |
---|
393 | }); | | }); |
---|
394 | }, | | }, |
---|
395 | submitUserInput: function(event) { | | submitUserInput: function(event) { |
---|
396 | event.preventDefault(); | | event.preventDefault(); |
---|
397 | var input = $('#user-input').val(); | | var input = $('#user-input').val(); |
---|
398 | if(this.source === 'ocd') { | | if(this.source === 'ocd') { |
---|
399 | this.loadOCDSearch(input); | | this.loadOCDSearch(input); |
---|
400 | } | | } |
---|
401 | else if (this.source === 'none') { | | else if (this.source === 'none') { |
---|
402 | this.loadURL(input); | | this.loadURL(input); |
---|
403 | } | | } |
---|
404 | }, | | }, |
---|
405 | // load a URL for annotation (can be of image or html resource for now) | | // load a URL for annotation (can be of image or html resource for now) |
---|
406 | loadURL: function(url, type) { | | loadURL: function(url, type) { |
---|
407 | //console.log('loadURL()'); | | //console.log('loadURL()'); |
---|
408 | if(this.source !== 'ocd') { | | if(this.source !== 'ocd') { |
---|
409 | $('#ocd-results').hide(); | | $('#ocd-results').hide(); |
---|
410 | } | | } |
---|
411 | $('#img-annotation-wrapper').show(); | | $('#img-annotation-wrapper').show(); |
---|
412 | if(!url || !url.match(/http/)) { | | if(!url || !url.match(/http/)) { |
---|
413 | this.helpview.step(13); | | this.helpview.step(13); |
---|
414 | return false; | | return false; |
---|
415 | } | | } |
---|
416 | // if type is given explicitly; we load it as such. | | // if type is given explicitly; we load it as such. |
---|
417 | if(type === 'image') { | | if(type === 'image') { |
---|
418 | if(swtr.imgAnnoView) { | | if(swtr.imgAnnoView) { |
---|
419 | swtr.imgAnnoView.setImage(url); | | swtr.imgAnnoView.setImage(url); |
---|
420 | } | | } |
---|
421 | else { | | else { |
---|
422 | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, | | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, |
---|
423 | img: this.$img[0], | | img: this.$img[0], |
---|
424 | $img: this.$img, | | $img: this.$img, |
---|
425 | url: url}); | | url: url}); |
---|
426 | } | | } |
---|
427 | return false; | | return false; |
---|
428 | } | | } |
---|
429 | // else try to find what resource is the URL.. | | // else try to find what resource is the URL.. |
---|
430 | // if url has an image extension then load the image annotation | | // if url has an image extension then load the image annotation |
---|
431 | if(url.match(/.jpg|.jpeg|.png|.gif|.bmp|.svg/)) { | | if(url.match(/.jpg|.jpeg|.png|.gif|.bmp|.svg/)) { |
---|
432 | if(swtr.imgAnnoView) { | | if(swtr.imgAnnoView) { |
---|
433 | swtr.imgAnnoView.setImage(url); | | swtr.imgAnnoView.setImage(url); |
---|
434 | } | | } |
---|
435 | else { | | else { |
---|
436 | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, | | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, |
---|
437 | img: this.$img[0], | | img: this.$img[0], |
---|
438 | $img: this.$img, | | $img: this.$img, |
---|
439 | url: url}); | | url: url}); |
---|
440 | } | | } |
---|
441 | | | |
---|
442 | return false; | | return false; |
---|
443 | } | | } |
---|
444 | // else check with our /media-type endpoint to see what type of resource | | // else check with our /media-type endpoint to see what type of resource |
---|
445 | // it is | | // it is |
---|
446 | else { | | else { |
---|
447 | this.helpview.step(12); | | this.helpview.step(12); |
---|
448 | this.$overlay.show(); | | this.$overlay.show(); |
---|
449 | var self = this; | | var self = this; |
---|
450 | $.get('/media-type', {where: url}, function(response) { | | $.get('/media-type', {where: url}, function(response) { |
---|
451 | //console.log(response); | | //console.log(response); |
---|
452 | self.$overlay.hide(); | | self.$overlay.hide(); |
---|
453 | if(response.type === 'image') { | | if(response.type === 'image') { |
---|
454 | if(swtr.imgAnnoView) { | | if(swtr.imgAnnoView) { |
---|
455 | swtr.imgAnnoView.setImage(url); | | swtr.imgAnnoView.setImage(url); |
---|
456 | } | | } |
---|
457 | else { | | else { |
---|
458 | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, | | swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, |
---|
459 | img: self.$img[0], | | img: self.$img[0], |
---|
460 | $img: self.$img, | | $img: self.$img, |
---|
461 | url: url}); | | url: url}); |
---|
462 | } | | } |
---|
463 | } | | } |
---|
464 | else { | | else { |
---|
465 | window.location.href = '/annotate?where=' + url; | | window.location.href = '/annotate?where=' + url; |
---|
466 | } | | } |
---|
467 | }); | | }); |
---|
468 | } | | } |
---|
469 | }, | | }, |
---|
470 | getSweets: function() { | | getSweets: function() { |
---|
471 | var annos = _.filter(anno.getAnnotations(), function(anno) { | | var annos = _.filter(anno.getAnnotations(), function(anno) { |
---|
472 | return (!_.has(anno, 'editable') || anno.editable === true); | | return (!_.has(anno, 'editable') || anno.editable === true); |
---|
473 | }); | | }); |
---|
474 | | | |
---|
475 | _.each(annos, function(anno) { | | _.each(annos, function(anno) { |
---|
476 | swtr.sweets.add({ | | swtr.sweets.add({ |
---|
477 | who: swtr.who, | | who: swtr.who, |
---|
478 | where: anno.src, | | where: anno.src, |
---|
479 | // remove the text field; we don't want to store that in the sweets | | // remove the text field; we don't want to store that in the sweets |
---|
480 | how: _.omit(anno, 'text') | | how: _.omit(anno, 'text') |
---|
481 | }); | | }); |
---|
482 | }); | | }); |
---|
483 | }, | | }, |
---|
484 | showSweets: function() { | | showSweets: function() { |
---|
485 | this.sweetsview.render(); | | this.sweetsview.render(); |
---|
486 | }, | | }, |
---|
487 | sweet: function() { | | sweet: function() { |
---|
488 | this.getSweets(); | | this.getSweets(); |
---|
489 | this.showSweets(); | | this.showSweets(); |
---|
490 | return false; | | return false; |
---|
491 | }, | | }, |
---|
492 | signIn: function(event) { | | signIn: function(event) { |
---|
493 | event.preventDefault(); | | event.preventDefault(); |
---|
494 | this.oauth.authorize(); | | this.oauth.authorize(); |
---|
495 | return false; | | return false; |
---|
496 | }, | | }, |
---|
497 | userLoggedIn: function(username) { | | userLoggedIn: function(username) { |
---|
498 | swtr.who = username; | | swtr.who = username; |
---|
499 | var text = 'Signed in as <b>' + swtr.who + '</b>'; | | var text = 'Signed in as <b>' + swtr.who + '</b>'; |
---|
500 | $('#signinview').html(text); | | $('#signinview').html(text); |
---|
501 | }, | | }, |
---|
502 | userLoggedOut: function() { | | userLoggedOut: function() { |
---|
503 | swtr.who = 'Guest'; | | swtr.who = 'Guest'; |
---|
504 | $('#signinview').html('Logged out'); | | $('#signinview').html('Logged out'); |
---|
505 | }, | | }, |
---|
506 | changeURLInputPlaceholder: function(source) { | | changeURLInputPlaceholder: function(source) { |
---|
507 | switch (source) { | | switch (source) { |
---|
508 | case 'ocd' : $('#user-input').attr('placeholder', 'Enter search query'); | | case 'ocd' : $('#user-input').attr('placeholder', 'Enter search query'); |
---|
509 | break; | | break; |
---|
510 | case 'none' : $('#user-input').attr('placeholder', 'Enter URL of image or web page'); | | case 'none' : $('#user-input').attr('placeholder', 'Enter URL of image or web page'); |
---|
511 | break; | | break; |
---|
512 | } | | } |
---|
513 | }, | | }, |
---|
514 | // function to change the source in the application and update the UI | | // function to change the source in the application and update the UI |
---|
515 | changeSource: function(source) { | | changeSource: function(source) { |
---|
516 | switch (source) { | | switch (source) { |
---|
517 | case 'ocd' : this.source = 'ocd'; | | case 'ocd' : this.source = 'ocd'; |
---|
518 | this.helpview.step(11); | | this.helpview.step(11); |
---|
519 | this.changeURLInputPlaceholder('ocd'); | | this.changeURLInputPlaceholder('ocd'); |
---|
520 | break; | | break; |
---|
521 | case 'none' : this.source = 'none'; | | case 'none' : this.source = 'none'; |
---|
522 | this.helpview.step(1); | | this.helpview.step(1); |
---|
523 | this.changeURLInputPlaceholder('none'); | | this.changeURLInputPlaceholder('none'); |
---|
524 | break; | | break; |
---|
525 | } | | } |
---|
526 | }, | | }, |
---|
527 | // event handler to capture control panel UI change of source | | // event handler to capture control panel UI change of source |
---|
528 | sourceChanged: function(event) { | | sourceChanged: function(event) { |
---|
529 | if($('#ocd-source').is(':checked')) { | | if($('#ocd-source').is(':checked')) { |
---|
530 | this.changeSource('ocd'); | | this.changeSource('ocd'); |
---|
531 | } | | } |
---|
532 | else { | | else { |
---|
533 | this.changeSource('none'); | | this.changeSource('none'); |
---|
534 | } | | } |
---|
535 | }, | | }, |
---|
536 | loadOCDSearch: function(input) { | | loadOCDSearch: function(input) { |
---|
537 | var self = this; | | var self = this; |
---|
538 | $('#img-annotation-wrapper').hide(); | | $('#img-annotation-wrapper').hide(); |
---|
539 | $('#ocd-results').show(); | | $('#ocd-results').show(); |
---|
540 | $('#ocd-results').html('<h4 style="text-align: center;">Loading..</h4>'); | | $('#ocd-results').html('<h4 style="text-align: center;">Loading..</h4>'); |
---|
541 | $.ajax({ | | $.ajax({ |
---|
542 | type: 'GET', | | type: 'GET', |
---|
543 | url: '/search/ocd', | | url: '/search/ocd', |
---|
544 | data: {query: input}, | | data: {query: input}, |
---|
545 | success: function(data) { | | success: function(data) { |
---|
546 | self.ocdView = new OCDView({ | | self.ocdView = new OCDView({ |
---|
547 | query: input, | | query: input, |
---|
548 | data: data, | | data: data, |
---|
549 | model: data.hits.hits | | model: data.hits.hits |
---|
550 | }); | | }); |
---|
551 | } | | } |
---|
552 | }); | | }); |
---|
553 | } | | } |
---|
554 | }); | | }); |
---|
555 | | | |
---|
556 | var OCDView = Backbone.View.extend({ | | var OCDView = Backbone.View.extend({ |
---|
557 | el: $('#ocd-view'), | | el: $('#ocd-view'), |
---|
558 | events: { | | events: { |
---|
559 | 'click .ocd-item a': 'onImgClick', | | 'click .ocd-item a': 'onImgClick', |
---|
560 | 'click .pager li': 'onPagerClick' | | 'click .pager li': 'onPagerClick' |
---|
561 | }, | | }, |
---|
562 | initialize: function(opts) { | | initialize: function(opts) { |
---|
563 | this.data = opts.data || {}; | | this.data = opts.data || {}; |
---|
564 | this.query = opts.query || ''; | | this.query = opts.query || ''; |
---|
565 | this.size = 9; // num of items per page | | this.size = 9; // num of items per page |
---|
566 | this.page = 0; | | this.page = 0; |
---|
567 | this.item_template = _.template($('#ocd-item-template').html()); | | this.item_template = _.template($('#ocd-item-template').html()); |
---|
568 | this.base_template = _.template($('#ocd-view-base-template').html()); | | this.base_template = _.template($('#ocd-view-base-template').html()); |
---|
569 | this.render(); | | this.render(); |
---|
570 | }, | | }, |
---|
571 | render: function() { | | render: function() { |
---|
572 | var $row_el; | | var $row_el; |
---|
573 | this.$el.html(''); | | this.$el.html(''); |
---|
574 | if(!this.model.length) { | | if(!this.model.length) { |
---|
575 | this.$el.html('No results could be found from your query.'); | | this.$el.html('No results could be found from your query.'); |
---|
576 | return; | | return; |
---|
577 | } | | } |
---|
578 | this.$el.html(this.base_template()); | | this.$el.html(this.base_template()); |
---|
579 | var $el = $('#ocd-results'); | | var $el = $('#ocd-results'); |
---|
580 | _.each(this.model, function(item, idx) { | | _.each(this.model, function(item, idx) { |
---|
581 | // put every 3 items in a row | | // put every 3 items in a row |
---|
582 | if(idx % 3 === 0) { | | if(idx % 3 === 0) { |
---|
583 | $row_el = $('<div class="row"></div>'); | | $row_el = $('<div class="row"></div>'); |
---|
584 | $el.append($row_el); | | $el.append($row_el); |
---|
585 | } | | } |
---|
586 | $row_el.append(this.item_template({ | | $row_el.append(this.item_template({ |
---|
587 | title: item._source.title, | | title: item._source.title, |
---|
588 | media_url: item._source.media_urls[0].url, | | media_url: item._source.media_urls[0].url, |
---|
589 | authors: item._source.authors | | authors: item._source.authors |
---|
590 | })); | | })); |
---|
591 | }, this); | | }, this); |
---|
592 | this.resolveOCDURLs(); | | this.resolveOCDURLs(); |
---|
593 | this.appendTotal(); | | this.appendTotal(); |
---|
594 | }, | | }, |
---|
595 | appendTotal: function() { | | appendTotal: function() { |
---|
596 | $('#ocd-total-results').html(this.data.hits.total + ' results found.'); | | $('#ocd-total-results').html(this.data.hits.total + ' results found.'); |
---|
597 | }, | | }, |
---|
598 | // resolve the OCD media URLs | | // resolve the OCD media URLs |
---|
599 | resolveOCDURLs: function() { | | resolveOCDURLs: function() { |
---|
600 | var self = this; | | var self = this; |
---|
601 | $('.ocd-item').each(function(idx, elem) { | | $('.ocd-item').each(function(idx, elem) { |
---|
602 | var temp_arr = self.model[idx]._source.media_urls[0].url.split('/'); | | var temp_arr = self.model[idx]._source.media_urls[0].url.split('/'); |
---|
603 | var media_hash = temp_arr[temp_arr.length - 1]; | | var media_hash = temp_arr[temp_arr.length - 1]; |
---|
604 | $.get('/resolve-ocd-media', {hash: media_hash}, function(resp) { | | $.get('/resolve-ocd-media', {hash: media_hash}, function(resp) { |
---|
605 | $(elem).find('img').attr('src', resp.url); | | $(elem).find('img').attr('src', resp.url); |
---|
606 | }); | | }); |
---|
607 | }); | | }); |
---|
608 | }, | | }, |
---|
609 | rerender: function(data) { | | rerender: function(data) { |
---|
610 | this.data = data; | | this.data = data; |
---|
611 | this.model = data.hits.hits; | | this.model = data.hits.hits; |
---|
612 | this.render(); | | this.render(); |
---|
613 | }, | | }, |
---|
614 | onPagerClick: function(event) { | | onPagerClick: function(event) { |
---|
615 | event.preventDefault(); | | event.preventDefault(); |
---|
616 | var elem = $(event.currentTarget); | | var elem = $(event.currentTarget); |
---|
617 | var self = this; | | var self = this; |
---|
618 | if(elem.hasClass('next')) { | | if(elem.hasClass('next')) { |
---|
619 | if((this.page + 1) * this.size >= this.data.hits.total) { | | if((this.page + 1) * this.size >= this.data.hits.total) { |
---|
620 | console.log('no next page to go to'); | | console.log('no next page to go to'); |
---|
621 | return false; | | return false; |
---|
622 | } | | } |
---|
623 | console.log('clicked next'); | | console.log('clicked next'); |
---|
624 | this.search({ | | this.search({ |
---|
625 | query: this.query, | | query: this.query, |
---|
626 | from: (this.page + 1) * this.size | | from: (this.page + 1) * this.size |
---|
627 | }, function(resp) { | | }, function(resp) { |
---|
628 | console.log('reached next page'); | | console.log('reached next page'); |
---|
629 | self.page = self.page + 1; | | self.page = self.page + 1; |
---|
630 | self.rerender(resp); | | self.rerender(resp); |
---|
631 | }); | | }); |
---|
632 | } | | } |
---|
633 | else if (elem.hasClass('previous')) { | | else if (elem.hasClass('previous')) { |
---|
634 | if(this.page <= 0) { | | if(this.page <= 0) { |
---|
635 | console.log('no prev page to go to'); | | console.log('no prev page to go to'); |
---|
636 | return false; | | return false; |
---|
637 | } | | } |
---|
638 | console.log('clicked prev'); | | console.log('clicked prev'); |
---|
639 | this.search({ | | this.search({ |
---|
640 | query: this.query, | | query: this.query, |
---|
641 | from: (this.page - 1) * this.size | | from: (this.page - 1) * this.size |
---|
642 | }, function(resp) { | | }, function(resp) { |
---|
643 | console.log('reached prev page'); | | console.log('reached prev page'); |
---|
644 | self.page = self.page - 1; | | self.page = self.page - 1; |
---|
645 | self.rerender(resp); | | self.rerender(resp); |
---|
646 | }); | | }); |
---|
647 | } | | } |
---|
648 | return false; | | return false; |
---|
649 | }, | | }, |
---|
650 | onImgClick: function(event) { | | onImgClick: function(event) { |
---|
651 | event.preventDefault(); | | event.preventDefault(); |
---|
652 | // TODO: init the image anno | | // TODO: init the image anno |
---|
653 | var url = $(event.currentTarget).find('img').attr('src'); | | var url = $(event.currentTarget).find('img').attr('src'); |
---|
654 | swtr.appView.loadURL(url, 'image'); | | swtr.appView.loadURL(url, 'image'); |
---|
655 | return false; | | return false; |
---|
656 | }, | | }, |
---|
657 | search: function(data, cb) { | | search: function(data, cb) { |
---|
658 | swtr.appView.$overlay.show(); | | swtr.appView.$overlay.show(); |
---|
659 | var self = this; | | var self = this; |
---|
660 | $.ajax({ | | $.ajax({ |
---|
661 | type: 'GET', | | type: 'GET', |
---|
662 | url: '/search/ocd', | | url: '/search/ocd', |
---|
663 | data: data, | | data: data, |
---|
664 | success: function(resp) { | | success: function(resp) { |
---|
665 | swtr.appView.$overlay.hide(); | | swtr.appView.$overlay.hide(); |
---|
666 | cb(resp); | | cb(resp); |
---|
667 | } | | } |
---|
668 | }); | | }); |
---|
669 | } | | } |
---|
670 | }); | | }); |
---|
671 | | | |
---|
672 | var HelpView = Backbone.View.extend({ | | var HelpView = Backbone.View.extend({ |
---|
673 | el: $('#helpview'), | | el: $('#helpview'), |
---|
674 | events: { | | events: { |
---|
675 | }, | | }, |
---|
676 | initialize: function() { | | initialize: function() { |
---|
677 | this.$text_el = $('#helpview-text'); | | this.$text_el = $('#helpview-text'); |
---|
678 | }, | | }, |
---|
679 | //TODO: move from number based steps to something else. number based steps | | //TODO: move from number based steps to something else. number based steps |
---|
680 | //implicitly imply sequential processing..which does not happen in this | | //implicitly imply sequential processing..which does not happen in this |
---|
681 | //case.. | | //case.. |
---|
682 | //following helps can be async.. | | //following helps can be async.. |
---|
683 | step: function(n) { | | step: function(n) { |
---|
684 | var text = ''; | | var text = ''; |
---|
685 | switch (n) { | | switch (n) { |
---|
686 | case 0 : text = 'Getting annotations..'; | | case 0 : text = 'Getting annotations..'; |
---|
687 | break; | | break; |
---|
688 | case 1: text = 'Enter URL of an image or web page below, and start annotating!'; | | case 1: text = 'Enter URL of an image or web page below, and start annotating!'; |
---|
689 | break; | | break; |
---|
690 | case 2: text = 'Annotate the image, or see other annotations'; | | case 2: text = 'Annotate the image, or see other annotations'; |
---|
691 | break; | | break; |
---|
692 | case 3: text = 'Now you can sweet this annotation, or add more annotations'; | | case 3: text = 'Now you can sweet this annotation, or add more annotations'; |
---|
693 | break; | | break; |
---|
694 | case 4: text = 'Click Sweet button to publish these annotations to the Sweet Store'; | | case 4: text = 'Click Sweet button to publish these annotations to the Sweet Store'; |
---|
695 | break; | | break; |
---|
696 | case 5: text = 'Publishing your sweets'; | | case 5: text = 'Publishing your sweets'; |
---|
697 | break; | | break; |
---|
698 | case 6: text = 'Sweets successfully posted'; | | case 6: text = 'Sweets successfully posted'; |
---|
699 | break; | | break; |
---|
700 | case 7: text = 'Fetching your image..'; | | case 7: text = 'Fetching your image..'; |
---|
701 | break; | | break; |
---|
702 | case 8: text = 'Oops! Seems like the image URL is wrong! Or we couldn\'t fetch the image.'; | | case 8: text = 'Oops! Seems like the image URL is wrong! Or we couldn\'t fetch the image.'; |
---|
703 | break; | | break; |
---|
704 | case 9: text = 'You have to be <i>signed in</i> to sweet store to post sweets'; | | case 9: text = 'You have to be <i>signed in</i> to sweet store to post sweets'; |
---|
705 | break; | | break; |
---|
706 | case 10: text = 'Oops! Something went wrong. We couldn\'t publish the sweets. Try again.' | | case 10: text = 'Oops! Something went wrong. We couldn\'t publish the sweets. Try again.' |
---|
707 | break; | | break; |
---|
708 | case 11: text = 'Search in <a href="http://www.opencultuurdata.nl/">Open Cuultur Data API</a>'; | | case 11: text = 'Search in <a href="http://www.opencultuurdata.nl/">Open Cuultur Data API</a>'; |
---|
709 | break; | | break; |
---|
710 | case 12: text = 'Analyzing the resource type..'; | | case 12: text = 'Analyzing the resource type..'; |
---|
711 | break; | | break; |
---|
712 | case 13: text = 'This does not seem to be a URL. Please enter a valid URL.'; | | case 13: text = 'This does not seem to be a URL. Please enter a valid URL.'; |
---|
713 | break; | | break; |
---|
714 | } | | } |
---|
715 | $(this.$text_el).html(text); | | $(this.$text_el).html(text); |
---|
716 | $(window).scrollTop(0, 0); | | $(window).scrollTop(0, 0); |
---|
717 | } | | } |
---|
718 | }); | | }); |
---|
719 | | | |
---|
720 | | | |
---|
721 | // utilities and helper functions to go here | | // utilities and helper functions to go here |
---|
722 | swtr.utils = { | | swtr.utils = { |
---|
723 | linkify: function(link) { | | linkify: function(link) { |
---|
724 | if(link.match('http')) { | | if(link.match('http')) { |
---|
725 | return link; | | return link; |
---|
726 | } | | } |
---|
727 | else { | | else { |
---|
728 | return 'http://' + link; | | return 'http://' + link; |
---|
729 | } | | } |
---|
730 | } | | } |
---|
731 | }; | | }; |
---|
732 | //swtr.AppView = AppView; | | //swtr.AppView = AppView; |
---|
733 | | | |
---|
734 | var AppRouter = Backbone.Router.extend({ | | var AppRouter = Backbone.Router.extend({ |
---|
735 | routes: { | | routes: { |
---|
736 | 'home': 'home', | | 'home': 'home', |
---|
737 | 'linked-data': 'linkedData', | | 'linked-data': 'linkedData', |
---|
738 | 'play': 'play', | | 'play': 'play', |
---|
739 | 'search': 'search' | | 'search': 'search' |
---|
740 | }, | | }, |
---|
741 | home: function() { | | home: function() { |
---|
742 | this.hideAll(); | | this.hideAll(); |
---|
743 | this.show('home-page'); | | this.show('home-page'); |
---|
744 | }, | | }, |
---|
745 | linkedData: function() { | | linkedData: function() { |
---|
746 | this.hideAll(); | | this.hideAll(); |
---|
747 | this.show('linked-data-page'); | | this.show('linked-data-page'); |
---|
748 | }, | | }, |
---|
749 | play: function() { | | play: function() { |
---|
750 | this.hideAll(); | | this.hideAll(); |
---|
751 | this.show('play-page'); | | this.show('play-page'); |
---|
752 | }, | | }, |
---|
753 | search: function() { | | search: function() { |
---|
754 | this.hideAll(); | | this.hideAll(); |
---|
755 | this.show('search-page'); | | this.show('search-page'); |
---|
756 | }, | | }, |
---|
757 | hideAll: function() { | | hideAll: function() { |
---|
758 | $('.page').hide(); | | $('.page').hide(); |
---|
759 | }, | | }, |
---|
760 | show: function(id) { | | show: function(id) { |
---|
761 | $('#' + id).show(); | | $('#' + id).show(); |
---|
762 | this.highlight(id); | | this.highlight(id); |
---|
763 | }, | | }, |
---|
764 | highlight: function(id) { | | highlight: function(id) { |
---|
765 | $('#swtr-navbar-collapse li').removeClass('active'); | | $('#swtr-navbar-collapse li').removeClass('active'); |
---|
766 | var href = id.split('-page')[0]; | | var href = id.split('-page')[0]; |
---|
767 | var selector = '#swtr-navbar-collapse a[href="#/' + href + '"]'; | | var selector = '#swtr-navbar-collapse a[href="#/' + href + '"]'; |
---|
768 | $(selector).parent('li').addClass('active'); | | $(selector).parent('li').addClass('active'); |
---|
769 | } | | } |
---|
770 | }); | | }); |
---|
771 | | | |
---|
772 | })(swtr); | | })(swtr); |
---|
| | | | 179 | <script src="{{ url_for('static', filename='js/lib/custom-fields-plugin.js') }}"></script> | 179 | <script src="{{ url_for('static', filename='js/lib/custom-fields-plugin.js') }}"></script> |
---|
180 | <script src="{{ url_for('static', filename='js/oauth.js') }}"></script> | 180 | <script src="{{ url_for('static', filename='js/oauth.js') }}"></script> |
---|
181 | <script type="text/javascript" src="{{ url_for('static', filename='js/lib/bootstrap-tags.min.js') }}"></script> | 181 | <script type="text/javascript" src="{{ url_for('static', filename='js/lib/bootstrap-tags.min.js') }}"></script> |
---|
182 | <script src="{{ url_for('static', filename='js/imganno.js') }}"></script> | | <script src="{{ url_for('static', filename='js/imganno.js') }}"></script> |
---|
183 | <script src="{{ url_for('static', filename='js/swtmaker.js') }}"></script> | | <script src="{{ url_for('static', filename='js/swtmaker.js') }}"></script> |
---|
| | 182 | <script src="{{ url_for('static', filename='js/img_swtr.js') }}"></script> | | | 183 | <script src="{{ url_for('static', filename='js/main.js') }}"></script> |
---|
184 | | 184 | |
---|
185 | <script type="text/template" id="sweet-template"> | 185 | <script type="text/template" id="sweet-template"> |
---|
186 | <li class="sweet"> | 186 | <li class="sweet"> |
---|