29 |
31 |
30 var removeChars = [ |
32 var removeChars = [ |
31 String.fromCharCode(768), String.fromCharCode(769), String.fromCharCode(770), String.fromCharCode(771), String.fromCharCode(807), |
33 String.fromCharCode(768), String.fromCharCode(769), String.fromCharCode(770), String.fromCharCode(771), String.fromCharCode(807), |
32 "{", "}", "(", ")", "[", "]", "【", "】", "、", "・", "‥", "。", "「", "」", "『", "』", "〜", ":", "!", "?", " ", |
34 "{", "}", "(", ")", "[", "]", "【", "】", "、", "・", "‥", "。", "「", "」", "『", "』", "〜", ":", "!", "?", " ", |
33 ",", " ", ";", "(", ")", ".", "*", "+", "\\", "?", "|", "{", "}", "[", "]", "^", "#", "/" |
35 ",", " ", ";", "(", ")", ".", "*", "+", "\\", "?", "|", "{", "}", "[", "]", "^", "#", "/" |
34 ] |
36 ]; |
35 |
37 |
36 var Model = { |
38 var Model = {}, |
37 _SOURCE_STATUS_EMPTY : 0, |
39 _SOURCE_STATUS_EMPTY = Model._SOURCE_STATUS_EMPTY = 0, |
38 _SOURCE_STATUS_WAITING : 1, |
40 _SOURCE_STATUS_WAITING = Model._SOURCE_STATUS_WAITING = 1, |
39 _SOURCE_STATUS_READY : 2, |
41 _SOURCE_STATUS_READY = Model._SOURCE_STATUS_READY = 2, |
40 getUID : function() { |
42 extendPrototype = Model.extendPrototype = function(toClass, fromClass) { |
|
43 var fromP = fromClass.prototype, |
|
44 toP = toClass.prototype; |
|
45 for (var k in fromP) { |
|
46 if (fromP.hasOwnProperty(k)) { |
|
47 toP[k] = fromP[k]; |
|
48 } |
|
49 } |
|
50 }, |
|
51 getUID = Model.getUID = function() { |
41 return uidbase + pad(4, (++uidincrement % 0x10000), 16) + "-" + rand16(4) + "-" + rand16(6) + rand16(6); |
52 return uidbase + pad(4, (++uidincrement % 0x10000), 16) + "-" + rand16(4) + "-" + rand16(6) + rand16(6); |
42 }, |
53 }, |
43 isLocalURL : function(url) { |
54 isLocalURL = Model.isLocalURL = function(url) { |
44 var matches = url.match(/^(\w+:)\/\/([^/]+)/); |
55 var matches = url.match(/^(\w+:)\/\/([^/]+)/); |
45 if (matches) { |
56 if (matches) { |
46 return(matches[1] === document.location.protocol && matches[2] === document.location.host) |
57 return(matches[1] === document.location.protocol && matches[2] === document.location.host); |
47 } |
58 } |
48 return true; |
59 return true; |
49 }, |
60 }, |
50 regexpFromTextOrArray : function(_textOrArray, _testOnly, _iexact) { |
61 regexpFromTextOrArray = Model.regexpFromTextOrArray = function(_textOrArray, _testOnly, _iexact) { |
51 var _testOnly = _testOnly || false, |
62 var _testOnly = _testOnly || false, |
52 _iexact = _iexact || false; |
63 _iexact = _iexact || false; |
53 function escapeText(_text) { |
64 function escapeText(_text) { |
54 return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1'); |
65 return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1'); |
55 } |
66 } |
111 time = (Number(date) + (offset * 60 * 1000)); |
122 time = (Number(date) + (offset * 60 * 1000)); |
112 var _res = new Date(); |
123 var _res = new Date(); |
113 _res.setTime(Number(time)); |
124 _res.setTime(Number(time)); |
114 return _res; |
125 return _res; |
115 }, |
126 }, |
116 dateToIso : function(_d) { |
127 dateToIso = Model.dateToIso = function(_d) { |
117 var d = _d ? new Date(_d) : new Date(); |
128 var d = _d ? new Date(_d) : new Date(); |
118 return d.getUTCFullYear()+'-' |
129 return d.getUTCFullYear()+'-' |
119 + pad(2, d.getUTCMonth()+1)+'-' |
130 + pad(2, d.getUTCMonth()+1)+'-' |
120 + pad(2, d.getUTCDate())+'T' |
131 + pad(2, d.getUTCDate())+'T' |
121 + pad(2, d.getUTCHours())+':' |
132 + pad(2, d.getUTCHours())+':' |
122 + pad(2, d.getUTCMinutes())+':' |
133 + pad(2, d.getUTCMinutes())+':' |
123 + pad(2, d.getUTCSeconds())+'Z' |
134 + pad(2, d.getUTCSeconds())+'Z' ; |
124 } |
135 }; |
125 } |
|
126 |
136 |
127 /* |
137 /* |
128 * Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) |
138 * List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) |
129 */ |
139 */ |
130 Model.List = function(_directory) { |
140 var List = Model.List = function(_directory) { |
131 Array.call(this); |
141 Array.call(this); |
132 this.directory = _directory; |
142 this.directory = _directory; |
133 this.idIndex = []; |
143 this.idIndex = []; |
134 this.__events = {}; |
144 this.__events = {}; |
135 if (typeof _directory == "undefined") { |
145 if (typeof _directory == "undefined") { |
136 console.trace(); |
146 console.trace(); |
137 throw "Error : new Model.List(directory): directory is undefined"; |
147 throw "Error : new List(directory): directory is undefined"; |
138 } |
148 } |
139 var _this = this; |
149 var _this = this; |
140 this.on("clear-search", function() { |
150 this.on("clear-search", function() { |
141 _this.searching = false; |
151 _this.searching = false; |
142 _this.regexp = undefined; |
152 _this.regexp = undefined; |
143 _this.forEach(function(_element) { |
153 _this.forEach(function(_element) { |
144 _element.found = undefined; |
154 _element.found = undefined; |
145 }); |
155 }); |
146 _this.trigger("search-cleared"); |
156 _this.trigger("search-cleared"); |
147 }) |
157 }); |
148 } |
158 }; |
149 |
159 |
150 Model.List.prototype = new Array(); |
160 List.prototype = new Array(); |
151 |
161 |
152 Model.List.prototype.hasId = function(_id) { |
162 List.prototype.hasId = function(_id) { |
153 return ns._(this.idIndex).include(_id); |
163 return ns._(this.idIndex).include(_id); |
154 } |
164 }; |
155 |
165 |
156 /* On recent browsers, forEach and map are defined and do what we want. |
166 /* On recent browsers, forEach and map are defined and do what we want. |
157 * Otherwise, we'll use the Underscore.js functions |
167 * Otherwise, we'll use the Underscore.js functions |
158 */ |
168 */ |
159 if (typeof Array.prototype.forEach === "undefined") { |
169 if (typeof Array.prototype.forEach === "undefined") { |
160 Model.List.prototype.forEach = function(_callback) { |
170 List.prototype.forEach = function(_callback) { |
161 var _this = this; |
171 var _this = this; |
162 ns._(this).forEach(function(_value, _key) { |
172 ns._(this).forEach(function(_value, _key) { |
163 _callback(_value, _key, _this); |
173 _callback(_value, _key, _this); |
164 }); |
174 }); |
165 } |
175 }; |
166 } |
176 }; |
167 |
177 |
168 if (typeof Array.prototype.map === "undefined") { |
178 if (typeof Array.prototype.map === "undefined") { |
169 Model.List.prototype.map = function(_callback) { |
179 List.prototype.map = function(_callback) { |
170 var _this = this; |
180 var _this = this; |
171 return ns._(this).map(function(_value, _key) { |
181 return ns._(this).map(function(_value, _key) { |
172 return _callback(_value, _key, _this); |
182 return _callback(_value, _key, _this); |
173 }); |
183 }); |
174 } |
184 }; |
175 } |
185 }; |
176 |
186 |
177 Model.List.prototype.pluck = function(_key) { |
187 List.prototype.pluck = function(_key) { |
178 return this.map(function(_value) { |
188 return this.map(function(_value) { |
179 return _value[_key]; |
189 return _value[_key]; |
180 }); |
190 }); |
181 } |
191 }; |
182 |
192 |
183 /* We override Array's filter function because it doesn't return an Model.List |
193 /* We override Array's filter function because it doesn't return an List |
184 */ |
194 */ |
185 Model.List.prototype.filter = function(_callback) { |
195 List.prototype.filter = function(_callback) { |
186 var _this = this, |
196 var _this = this, |
187 _res = new Model.List(this.directory); |
197 _res = new List(this.directory); |
188 _res.addElements(ns._(this).filter(function(_value, _key) { |
198 _res.addElements(ns._(this).filter(function(_value, _key) { |
189 return _callback(_value, _key, _this); |
199 return _callback(_value, _key, _this); |
190 })); |
200 })); |
191 return _res; |
201 return _res; |
192 } |
202 }; |
193 |
203 |
194 Model.List.prototype.slice = function(_start, _end) { |
204 List.prototype.slice = function(_start, _end) { |
195 var _res = new Model.List(this.directory); |
205 var _res = new List(this.directory); |
196 _res.addElements(Array.prototype.slice.call(this, _start, _end)); |
206 _res.addElements(Array.prototype.slice.call(this, _start, _end)); |
197 return _res; |
207 return _res; |
198 } |
208 }; |
199 |
209 |
200 Model.List.prototype.splice = function(_start, _end) { |
210 List.prototype.splice = function(_start, _end) { |
201 var _res = new Model.List(this.directory); |
211 var _res = new List(this.directory); |
202 _res.addElements(Array.prototype.splice.call(this, _start, _end)); |
212 _res.addElements(Array.prototype.splice.call(this, _start, _end)); |
203 this.idIndex.splice(_start, _end); |
213 this.idIndex.splice(_start, _end); |
204 return _res; |
214 return _res; |
205 } |
215 }; |
206 |
216 |
207 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy |
217 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy |
208 * and won't return a new Model.List |
218 * and won't return a new List |
209 */ |
219 */ |
210 Model.List.prototype.sortBy = function(_callback) { |
220 List.prototype.sortBy = function(_callback) { |
211 var _this = this, |
221 var _this = this, |
212 _res = new Model.List(this.directory); |
222 _res = new List(this.directory); |
213 _res.addElements(ns._(this).sortBy(function(_value, _key) { |
223 _res.addElements(ns._(this).sortBy(function(_value, _key) { |
214 return _callback(_value, _key, _this); |
224 return _callback(_value, _key, _this); |
215 })); |
225 })); |
216 return _res; |
226 return _res; |
217 } |
227 }; |
218 |
228 |
219 /* Title and Description are basic information for (almost) all element types, |
229 /* Title and Description are basic information for (almost) all element types, |
220 * here we can search by these criteria |
230 * here we can search by these criteria |
221 */ |
231 */ |
222 Model.List.prototype.searchByTitle = function(_text, _iexact) { |
232 List.prototype.searchByTitle = function(_text, _iexact) { |
223 var _iexact = _iexact || false, |
233 var _iexact = _iexact || false, |
224 _rgxp = Model.regexpFromTextOrArray(_text, true, _iexact); |
234 _rgxp = regexpFromTextOrArray(_text, true, _iexact); |
225 return this.filter(function(_element) { |
235 return this.filter(function(_element) { |
226 return _rgxp.test(_element.title); |
236 return _rgxp.test(_element.title); |
227 }); |
237 }); |
228 } |
238 }; |
229 |
239 |
230 Model.List.prototype.searchByDescription = function(_text, _iexact) { |
240 List.prototype.searchByDescription = function(_text, _iexact) { |
231 var _iexact = _iexact || false, |
241 var _iexact = _iexact || false, |
232 _rgxp = Model.regexpFromTextOrArray(_text, true, _iexact); |
242 _rgxp = regexpFromTextOrArray(_text, true, _iexact); |
233 return this.filter(function(_element) { |
243 return this.filter(function(_element) { |
234 return _rgxp.test(_element.description); |
244 return _rgxp.test(_element.description); |
235 }); |
245 }); |
236 } |
246 }; |
237 |
247 |
238 Model.List.prototype.searchByTextFields = function(_text, _iexact) { |
248 List.prototype.searchByTextFields = function(_text, _iexact) { |
239 var _iexact = _iexact || false, |
249 var _iexact = _iexact || false, |
240 _rgxp = Model.regexpFromTextOrArray(_text, true, _iexact); |
250 _rgxp = regexpFromTextOrArray(_text, true, _iexact); |
241 return this.filter(function(_element) { |
251 return this.filter(function(_element) { |
242 var keywords = (_element.keywords || _element.getTagTexts() || []).join(", "); |
252 var keywords = (_element.keywords || _element.getTagTexts() || []).join(", "); |
243 return _rgxp.test(_element.description) || _rgxp.test(_element.title) || _rgxp.test(keywords); |
253 return _rgxp.test(_element.description) || _rgxp.test(_element.title) || _rgxp.test(keywords); |
244 }); |
254 }); |
245 } |
255 }; |
246 |
256 |
247 Model.List.prototype.search = function(_text) { |
257 List.prototype.search = function(_text) { |
248 if (!_text) { |
258 if (!_text) { |
249 this.trigger("clear-search"); |
259 this.trigger("clear-search"); |
250 return this; |
260 return this; |
251 } |
261 } |
252 this.searching = true; |
262 this.searching = true; |
253 this.trigger("search", _text); |
263 this.trigger("search", _text); |
254 var rxsource = Model.fullTextRegexps(_text) |
264 var rxsource = fullTextRegexps(_text), |
255 rgxp = new RegExp(rxsource,"im"), |
265 rgxp = new RegExp(rxsource,"im"); |
256 this.regexp = new RegExp(rxsource,"gim"); |
266 this.regexp = new RegExp(rxsource,"gim"); |
257 var res = this.filter(function(_element, _k) { |
267 var res = this.filter(function(_element, _k) { |
258 var titlematch = rgxp.test(_element.title), |
268 var titlematch = rgxp.test(_element.title), |
259 descmatch = rgxp.test(_element.description), |
269 descmatch = rgxp.test(_element.description), |
260 _isfound = !!(titlematch || descmatch); |
270 _isfound = !!(titlematch || descmatch); |
261 _element.found = _isfound; |
271 _element.found = _isfound; |
262 _element.trigger(_isfound ? "found" : "not-found"); |
272 _element.trigger(_isfound ? "found" : "not-found"); |
263 return _isfound; |
273 return _isfound; |
264 }); |
274 }); |
265 this.trigger(res.length ? "found" : "not-found",res); |
275 this.trigger(res.length ? "found" : "not-found",res); |
266 return res; |
276 return res; |
267 } |
277 }; |
268 |
278 |
269 Model.List.prototype.getTitles = function() { |
279 List.prototype.getTitles = function() { |
270 return this.map(function(_el) { |
280 return this.map(function(_el) { |
271 return _el.title; |
281 return _el.title; |
272 }); |
282 }); |
273 } |
283 }; |
274 |
284 |
275 Model.List.prototype.addId = function(_id) { |
285 List.prototype.addId = function(_id) { |
276 var _el = this.directory.getElement(_id) |
286 var _el = this.directory.getElement(_id); |
277 if (!this.hasId(_id) && typeof _el !== "undefined") { |
287 if (!this.hasId(_id) && typeof _el !== "undefined") { |
278 this.idIndex.push(_id); |
288 this.idIndex.push(_id); |
279 Array.prototype.push.call(this, _el); |
289 Array.prototype.push.call(this, _el); |
280 } |
290 } |
281 } |
291 }; |
282 |
292 |
283 Model.List.prototype.push = function(_el) { |
293 List.prototype.push = function(_el) { |
284 if (typeof _el === "undefined") { |
294 if (typeof _el === "undefined") { |
285 return; |
295 return; |
286 } |
296 } |
287 var _index = (ns._(this.idIndex).indexOf(_el.id)); |
297 var _index = (ns._(this.idIndex).indexOf(_el.id)); |
288 if (_index === -1) { |
298 if (_index === -1) { |
289 this.idIndex.push(_el.id); |
299 this.idIndex.push(_el.id); |
290 Array.prototype.push.call(this, _el); |
300 Array.prototype.push.call(this, _el); |
291 } else { |
301 } else { |
292 this[_index] = _el; |
302 this[_index] = _el; |
293 } |
303 } |
294 } |
304 }; |
295 |
305 |
296 Model.List.prototype.addIds = function(_array) { |
306 List.prototype.addIds = function(_array) { |
297 var _l = _array.length, |
307 var _l = _array.length, |
298 _this = this; |
308 _this = this; |
299 ns._(_array).forEach(function(_id) { |
309 ns._(_array).forEach(function(_id) { |
300 _this.addId(_id); |
310 _this.addId(_id); |
301 }); |
311 }); |
302 } |
312 }; |
303 |
313 |
304 Model.List.prototype.addElements = function(_array) { |
314 List.prototype.addElements = function(_array) { |
305 var _this = this; |
315 var _this = this; |
306 ns._(_array).forEach(function(_el) { |
316 ns._(_array).forEach(function(_el) { |
307 _this.push(_el); |
317 _this.push(_el); |
308 }); |
318 }); |
309 } |
319 }; |
310 |
320 |
311 Model.List.prototype.removeId = function(_id, _deleteFromDirectory) { |
321 List.prototype.removeId = function(_id, _deleteFromDirectory) { |
312 var _deleteFromDirectory = _deleteFromDirectory || false, |
322 var _deleteFromDirectory = _deleteFromDirectory || false, |
313 _index = (ns._(this.idIndex).indexOf(_id)); |
323 _index = (ns._(this.idIndex).indexOf(_id)); |
314 if (_index !== -1) { |
324 if (_index !== -1) { |
315 this.splice(_index,1); |
325 this.splice(_index,1); |
316 } |
326 } |
317 if (_deleteFromDirectory) { |
327 if (_deleteFromDirectory) { |
318 delete this.directory.elements[_id]; |
328 delete this.directory.elements[_id]; |
319 } |
329 } |
320 } |
330 }; |
321 |
331 |
322 Model.List.prototype.removeElement = function(_el, _deleteFromDirectory) { |
332 List.prototype.removeElement = function(_el, _deleteFromDirectory) { |
323 var _deleteFromDirectory = _deleteFromDirectory || false; |
333 var _deleteFromDirectory = _deleteFromDirectory || false; |
324 this.removeId(_el.id); |
334 this.removeId(_el.id); |
325 } |
335 }; |
326 |
336 |
327 Model.List.prototype.removeIds = function(_list, _deleteFromDirectory) { |
337 List.prototype.removeIds = function(_list, _deleteFromDirectory) { |
328 var _deleteFromDirectory = _deleteFromDirectory || false, |
338 var _deleteFromDirectory = _deleteFromDirectory || false, |
329 _this = this; |
339 _this = this; |
330 ns._(_list).forEach(function(_id) { |
340 ns._(_list).forEach(function(_id) { |
331 _this.removeId(_id); |
341 _this.removeId(_id); |
332 }); |
342 }); |
333 } |
343 }; |
334 |
344 |
335 Model.List.prototype.removeElements = function(_list, _deleteFromDirectory) { |
345 List.prototype.removeElements = function(_list, _deleteFromDirectory) { |
336 var _deleteFromDirectory = _deleteFromDirectory || false, |
346 var _deleteFromDirectory = _deleteFromDirectory || false, |
337 _this = this; |
347 _this = this; |
338 ns._(_list).forEach(function(_el) { |
348 ns._(_list).forEach(function(_el) { |
339 _this.removeElement(_el); |
349 _this.removeElement(_el); |
340 }); |
350 }); |
341 } |
351 }; |
342 |
352 |
343 Model.List.prototype.on = function(_event, _callback) { |
353 List.prototype.on = function(_event, _callback) { |
344 if (typeof this.__events[_event] === "undefined") { |
354 if (typeof this.__events[_event] === "undefined") { |
345 this.__events[_event] = []; |
355 this.__events[_event] = []; |
346 } |
356 } |
347 this.__events[_event].push(_callback); |
357 this.__events[_event].push(_callback); |
348 } |
358 }; |
349 |
359 |
350 Model.List.prototype.off = function(_event, _callback) { |
360 List.prototype.off = function(_event, _callback) { |
351 if (typeof this.__events[_event] !== "undefined") { |
361 if (typeof this.__events[_event] !== "undefined") { |
352 this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) { |
362 this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) { |
353 return _fn === _callback; |
363 return _fn === _callback; |
354 }); |
364 }); |
355 } |
365 } |
356 } |
366 }; |
357 |
367 |
358 Model.List.prototype.trigger = function(_event, _data) { |
368 List.prototype.trigger = function(_event, _data) { |
359 var _list = this; |
369 var _list = this; |
360 ns._(this.__events[_event]).each(function(_callback) { |
370 ns._(this.__events[_event]).each(function(_callback) { |
361 _callback.call(_list, _data); |
371 _callback.call(_list, _data); |
362 }); |
372 }); |
363 } |
373 }; |
364 |
374 |
365 /* A simple time management object, that helps converting millisecs to seconds and strings, |
375 /* A simple time management object, that helps converting millisecs to seconds and strings, |
366 * without the clumsiness of the original Date object. |
376 * without the clumsiness of the original Date object. |
367 */ |
377 */ |
368 |
378 |
369 Model.Time = function(_milliseconds) { |
379 var Time = Model.Time = function(_milliseconds) { |
370 this.milliseconds = 0; |
380 this.milliseconds = 0; |
371 this.setMilliseconds(_milliseconds); |
381 this.setMilliseconds(_milliseconds); |
372 } |
382 }; |
373 |
383 |
374 Model.Time.prototype.setMilliseconds = function(_milliseconds) { |
384 Time.prototype.setMilliseconds = function(_milliseconds) { |
375 var _ante = this.milliseconds; |
385 var _ante = this.milliseconds; |
376 switch(typeof _milliseconds) { |
386 switch(typeof _milliseconds) { |
377 case "string": |
387 case "string": |
378 this.milliseconds = parseInt(_milliseconds); |
388 this.milliseconds = parseInt(_milliseconds); |
379 break; |
389 break; |
387 this.milliseconds = 0; |
397 this.milliseconds = 0; |
388 } |
398 } |
389 if (this.milliseconds === NaN) { |
399 if (this.milliseconds === NaN) { |
390 this.milliseconds = _ante; |
400 this.milliseconds = _ante; |
391 } |
401 } |
392 } |
402 }; |
393 |
403 |
394 Model.Time.prototype.setSeconds = function(_seconds) { |
404 Time.prototype.setSeconds = function(_seconds) { |
395 this.milliseconds = 1000 * _seconds; |
405 this.milliseconds = 1000 * _seconds; |
396 } |
406 }; |
397 |
407 |
398 Model.Time.prototype.getSeconds = function() { |
408 Time.prototype.getSeconds = function() { |
399 return this.milliseconds / 1000; |
409 return this.milliseconds / 1000; |
400 } |
410 }; |
401 |
411 |
402 Model.Time.prototype.getHMS = function() { |
412 Time.prototype.getHMS = function() { |
403 var _totalSeconds = Math.abs(Math.floor(this.getSeconds())); |
413 var _totalSeconds = Math.abs(Math.floor(this.getSeconds())); |
404 return { |
414 return { |
405 hours : Math.floor(_totalSeconds / 3600), |
415 hours : Math.floor(_totalSeconds / 3600), |
406 minutes : (Math.floor(_totalSeconds / 60) % 60), |
416 minutes : (Math.floor(_totalSeconds / 60) % 60), |
407 seconds : _totalSeconds % 60, |
417 seconds : _totalSeconds % 60, |
408 milliseconds: this.milliseconds % 1000 |
418 milliseconds: this.milliseconds % 1000 |
409 } |
419 }; |
410 } |
420 }; |
411 |
421 |
412 Model.Time.prototype.add = function(_milliseconds) { |
422 Time.prototype.add = function(_milliseconds) { |
413 this.milliseconds += new Model.Time(_milliseconds).milliseconds; |
423 this.milliseconds += new Time(_milliseconds).milliseconds; |
414 } |
424 }; |
415 |
425 |
416 Model.Time.prototype.valueOf = function() { |
426 Time.prototype.valueOf = function() { |
417 return this.milliseconds; |
427 return this.milliseconds; |
418 } |
428 }; |
419 |
429 |
420 Model.Time.prototype.toString = function(showCs) { |
430 Time.prototype.toString = function(showCs) { |
421 var _hms = this.getHMS(), |
431 var _hms = this.getHMS(), |
422 _res = ''; |
432 _res = ''; |
423 if (_hms.hours) { |
433 if (_hms.hours) { |
424 _res += _hms.hours + ':' |
434 _res += _hms.hours + ':'; |
425 } |
435 } |
426 _res += pad(2, _hms.minutes) + ':' + pad(2, _hms.seconds); |
436 _res += pad(2, _hms.minutes) + ':' + pad(2, _hms.seconds); |
427 if (showCs) { |
437 if (showCs) { |
428 _res += "." + Math.floor(_hms.milliseconds / 100) |
438 _res += "." + Math.floor(_hms.milliseconds / 100); |
429 } |
439 } |
430 return _res; |
440 return _res; |
431 } |
441 }; |
432 |
442 |
433 /* Model.Reference handles references between elements |
443 /* Reference handles references between elements |
434 */ |
444 */ |
435 |
445 |
436 Model.Reference = function(_source, _idRef) { |
446 var Reference = Model.Reference = function(_source, _idRef) { |
437 this.source = _source; |
447 this.source = _source; |
438 this.id = _idRef; |
448 this.id = _idRef; |
439 if (typeof _idRef === "object") { |
449 if (typeof _idRef === "object") { |
440 this.isList = true; |
450 this.isList = true; |
441 } else { |
451 } else { |
442 this.isList = false; |
452 this.isList = false; |
443 } |
453 } |
444 this.refresh(); |
454 this.refresh(); |
445 } |
455 }; |
446 |
456 |
447 Model.Reference.prototype.refresh = function() { |
457 Reference.prototype.refresh = function() { |
448 if (this.isList) { |
458 if (this.isList) { |
449 this.contents = new Model.List(this.source.directory); |
459 this.contents = new List(this.source.directory); |
450 this.contents.addIds(this.id); |
460 this.contents.addIds(this.id); |
451 } else { |
461 } else { |
452 this.contents = this.source.getElement(this.id); |
462 this.contents = this.source.getElement(this.id); |
453 } |
463 } |
454 |
464 |
455 } |
465 }; |
456 |
466 |
457 Model.Reference.prototype.getContents = function() { |
467 Reference.prototype.getContents = function() { |
458 if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) { |
468 if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) { |
459 this.refresh(); |
469 this.refresh(); |
460 } |
470 } |
461 return this.contents; |
471 return this.contents; |
462 } |
472 }; |
463 |
473 |
464 Model.Reference.prototype.isOrHasId = function(_idRef) { |
474 Reference.prototype.isOrHasId = function(_idRef) { |
465 if (this.isList) { |
475 if (this.isList) { |
466 return (ns._(this.id).indexOf(_idRef) !== -1) |
476 return (ns._(this.id).indexOf(_idRef) !== -1); |
467 } else { |
477 } else { |
468 return (this.id == _idRef); |
478 return (this.id == _idRef); |
469 } |
479 } |
470 } |
480 }; |
471 |
481 |
472 /* */ |
482 /* */ |
473 |
483 |
474 Model.Element = function(_id, _source) { |
484 var BaseElement = Model.Element = function(_id, _source) { |
475 this.elementType = 'element'; |
485 this.elementType = 'element'; |
476 this.title = ""; |
486 this.title = ""; |
477 this.description = ""; |
487 this.description = ""; |
478 this.__events = {} |
488 this.__events = {}; |
479 if (typeof _source === "undefined") { |
489 if (typeof _source === "undefined") { |
480 return; |
490 return; |
481 } |
491 } |
482 if (typeof _id === "undefined" || !_id) { |
492 if (typeof _id === "undefined" || !_id) { |
483 _id = Model.getUID(); |
493 _id = getUID(); |
484 } |
494 } |
485 this.id = _id; |
495 this.id = _id; |
486 this.source = _source; |
496 this.source = _source; |
487 if (_source !== this) { |
497 if (_source !== this) { |
488 this.source.directory.addElement(this); |
498 this.source.directory.addElement(this); |
489 } |
499 } |
490 } |
500 }; |
491 |
501 |
492 Model.Element.prototype.toString = function() { |
502 BaseElement.prototype.toString = function() { |
493 return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : ''); |
503 return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : ''); |
494 } |
504 }; |
495 |
505 |
496 Model.Element.prototype.setReference = function(_elementType, _idRef) { |
506 BaseElement.prototype.setReference = function(_elementType, _idRef) { |
497 this[_elementType] = new Model.Reference(this.source, _idRef); |
507 this[_elementType] = new Reference(this.source, _idRef); |
498 } |
508 }; |
499 |
509 |
500 Model.Element.prototype.getReference = function(_elementType) { |
510 BaseElement.prototype.getReference = function(_elementType) { |
501 if (typeof this[_elementType] !== "undefined") { |
511 if (typeof this[_elementType] !== "undefined") { |
502 return this[_elementType].getContents(); |
512 return this[_elementType].getContents(); |
503 } |
513 } |
504 } |
514 }; |
505 |
515 |
506 Model.Element.prototype.getRelated = function(_elementType, _global) { |
516 BaseElement.prototype.getRelated = function(_elementType, _global) { |
507 _global = (typeof _global !== "undefined" && _global); |
517 _global = (typeof _global !== "undefined" && _global); |
508 var _this = this; |
518 var _this = this; |
509 return this.source.getList(_elementType, _global).filter(function(_el) { |
519 return this.source.getList(_elementType, _global).filter(function(_el) { |
510 var _ref = _el[_this.elementType]; |
520 var _ref = _el[_this.elementType]; |
511 return _ref && _ref.isOrHasId(_this.id); |
521 return _ref && _ref.isOrHasId(_this.id); |
512 }); |
522 }); |
513 } |
523 }; |
514 |
524 |
515 Model.Element.prototype.on = function(_event, _callback) { |
525 BaseElement.prototype.on = function(_event, _callback) { |
516 if (typeof this.__events[_event] === "undefined") { |
526 if (typeof this.__events[_event] === "undefined") { |
517 this.__events[_event] = []; |
527 this.__events[_event] = []; |
518 } |
528 } |
519 this.__events[_event].push(_callback); |
529 this.__events[_event].push(_callback); |
520 } |
530 }; |
521 |
531 |
522 Model.Element.prototype.off = function(_event, _callback) { |
532 BaseElement.prototype.off = function(_event, _callback) { |
523 if (typeof this.__events[_event] !== "undefined") { |
533 if (typeof this.__events[_event] !== "undefined") { |
524 this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) { |
534 this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) { |
525 return _fn === _callback; |
535 return _fn === _callback; |
526 }); |
536 }); |
527 } |
537 } |
528 } |
538 }; |
529 |
539 |
530 Model.Element.prototype.trigger = function(_event, _data) { |
540 BaseElement.prototype.trigger = function(_event, _data) { |
531 var _element = this; |
541 var _element = this; |
532 ns._(this.__events[_event]).each(function(_callback) { |
542 ns._(this.__events[_event]).each(function(_callback) { |
533 _callback.call(_element, _data); |
543 _callback.call(_element, _data); |
534 }); |
544 }); |
535 } |
545 }; |
536 |
546 |
537 /* */ |
547 /* */ |
538 |
548 |
539 Model.Playable = function(_id, _source) { |
549 var Playable = Model.Playable = function(_id, _source) { |
540 Model.Element.call(this, _id, _source); |
550 BaseElement.call(this, _id, _source); |
541 if (typeof _source === "undefined") { |
551 if (typeof _source === "undefined") { |
542 return; |
552 return; |
543 } |
553 } |
544 this.elementType = 'playable'; |
554 this.elementType = 'playable'; |
545 this.currentTime = new Model.Time(); |
555 this.currentTime = new Time(); |
546 this.volume = .5; |
556 this.volume = .5; |
547 this.paused = true; |
557 this.paused = true; |
548 this.muted = false; |
558 this.muted = false; |
549 this.loadedMetadata = false; |
559 this.loadedMetadata = false; |
550 var _this = this; |
560 var _this = this; |
555 _this.paused = true; |
565 _this.paused = true; |
556 }); |
566 }); |
557 this.on("timeupdate", function(_time) { |
567 this.on("timeupdate", function(_time) { |
558 _this.currentTime = _time; |
568 _this.currentTime = _time; |
559 _this.getAnnotations().filter(function(_a) { |
569 _this.getAnnotations().filter(function(_a) { |
560 return (_a.end <= _time || _a.begin > _time) && _a.playing |
570 return (_a.end <= _time || _a.begin > _time) && _a.playing; |
561 }).forEach(function(_a) { |
571 }).forEach(function(_a) { |
562 _a.playing = false; |
572 _a.playing = false; |
563 _a.trigger("leave"); |
573 _a.trigger("leave"); |
564 _this.trigger("leave-annotation",_a); |
574 _this.trigger("leave-annotation",_a); |
565 }); |
575 }); |
566 _this.getAnnotations().filter(function(_a) { |
576 _this.getAnnotations().filter(function(_a) { |
567 return _a.begin <= _time && _a.end > _time && !_a.playing |
577 return _a.begin <= _time && _a.end > _time && !_a.playing; |
568 }).forEach(function(_a) { |
578 }).forEach(function(_a) { |
569 _a.playing = true; |
579 _a.playing = true; |
570 _a.trigger("enter"); |
580 _a.trigger("enter"); |
571 _this.trigger("enter-annotation",_a); |
581 _this.trigger("enter-annotation",_a); |
572 }); |
582 }); |
573 }); |
583 }); |
574 this.on("loadedmetadata", function() { |
584 this.on("loadedmetadata", function() { |
575 _this.loadedMetadata = true; |
585 _this.loadedMetadata = true; |
576 }) |
586 }); |
577 } |
587 }; |
578 |
588 |
579 Model.Playable.prototype = new Model.Element(); |
589 extendPrototype(Playable, BaseElement); |
580 |
590 |
581 Model.Playable.prototype.getCurrentTime = function() { |
591 Playable.prototype.getCurrentTime = function() { |
582 return this.currentTime; |
592 return this.currentTime; |
583 } |
593 }; |
584 |
594 |
585 Model.Playable.prototype.getVolume = function() { |
595 Playable.prototype.getVolume = function() { |
586 return this.volume; |
596 return this.volume; |
587 } |
597 }; |
588 |
598 |
589 Model.Playable.prototype.getPaused = function() { |
599 Playable.prototype.getPaused = function() { |
590 return this.paused; |
600 return this.paused; |
591 } |
601 }; |
592 |
602 |
593 Model.Playable.prototype.getMuted = function() { |
603 Playable.prototype.getMuted = function() { |
594 return this.muted; |
604 return this.muted; |
595 } |
605 }; |
596 |
606 |
597 Model.Playable.prototype.setCurrentTime = function(_time) { |
607 Playable.prototype.setCurrentTime = function(_time) { |
598 this.trigger("setcurrenttime",_time); |
608 this.trigger("setcurrenttime",_time); |
599 } |
609 }; |
600 |
610 |
601 Model.Playable.prototype.setVolume = function(_vol) { |
611 Playable.prototype.setVolume = function(_vol) { |
602 this.trigger("setvolume",_vol); |
612 this.trigger("setvolume",_vol); |
603 } |
613 }; |
604 |
614 |
605 Model.Playable.prototype.setMuted = function(_muted) { |
615 Playable.prototype.setMuted = function(_muted) { |
606 this.trigger("setmuted",_muted); |
616 this.trigger("setmuted",_muted); |
607 } |
617 }; |
608 |
618 |
609 Model.Playable.prototype.play = function() { |
619 Playable.prototype.play = function() { |
610 this.trigger("setplay"); |
620 this.trigger("setplay"); |
611 } |
621 }; |
612 |
622 |
613 Model.Playable.prototype.pause = function() { |
623 Playable.prototype.pause = function() { |
614 this.trigger("setpause"); |
624 this.trigger("setpause"); |
615 } |
625 }; |
616 |
626 |
617 Model.Playable.prototype.show = function() {} |
627 Playable.prototype.show = function() {}; |
618 |
628 |
619 Model.Playable.prototype.hide = function() {} |
629 Playable.prototype.hide = function() {}; |
620 |
630 |
621 /* */ |
631 /* */ |
622 |
632 |
623 Model.Media = function(_id, _source) { |
633 var Media = Model.Media = function(_id, _source) { |
624 Model.Playable.call(this, _id, _source); |
634 Playable.call(this, _id, _source); |
625 this.elementType = 'media'; |
635 this.elementType = 'media'; |
626 this.duration = new Model.Time(); |
636 this.duration = new Time(); |
627 this.video = ''; |
637 this.video = ''; |
628 var _this = this; |
638 var _this = this; |
629 } |
639 }; |
630 |
640 |
631 Model.Media.prototype = new Model.Playable(); |
641 extendPrototype(Media, Playable); |
632 |
642 |
633 /* Default functions to be overriden by players */ |
643 /* Default functions to be overriden by players */ |
634 |
644 |
635 Model.Media.prototype.setDuration = function(_durationMs) { |
645 Media.prototype.setDuration = function(_durationMs) { |
636 this.duration.setMilliseconds(_durationMs); |
646 this.duration.setMilliseconds(_durationMs); |
637 } |
647 }; |
638 |
648 |
639 Model.Media.prototype.getAnnotations = function() { |
649 Media.prototype.getAnnotations = function() { |
640 return this.getRelated("annotation"); |
650 return this.getRelated("annotation"); |
641 } |
651 }; |
642 |
652 |
643 Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) { |
653 Media.prototype.getAnnotationsByTypeTitle = function(_title) { |
644 var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); |
654 var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); |
645 if (_annTypes.length) { |
655 if (_annTypes.length) { |
646 return this.getAnnotations().filter(function(_annotation) { |
656 return this.getAnnotations().filter(function(_annotation) { |
647 return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; |
657 return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; |
648 }); |
658 }); |
649 } else { |
659 } else { |
650 return new Model.List(this.source.directory) |
660 return new List(this.source.directory); |
651 } |
661 } |
652 } |
662 }; |
653 |
663 |
654 /* */ |
664 /* */ |
655 |
665 |
656 Model.Tag = function(_id, _source) { |
666 var Tag = Model.Tag = function(_id, _source) { |
657 Model.Element.call(this, _id, _source); |
667 BaseElement.call(this, _id, _source); |
658 this.elementType = 'tag'; |
668 this.elementType = 'tag'; |
659 } |
669 }; |
660 |
670 |
661 Model.Tag.prototype = new Model.Element(); |
671 extendPrototype(Tag, BaseElement); |
662 |
672 |
663 Model.Tag.prototype.getAnnotations = function() { |
673 Tag.prototype.getAnnotations = function() { |
664 return this.getRelated("annotation"); |
674 return this.getRelated("annotation"); |
665 } |
675 }; |
666 |
676 |
667 /* */ |
677 /* */ |
668 Model.AnnotationType = function(_id, _source) { |
678 var AnnotationType = Model.AnnotationType = function(_id, _source) { |
669 Model.Element.call(this, _id, _source); |
679 BaseElement.call(this, _id, _source); |
670 this.elementType = 'annotationType'; |
680 this.elementType = 'annotationType'; |
671 } |
681 }; |
672 |
682 |
673 Model.AnnotationType.prototype = new Model.Element(); |
683 extendPrototype(AnnotationType, BaseElement); |
674 |
684 |
675 Model.AnnotationType.prototype.getAnnotations = function() { |
685 AnnotationType.prototype.getAnnotations = function() { |
676 return this.getRelated("annotation"); |
686 return this.getRelated("annotation"); |
677 } |
687 }; |
678 |
688 |
679 /* Annotation |
689 /* Annotation |
680 * */ |
690 * */ |
681 |
691 |
682 Model.Annotation = function(_id, _source) { |
692 var Annotation = Model.Annotation = function(_id, _source) { |
683 Model.Element.call(this, _id, _source); |
693 BaseElement.call(this, _id, _source); |
684 this.elementType = 'annotation'; |
694 this.elementType = 'annotation'; |
685 this.begin = new Model.Time(); |
695 this.begin = new Time(); |
686 this.end = new Model.Time(); |
696 this.end = new Time(); |
687 this.tag = new Model.Reference(_source, []); |
697 this.tag = new Reference(_source, []); |
688 this.playing = false; |
698 this.playing = false; |
689 var _this = this; |
699 var _this = this; |
690 this.on("click", function() { |
700 this.on("click", function() { |
691 _this.getMedia().setCurrentTime(_this.begin); |
701 _this.getMedia().setCurrentTime(_this.begin); |
692 }); |
702 }); |
693 } |
703 }; |
694 |
704 |
695 Model.Annotation.prototype = new Model.Element(); |
705 extendPrototype(Annotation, BaseElement); |
696 |
706 |
697 Model.Annotation.prototype.setBegin = function(_beginMs) { |
707 Annotation.prototype.setBegin = function(_beginMs) { |
698 this.begin.setMilliseconds(Math.max(0,_beginMs)); |
708 this.begin.setMilliseconds(Math.max(0,_beginMs)); |
699 this.trigger("change-begin"); |
709 this.trigger("change-begin"); |
700 if (this.end < this.begin) { |
710 if (this.end < this.begin) { |
701 this.setEnd(this.begin); |
711 this.setEnd(this.begin); |
702 } |
712 } |
703 } |
713 }; |
704 |
714 |
705 Model.Annotation.prototype.setEnd = function(_endMs) { |
715 Annotation.prototype.setEnd = function(_endMs) { |
706 this.end.setMilliseconds(Math.min(_endMs, this.getMedia().duration.milliseconds)); |
716 this.end.setMilliseconds(Math.min(_endMs, this.getMedia().duration.milliseconds)); |
707 this.trigger("change-end"); |
717 this.trigger("change-end"); |
708 if (this.end < this.begin) { |
718 if (this.end < this.begin) { |
709 this.setBegin(this.end); |
719 this.setBegin(this.end); |
710 } |
720 } |
711 } |
721 }; |
712 |
722 |
713 Model.Annotation.prototype.setDuration = function(_durMs) { |
723 Annotation.prototype.setDuration = function(_durMs) { |
714 this.setEnd(_durMs + this.begin.milliseconds); |
724 this.setEnd(_durMs + this.begin.milliseconds); |
715 } |
725 }; |
716 |
726 |
717 Model.Annotation.prototype.setMedia = function(_idRef) { |
727 Annotation.prototype.setMedia = function(_idRef) { |
718 this.setReference("media", _idRef); |
728 this.setReference("media", _idRef); |
719 } |
729 }; |
720 |
730 |
721 Model.Annotation.prototype.getMedia = function() { |
731 Annotation.prototype.getMedia = function() { |
722 return this.getReference("media"); |
732 return this.getReference("media"); |
723 } |
733 }; |
724 |
734 |
725 Model.Annotation.prototype.setAnnotationType = function(_idRef) { |
735 Annotation.prototype.setAnnotationType = function(_idRef) { |
726 this.setReference("annotationType", _idRef); |
736 this.setReference("annotationType", _idRef); |
727 } |
737 }; |
728 |
738 |
729 Model.Annotation.prototype.getAnnotationType = function() { |
739 Annotation.prototype.getAnnotationType = function() { |
730 return this.getReference("annotationType"); |
740 return this.getReference("annotationType"); |
731 } |
741 }; |
732 |
742 |
733 Model.Annotation.prototype.setTags = function(_idRefs) { |
743 Annotation.prototype.setTags = function(_idRefs) { |
734 this.setReference("tag", _idRefs); |
744 this.setReference("tag", _idRefs); |
735 } |
745 }; |
736 |
746 |
737 Model.Annotation.prototype.getTags = function() { |
747 Annotation.prototype.getTags = function() { |
738 return this.getReference("tag"); |
748 return this.getReference("tag"); |
739 } |
749 }; |
740 |
750 |
741 Model.Annotation.prototype.getTagTexts = function() { |
751 Annotation.prototype.getTagTexts = function() { |
742 return this.getTags().getTitles(); |
752 return this.getTags().getTitles(); |
743 } |
753 }; |
744 |
754 |
745 Model.Annotation.prototype.getDuration = function() { |
755 Annotation.prototype.getDuration = function() { |
746 return new Model.Time(this.end.milliseconds - this.begin.milliseconds) |
756 return new Time(this.end.milliseconds - this.begin.milliseconds); |
747 } |
757 }; |
748 |
758 |
749 /* */ |
759 /* */ |
750 |
760 |
751 Model.MashedAnnotation = function(_mashup, _annotation) { |
761 var MashedAnnotation = Model.MashedAnnotation = function(_mashup, _annotation) { |
752 Model.Element.call(this, _mashup.id + "_" + _annotation.id, _annotation.source); |
762 BaseElement.call(this, _mashup.id + "_" + _annotation.id, _annotation.source); |
753 this.elementType = 'mashedAnnotation'; |
763 this.elementType = 'mashedAnnotation'; |
754 this.annotation = _annotation; |
764 this.annotation = _annotation; |
755 this.begin = new Model.Time(); |
765 this.begin = new Time(); |
756 this.end = new Model.Time(); |
766 this.end = new Time(); |
757 this.duration = new Model.Time(); |
767 this.duration = new Time(); |
758 this.title = this.annotation.title; |
768 this.title = this.annotation.title; |
759 this.description = this.annotation.description; |
769 this.description = this.annotation.description; |
760 this.color = this.annotation.color; |
770 this.color = this.annotation.color; |
761 var _this = this; |
771 var _this = this; |
762 this.on("click", function() { |
772 this.on("click", function() { |
766 _this.annotation.trigger("enter"); |
776 _this.annotation.trigger("enter"); |
767 }); |
777 }); |
768 this.on("leave", function() { |
778 this.on("leave", function() { |
769 _this.annotation.trigger("leave"); |
779 _this.annotation.trigger("leave"); |
770 }); |
780 }); |
771 } |
781 }; |
772 |
782 |
773 Model.MashedAnnotation.prototype = new Model.Element(null); |
783 extendPrototype(MashedAnnotation, BaseElement); |
774 |
784 |
775 Model.MashedAnnotation.prototype.getMedia = function() { |
785 MashedAnnotation.prototype.getMedia = function() { |
776 return this.annotation.getReference("media"); |
786 return this.annotation.getReference("media"); |
777 } |
787 }; |
778 |
788 |
779 Model.MashedAnnotation.prototype.getAnnotationType = function() { |
789 MashedAnnotation.prototype.getAnnotationType = function() { |
780 return this.annotation.getReference("annotationType"); |
790 return this.annotation.getReference("annotationType"); |
781 } |
791 }; |
782 |
792 |
783 Model.MashedAnnotation.prototype.getTags = function() { |
793 MashedAnnotation.prototype.getTags = function() { |
784 return this.annotation.getReference("tag"); |
794 return this.annotation.getReference("tag"); |
785 } |
795 }; |
786 |
796 |
787 Model.MashedAnnotation.prototype.getTagTexts = function() { |
797 MashedAnnotation.prototype.getTagTexts = function() { |
788 return this.annotation.getTags().getTitles(); |
798 return this.annotation.getTags().getTitles(); |
789 } |
799 }; |
790 |
800 |
791 Model.MashedAnnotation.prototype.getDuration = function() { |
801 MashedAnnotation.prototype.getDuration = function() { |
792 return this.annotation.getDuration(); |
802 return this.annotation.getDuration(); |
793 } |
803 }; |
794 |
804 |
795 Model.MashedAnnotation.prototype.setBegin = function(_begin) { |
805 MashedAnnotation.prototype.setBegin = function(_begin) { |
796 this.begin.setMilliseconds(_begin); |
806 this.begin.setMilliseconds(_begin); |
797 this.duration.setMilliseconds(this.annotation.getDuration()); |
807 this.duration.setMilliseconds(this.annotation.getDuration()); |
798 this.end.setMilliseconds(_begin + this.duration); |
808 this.end.setMilliseconds(_begin + this.duration); |
799 } |
809 }; |
800 |
810 |
801 /* */ |
811 /* */ |
802 |
812 |
803 Model.Mashup = function(_id, _source) { |
813 var Mashup = Model.Mashup = function(_id, _source) { |
804 Model.Playable.call(this, _id, _source); |
814 Playable.call(this, _id, _source); |
805 this.elementType = 'mashup'; |
815 this.elementType = 'mashup'; |
806 this.duration = new Model.Time(); |
816 this.duration = new Time(); |
807 this.segments = new Model.List(_source.directory); |
817 this.segments = new List(_source.directory); |
808 this.loaded = false; |
818 this.loaded = false; |
809 var _this = this; |
819 var _this = this; |
810 this._updateTimes = function() { |
820 this._updateTimes = function() { |
811 _this.updateTimes(); |
821 _this.updateTimes(); |
812 _this.trigger("change"); |
822 _this.trigger("change"); |
813 } |
823 }; |
814 this.on("add", this._updateTimes); |
824 this.on("add", this._updateTimes); |
815 this.on("remove", this._updateTimes); |
825 this.on("remove", this._updateTimes); |
816 } |
826 }; |
817 |
827 |
818 Model.Mashup.prototype = new Model.Playable(); |
828 extendPrototype(Mashup, Playable); |
819 |
829 |
820 Model.Mashup.prototype.updateTimes = function() { |
830 Mashup.prototype.updateTimes = function() { |
821 var _time = 0; |
831 var _time = 0; |
822 this.segments.forEach(function(_segment) { |
832 this.segments.forEach(function(_segment) { |
823 _segment.setBegin(_time); |
833 _segment.setBegin(_time); |
824 _time = _segment.end; |
834 _time = _segment.end; |
825 }); |
835 }); |
826 this.duration.setMilliseconds(_time); |
836 this.duration.setMilliseconds(_time); |
827 } |
837 }; |
828 |
838 |
829 Model.Mashup.prototype.addAnnotation = function(_annotation, _defer) { |
839 Mashup.prototype.addAnnotation = function(_annotation, _defer) { |
830 var _mashedAnnotation = new Model.MashedAnnotation(this, _annotation), |
840 var _mashedAnnotation = new MashedAnnotation(this, _annotation), |
831 _defer = _defer || false; |
841 _defer = _defer || false; |
832 this.segments.push(_mashedAnnotation); |
842 this.segments.push(_mashedAnnotation); |
833 _annotation.on("change-begin", this._updateTimes); |
843 _annotation.on("change-begin", this._updateTimes); |
834 _annotation.on("change-end", this._updateTimes); |
844 _annotation.on("change-end", this._updateTimes); |
835 if (!_defer) { |
845 if (!_defer) { |
836 this.trigger("add"); |
846 this.trigger("add"); |
837 } |
847 } |
838 } |
848 }; |
839 |
849 |
840 Model.Mashup.prototype.addAnnotationById = function(_elId, _defer) { |
850 Mashup.prototype.addAnnotationById = function(_elId, _defer) { |
841 var _annotation = this.source.getElement(_elId), |
851 var _annotation = this.source.getElement(_elId), |
842 _defer = _defer || false; |
852 _defer = _defer || false; |
843 if (typeof _annotation !== "undefined") { |
853 if (typeof _annotation !== "undefined") { |
844 this.addAnnotation(_annotation, _defer); |
854 this.addAnnotation(_annotation, _defer); |
845 } |
855 } |
846 } |
856 }; |
847 |
857 |
848 Model.Mashup.prototype.addAnnotations = function(_segments) { |
858 Mashup.prototype.addAnnotations = function(_segments) { |
849 var _this = this; |
859 var _this = this; |
850 ns._(_segments).forEach(function(_segment) { |
860 ns._(_segments).forEach(function(_segment) { |
851 _this.addAnnotation(_segment, true); |
861 _this.addAnnotation(_segment, true); |
852 }); |
862 }); |
853 this.trigger("add"); |
863 this.trigger("add"); |
854 } |
864 }; |
855 |
865 |
856 Model.Mashup.prototype.addAnnotationsById = function(_segments) { |
866 Mashup.prototype.addAnnotationsById = function(_segments) { |
857 var _this = this; |
867 var _this = this; |
858 ns._(_segments).forEach(function(_segment) { |
868 ns._(_segments).forEach(function(_segment) { |
859 _this.addAnnotationById(_segment, true); |
869 _this.addAnnotationById(_segment, true); |
860 }); |
870 }); |
861 this.trigger("add"); |
871 this.trigger("add"); |
862 } |
872 }; |
863 |
873 |
864 Model.Mashup.prototype.removeAnnotation = function(_annotation, _defer) { |
874 Mashup.prototype.removeAnnotation = function(_annotation, _defer) { |
865 var _defer = _defer || false; |
875 var _defer = _defer || false; |
866 _annotation.off("change-begin", this._updateTimes); |
876 _annotation.off("change-begin", this._updateTimes); |
867 _annotation.off("change-end", this._updateTimes); |
877 _annotation.off("change-end", this._updateTimes); |
868 this.segments.removeId(this.id + "_" + _annotation.id); |
878 this.segments.removeId(this.id + "_" + _annotation.id); |
869 if (!_defer) { |
879 if (!_defer) { |
870 this.trigger("remove"); |
880 this.trigger("remove"); |
871 } |
881 } |
872 } |
882 }; |
873 |
883 |
874 Model.Mashup.prototype.removeAnnotationById = function(_annId, _defer) { |
884 Mashup.prototype.removeAnnotationById = function(_annId, _defer) { |
875 var _defer = _defer || false; |
885 var _defer = _defer || false; |
876 var _annotation = this.source.getElement(_annId); |
886 var _annotation = this.source.getElement(_annId); |
877 |
887 |
878 if (_annotation) { |
888 if (_annotation) { |
879 this.removeAnnotation(_annotation, _defer); |
889 this.removeAnnotation(_annotation, _defer); |
880 } |
890 } |
881 if (!_defer) { |
891 if (!_defer) { |
882 this.trigger("remove"); |
892 this.trigger("remove"); |
883 } |
893 } |
884 } |
894 }; |
885 |
895 |
886 Model.Mashup.prototype.setAnnotations = function(_segments) { |
896 Mashup.prototype.setAnnotations = function(_segments) { |
887 while (this.segments.length) { |
897 while (this.segments.length) { |
888 this.removeAnnotation(this.segments[0].annotation, true); |
898 this.removeAnnotation(this.segments[0].annotation, true); |
889 } |
899 } |
890 this.addAnnotations(_segments); |
900 this.addAnnotations(_segments); |
891 } |
901 }; |
892 |
902 |
893 Model.Mashup.prototype.setAnnotationsById = function(_segments) { |
903 Mashup.prototype.setAnnotationsById = function(_segments) { |
894 while (this.segments.length) { |
904 while (this.segments.length) { |
895 this.removeAnnotation(this.segments[0].annotation, true); |
905 this.removeAnnotation(this.segments[0].annotation, true); |
896 } |
906 } |
897 this.addAnnotationsById(_segments); |
907 this.addAnnotationsById(_segments); |
898 } |
908 }; |
899 |
909 |
900 Model.Mashup.prototype.hasAnnotation = function(_annotation) { |
910 Mashup.prototype.hasAnnotation = function(_annotation) { |
901 return !!ns._(this.segments).find(function(_s) { |
911 return !!ns._(this.segments).find(function(_s) { |
902 return _s.annotation === _annotation |
912 return _s.annotation === _annotation; |
903 }); |
913 }); |
904 } |
914 }; |
905 |
915 |
906 Model.Mashup.prototype.getAnnotation = function(_annotation) { |
916 Mashup.prototype.getAnnotation = function(_annotation) { |
907 return ns._(this.segments).find(function(_s) { |
917 return ns._(this.segments).find(function(_s) { |
908 return _s.annotation === _annotation |
918 return _s.annotation === _annotation; |
909 }); |
919 }); |
910 } |
920 }; |
911 |
921 |
912 Model.Mashup.prototype.getAnnotationById = function(_id) { |
922 Mashup.prototype.getAnnotationById = function(_id) { |
913 return ns._(this.segments).find(function(_s) { |
923 return ns._(this.segments).find(function(_s) { |
914 return _s.annotation.id === _id |
924 return _s.annotation.id === _id; |
915 }); |
925 }); |
916 } |
926 }; |
917 |
927 |
918 Model.Mashup.prototype.getAnnotations = function() { |
928 Mashup.prototype.getAnnotations = function() { |
919 return this.segments; |
929 return this.segments; |
920 } |
930 }; |
921 |
931 |
922 Model.Mashup.prototype.getOriginalAnnotations = function() { |
932 Mashup.prototype.getOriginalAnnotations = function() { |
923 var annotations = new Model.List(this.source.directory); |
933 var annotations = new List(this.source.directory); |
924 this.segments.forEach(function(_s) { |
934 this.segments.forEach(function(_s) { |
925 annotations.push(_s.annotation); |
935 annotations.push(_s.annotation); |
926 }); |
936 }); |
927 return annotations; |
937 return annotations; |
928 } |
938 }; |
929 |
939 |
930 Model.Mashup.prototype.getMedias = function() { |
940 Mashup.prototype.getMedias = function() { |
931 var medias = new Model.List(this.source.directory); |
941 var medias = new List(this.source.directory); |
932 this.segments.forEach(function(_annotation) { |
942 this.segments.forEach(function(_annotation) { |
933 medias.push(_annotation.getMedia()) |
943 medias.push(_annotation.getMedia()); |
934 }) |
944 }); |
935 return medias; |
945 return medias; |
936 } |
946 }; |
937 |
947 |
938 Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) { |
948 Mashup.prototype.getAnnotationsByTypeTitle = function(_title) { |
939 var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); |
949 var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); |
940 if (_annTypes.length) { |
950 if (_annTypes.length) { |
941 return this.getAnnotations().filter(function(_annotation) { |
951 return this.getAnnotations().filter(function(_annotation) { |
942 return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; |
952 return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; |
943 }); |
953 }); |
944 } else { |
954 } else { |
945 return new Model.List(this.source.directory) |
955 return new List(this.source.directory); |
946 } |
956 } |
947 } |
957 }; |
948 |
958 |
949 Model.Mashup.prototype.getAnnotationAtTime = function(_time) { |
959 Mashup.prototype.getAnnotationAtTime = function(_time) { |
950 var _list = this.segments.filter(function(_annotation) { |
960 var _list = this.segments.filter(function(_annotation) { |
951 return _annotation.begin <= _time && _annotation.end > _time; |
961 return _annotation.begin <= _time && _annotation.end > _time; |
952 }); |
962 }); |
953 if (_list.length) { |
963 if (_list.length) { |
954 return _list[0]; |
964 return _list[0]; |
955 } else { |
965 } else { |
956 return undefined; |
966 return undefined; |
957 } |
967 } |
958 } |
968 }; |
959 |
969 |
960 Model.Mashup.prototype.getMediaAtTime = function(_time) { |
970 Mashup.prototype.getMediaAtTime = function(_time) { |
961 var _annotation = this.getAnnotationAtTime(_time); |
971 var _annotation = this.getAnnotationAtTime(_time); |
962 if (typeof _annotation !== "undefined") { |
972 if (typeof _annotation !== "undefined") { |
963 return _annotation.getMedia(); |
973 return _annotation.getMedia(); |
964 } else { |
974 } else { |
965 return undefined; |
975 return undefined; |
966 } |
976 } |
967 } |
977 }; |
968 |
978 |
969 /* */ |
979 /* */ |
970 |
980 |
971 Model.Source = function(_config) { |
981 var Source = Model.Source = function(_config) { |
972 Model.Element.call(this, false, this); |
982 BaseElement.call(this, false, this); |
973 this.status = Model._SOURCE_STATUS_EMPTY; |
983 this.status = _SOURCE_STATUS_EMPTY; |
974 this.elementType = "source"; |
984 this.elementType = "source"; |
975 if (typeof _config !== "undefined") { |
985 if (typeof _config !== "undefined") { |
976 var _this = this; |
986 var _this = this; |
977 ns._(_config).forEach(function(_v, _k) { |
987 ns._(_config).forEach(function(_v, _k) { |
978 _this[_k] = _v; |
988 _this[_k] = _v; |
979 }) |
989 }); |
980 this.callbackQueue = []; |
990 this.callbackQueue = []; |
981 this.contents = {}; |
991 this.contents = {}; |
982 this.get(); |
992 this.get(); |
983 } |
993 } |
984 } |
994 }; |
985 |
995 |
986 Model.Source.prototype = new Model.Element(); |
996 extendPrototype(Source, BaseElement); |
987 |
997 |
988 Model.Source.prototype.addList = function(_listId, _contents) { |
998 Source.prototype.addList = function(_listId, _contents) { |
989 if (typeof this.contents[_listId] === "undefined") { |
999 if (typeof this.contents[_listId] === "undefined") { |
990 this.contents[_listId] = new Model.List(this.directory); |
1000 this.contents[_listId] = new List(this.directory); |
991 } |
1001 } |
992 this.contents[_listId].addElements(_contents); |
1002 this.contents[_listId].addElements(_contents); |
993 } |
1003 }; |
994 |
1004 |
995 Model.Source.prototype.getList = function(_listId, _global) { |
1005 Source.prototype.getList = function(_listId, _global) { |
996 _global = (typeof _global !== "undefined" && _global); |
1006 _global = (typeof _global !== "undefined" && _global); |
997 if (_global) { |
1007 if (_global) { |
998 return this.directory.getGlobalList().filter(function(_e) { |
1008 return this.directory.getGlobalList().filter(function(_e) { |
999 return (_e.elementType === _listId); |
1009 return (_e.elementType === _listId); |
1000 }); |
1010 }); |
1001 } else { |
1011 } else { |
1002 return this.contents[_listId] || new IriSP.Model.List(this.directory); |
1012 if (typeof this.contents[_listId] === "undefined") { |
1003 } |
1013 this.contents[_listId] = new List(this.directory); |
1004 } |
1014 } |
1005 |
1015 return this.contents[_listId]; |
1006 Model.Source.prototype.forEach = function(_callback) { |
1016 } |
|
1017 }; |
|
1018 |
|
1019 Source.prototype.forEach = function(_callback) { |
1007 var _this = this; |
1020 var _this = this; |
1008 ns._(this.contents).forEach(function(_value, _key) { |
1021 ns._(this.contents).forEach(function(_value, _key) { |
1009 _callback.call(_this, _value, _key); |
1022 _callback.call(_this, _value, _key); |
1010 }) |
1023 }); |
1011 } |
1024 }; |
1012 |
1025 |
1013 Model.Source.prototype.getElement = function(_elId) { |
1026 Source.prototype.getElement = function(_elId) { |
1014 return this.directory.getElement(_elId); |
1027 return this.directory.getElement(_elId); |
1015 } |
1028 }; |
1016 |
1029 |
1017 Model.Source.prototype.get = function() { |
1030 Source.prototype.get = function() { |
1018 this.status = Model._SOURCE_STATUS_WAITING; |
1031 this.status = _SOURCE_STATUS_WAITING; |
1019 this.handleCallbacks(); |
1032 this.handleCallbacks(); |
1020 } |
1033 }; |
1021 |
1034 |
1022 /* We defer the callbacks calls so they execute after the queue is cleared */ |
1035 /* We defer the callbacks calls so they execute after the queue is cleared */ |
1023 Model.Source.prototype.deferCallback = function(_callback) { |
1036 Source.prototype.deferCallback = function(_callback) { |
1024 var _this = this; |
1037 var _this = this; |
1025 ns._.defer(function() { |
1038 ns._.defer(function() { |
1026 _callback.call(_this); |
1039 _callback.call(_this); |
1027 }); |
1040 }); |
1028 } |
1041 }; |
1029 |
1042 |
1030 Model.Source.prototype.handleCallbacks = function() { |
1043 Source.prototype.handleCallbacks = function() { |
1031 this.status = Model._SOURCE_STATUS_READY; |
1044 this.status = _SOURCE_STATUS_READY; |
1032 while (this.callbackQueue.length) { |
1045 while (this.callbackQueue.length) { |
1033 this.deferCallback(this.callbackQueue.splice(0,1)[0]); |
1046 this.deferCallback(this.callbackQueue.splice(0,1)[0]); |
1034 } |
1047 } |
1035 } |
1048 }; |
1036 Model.Source.prototype.onLoad = function(_callback) { |
1049 Source.prototype.onLoad = function(_callback) { |
1037 if (this.status === Model._SOURCE_STATUS_READY) { |
1050 if (this.status === _SOURCE_STATUS_READY) { |
1038 this.deferCallback(_callback); |
1051 this.deferCallback(_callback); |
1039 } else { |
1052 } else { |
1040 this.callbackQueue.push(_callback); |
1053 this.callbackQueue.push(_callback); |
1041 } |
1054 } |
1042 } |
1055 }; |
1043 |
1056 |
1044 Model.Source.prototype.serialize = function() { |
1057 Source.prototype.serialize = function() { |
1045 return this.serializer.serialize(this); |
1058 return this.serializer.serialize(this); |
1046 } |
1059 }; |
1047 |
1060 |
1048 Model.Source.prototype.deSerialize = function(_data) { |
1061 Source.prototype.deSerialize = function(_data) { |
1049 this.serializer.deSerialize(_data, this); |
1062 this.serializer.deSerialize(_data, this); |
1050 } |
1063 }; |
1051 |
1064 |
1052 Model.Source.prototype.getAnnotations = function(_global) { |
1065 Source.prototype.getAnnotations = function(_global) { |
1053 _global = (typeof _global !== "undefined" && _global); |
1066 _global = (typeof _global !== "undefined" && _global); |
1054 return this.getList("annotation", _global); |
1067 return this.getList("annotation", _global); |
1055 } |
1068 }; |
1056 |
1069 |
1057 Model.Source.prototype.getMedias = function(_global) { |
1070 Source.prototype.getMedias = function(_global) { |
1058 _global = (typeof _global !== "undefined" && _global); |
1071 _global = (typeof _global !== "undefined" && _global); |
1059 return this.getList("media", _global); |
1072 return this.getList("media", _global); |
1060 } |
1073 }; |
1061 |
1074 |
1062 Model.Source.prototype.getTags = function(_global) { |
1075 Source.prototype.getTags = function(_global) { |
1063 _global = (typeof _global !== "undefined" && _global); |
1076 _global = (typeof _global !== "undefined" && _global); |
1064 return this.getList("tag", _global); |
1077 return this.getList("tag", _global); |
1065 } |
1078 }; |
1066 |
1079 |
1067 Model.Source.prototype.getMashups = function(_global) { |
1080 Source.prototype.getMashups = function(_global) { |
1068 _global = (typeof _global !== "undefined" && _global); |
1081 _global = (typeof _global !== "undefined" && _global); |
1069 return this.getList("mashup", _global); |
1082 return this.getList("mashup", _global); |
1070 } |
1083 }; |
1071 |
1084 |
1072 Model.Source.prototype.getAnnotationTypes = function(_global) { |
1085 Source.prototype.getAnnotationTypes = function(_global) { |
1073 _global = (typeof _global !== "undefined" && _global); |
1086 _global = (typeof _global !== "undefined" && _global); |
1074 return this.getList("annotationType", _global); |
1087 return this.getList("annotationType", _global); |
1075 } |
1088 }; |
1076 |
1089 |
1077 Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) { |
1090 Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) { |
1078 _global = (typeof _global !== "undefined" && _global); |
1091 _global = (typeof _global !== "undefined" && _global); |
1079 var _res = new Model.List(this.directory), |
1092 var _res = new List(this.directory), |
1080 _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title); |
1093 _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title); |
1081 _annTypes.forEach(function(_annType) { |
1094 _annTypes.forEach(function(_annType) { |
1082 _res.addElements(_annType.getAnnotations(_global)); |
1095 _res.addElements(_annType.getAnnotations(_global)); |
1083 }) |
1096 }); |
1084 return _res; |
1097 return _res; |
1085 } |
1098 }; |
1086 |
1099 |
1087 Model.Source.prototype.getDuration = function() { |
1100 Source.prototype.getDuration = function() { |
1088 var _m = this.currentMedia; |
1101 var _m = this.currentMedia; |
1089 if (typeof _m !== "undefined") { |
1102 if (typeof _m !== "undefined") { |
1090 return this.currentMedia.duration; |
1103 return this.currentMedia.duration; |
1091 } |
1104 } |
1092 } |
1105 }; |
1093 |
1106 |
1094 Model.Source.prototype.getCurrentMedia = function(_opts) { |
1107 Source.prototype.getCurrentMedia = function(_opts) { |
1095 if (typeof this.currentMedia === "undefined") { |
1108 if (typeof this.currentMedia === "undefined") { |
1096 if (_opts.is_mashup) { |
1109 if (_opts.is_mashup) { |
1097 var _mashups = this.getMashups(); |
1110 var _mashups = this.getMashups(); |
1098 if (_mashups.length) { |
1111 if (_mashups.length) { |
1099 this.currentMedia = _mashups[0]; |
1112 this.currentMedia = _mashups[0]; |