--- /dev/null +++ b/swtr/static/js/img_swtr.js @@ -1 +1,229 @@ +(function(swtr) { + swtr.ImgAnnoView = Backbone.View.extend({ + el: $("#img-annotation-wrapper"), + events: { + 'change #custom-dropdown ': 'getFormValue', + 'click #setbox': 'showHide' + }, + initialize: function(options) { + this.listenTo(this.collection, 'add', this.render); + // attach event handlers to the anno object + anno.addHandler('onAnnotationCreated', this.showSwtHelp); + anno.addHandler('onAnnotationCreated', this.updateNewAnno); + anno.addHandler('onAnnotationUpdated', this.showSwtHelp); + anno.addHandler('onSelectionStarted', function(annotation) { + anno.hideAnnotations(); + }); + anno.addHandler('onSelectionCompleted', function(annotation) { + anno.showAnnotations(); + }); + anno.addPlugin('CustomFields', {}); + anno.addHandler('onSelectionCompleted', this.hideOriginalEditor); + if(options.img) { + this.img = options.img; + this.$img = options.$img; + options.$img.on('load', this, this.imageLoaded); + options.$img.on('error', this, this.onImageLoadError); + this.setImage(options.url); + } + }, + render: function(model) { + var swt = model.toJSON(); + swt.how['editable'] = false; + swt.how.text = swtr.imgAnnoView.createPopupText(swt.how); + swt.how.text += '\n - by ' + swt.who; + anno.addAnnotation(swt.how); + }, + renderWith: function() { + _.each(this.collection, this.render); + }, + showSwtHelp: function(annotation) { + var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback + swtr.appView.helpview.step(3); + $('#sweet').show(); + }, + updateNewAnno: function(annotation) { + console.log('updateNewAnno()'); + var self = swtr.imgAnnoView; + // get the final value/input from the editor + var selected = $('select option:selected').text().toLowerCase(); + var text_input = $('.annotorious-editor-text').val(); + if( selected === "tags") { + self.new_anno[selected] = $('#tags-input').tags().getTags(); + } + else { + // update it in our annotation object + self.new_anno[selected] = text_input; + } + // prepare the text field + self.new_anno.text = self.createPopupText(self.new_anno); + // update the annotorious annotation object with the new values + if(self.new_anno.comment) { + annotation.comment = self.new_anno.comment; + } + if(self.new_anno.link) { + annotation.link = self.new_anno.link; + } + if(self.new_anno.tags) { + annotation.tags = self.new_anno.tags; + } + if(self.new_anno.title) { + annotation.title = self.new_anno.title; + } + annotation.text = self.new_anno.text; + console.log(self.new_anno, annotation); + }, + // hide the original editor window, when user has completed selecting part + // of the image to annotate.. + hideOriginalEditor: function(annotation) { + console.log('hideOriginalEditor()'); + var self = swtr.imgAnnoView; + self.new_anno = {}; + self.getSuggestionsForTags(); + //$('.annotorious-editor-text').hide(); + //$('.annotorious-editor').css('width', '100%'); + }, + getFormValue: function(event) { + console.log('getFormValue()'); + + var self = swtr.imgAnnoView; + // show the editor field to input text + var $anno_form = $('.annotorious-editor-text'); + //$anno_form.slideDown(); + // get the previous item entered + var $selected = $('select option:selected'); + var text_input = $anno_form.val(); + + // if there was a input and it was not tags.. + if(text_input && $selected.prev().text() !== 'Tags') { + var field = $selected.prev().text().toLowerCase(); + // update it in our annotation object + self.new_anno[field] = text_input; + } + // if it was tags.. + else if ($selected.prev().text() === 'Tags') { + // directly save it.. + self.new_anno['tags'] = $('#tags-input').tags().getTags(); + } + + // if the current selected is tags + if($selected.text() === 'Tags') { + $('#tags-input').tags({ + tagSize: 'md', + promptText: 'Type word (and press enter)..', + caseInsensitive: true, + suggestions: self.tags_suggestions + }); + $('#tags-input').show(); + $('.annotorious-editor-text').hide(); + } + else { + $('#tags-input').hide(); + $('.annotorious-editor-text').show(); + } + $anno_form.val(''); + $anno_form.attr('placeholder', 'Add ' + $selected.text()); + console.log(self.new_anno); + }, + createPopupText: function(annotation) { + // title + var text = (annotation.title) ? '

' + annotation.title + '

' : ''; + + // comment + text += (annotation.comment) ? '

' + annotation.comment + '

' : ''; + + // link + text += (annotation.link) ? '' + annotation.link + + '' : ''; + + // tags + text += (annotation.tags) ? '

' + annotation.tags + '

' : ''; + + // if older annotation i.e w/o comment,title etc fields + // add text field as text + if(!text) { + text = annotation.text; + } + return text; + }, + // load the suggestions for the tag spraying.. + getSuggestionsForTags: function() { + var self = swtr.imgAnnoView; + $.ajax({ + url: '/static/data/tags_suggestions.json', + success: function(data) { + self.tags_suggestions = data; + } + }); + }, + setImage: function(url) { + this.imgURL = url; + console.log(url); + if(this.$img.attr('src') === this.imgURL) { + return; + } + anno.reset(); + var self = this; + swtr.appView.$overlay.show(); + swtr.appView.helpview.step(7); + this.$img.attr('src', this.imgURL); + }, + imageLoaded: function(event) { + var self = event.data; + console.log('image loaded', self); + swtr.appView.$overlay.hide(); + // reset the collection + swtr.sweets.reset(); + anno.makeAnnotatable(swtr.imgAnnoView.img); + swtr.imgAnnoView.getExistingAnnotations(); + }, + // when image fails to load - could be because of broken URL or network + // issues + onImageLoadError: function(event) { + var self = event.data; + console.log('error while loading image'); + swtr.appView.$overlay.hide(); + swtr.appView.helpview.step(8); + }, + initImageAnno: function() { + // img is a jquery object which annotorious doesn't accept; instead it + // takes the native object returned by a browser API; fortunately, jqeury + // stores a copy of the native object too! + + this.getExistingAnnotations(); + + }, + getExistingAnnotations: function() { + var self = this; + swtr.appView.helpview.step(0); + swtr.appView.$overlay.show(); + swtr.sweets.getAll({ + where: this.imgURL, + success: function(data) { + if(_.isArray(data)) { + swtr.sweets.add(data); + swtr.appView.$overlay.hide(); + swtr.appView.helpview.step(2); + } + }, + error: function(jqxhr, error, statusText) { + if(jqxhr.status === 404) { //annotations don't exist for this image + console.log('annotations don\'t exist for this image. Create one!'); + } + swtr.appView.$overlay.hide(); + swtr.appView.helpview.step(2); + } + }); + }, + showHide: function() { + if($("#setbox:checked").length) { + $('.annotorious-item-unfocus').css("opacity", "0.5"); + } + else { + $('.annotorious-item-unfocus').css("opacity", "0"); + } + } + }); +})(swtr); --- a/swtr/static/js/imganno.js +++ /dev/null @@ -1,229 +1 @@ -(function(swtr) { - swtr.ImgAnnoView = Backbone.View.extend({ - el: $("#img-annotation-wrapper"), - events: { - 'change #custom-dropdown ': 'getFormValue', - 'click #setbox': 'showHide' - }, - initialize: function(options) { - this.listenTo(this.collection, 'add', this.render); - // attach event handlers to the anno object - anno.addHandler('onAnnotationCreated', this.showSwtHelp); - anno.addHandler('onAnnotationCreated', this.updateNewAnno); - anno.addHandler('onAnnotationUpdated', this.showSwtHelp); - anno.addHandler('onSelectionStarted', function(annotation) { - anno.hideAnnotations(); - }); - anno.addHandler('onSelectionCompleted', function(annotation) { - anno.showAnnotations(); - }); - anno.addPlugin('CustomFields', {}); - anno.addHandler('onSelectionCompleted', this.hideOriginalEditor); - if(options.img) { - this.img = options.img; - this.$img = options.$img; - options.$img.on('load', this, this.imageLoaded); - options.$img.on('error', this, this.onImageLoadError); - this.setImage(options.url); - } - }, - render: function(model) { - var swt = model.toJSON(); - swt.how['editable'] = false; - swt.how.text = swtr.imgAnnoView.createPopupText(swt.how); - swt.how.text += '\n - by ' + swt.who; - anno.addAnnotation(swt.how); - }, - renderWith: function() { - _.each(this.collection, this.render); - }, - showSwtHelp: function(annotation) { - var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback - swtr.appView.helpview.step(3); - $('#sweet').show(); - }, - updateNewAnno: function(annotation) { - console.log('updateNewAnno()'); - var self = swtr.imgAnnoView; - // get the final value/input from the editor - var selected = $('select option:selected').text().toLowerCase(); - var text_input = $('.annotorious-editor-text').val(); - if( selected === "tags") { - self.new_anno[selected] = $('#tags-input').tags().getTags(); - } - else { - // update it in our annotation object - self.new_anno[selected] = text_input; - } - // prepare the text field - self.new_anno.text = self.createPopupText(self.new_anno); - // update the annotorious annotation object with the new values - if(self.new_anno.comment) { - annotation.comment = self.new_anno.comment; - } - if(self.new_anno.link) { - annotation.link = self.new_anno.link; - } - if(self.new_anno.tags) { - annotation.tags = self.new_anno.tags; - } - if(self.new_anno.title) { - annotation.title = self.new_anno.title; - } - annotation.text = self.new_anno.text; - console.log(self.new_anno, annotation); - }, - // hide the original editor window, when user has completed selecting part - // of the image to annotate.. - hideOriginalEditor: function(annotation) { - console.log('hideOriginalEditor()'); - var self = swtr.imgAnnoView; - self.new_anno = {}; - self.getSuggestionsForTags(); - //$('.annotorious-editor-text').hide(); - //$('.annotorious-editor').css('width', '100%'); - }, - getFormValue: function(event) { - console.log('getFormValue()'); - - var self = swtr.imgAnnoView; - // show the editor field to input text - var $anno_form = $('.annotorious-editor-text'); - //$anno_form.slideDown(); - // get the previous item entered - var $selected = $('select option:selected'); - var text_input = $anno_form.val(); - - // if there was a input and it was not tags.. - if(text_input && $selected.prev().text() !== 'Tags') { - var field = $selected.prev().text().toLowerCase(); - // update it in our annotation object - self.new_anno[field] = text_input; - } - // if it was tags.. - else if ($selected.prev().text() === 'Tags') { - // directly save it.. - self.new_anno['tags'] = $('#tags-input').tags().getTags(); - } - - // if the current selected is tags - if($selected.text() === 'Tags') { - $('#tags-input').tags({ - tagSize: 'md', - promptText: 'Type word (and press enter)..', - caseInsensitive: true, - suggestions: self.tags_suggestions - }); - $('#tags-input').show(); - $('.annotorious-editor-text').hide(); - } - else { - $('#tags-input').hide(); - $('.annotorious-editor-text').show(); - } - $anno_form.val(''); - $anno_form.attr('placeholder', 'Add ' + $selected.text()); - console.log(self.new_anno); - }, - createPopupText: function(annotation) { - // title - var text = (annotation.title) ? '

' + annotation.title + '

' : ''; - - // comment - text += (annotation.comment) ? '

' + annotation.comment + '

' : ''; - - // link - text += (annotation.link) ? '' + annotation.link + - '' : ''; - - // tags - text += (annotation.tags) ? '

' + annotation.tags + '

' : ''; - - // if older annotation i.e w/o comment,title etc fields - // add text field as text - if(!text) { - text = annotation.text; - } - return text; - }, - // load the suggestions for the tag spraying.. - getSuggestionsForTags: function() { - var self = swtr.imgAnnoView; - $.ajax({ - url: '/static/data/tags_suggestions.json', - success: function(data) { - self.tags_suggestions = data; - } - }); - }, - setImage: function(url) { - this.imgURL = url; - console.log(url); - if(this.$img.attr('src') === this.imgURL) { - return; - } - anno.reset(); - var self = this; - swtr.appView.$overlay.show(); - swtr.appView.helpview.step(7); - this.$img.attr('src', this.imgURL); - }, - imageLoaded: function(event) { - var self = event.data; - console.log('image loaded', self); - swtr.appView.$overlay.hide(); - // reset the collection - swtr.sweets.reset(); - anno.makeAnnotatable(swtr.imgAnnoView.img); - swtr.imgAnnoView.getExistingAnnotations(); - }, - // when image fails to load - could be because of broken URL or network - // issues - onImageLoadError: function(event) { - var self = event.data; - console.log('error while loading image'); - swtr.appView.$overlay.hide(); - swtr.appView.helpview.step(8); - }, - initImageAnno: function() { - // img is a jquery object which annotorious doesn't accept; instead it - // takes the native object returned by a browser API; fortunately, jqeury - // stores a copy of the native object too! - - this.getExistingAnnotations(); - - }, - getExistingAnnotations: function() { - var self = this; - swtr.appView.helpview.step(0); - swtr.appView.$overlay.show(); - swtr.sweets.getAll({ - where: this.imgURL, - success: function(data) { - if(_.isArray(data)) { - swtr.sweets.add(data); - swtr.appView.$overlay.hide(); - swtr.appView.helpview.step(2); - } - }, - error: function(jqxhr, error, statusText) { - if(jqxhr.status === 404) { //annotations don't exist for this image - console.log('annotations don\'t exist for this image. Create one!'); - } - swtr.appView.$overlay.hide(); - swtr.appView.helpview.step(2); - } - }); - }, - showHide: function() { - if($("#setbox:checked").length) { - $('.annotorious-item-unfocus').css("opacity", "0.5"); - } - else { - $('.annotorious-item-unfocus').css("opacity", "0"); - } - } - }); -})(swtr); --- /dev/null +++ b/swtr/static/js/main.js @@ -1 +1,773 @@ +(function(swtr) { + + //TODO: find a better way to init. + //Find a better way to do closure + //Remove script code from the HTML page + swtr.init = function() { + this.sweets = new ImgAnnoSwts(); + this.appView = new AppView(); + this.who = 'Guest'; + + this.app_router = new AppRouter(); + Backbone.history.start(); + this.app_router.navigate('home'); + + $.ajaxSetup({ + xhrFields: { + // we need this to send cookies to cross-domain requests + withCredentials: true + }, + //some browsers won't make cross-domain ajax until it is explicitly set + crossDomain: true + }); + this.handleOAuth(); + }; + + swtr.handleOAuth = function() { + if(swtr.access_token) { + $('#signinview').html('Signing you in..'); + $.ajax({ + url: swtr.swtstoreURL()+'/api/users/me?access_token='+ + swtr.access_token, + success: function(data) { + swtr.appView.userLoggedIn(data.username); + }, + error: function() { + $('#signinview').html('Error signing in! Please try again'); + } + }); + } + }; + + /* Model for Image Annotation Sweets */ + var ImgAnnoSwt = Backbone.Model.extend({ + defaults: { + 'who': '', + 'what': 'img-anno', + 'where': '', + 'how': {} + }, + initialize: function() { + } + }); + + /* Collection to hold all multiple ImgAnnoSwt */ + var ImgAnnoSwts = Backbone.Collection.extend({ + model: ImgAnnoSwt, + url: function() { + return swtr.swtstoreURL() + '/sweets'; + }, + // get all sweets/annotations of type #img-anno for a particular URI + // (where) + // @options is a javascript object, + // @options.where : URI of the resource for which swts to be fetched + // @options.who: optional username to filter sweets + // @options.success: success callback to call + // @options.error: error callback to call + getAll: function(options) { + // error checking + if(!options.where) { + throw Error('"where" option must be passed to get sweets of a URI'); + return false; + } + // setting up params + var where = options.where, + who = options.who || null; + url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' + + encodeURIComponent(where) + '&access_token=' + swtr.access_token; + if(who) { + url += '&who=' + who; + } + // get them! + this.sync('read', this, { + url: url, + success: function() { + if(typeof options.success === 'function') { + options.success.apply(this, arguments); + } + }, + error: function() { + if(typeof options.error === 'function') { + options.error.apply(this, arguments); + } + } + }); + }, + // post newly created sweets to a sweet store + // @options is a javascript object, + // @options.where : URI of the resource for which swts to be fetched + // @options.who: optional username to filter sweets + // @options.success: success callback to call + // @options.error: error callback to call, + post: function(options) { + var new_sweets = this.getNew(); + var dummy_collection = new Backbone.Collection(new_sweets); + + if(!swtr.access_token) { + throw new Error('Access Token is required to sweet'); + return; + } + + var url = swtr.swtstoreURL() + swtr.endpoints.post + + '?access_token=' + swtr.access_token; + + this.sync('create', dummy_collection, { + url: url, + success: function() { + if(typeof options.success === 'function') { + options.success.apply(this, arguments); + } + }, + error: function() { + if(typeof options.error === 'function') { + options.error.apply(this, arguments); + } + } + }); + }, + // return newly created models from the collection + getNew: function() { + var new_models = []; + this.each(function(model) { + if(model.isNew()) { + new_models.push(model); + } + }); + return new_models; + }, + // update part of the collection after a save on the server + update: function() { + } + }); + + var SweetsView = Backbone.View.extend({ + el: $('#sweet-list-wrapper'), + events: { + 'click #sweet-cancel': 'cancelSweeting', + 'click #post-sweet': 'postSweets' + }, + initialize: function() { + this.template = _.template($('#sweet-template').html()); + }, + render: function() { + $('#sweet-list').html('

These are your sweet annotations!

'); + _.each(this.collection.models, function(swt) { + if(swt.has('id')) { + return false; + } + $('#sweet-list').append(this.template({ + who: swt.get('who'), + what: swt.get('what'), + where: swt.get('where'), + how: JSON.stringify(this.getHumanReadableParts(swt.get('how'))) + })); + }, this); + $(this.el).fadeIn(300); + }, + getHumanReadableParts: function(how) { + var human_readable_json = {}; + if(how.comment) { + human_readable_json['comment'] = how.comment; + } + if(how.title) { + human_readable_json['title'] = how.title; + } + if(how.tags) { + human_readable_json['tags'] = how.tags; + } + if(how.link) { + human_readable_json['link'] = how.link; + } + return human_readable_json; + }, + cancelSweeting: function() { + this.removeSwtsNotPosted(); + this.cleanUp(); + }, + removeSwtsNotPosted: function() { + var notPosted = this.collection.filter(function(model) { + return !model.has('id'); + }); + this.collection.remove(notPosted); + }, + postSweets: function() { + console.log("postSWr"); + var appView = swtr.appView; + appView.helpview.step(5); + appView.$overlay.show(); + try { + this.collection.post({ + success: function(collection, response) { + console.log(collection, response); + swtr.sweets.set(collection); + //TODO: move this to a annotation view or something +// anno.removeAll(); + // _.each(swtr.sweets.models, function(swt) { + // if(!_.has(swt.get('how'), 'editable')) { + // swt.get('how')['editable'] = false; + // //console.log(swt.get('how').text.Comment); + // swt.get('how').text = swtr.imgAnnoView.createPopupText(swt.get('how')); + // //console.log(swt.get('how')); + // swt.get('how').text += '\n - by ' + swt.get('who'); + // } + // //console.log(swt.get('how')); + // anno.addAnnotation(swt.get('how')); + // }); + //console.log(swtr.sweets.toJSON()); + swtr.appView.$overlay.hide(); + swtr.appView.helpview.step(6); + }, + error: function(jqxhr, error, text) { + console.log(jqxhr, error, text); + swtr.appView.$overlay.hide(); + swtr.appView.helpview.step(10); + } + }); + } catch(e) { + if(e.message == 'Access Token is required to sweet') { + appView.$overlay.hide(); + appView.helpview.step(9); + } + } + this.cleanUp(); + return false; + }, + cleanUp: function() { + //console.log('cleaning up'); + $(this.el).hide(); + } + }); + + var FilterView = Backbone.View.extend({ + el: $('#filter-div'), + events: { + 'click #filter-user-div input': 'filter', + 'click #filter-tags-div input': 'filter' + }, + initialize: function() { + this.filter_users_template = _.template($('#filter-users').html()); + this.filter_tags_template = _.template($('#filter-tags').html()); + this.render(); + }, + render: function() { + //console.log(this.collection); + // pluck uniq authors of sweets + var authors = _.uniq(this.collection.pluck('who')); + // render them as filter controls + _.each(authors, function(author) { + $('#filter-user-div').append(this.filter_users_template({ + who: author + })); + }, this); + + // pluck uniq tags of sweets + var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). + uniq().value(); + // render them as filter controls + _.each(tags, function(tag) { + if(tag) { + $('#filter-tags-div').append(this.filter_tags_template({ + tag: tag + })); + } + }, this); + + //this.delegateEvents(); + }, + filter: function(event) { + // get id of div - parent to parent to the clicked input + var target_id = $(event.currentTarget).parent().parent().attr('id'); + // find out user/tag div + var which = target_id.split('-')[1]; + + var selected = []; + $('#'+target_id + ' input:checked').each(function() { + selected.push($(this).attr('name')); + }); + + if(which === 'user') { + this.filterUsers(selected); + } + else if(which === 'tags') { + this.filterTags(selected); + } + }, + filterUsers: function(users) { + if(!users.length) { + return; + } + var filtered_swts = this.collection.filter(function(model) { + if(_.indexOf(users, model.get('who')) > -1) { + return model; + } + }); + if(filtered_swts.length) { + anno.removeAll(); + _.each(filtered_swts, function(swt) { + anno.addAnnotation(swt.get('how')); + }); + } + }, + filterTags: function(tags) { + if(!tags.length) { + return; + } + var filtered_swts = this.collection.filter(function(model) { + //TODO: find a better way of doing this.. + var flag = false; + _.each(model.get('how').tags, function(tag) { + if(_.indexOf(tags, tag) > -1) { + flag = true; + } + }); + if(flag === true) { + return model; + } + }); + if(filtered_swts.length) { + anno.removeAll(); + _.each(filtered_swts, function(swt) { + anno.addAnnotation(swt.get('how')); + }); + } + }, + filterSweet: function(event) { + /*if(!event.currentTarget.checked) { + var results = this.collection.filter(function(model) { + if(model.get('who') != event.currentTarget.name) + return model; + }); + if(results.length) { + _.each(results, function(result) { + anno.removeAnnotation(result.get('how')); + }); + } + else { // if results is empty then remove all anno. + anno.removeAll(); + } + } + else { + results = this.collection.filter(function(model) { + if(model.get('who') == event.currentTarget.name) + return model; + }); + _.each(results, function(result) { + anno.addAnnotation(result.get('how')); + }); + + } + // if(results) { + // anno.removeAll(); + // } + // swtr.annoView.collection = results; + // swtr.annoView.renderWith();*/ + } + }); + + var AppView = Backbone.View.extend({ + el: $('body'), + events: { + 'click #user-input-submit': 'submitUserInput', + 'click #sweet': 'sweet', + 'click #sign-in': 'signIn', + 'click #ocd-source': 'sourceChanged' + //'mouseup .annotorious-editor-button-save': 'addnew_anno' + }, + initialize: function() { + // initialize components + this.source = 'none'; + this.helpview = new HelpView(); + this.sweetsview = new SweetsView({collection: swtr.sweets}); + + // cache jquery selected elements which are used frequently + this.$overlay = $('#app-overlay'); + this.$img = $('#annotatable-img'); + + this.helpview.step(1); + // initialize the oauth stuff + this.oauth = new Oauth({ + app_id: swtr.app_id, + endpoint: swtr.swtstoreURL() + swtr.endpoints.auth, + redirect_uri: swtr.oauth_redirect_uri, + scopes: 'email,sweet' + }); + }, + submitUserInput: function(event) { + event.preventDefault(); + var input = $('#user-input').val(); + if(this.source === 'ocd') { + this.loadOCDSearch(input); + } + else if (this.source === 'none') { + this.loadURL(input); + } + }, + // load a URL for annotation (can be of image or html resource for now) + loadURL: function(url, type) { + //console.log('loadURL()'); + if(this.source !== 'ocd') { + $('#ocd-results').hide(); + } + $('#img-annotation-wrapper').show(); + if(!url || !url.match(/http/)) { + this.helpview.step(13); + return false; + } + // if type is given explicitly; we load it as such. + if(type === 'image') { + if(swtr.imgAnnoView) { + swtr.imgAnnoView.setImage(url); + } + else { + swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, + img: this.$img[0], + $img: this.$img, + url: url}); + } + return false; + } + // else try to find what resource is the URL.. + // if url has an image extension then load the image annotation + if(url.match(/.jpg|.jpeg|.png|.gif|.bmp|.svg/)) { + if(swtr.imgAnnoView) { + swtr.imgAnnoView.setImage(url); + } + else { + swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, + img: this.$img[0], + $img: this.$img, + url: url}); + } + + return false; + } + // else check with our /media-type endpoint to see what type of resource + // it is + else { + this.helpview.step(12); + this.$overlay.show(); + var self = this; + $.get('/media-type', {where: url}, function(response) { + //console.log(response); + self.$overlay.hide(); + if(response.type === 'image') { + if(swtr.imgAnnoView) { + swtr.imgAnnoView.setImage(url); + } + else { + swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, + img: self.$img[0], + $img: self.$img, + url: url}); + } + } + else { + window.location.href = '/annotate?where=' + url; + } + }); + } + }, + getSweets: function() { + var annos = _.filter(anno.getAnnotations(), function(anno) { + return (!_.has(anno, 'editable') || anno.editable === true); + }); + + _.each(annos, function(anno) { + swtr.sweets.add({ + who: swtr.who, + where: anno.src, + // remove the text field; we don't want to store that in the sweets + how: _.omit(anno, 'text') + }); + }); + }, + showSweets: function() { + this.sweetsview.render(); + }, + sweet: function() { + this.getSweets(); + this.showSweets(); + return false; + }, + signIn: function(event) { + event.preventDefault(); + this.oauth.authorize(); + return false; + }, + userLoggedIn: function(username) { + swtr.who = username; + var text = 'Signed in as ' + swtr.who + ''; + $('#signinview').html(text); + }, + userLoggedOut: function() { + swtr.who = 'Guest'; + $('#signinview').html('Logged out'); + }, + changeURLInputPlaceholder: function(source) { + switch (source) { + case 'ocd' : $('#user-input').attr('placeholder', 'Enter search query'); + break; + case 'none' : $('#user-input').attr('placeholder', 'Enter URL of image or web page'); + break; + } + }, + // function to change the source in the application and update the UI + changeSource: function(source) { + switch (source) { + case 'ocd' : this.source = 'ocd'; + this.helpview.step(11); + this.changeURLInputPlaceholder('ocd'); + break; + case 'none' : this.source = 'none'; + this.helpview.step(1); + this.changeURLInputPlaceholder('none'); + break; + } + }, + // event handler to capture control panel UI change of source + sourceChanged: function(event) { + if($('#ocd-source').is(':checked')) { + this.changeSource('ocd'); + } + else { + this.changeSource('none'); + } + }, + loadOCDSearch: function(input) { + var self = this; + $('#img-annotation-wrapper').hide(); + $('#ocd-results').show(); + $('#ocd-results').html('

Loading..

'); + $.ajax({ + type: 'GET', + url: '/search/ocd', + data: {query: input}, + success: function(data) { + self.ocdView = new OCDView({ + query: input, + data: data, + model: data.hits.hits + }); + } + }); + } + }); + + var OCDView = Backbone.View.extend({ + el: $('#ocd-view'), + events: { + 'click .ocd-item a': 'onImgClick', + 'click .pager li': 'onPagerClick' + }, + initialize: function(opts) { + this.data = opts.data || {}; + this.query = opts.query || ''; + this.size = 9; // num of items per page + this.page = 0; + this.item_template = _.template($('#ocd-item-template').html()); + this.base_template = _.template($('#ocd-view-base-template').html()); + this.render(); + }, + render: function() { + var $row_el; + this.$el.html(''); + if(!this.model.length) { + this.$el.html('No results could be found from your query.'); + return; + } + this.$el.html(this.base_template()); + var $el = $('#ocd-results'); + _.each(this.model, function(item, idx) { + // put every 3 items in a row + if(idx % 3 === 0) { + $row_el = $('
'); + $el.append($row_el); + } + $row_el.append(this.item_template({ + title: item._source.title, + media_url: item._source.media_urls[0].url, + authors: item._source.authors + })); + }, this); + this.resolveOCDURLs(); + this.appendTotal(); + }, + appendTotal: function() { + $('#ocd-total-results').html(this.data.hits.total + ' results found.'); + }, + // resolve the OCD media URLs + resolveOCDURLs: function() { + var self = this; + $('.ocd-item').each(function(idx, elem) { + var temp_arr = self.model[idx]._source.media_urls[0].url.split('/'); + var media_hash = temp_arr[temp_arr.length - 1]; + $.get('/resolve-ocd-media', {hash: media_hash}, function(resp) { + $(elem).find('img').attr('src', resp.url); + }); + }); + }, + rerender: function(data) { + this.data = data; + this.model = data.hits.hits; + this.render(); + }, + onPagerClick: function(event) { + event.preventDefault(); + var elem = $(event.currentTarget); + var self = this; + if(elem.hasClass('next')) { + if((this.page + 1) * this.size >= this.data.hits.total) { + console.log('no next page to go to'); + return false; + } + console.log('clicked next'); + this.search({ + query: this.query, + from: (this.page + 1) * this.size + }, function(resp) { + console.log('reached next page'); + self.page = self.page + 1; + self.rerender(resp); + }); + } + else if (elem.hasClass('previous')) { + if(this.page <= 0) { + console.log('no prev page to go to'); + return false; + } + console.log('clicked prev'); + this.search({ + query: this.query, + from: (this.page - 1) * this.size + }, function(resp) { + console.log('reached prev page'); + self.page = self.page - 1; + self.rerender(resp); + }); + } + return false; + }, + onImgClick: function(event) { + event.preventDefault(); + // TODO: init the image anno + var url = $(event.currentTarget).find('img').attr('src'); + swtr.appView.loadURL(url, 'image'); + return false; + }, + search: function(data, cb) { + swtr.appView.$overlay.show(); + var self = this; + $.ajax({ + type: 'GET', + url: '/search/ocd', + data: data, + success: function(resp) { + swtr.appView.$overlay.hide(); + cb(resp); + } + }); + } + }); + + var HelpView = Backbone.View.extend({ + el: $('#helpview'), + events: { + }, + initialize: function() { + this.$text_el = $('#helpview-text'); + }, + //TODO: move from number based steps to something else. number based steps + //implicitly imply sequential processing..which does not happen in this + //case.. + //following helps can be async.. + step: function(n) { + var text = ''; + switch (n) { + case 0 : text = 'Getting annotations..'; + break; + case 1: text = 'Enter URL of an image or web page below, and start annotating!'; + break; + case 2: text = 'Annotate the image, or see other annotations'; + break; + case 3: text = 'Now you can sweet this annotation, or add more annotations'; + break; + case 4: text = 'Click Sweet button to publish these annotations to the Sweet Store'; + break; + case 5: text = 'Publishing your sweets'; + break; + case 6: text = 'Sweets successfully posted'; + break; + case 7: text = 'Fetching your image..'; + break; + case 8: text = 'Oops! Seems like the image URL is wrong! Or we couldn\'t fetch the image.'; + break; + case 9: text = 'You have to be signed in to sweet store to post sweets'; + break; + case 10: text = 'Oops! Something went wrong. We couldn\'t publish the sweets. Try again.' + break; + case 11: text = 'Search in Open Cuultur Data API'; + break; + case 12: text = 'Analyzing the resource type..'; + break; + case 13: text = 'This does not seem to be a URL. Please enter a valid URL.'; + break; + } + $(this.$text_el).html(text); + $(window).scrollTop(0, 0); + } + }); + + + // utilities and helper functions to go here + swtr.utils = { + linkify: function(link) { + if(link.match('http')) { + return link; + } + else { + return 'http://' + link; + } + } + }; + //swtr.AppView = AppView; + + var AppRouter = Backbone.Router.extend({ + routes: { + 'home': 'home', + 'linked-data': 'linkedData', + 'play': 'play', + 'search': 'search' + }, + home: function() { + this.hideAll(); + this.show('home-page'); + }, + linkedData: function() { + this.hideAll(); + this.show('linked-data-page'); + }, + play: function() { + this.hideAll(); + this.show('play-page'); + }, + search: function() { + this.hideAll(); + this.show('search-page'); + }, + hideAll: function() { + $('.page').hide(); + }, + show: function(id) { + $('#' + id).show(); + this.highlight(id); + }, + highlight: function(id) { + $('#swtr-navbar-collapse li').removeClass('active'); + var href = id.split('-page')[0]; + var selector = '#swtr-navbar-collapse a[href="#/' + href + '"]'; + $(selector).parent('li').addClass('active'); + } + }); + +})(swtr); --- a/swtr/static/js/swtmaker.js +++ /dev/null @@ -1,773 +1 @@ -(function(swtr) { - - //TODO: find a better way to init. - //Find a better way to do closure - //Remove script code from the HTML page - swtr.init = function() { - this.sweets = new ImgAnnoSwts(); - this.appView = new AppView(); - this.who = 'Guest'; - - this.app_router = new AppRouter(); - Backbone.history.start(); - this.app_router.navigate('home'); - - $.ajaxSetup({ - xhrFields: { - // we need this to send cookies to cross-domain requests - withCredentials: true - }, - //some browsers won't make cross-domain ajax until it is explicitly set - crossDomain: true - }); - this.handleOAuth(); - }; - - swtr.handleOAuth = function() { - if(swtr.access_token) { - $('#signinview').html('Signing you in..'); - $.ajax({ - url: swtr.swtstoreURL()+'/api/users/me?access_token='+ - swtr.access_token, - success: function(data) { - swtr.appView.userLoggedIn(data.username); - }, - error: function() { - $('#signinview').html('Error signing in! Please try again'); - } - }); - } - }; - - /* Model for Image Annotation Sweets */ - var ImgAnnoSwt = Backbone.Model.extend({ - defaults: { - 'who': '', - 'what': 'img-anno', - 'where': '', - 'how': {} - }, - initialize: function() { - } - }); - - /* Collection to hold all multiple ImgAnnoSwt */ - var ImgAnnoSwts = Backbone.Collection.extend({ - model: ImgAnnoSwt, - url: function() { - return swtr.swtstoreURL() + '/sweets'; - }, - // get all sweets/annotations of type #img-anno for a particular URI - // (where) - // @options is a javascript object, - // @options.where : URI of the resource for which swts to be fetched - // @options.who: optional username to filter sweets - // @options.success: success callback to call - // @options.error: error callback to call - getAll: function(options) { - // error checking - if(!options.where) { - throw Error('"where" option must be passed to get sweets of a URI'); - return false; - } - // setting up params - var where = options.where, - who = options.who || null; - url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' + - encodeURIComponent(where) + '&access_token=' + swtr.access_token; - if(who) { - url += '&who=' + who; - } - // get them! - this.sync('read', this, { - url: url, - success: function() { - if(typeof options.success === 'function') { - options.success.apply(this, arguments); - } - }, - error: function() { - if(typeof options.error === 'function') { - options.error.apply(this, arguments); - } - } - }); - }, - // post newly created sweets to a sweet store - // @options is a javascript object, - // @options.where : URI of the resource for which swts to be fetched - // @options.who: optional username to filter sweets - // @options.success: success callback to call - // @options.error: error callback to call, - post: function(options) { - var new_sweets = this.getNew(); - var dummy_collection = new Backbone.Collection(new_sweets); - - if(!swtr.access_token) { - throw new Error('Access Token is required to sweet'); - return; - } - - var url = swtr.swtstoreURL() + swtr.endpoints.post + - '?access_token=' + swtr.access_token; - - this.sync('create', dummy_collection, { - url: url, - success: function() { - if(typeof options.success === 'function') { - options.success.apply(this, arguments); - } - }, - error: function() { - if(typeof options.error === 'function') { - options.error.apply(this, arguments); - } - } - }); - }, - // return newly created models from the collection - getNew: function() { - var new_models = []; - this.each(function(model) { - if(model.isNew()) { - new_models.push(model); - } - }); - return new_models; - }, - // update part of the collection after a save on the server - update: function() { - } - }); - - var SweetsView = Backbone.View.extend({ - el: $('#sweet-list-wrapper'), - events: { - 'click #sweet-cancel': 'cancelSweeting', - 'click #post-sweet': 'postSweets' - }, - initialize: function() { - this.template = _.template($('#sweet-template').html()); - }, - render: function() { - $('#sweet-list').html('

These are your sweet annotations!

'); - _.each(this.collection.models, function(swt) { - if(swt.has('id')) { - return false; - } - $('#sweet-list').append(this.template({ - who: swt.get('who'), - what: swt.get('what'), - where: swt.get('where'), - how: JSON.stringify(this.getHumanReadableParts(swt.get('how'))) - })); - }, this); - $(this.el).fadeIn(300); - }, - getHumanReadableParts: function(how) { - var human_readable_json = {}; - if(how.comment) { - human_readable_json['comment'] = how.comment; - } - if(how.title) { - human_readable_json['title'] = how.title; - } - if(how.tags) { - human_readable_json['tags'] = how.tags; - } - if(how.link) { - human_readable_json['link'] = how.link; - } - return human_readable_json; - }, - cancelSweeting: function() { - this.removeSwtsNotPosted(); - this.cleanUp(); - }, - removeSwtsNotPosted: function() { - var notPosted = this.collection.filter(function(model) { - return !model.has('id'); - }); - this.collection.remove(notPosted); - }, - postSweets: function() { - console.log("postSWr"); - var appView = swtr.appView; - appView.helpview.step(5); - appView.$overlay.show(); - try { - this.collection.post({ - success: function(collection, response) { - console.log(collection, response); - swtr.sweets.set(collection); - //TODO: move this to a annotation view or something -// anno.removeAll(); - // _.each(swtr.sweets.models, function(swt) { - // if(!_.has(swt.get('how'), 'editable')) { - // swt.get('how')['editable'] = false; - // //console.log(swt.get('how').text.Comment); - // swt.get('how').text = swtr.imgAnnoView.createPopupText(swt.get('how')); - // //console.log(swt.get('how')); - // swt.get('how').text += '\n - by ' + swt.get('who'); - // } - // //console.log(swt.get('how')); - // anno.addAnnotation(swt.get('how')); - // }); - //console.log(swtr.sweets.toJSON()); - swtr.appView.$overlay.hide(); - swtr.appView.helpview.step(6); - }, - error: function(jqxhr, error, text) { - console.log(jqxhr, error, text); - swtr.appView.$overlay.hide(); - swtr.appView.helpview.step(10); - } - }); - } catch(e) { - if(e.message == 'Access Token is required to sweet') { - appView.$overlay.hide(); - appView.helpview.step(9); - } - } - this.cleanUp(); - return false; - }, - cleanUp: function() { - //console.log('cleaning up'); - $(this.el).hide(); - } - }); - - var FilterView = Backbone.View.extend({ - el: $('#filter-div'), - events: { - 'click #filter-user-div input': 'filter', - 'click #filter-tags-div input': 'filter' - }, - initialize: function() { - this.filter_users_template = _.template($('#filter-users').html()); - this.filter_tags_template = _.template($('#filter-tags').html()); - this.render(); - }, - render: function() { - //console.log(this.collection); - // pluck uniq authors of sweets - var authors = _.uniq(this.collection.pluck('who')); - // render them as filter controls - _.each(authors, function(author) { - $('#filter-user-div').append(this.filter_users_template({ - who: author - })); - }, this); - - // pluck uniq tags of sweets - var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten(). - uniq().value(); - // render them as filter controls - _.each(tags, function(tag) { - if(tag) { - $('#filter-tags-div').append(this.filter_tags_template({ - tag: tag - })); - } - }, this); - - //this.delegateEvents(); - }, - filter: function(event) { - // get id of div - parent to parent to the clicked input - var target_id = $(event.currentTarget).parent().parent().attr('id'); - // find out user/tag div - var which = target_id.split('-')[1]; - - var selected = []; - $('#'+target_id + ' input:checked').each(function() { - selected.push($(this).attr('name')); - }); - - if(which === 'user') { - this.filterUsers(selected); - } - else if(which === 'tags') { - this.filterTags(selected); - } - }, - filterUsers: function(users) { - if(!users.length) { - return; - } - var filtered_swts = this.collection.filter(function(model) { - if(_.indexOf(users, model.get('who')) > -1) { - return model; - } - }); - if(filtered_swts.length) { - anno.removeAll(); - _.each(filtered_swts, function(swt) { - anno.addAnnotation(swt.get('how')); - }); - } - }, - filterTags: function(tags) { - if(!tags.length) { - return; - } - var filtered_swts = this.collection.filter(function(model) { - //TODO: find a better way of doing this.. - var flag = false; - _.each(model.get('how').tags, function(tag) { - if(_.indexOf(tags, tag) > -1) { - flag = true; - } - }); - if(flag === true) { - return model; - } - }); - if(filtered_swts.length) { - anno.removeAll(); - _.each(filtered_swts, function(swt) { - anno.addAnnotation(swt.get('how')); - }); - } - }, - filterSweet: function(event) { - /*if(!event.currentTarget.checked) { - var results = this.collection.filter(function(model) { - if(model.get('who') != event.currentTarget.name) - return model; - }); - if(results.length) { - _.each(results, function(result) { - anno.removeAnnotation(result.get('how')); - }); - } - else { // if results is empty then remove all anno. - anno.removeAll(); - } - } - else { - results = this.collection.filter(function(model) { - if(model.get('who') == event.currentTarget.name) - return model; - }); - _.each(results, function(result) { - anno.addAnnotation(result.get('how')); - }); - - } - // if(results) { - // anno.removeAll(); - // } - // swtr.annoView.collection = results; - // swtr.annoView.renderWith();*/ - } - }); - - var AppView = Backbone.View.extend({ - el: $('body'), - events: { - 'click #user-input-submit': 'submitUserInput', - 'click #sweet': 'sweet', - 'click #sign-in': 'signIn', - 'click #ocd-source': 'sourceChanged' - //'mouseup .annotorious-editor-button-save': 'addnew_anno' - }, - initialize: function() { - // initialize components - this.source = 'none'; - this.helpview = new HelpView(); - this.sweetsview = new SweetsView({collection: swtr.sweets}); - - // cache jquery selected elements which are used frequently - this.$overlay = $('#app-overlay'); - this.$img = $('#annotatable-img'); - - this.helpview.step(1); - // initialize the oauth stuff - this.oauth = new Oauth({ - app_id: swtr.app_id, - endpoint: swtr.swtstoreURL() + swtr.endpoints.auth, - redirect_uri: swtr.oauth_redirect_uri, - scopes: 'email,sweet' - }); - }, - submitUserInput: function(event) { - event.preventDefault(); - var input = $('#user-input').val(); - if(this.source === 'ocd') { - this.loadOCDSearch(input); - } - else if (this.source === 'none') { - this.loadURL(input); - } - }, - // load a URL for annotation (can be of image or html resource for now) - loadURL: function(url, type) { - //console.log('loadURL()'); - if(this.source !== 'ocd') { - $('#ocd-results').hide(); - } - $('#img-annotation-wrapper').show(); - if(!url || !url.match(/http/)) { - this.helpview.step(13); - return false; - } - // if type is given explicitly; we load it as such. - if(type === 'image') { - if(swtr.imgAnnoView) { - swtr.imgAnnoView.setImage(url); - } - else { - swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, - img: this.$img[0], - $img: this.$img, - url: url}); - } - return false; - } - // else try to find what resource is the URL.. - // if url has an image extension then load the image annotation - if(url.match(/.jpg|.jpeg|.png|.gif|.bmp|.svg/)) { - if(swtr.imgAnnoView) { - swtr.imgAnnoView.setImage(url); - } - else { - swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, - img: this.$img[0], - $img: this.$img, - url: url}); - } - - return false; - } - // else check with our /media-type endpoint to see what type of resource - // it is - else { - this.helpview.step(12); - this.$overlay.show(); - var self = this; - $.get('/media-type', {where: url}, function(response) { - //console.log(response); - self.$overlay.hide(); - if(response.type === 'image') { - if(swtr.imgAnnoView) { - swtr.imgAnnoView.setImage(url); - } - else { - swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets, - img: self.$img[0], - $img: self.$img, - url: url}); - } - } - else { - window.location.href = '/annotate?where=' + url; - } - }); - } - }, - getSweets: function() { - var annos = _.filter(anno.getAnnotations(), function(anno) { - return (!_.has(anno, 'editable') || anno.editable === true); - }); - - _.each(annos, function(anno) { - swtr.sweets.add({ - who: swtr.who, - where: anno.src, - // remove the text field; we don't want to store that in the sweets - how: _.omit(anno, 'text') - }); - }); - }, - showSweets: function() { - this.sweetsview.render(); - }, - sweet: function() { - this.getSweets(); - this.showSweets(); - return false; - }, - signIn: function(event) { - event.preventDefault(); - this.oauth.authorize(); - return false; - }, - userLoggedIn: function(username) { - swtr.who = username; - var text = 'Signed in as ' + swtr.who + ''; - $('#signinview').html(text); - }, - userLoggedOut: function() { - swtr.who = 'Guest'; - $('#signinview').html('Logged out'); - }, - changeURLInputPlaceholder: function(source) { - switch (source) { - case 'ocd' : $('#user-input').attr('placeholder', 'Enter search query'); - break; - case 'none' : $('#user-input').attr('placeholder', 'Enter URL of image or web page'); - break; - } - }, - // function to change the source in the application and update the UI - changeSource: function(source) { - switch (source) { - case 'ocd' : this.source = 'ocd'; - this.helpview.step(11); - this.changeURLInputPlaceholder('ocd'); - break; - case 'none' : this.source = 'none'; - this.helpview.step(1); - this.changeURLInputPlaceholder('none'); - break; - } - }, - // event handler to capture control panel UI change of source - sourceChanged: function(event) { - if($('#ocd-source').is(':checked')) { - this.changeSource('ocd'); - } - else { - this.changeSource('none'); - } - }, - loadOCDSearch: function(input) { - var self = this; - $('#img-annotation-wrapper').hide(); - $('#ocd-results').show(); - $('#ocd-results').html('

Loading..

'); - $.ajax({ - type: 'GET', - url: '/search/ocd', - data: {query: input}, - success: function(data) { - self.ocdView = new OCDView({ - query: input, - data: data, - model: data.hits.hits - }); - } - }); - } - }); - - var OCDView = Backbone.View.extend({ - el: $('#ocd-view'), - events: { - 'click .ocd-item a': 'onImgClick', - 'click .pager li': 'onPagerClick' - }, - initialize: function(opts) { - this.data = opts.data || {}; - this.query = opts.query || ''; - this.size = 9; // num of items per page - this.page = 0; - this.item_template = _.template($('#ocd-item-template').html()); - this.base_template = _.template($('#ocd-view-base-template').html()); - this.render(); - }, - render: function() { - var $row_el; - this.$el.html(''); - if(!this.model.length) { - this.$el.html('No results could be found from your query.'); - return; - } - this.$el.html(this.base_template()); - var $el = $('#ocd-results'); - _.each(this.model, function(item, idx) { - // put every 3 items in a row - if(idx % 3 === 0) { - $row_el = $('
'); - $el.append($row_el); - } - $row_el.append(this.item_template({ - title: item._source.title, - media_url: item._source.media_urls[0].url, - authors: item._source.authors - })); - }, this); - this.resolveOCDURLs(); - this.appendTotal(); - }, - appendTotal: function() { - $('#ocd-total-results').html(this.data.hits.total + ' results found.'); - }, - // resolve the OCD media URLs - resolveOCDURLs: function() { - var self = this; - $('.ocd-item').each(function(idx, elem) { - var temp_arr = self.model[idx]._source.media_urls[0].url.split('/'); - var media_hash = temp_arr[temp_arr.length - 1]; - $.get('/resolve-ocd-media', {hash: media_hash}, function(resp) { - $(elem).find('img').attr('src', resp.url); - }); - }); - }, - rerender: function(data) { - this.data = data; - this.model = data.hits.hits; - this.render(); - }, - onPagerClick: function(event) { - event.preventDefault(); - var elem = $(event.currentTarget); - var self = this; - if(elem.hasClass('next')) { - if((this.page + 1) * this.size >= this.data.hits.total) { - console.log('no next page to go to'); - return false; - } - console.log('clicked next'); - this.search({ - query: this.query, - from: (this.page + 1) * this.size - }, function(resp) { - console.log('reached next page'); - self.page = self.page + 1; - self.rerender(resp); - }); - } - else if (elem.hasClass('previous')) { - if(this.page <= 0) { - console.log('no prev page to go to'); - return false; - } - console.log('clicked prev'); - this.search({ - query: this.query, - from: (this.page - 1) * this.size - }, function(resp) { - console.log('reached prev page'); - self.page = self.page - 1; - self.rerender(resp); - }); - } - return false; - }, - onImgClick: function(event) { - event.preventDefault(); - // TODO: init the image anno - var url = $(event.currentTarget).find('img').attr('src'); - swtr.appView.loadURL(url, 'image'); - return false; - }, - search: function(data, cb) { - swtr.appView.$overlay.show(); - var self = this; - $.ajax({ - type: 'GET', - url: '/search/ocd', - data: data, - success: function(resp) { - swtr.appView.$overlay.hide(); - cb(resp); - } - }); - } - }); - - var HelpView = Backbone.View.extend({ - el: $('#helpview'), - events: { - }, - initialize: function() { - this.$text_el = $('#helpview-text'); - }, - //TODO: move from number based steps to something else. number based steps - //implicitly imply sequential processing..which does not happen in this - //case.. - //following helps can be async.. - step: function(n) { - var text = ''; - switch (n) { - case 0 : text = 'Getting annotations..'; - break; - case 1: text = 'Enter URL of an image or web page below, and start annotating!'; - break; - case 2: text = 'Annotate the image, or see other annotations'; - break; - case 3: text = 'Now you can sweet this annotation, or add more annotations'; - break; - case 4: text = 'Click Sweet button to publish these annotations to the Sweet Store'; - break; - case 5: text = 'Publishing your sweets'; - break; - case 6: text = 'Sweets successfully posted'; - break; - case 7: text = 'Fetching your image..'; - break; - case 8: text = 'Oops! Seems like the image URL is wrong! Or we couldn\'t fetch the image.'; - break; - case 9: text = 'You have to be signed in to sweet store to post sweets'; - break; - case 10: text = 'Oops! Something went wrong. We couldn\'t publish the sweets. Try again.' - break; - case 11: text = 'Search in Open Cuultur Data API'; - break; - case 12: text = 'Analyzing the resource type..'; - break; - case 13: text = 'This does not seem to be a URL. Please enter a valid URL.'; - break; - } - $(this.$text_el).html(text); - $(window).scrollTop(0, 0); - } - }); - - - // utilities and helper functions to go here - swtr.utils = { - linkify: function(link) { - if(link.match('http')) { - return link; - } - else { - return 'http://' + link; - } - } - }; - //swtr.AppView = AppView; - - var AppRouter = Backbone.Router.extend({ - routes: { - 'home': 'home', - 'linked-data': 'linkedData', - 'play': 'play', - 'search': 'search' - }, - home: function() { - this.hideAll(); - this.show('home-page'); - }, - linkedData: function() { - this.hideAll(); - this.show('linked-data-page'); - }, - play: function() { - this.hideAll(); - this.show('play-page'); - }, - search: function() { - this.hideAll(); - this.show('search-page'); - }, - hideAll: function() { - $('.page').hide(); - }, - show: function(id) { - $('#' + id).show(); - this.highlight(id); - }, - highlight: function(id) { - $('#swtr-navbar-collapse li').removeClass('active'); - var href = id.split('-page')[0]; - var selector = '#swtr-navbar-collapse a[href="#/' + href + '"]'; - $(selector).parent('li').addClass('active'); - } - }); - -})(swtr); --- a/swtr/templates/index.html +++ b/swtr/templates/index.html @@ -179,8 +179,8 @@ - - + +