1 | // Generated by CoffeeScript 1.3.3 |
---|
2 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, |
---|
3 | __hasProp = {}.hasOwnProperty, |
---|
4 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, |
---|
5 | __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; |
---|
6 | |
---|
7 | Annotator.Plugin.Store = (function(_super) { |
---|
8 | |
---|
9 | __extends(Store, _super); |
---|
10 | |
---|
11 | Store.prototype.events = { |
---|
12 | 'annotationCreated': 'annotationCreated', |
---|
13 | 'annotationDeleted': 'annotationDeleted', |
---|
14 | 'annotationUpdated': 'annotationUpdated' |
---|
15 | }; |
---|
16 | |
---|
17 | Store.prototype.options = { |
---|
18 | prefix: '/store', |
---|
19 | autoFetch: true, |
---|
20 | annotationData: {}, |
---|
21 | loadFromSearch: false, |
---|
22 | urls: { |
---|
23 | create: '/annotations', |
---|
24 | read: '/annotations/:id', |
---|
25 | update: '/annotations/:id', |
---|
26 | destroy: '/annotations/:id', |
---|
27 | search: '/search' |
---|
28 | } |
---|
29 | }; |
---|
30 | |
---|
31 | function Store(element, options) { |
---|
32 | this._onError = __bind(this._onError, this); |
---|
33 | |
---|
34 | this._onLoadAnnotationsFromSearch = __bind(this._onLoadAnnotationsFromSearch, this); |
---|
35 | |
---|
36 | this._onLoadAnnotations = __bind(this._onLoadAnnotations, this); |
---|
37 | |
---|
38 | this._getAnnotations = __bind(this._getAnnotations, this); |
---|
39 | Store.__super__.constructor.apply(this, arguments); |
---|
40 | this.annotations = []; |
---|
41 | } |
---|
42 | |
---|
43 | Store.prototype.pluginInit = function() { |
---|
44 | if (!Annotator.supported()) { |
---|
45 | return; |
---|
46 | } |
---|
47 | if (this.annotator.plugins.Auth) { |
---|
48 | return this.annotator.plugins.Auth.withToken(this._getAnnotations); |
---|
49 | } else { |
---|
50 | return this._getAnnotations(); |
---|
51 | } |
---|
52 | }; |
---|
53 | |
---|
54 | Store.prototype._getAnnotations = function() { |
---|
55 | if (this.options.loadFromSearch) { |
---|
56 | return this.loadAnnotationsFromSearch(this.options.loadFromSearch); |
---|
57 | } else { |
---|
58 | return this.loadAnnotations(); |
---|
59 | } |
---|
60 | }; |
---|
61 | |
---|
62 | Store.prototype.annotationCreated = function(annotation) { |
---|
63 | var _this = this; |
---|
64 | if (__indexOf.call(this.annotations, annotation) < 0) { |
---|
65 | this.registerAnnotation(annotation); |
---|
66 | return this._apiRequest('create', annotation, function(data) { |
---|
67 | if (!(data.id != null)) { |
---|
68 | console.warn(Annotator._t("Warning: No ID returned from server for annotation "), annotation); |
---|
69 | } |
---|
70 | return _this.updateAnnotation(annotation, data); |
---|
71 | }); |
---|
72 | } else { |
---|
73 | return this.updateAnnotation(annotation, {}); |
---|
74 | } |
---|
75 | }; |
---|
76 | |
---|
77 | Store.prototype.annotationUpdated = function(annotation) { |
---|
78 | var _this = this; |
---|
79 | if (__indexOf.call(this.annotations, annotation) >= 0) { |
---|
80 | return this._apiRequest('update', annotation, (function(data) { |
---|
81 | return _this.updateAnnotation(annotation, data); |
---|
82 | })); |
---|
83 | } |
---|
84 | }; |
---|
85 | |
---|
86 | Store.prototype.annotationDeleted = function(annotation) { |
---|
87 | var _this = this; |
---|
88 | if (__indexOf.call(this.annotations, annotation) >= 0) { |
---|
89 | return this._apiRequest('destroy', annotation, (function() { |
---|
90 | return _this.unregisterAnnotation(annotation); |
---|
91 | })); |
---|
92 | } |
---|
93 | }; |
---|
94 | |
---|
95 | Store.prototype.registerAnnotation = function(annotation) { |
---|
96 | return this.annotations.push(annotation); |
---|
97 | }; |
---|
98 | |
---|
99 | Store.prototype.unregisterAnnotation = function(annotation) { |
---|
100 | return this.annotations.splice(this.annotations.indexOf(annotation), 1); |
---|
101 | }; |
---|
102 | |
---|
103 | Store.prototype.updateAnnotation = function(annotation, data) { |
---|
104 | if (__indexOf.call(this.annotations, annotation) < 0) { |
---|
105 | console.error(Annotator._t("Trying to update unregistered annotation!")); |
---|
106 | } else { |
---|
107 | $.extend(annotation, data); |
---|
108 | } |
---|
109 | return $(annotation.highlights).data('annotation', annotation); |
---|
110 | }; |
---|
111 | |
---|
112 | Store.prototype.loadAnnotations = function() { |
---|
113 | return this._apiRequest('read', null, this._onLoadAnnotations); |
---|
114 | }; |
---|
115 | |
---|
116 | Store.prototype._onLoadAnnotations = function(data) { |
---|
117 | if (data == null) { |
---|
118 | data = []; |
---|
119 | } |
---|
120 | this.annotations = data; |
---|
121 | return this.annotator.loadAnnotations(data.slice()); |
---|
122 | }; |
---|
123 | |
---|
124 | Store.prototype.loadAnnotationsFromSearch = function(searchOptions) { |
---|
125 | return this._apiRequest('search', searchOptions, this._onLoadAnnotationsFromSearch); |
---|
126 | }; |
---|
127 | |
---|
128 | Store.prototype._onLoadAnnotationsFromSearch = function(data) { |
---|
129 | if (data == null) { |
---|
130 | data = {}; |
---|
131 | } |
---|
132 | return this._onLoadAnnotations(data.rows || []); |
---|
133 | }; |
---|
134 | |
---|
135 | Store.prototype.dumpAnnotations = function() { |
---|
136 | var ann, _i, _len, _ref, _results; |
---|
137 | _ref = this.annotations; |
---|
138 | _results = []; |
---|
139 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
---|
140 | ann = _ref[_i]; |
---|
141 | _results.push(JSON.parse(this._dataFor(ann))); |
---|
142 | } |
---|
143 | return _results; |
---|
144 | }; |
---|
145 | |
---|
146 | Store.prototype._apiRequest = function(action, obj, onSuccess) { |
---|
147 | var id, options, request, url; |
---|
148 | id = obj && obj.id; |
---|
149 | url = this._urlFor(action, id); |
---|
150 | options = this._apiRequestOptions(action, obj, onSuccess); |
---|
151 | request = $.ajax(url, options); |
---|
152 | request._id = id; |
---|
153 | request._action = action; |
---|
154 | return request; |
---|
155 | }; |
---|
156 | |
---|
157 | Store.prototype._apiRequestOptions = function(action, obj, onSuccess) { |
---|
158 | var opts; |
---|
159 | opts = { |
---|
160 | type: this._methodFor(action), |
---|
161 | headers: this.element.data('annotator:headers'), |
---|
162 | dataType: "json", |
---|
163 | success: onSuccess || function() {}, |
---|
164 | error: this._onError |
---|
165 | }; |
---|
166 | if (action === "search") { |
---|
167 | opts = $.extend(opts, { |
---|
168 | data: obj |
---|
169 | }); |
---|
170 | } else { |
---|
171 | opts = $.extend(opts, { |
---|
172 | data: obj && this._dataFor(obj), |
---|
173 | contentType: "application/json; charset=utf-8" |
---|
174 | }); |
---|
175 | } |
---|
176 | return opts; |
---|
177 | }; |
---|
178 | |
---|
179 | Store.prototype._urlFor = function(action, id) { |
---|
180 | var replaceWith, url; |
---|
181 | replaceWith = id != null ? '/' + id : ''; |
---|
182 | url = this.options.prefix || '/'; |
---|
183 | url += this.options.urls[action]; |
---|
184 | url = url.replace(/\/:id/, replaceWith); |
---|
185 | return url; |
---|
186 | }; |
---|
187 | |
---|
188 | Store.prototype._methodFor = function(action) { |
---|
189 | var table; |
---|
190 | table = { |
---|
191 | 'create': 'POST', |
---|
192 | 'read': 'GET', |
---|
193 | 'update': 'PUT', |
---|
194 | 'destroy': 'DELETE', |
---|
195 | 'search': 'GET' |
---|
196 | }; |
---|
197 | return table[action]; |
---|
198 | }; |
---|
199 | |
---|
200 | Store.prototype._dataFor = function(annotation) { |
---|
201 | var data, highlights; |
---|
202 | highlights = annotation.highlights; |
---|
203 | delete annotation.highlights; |
---|
204 | $.extend(annotation, this.options.annotationData); |
---|
205 | data = JSON.stringify(annotation); |
---|
206 | if (highlights) { |
---|
207 | annotation.highlights = highlights; |
---|
208 | } |
---|
209 | return data; |
---|
210 | }; |
---|
211 | |
---|
212 | Store.prototype._onError = function(xhr) { |
---|
213 | var action, message; |
---|
214 | action = xhr._action; |
---|
215 | message = Annotator._t("Sorry we could not ") + action + Annotator._t(" this annotation"); |
---|
216 | if (xhr._action === 'search') { |
---|
217 | message = Annotator._t("Sorry we could not search the store for annotations"); |
---|
218 | } else if (xhr._action === 'read' && !xhr._id) { |
---|
219 | message = Annotator._t("Sorry we could not ") + action + Annotator._t(" the annotations from the store"); |
---|
220 | } |
---|
221 | switch (xhr.status) { |
---|
222 | case 401: |
---|
223 | message = Annotator._t("Sorry you are not allowed to ") + action + Annotator._t(" this annotation"); |
---|
224 | break; |
---|
225 | case 404: |
---|
226 | message = Annotator._t("Sorry we could not connect to the annotations store"); |
---|
227 | break; |
---|
228 | case 500: |
---|
229 | message = Annotator._t("Sorry something went wrong with the annotation store"); |
---|
230 | } |
---|
231 | Annotator.showNotification(message, Annotator.Notification.ERROR); |
---|
232 | return console.error(Annotator._t("API request failed:") + (" '" + xhr.status + "'")); |
---|
233 | }; |
---|
234 | |
---|
235 | return Store; |
---|
236 | |
---|
237 | })(Annotator.Plugin); |
---|