1 /* model.js is where data is stored in a standard form, whatever the serializer */ |
1 /* model.js is where data is stored in a standard form, whatever the serializer */ |
2 |
2 |
3 IriSP.Model = { |
3 IriSP.Model = { |
4 SOURCE_STATUS_EMPTY : 0, |
4 _SOURCE_STATUS_EMPTY : 0, |
5 SOURCE_STATUS_WAITING : 1, |
5 _SOURCE_STATUS_WAITING : 1, |
6 SOURCE_STATUS_READY : 2, |
6 _SOURCE_STATUS_READY : 2, |
7 ID_AUTO_INCREMENT : 0, |
7 _ID_AUTO_INCREMENT : 0, |
8 getAI : function() { |
8 getAI : function() { |
9 return "autoid-" + (++this.ID_AUTO_INCREMENT); |
9 return "autoid-" + (++this._ID_AUTO_INCREMENT); |
10 }, |
10 }, |
11 isoToDate : function(_str) { |
11 isoToDate : function(_str) { |
12 // http://delete.me.uk/2005/03/iso8601.html |
12 // http://delete.me.uk/2005/03/iso8601.html |
13 var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"; |
13 var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"; |
14 var d = _str.match(new RegExp(regexp)); |
14 var d = _str.match(new RegExp(regexp)); |
42 + pad(d.getUTCMinutes())+':' |
42 + pad(d.getUTCMinutes())+':' |
43 + pad(d.getUTCSeconds())+'Z' |
43 + pad(d.getUTCSeconds())+'Z' |
44 } |
44 } |
45 } |
45 } |
46 |
46 |
47 /* */ |
47 /* |
48 |
48 * IriSP.Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) |
|
49 */ |
49 IriSP.Model.List = function(_directory) { |
50 IriSP.Model.List = function(_directory) { |
50 Array.call(this); |
51 Array.call(this); |
51 this.directory = _directory; |
52 this.directory = _directory; |
52 this.idIndex = []; |
53 this.idIndex = []; |
53 if (typeof _directory == "undefined") { |
54 if (typeof _directory == "undefined") { |
65 |
66 |
66 IriSP.Model.List.prototype.hasId = function(_id) { |
67 IriSP.Model.List.prototype.hasId = function(_id) { |
67 return (IriSP._(this.idIndex).indexOf(_id) !== -1); |
68 return (IriSP._(this.idIndex).indexOf(_id) !== -1); |
68 } |
69 } |
69 |
70 |
|
71 /* On recent browsers, forEach and map are defined and do what we want. |
|
72 * Otherwise, we'll use the Underscore.js functions |
|
73 */ |
70 if (typeof Array.prototype.forEach === "undefined") { |
74 if (typeof Array.prototype.forEach === "undefined") { |
71 IriSP.Model.List.prototype.forEach = function(_callback) { |
75 IriSP.Model.List.prototype.forEach = function(_callback) { |
72 var _this = this; |
76 var _this = this; |
73 IriSP._(this).forEach(function(_value, _key) { |
77 IriSP._(this).forEach(function(_value, _key) { |
74 _callback(_value, _key, _this); |
78 _callback(_value, _key, _this); |
83 return _callback(_value, _key, _this); |
87 return _callback(_value, _key, _this); |
84 }); |
88 }); |
85 } |
89 } |
86 } |
90 } |
87 |
91 |
88 /* We override Array's filter function because it doesn't return an IriSP.Model.List */ |
92 /* We override Array's filter function because it doesn't return an IriSP.Model.List |
|
93 */ |
89 IriSP.Model.List.prototype.filter = function(_callback) { |
94 IriSP.Model.List.prototype.filter = function(_callback) { |
90 var _this = this, |
95 var _this = this, |
91 _res = new IriSP.Model.List(this.directory); |
96 _res = new IriSP.Model.List(this.directory); |
92 _res.addElements(IriSP._(this).filter(function(_value, _key) { |
97 _res.addElements(IriSP._(this).filter(function(_value, _key) { |
93 return _callback(_value, _key, _this); |
98 return _callback(_value, _key, _this); |
94 })); |
99 })); |
95 return _res; |
100 return _res; |
96 } |
101 } |
97 |
102 |
|
103 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy |
|
104 * and won't return a new IriSP.Model.List |
|
105 */ |
98 IriSP.Model.List.prototype.sortBy = function(_callback) { |
106 IriSP.Model.List.prototype.sortBy = function(_callback) { |
99 var _this = this, |
107 var _this = this, |
100 _res = new IriSP.Model.List(this.directory); |
108 _res = new IriSP.Model.List(this.directory); |
101 _res.contents = IriSP._(this).sortBy(function(_value, _key) { |
109 _res.contents = IriSP._(this).sortBy(function(_value, _key) { |
102 return _callback(_value, _key, _this); |
110 return _callback(_value, _key, _this); |
103 }); |
111 }); |
104 return _res; |
112 return _res; |
105 } |
113 } |
106 |
114 |
|
115 /* Title and Description are basic information for (almost) all element types, |
|
116 * here we can search by these criteria |
|
117 */ |
107 IriSP.Model.List.prototype.searchByTitle = function(_text) { |
118 IriSP.Model.List.prototype.searchByTitle = function(_text) { |
108 var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim'); |
119 var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim'); |
109 return this.filter(function(_element) { |
120 return this.filter(function(_element) { |
110 return _rgxp.test(_element.title); |
121 return _rgxp.test(_element.title); |
111 }); |
122 }); |
135 |
146 |
136 IriSP.Model.List.prototype.push = function(_el) { |
147 IriSP.Model.List.prototype.push = function(_el) { |
137 if (typeof this.directory.getElement(_el.id) === "undefined") { |
148 if (typeof this.directory.getElement(_el.id) === "undefined") { |
138 this.directory.addElement(_el); |
149 this.directory.addElement(_el); |
139 } |
150 } |
140 this.idIndex.push(_el.id); |
151 var _index = (IriSP._(this.idIndex).indexOf(_el.id)); |
141 Array.prototype.push.call(this, _el); |
152 if (_index === -1) { |
|
153 this.idIndex.push(_el.id); |
|
154 Array.prototype.push.call(this, _el); |
|
155 } else { |
|
156 this[_index] = _el; |
|
157 } |
142 } |
158 } |
143 |
159 |
144 IriSP.Model.List.prototype.addIds = function(_array) { |
160 IriSP.Model.List.prototype.addIds = function(_array) { |
145 var _l = _array.length, |
161 var _l = _array.length, |
146 _this = this; |
162 _this = this; |
155 IriSP._(_array).forEach(function(_el) { |
171 IriSP._(_array).forEach(function(_el) { |
156 _this.push(_el); |
172 _this.push(_el); |
157 }); |
173 }); |
158 } |
174 } |
159 |
175 |
160 /* */ |
176 /* A simple time management object, that helps converting millisecs to seconds and strings, |
|
177 * without the clumsiness of the original Date object. |
|
178 */ |
161 |
179 |
162 IriSP.Model.Time = function(_milliseconds) { |
180 IriSP.Model.Time = function(_milliseconds) { |
163 this.milliseconds = parseInt(typeof _milliseconds !== "undefined" ? _milliseconds : 0); |
181 this.milliseconds = parseInt(typeof _milliseconds !== "undefined" ? _milliseconds : 0); |
164 } |
182 } |
165 |
183 |
195 } |
213 } |
196 _res += pad(_hms.minutes) + ':' + pad(_hms.seconds); |
214 _res += pad(_hms.minutes) + ':' + pad(_hms.seconds); |
197 return _res; |
215 return _res; |
198 } |
216 } |
199 |
217 |
200 /* */ |
218 /* IriSP.Model.Reference handles references between elements |
|
219 */ |
201 |
220 |
202 IriSP.Model.Reference = function(_source, _idRef) { |
221 IriSP.Model.Reference = function(_source, _idRef) { |
203 this.source = _source; |
222 this.source = _source; |
204 if (typeof _idRef === "object") { |
223 if (typeof _idRef === "object") { |
205 this.isList = true; |
224 this.isList = true; |
207 this.contents.addIds(IriSP._(_idRef).map(function(_id) { |
226 this.contents.addIds(IriSP._(_idRef).map(function(_id) { |
208 return _source.getNamespaced(_id).fullname; |
227 return _source.getNamespaced(_id).fullname; |
209 })); |
228 })); |
210 } else { |
229 } else { |
211 this.isList = false; |
230 this.isList = false; |
212 this.contents = _source.getNamespaced(_idRef).fullname; |
231 this.contents = this.source.directory.getElement(_source.getNamespaced(_idRef).fullname); |
213 } |
232 } |
214 } |
|
215 |
|
216 IriSP.Model.Reference.prototype.getContents = function() { |
|
217 return (this.isList ? this.contents : this.source.directory.getElement(this.contents)); |
|
218 } |
233 } |
219 |
234 |
220 /* */ |
235 /* */ |
221 |
236 |
222 IriSP.Model.Element = function(_id, _source) { |
237 IriSP.Model.Element = function(_id, _source) { |
241 this[_elementType] = new IriSP.Model.Reference(this.source, _idRef); |
256 this[_elementType] = new IriSP.Model.Reference(this.source, _idRef); |
242 } |
257 } |
243 |
258 |
244 IriSP.Model.Element.prototype.getReference = function(_elementType) { |
259 IriSP.Model.Element.prototype.getReference = function(_elementType) { |
245 if (typeof this[_elementType] !== "undefined") { |
260 if (typeof this[_elementType] !== "undefined") { |
246 return this[_elementType].getContents(); |
261 return this[_elementType].contents; |
247 } |
262 } |
248 } |
263 } |
249 |
264 |
250 IriSP.Model.Element.prototype.getRelated = function(_elementType) { |
265 IriSP.Model.Element.prototype.getRelated = function(_elementType) { |
251 var _this = this; |
266 var _this = this; |
446 }); |
461 }); |
447 return _nsls; |
462 return _nsls; |
448 } |
463 } |
449 |
464 |
450 IriSP.Model.Source.prototype.get = function() { |
465 IriSP.Model.Source.prototype.get = function() { |
451 this.status = IriSP.Model.SOURCE_STATUS_READY; |
466 this.status = IriSP.Model._SOURCE_STATUS_READY; |
452 var _this = this; |
467 var _this = this; |
453 if (_this.callbackQueue.length) { |
468 if (_this.callbackQueue.length) { |
454 IriSP._(_this.callbackQueue).forEach(function(_callback) { |
469 IriSP._(_this.callbackQueue).forEach(function(_callback) { |
455 _callback.call(_this); |
470 _callback.call(_this); |
456 }); |
471 }); |
461 IriSP.Model.Source.prototype.serialize = function() { |
476 IriSP.Model.Source.prototype.serialize = function() { |
462 return this.serializer.serialize(this); |
477 return this.serializer.serialize(this); |
463 } |
478 } |
464 |
479 |
465 IriSP.Model.Source.prototype.onLoad = function(_callback) { |
480 IriSP.Model.Source.prototype.onLoad = function(_callback) { |
466 if (this.status === IriSP.Model.SOURCE_STATUS_READY) { |
481 if (this.status === IriSP.Model._SOURCE_STATUS_READY) { |
467 callback.call(this); |
482 console.log("Called on load, Ready"); |
|
483 var _this = this; |
|
484 IriSP._.defer(function() { |
|
485 _callback.call(_this); |
|
486 }); |
468 } else { |
487 } else { |
|
488 console.log("Called on load, not ready"); |
469 this.callbackQueue.push(_callback); |
489 this.callbackQueue.push(_callback); |
470 } |
490 } |
471 } |
491 } |
472 |
492 |
473 IriSP.Model.Source.prototype.getAnnotations = function() { |
493 IriSP.Model.Source.prototype.getAnnotations = function() { |
503 } |
523 } |
504 |
524 |
505 IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source(); |
525 IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source(); |
506 |
526 |
507 IriSP.Model.RemoteSource.prototype.get = function() { |
527 IriSP.Model.RemoteSource.prototype.get = function() { |
508 this.status = IriSP.Model.SOURCE_STATUS_WAITING; |
528 this.status = IriSP.Model._SOURCE_STATUS_WAITING; |
509 var _this = this; |
529 var _this = this; |
510 IriSP.jQuery.getJSON(this.url, function(_result) { |
530 IriSP.jQuery.getJSON(this.url, function(_result) { |
511 _this.serializer.deSerialize(_result, _this); |
531 _this.serializer.deSerialize(_result, _this); |
|
532 console.log('Received data, we have '+_this.callbackQueue.length+' callbacks waiting'); |
512 if (_this.callbackQueue.length) { |
533 if (_this.callbackQueue.length) { |
513 IriSP._(_this.callbackQueue).forEach(function(_callback) { |
534 IriSP._(_this.callbackQueue).forEach(function(_callback) { |
514 _callback.call(_this); |
535 _callback.call(_this); |
515 }); |
536 }); |
516 } |
537 } |
517 _this.callbackQueue = []; |
538 _this.callbackQueue = []; |
518 _this.status = IriSP.Model.SOURCE_STATUS_READY; |
539 _this.status = IriSP.Model._SOURCE_STATUS_READY; |
519 }); |
540 }); |
520 } |
541 } |
521 |
542 |
522 /* */ |
543 /* */ |
523 |
544 |