src/js/model.js
branchnew-model
changeset 872 d777d05a16e4
parent 870 2c025db10a10
child 880 4c7b33bf2795
equal deleted inserted replaced
870:2c025db10a10 872:d777d05a16e4
     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     getUID : function() {
     8     getUID : function() {
     9         return "autoid-" + (++this._ID_AUTO_INCREMENT);
     9         return "autoid-" + (++this._ID_AUTO_INCREMENT);
       
    10     },
       
    11     regexpFromTextOrArray : function(_textOrArray) {
       
    12         function escapeText(_text) {
       
    13             return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
       
    14         }
       
    15         return new RegExp( '('
       
    16             + (
       
    17                 typeof _textOrArray === "string"
       
    18                 ? escapeText(_textOrArray)
       
    19                 : IriSP._(_textOrArray).map(escapeText).join("|")
       
    20             )
       
    21             + ')',
       
    22             'gim'
       
    23         );
    10     },
    24     },
    11     isoToDate : function(_str) {
    25     isoToDate : function(_str) {
    12         // http://delete.me.uk/2005/03/iso8601.html
    26         // 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})))?)?)?)?";
    27         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));
    28         var d = _str.match(new RegExp(regexp));
    50 IriSP.Model.List = function(_directory) {
    64 IriSP.Model.List = function(_directory) {
    51     Array.call(this);
    65     Array.call(this);
    52     this.directory = _directory;
    66     this.directory = _directory;
    53     this.idIndex = [];
    67     this.idIndex = [];
    54     if (typeof _directory == "undefined") {
    68     if (typeof _directory == "undefined") {
    55         throw("Error : new IriSP.Model.List(directory): directory is undefined");
    69         throw "Error : new IriSP.Model.List(directory): directory is undefined";
    56     }
    70     }
    57 }
    71 }
    58 
    72 
    59 IriSP.Model.List.prototype = new Array();
    73 IriSP.Model.List.prototype = new Array();
    60 
    74 
   105     var _res = new IriSP.Model.List(this.directory);
   119     var _res = new IriSP.Model.List(this.directory);
   106     _res.addElements(Array.prototype.slice.call(this, _start, _end));
   120     _res.addElements(Array.prototype.slice.call(this, _start, _end));
   107     return _res;
   121     return _res;
   108 }
   122 }
   109 
   123 
       
   124 IriSP.Model.List.prototype.splice = function(_start, _end) {
       
   125     var _res = new IriSP.Model.List(this.directory);
       
   126     _res.addElements(Array.prototype.splice.call(this, _start, _end));
       
   127     this.idIndex.splice(_start, _end);
       
   128     return _res;
       
   129 }
       
   130 
   110 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy
   131 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy
   111  * and won't return a new IriSP.Model.List
   132  * and won't return a new IriSP.Model.List
   112  */
   133  */
   113 IriSP.Model.List.prototype.sortBy = function(_callback) {
   134 IriSP.Model.List.prototype.sortBy = function(_callback) {
   114     var _this = this,
   135     var _this = this,
   121 
   142 
   122 /* Title and Description are basic information for (almost) all element types,
   143 /* Title and Description are basic information for (almost) all element types,
   123  * here we can search by these criteria
   144  * here we can search by these criteria
   124  */
   145  */
   125 IriSP.Model.List.prototype.searchByTitle = function(_text) {
   146 IriSP.Model.List.prototype.searchByTitle = function(_text) {
   126     var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim');
   147     var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
   127     return this.filter(function(_element) {
   148     return this.filter(function(_element) {
   128         return _rgxp.test(_element.title);
   149         return _rgxp.test(_element.title);
   129     });
   150     });
   130 }
   151 }
   131 
   152 
   132 IriSP.Model.List.prototype.searchByDescription = function(_text) {
   153 IriSP.Model.List.prototype.searchByDescription = function(_text) {
   133     var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim');
   154     var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
   134     return this.filter(function(_element) {
   155     return this.filter(function(_element) {
   135         return _rgxp.test(_element.description);
   156         return _rgxp.test(_element.description);
   136     });
   157     });
   137 }
   158 }
   138 
   159 
   139 IriSP.Model.List.prototype.searchByTextFields = function(_text) {
   160 IriSP.Model.List.prototype.searchByTextFields = function(_text) {
   140     var _rgxp = new RegExp('(' + _text.replace(/(\W)/gm,'\\$1') + ')','gim');
   161     var _rgxp =  IriSP.Model.regexpFromTextOrArray(_text);
   141     return this.filter(function(_element) {
   162     return this.filter(function(_element) {
   142         return _rgxp.test(_element.description) || _rgxp.test(_element.title);
   163         return _rgxp.test(_element.description) || _rgxp.test(_element.title);
   143     });
   164     });
   144 }
   165 }
   145 
   166 
   156         Array.prototype.push.call(this, _el);
   177         Array.prototype.push.call(this, _el);
   157     }
   178     }
   158 }
   179 }
   159 
   180 
   160 IriSP.Model.List.prototype.push = function(_el) {
   181 IriSP.Model.List.prototype.push = function(_el) {
   161     if (typeof this.directory.getElement(_el.id) === "undefined") {
   182     if (typeof _el === "undefined") {
   162         this.directory.addElement(_el);
   183         return;
   163     }
   184     }
   164     var _index = (IriSP._(this.idIndex).indexOf(_el.id));
   185     var _index = (IriSP._(this.idIndex).indexOf(_el.id));
   165     if (_index === -1) {
   186     if (_index === -1) {
   166         this.idIndex.push(_el.id);
   187         this.idIndex.push(_el.id);
   167         Array.prototype.push.call(this, _el);
   188         Array.prototype.push.call(this, _el);
   180 
   201 
   181 IriSP.Model.List.prototype.addElements = function(_array) {
   202 IriSP.Model.List.prototype.addElements = function(_array) {
   182     var _this = this;
   203     var _this = this;
   183     IriSP._(_array).forEach(function(_el) {
   204     IriSP._(_array).forEach(function(_el) {
   184         _this.push(_el);
   205         _this.push(_el);
       
   206     });
       
   207 }
       
   208 
       
   209 IriSP.Model.List.prototype.removeId = function(_id) {
       
   210     var _index = (IriSP._(this.idIndex).indexOf(_id));
       
   211     if (_index !== -1) {
       
   212         this.splice(_index,1);
       
   213     }
       
   214 }
       
   215 
       
   216 IriSP.Model.List.prototype.removeElement = function(_el) {
       
   217     this.removeId(_el.id);
       
   218 }
       
   219 
       
   220 IriSP.Model.List.prototype.removeIds = function(_list) {
       
   221     var _this = this;
       
   222     IriSP._(_list).forEach(function(_id) {
       
   223         _this.removeId(_id);
       
   224     });
       
   225 }
       
   226 
       
   227 IriSP.Model.List.prototype.removeElements = function(_list) {
       
   228     var _this = this;
       
   229     IriSP._(_list).forEach(function(_el) {
       
   230         _this.removeElement(_el);
   185     });
   231     });
   186 }
   232 }
   187 
   233 
   188 /* A simple time management object, that helps converting millisecs to seconds and strings,
   234 /* A simple time management object, that helps converting millisecs to seconds and strings,
   189  * without the clumsiness of the original Date object.
   235  * without the clumsiness of the original Date object.
   208         minutes : (Math.floor(_totalSeconds / 60) % 60),
   254         minutes : (Math.floor(_totalSeconds / 60) % 60),
   209         seconds : _totalSeconds % 60
   255         seconds : _totalSeconds % 60
   210     } 
   256     } 
   211 }
   257 }
   212 
   258 
       
   259 IriSP.Model.Time.prototype.valueOf = function() {
       
   260     return this.milliseconds;
       
   261 }
       
   262 
   213 IriSP.Model.Time.prototype.toString = function() {
   263 IriSP.Model.Time.prototype.toString = function() {
   214     function pad(_n) {
   264     function pad(_n) {
   215         var _res = _n.toString();
   265         var _res = _n.toString();
   216         while (_res.length < 2) {
   266         while (_res.length < 2) {
   217             _res = '0' + _res;
   267             _res = '0' + _res;
   232 
   282 
   233 IriSP.Model.Reference = function(_source, _idRef) {
   283 IriSP.Model.Reference = function(_source, _idRef) {
   234     this.source = _source;
   284     this.source = _source;
   235     if (typeof _idRef === "object") {
   285     if (typeof _idRef === "object") {
   236         this.isList = true;
   286         this.isList = true;
   237         this.contents = new IriSP.Model.List(this.source.directory);
   287         this.id = IriSP._(_idRef).map(function(_id) {
   238         this.contents.addIds(IriSP._(_idRef).map(function(_id) {
       
   239             return _source.getNamespaced(_id).fullname;
   288             return _source.getNamespaced(_id).fullname;
   240         }));
   289         });
   241     } else {
   290     } else {
   242         this.isList = false;
   291         this.isList = false;
   243         this.contents = this.source.directory.getElement(_source.getNamespaced(_idRef).fullname);
   292         this.id = _source.getNamespaced(_idRef).fullname;
       
   293     }
       
   294     this.refresh();
       
   295 }
       
   296 
       
   297 IriSP.Model.Reference.prototype.refresh = function() {
       
   298     if (this.isList) {
       
   299         this.contents = new IriSP.Model.List(this.source.directory);
       
   300         this.contents.addIds(this.id);
       
   301     } else {
       
   302         this.contents = this.source.directory.getElement(this.id);
       
   303     }
       
   304     
       
   305 }
       
   306 
       
   307 IriSP.Model.Reference.prototype.getContents = function() {
       
   308     if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) {
       
   309         this.refresh();
       
   310     }
       
   311     return this.contents;
       
   312 }
       
   313 
       
   314 IriSP.Model.Reference.prototype.isOrHasId = function(_idRef) {
       
   315     if (this.isList) {
       
   316         return (IriSP._(this.id).indexOf(_idRef) !== -1)
       
   317     } else {
       
   318         return (this.id == _idRef);
   244     }
   319     }
   245 }
   320 }
   246 
   321 
   247 /* */
   322 /* */
   248 
   323 
   249 IriSP.Model.Element = function(_id, _source) {
   324 IriSP.Model.Element = function(_id, _source) {
   250     this.elementType = 'element';
   325     this.elementType = 'element';
   251     if (typeof _source !== "undefined") {
   326     if (typeof _source === "undefined") {
   252         if (typeof _id === "undefined" || !_id) {
   327         return;
   253             _id = IriSP.Model.getUID();
   328     }
   254         }
   329     if (typeof _id === "undefined" || !_id) {
   255         this.source = _source;
   330         _id = IriSP.Model.getUID();
   256         this.namespacedId = _source.getNamespaced(_id)
   331     }
   257         this.id = this.namespacedId.fullname;
   332     this.source = _source;
   258         this.title = "";
   333     this.namespacedId = _source.getNamespaced(_id)
   259         this.description = "";
   334     this.id = this.namespacedId.fullname;
   260         this.source.directory.addElement(this);
   335     this.title = "";
   261     }
   336     this.description = "";
       
   337     this.source.directory.addElement(this);
   262 }
   338 }
   263 
   339 
   264 IriSP.Model.Element.prototype.toString = function() {
   340 IriSP.Model.Element.prototype.toString = function() {
   265     return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : '');
   341     return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : '');
   266 }
   342 }
   269     this[_elementType] = new IriSP.Model.Reference(this.source, _idRef);
   345     this[_elementType] = new IriSP.Model.Reference(this.source, _idRef);
   270 }
   346 }
   271 
   347 
   272 IriSP.Model.Element.prototype.getReference = function(_elementType) {
   348 IriSP.Model.Element.prototype.getReference = function(_elementType) {
   273     if (typeof this[_elementType] !== "undefined") {
   349     if (typeof this[_elementType] !== "undefined") {
   274         return this[_elementType].contents;
   350         return this[_elementType].getContents();
   275     }
   351     }
   276 }
   352 }
   277 
   353 
   278 IriSP.Model.Element.prototype.getRelated = function(_elementType) {
   354 IriSP.Model.Element.prototype.getRelated = function(_elementType, _global) {
       
   355     _global = (typeof _global !== "undefined" && _global);
   279     var _this = this;
   356     var _this = this;
   280     return this.source.getList(_elementType).filter(function(_el) {
   357     return this.source.getList(_elementType, _global).filter(function(_el) {
   281         var _ref = _el[_this.elementType];
   358         var _ref = _el[_this.elementType];
   282         if (_ref.isList) {
   359         return _ref.isOrHasId(_this.id);
   283             return _ref.contents.hasId(_this.id);
       
   284         }
       
   285         else {
       
   286             return _ref.contents.id === _this.id;
       
   287         }
       
   288     });
   360     });
   289 }
   361 }
   290 
   362 
   291 /* */
   363 /* */
   292 
   364 
   391             _this[_k] = _v;
   463             _this[_k] = _v;
   392         })
   464         })
   393         this.callbackQueue = [];
   465         this.callbackQueue = [];
   394         this.contents = {};
   466         this.contents = {};
   395         if (typeof this.namespace === "undefined") {
   467         if (typeof this.namespace === "undefined") {
   396             this.namespace = IriSP.Model.getUID();
   468             this.namespace = "metadataplayer";
       
   469         } else {
       
   470             if (typeof this.namespaceUrl === "undefined" && typeof this.url !== "undefined") {
       
   471                 var _matches = this.url.match(/(^[^?&]+|[^?&][a-zA-Z0-9_%=?]+)/g),
       
   472                     _url = _matches[0];
       
   473                 if (_matches.length > 1) {
       
   474                     _matches = IriSP._(_matches.slice(1)).reject(function(_txt) {
       
   475                         return /\?$/.test(_txt);
       
   476                     });
       
   477                 }
       
   478                 if (_matches.length > 0) {
       
   479                     _url += '?' + _matches.join('&');
       
   480                 }
       
   481                 this.namespaceUrl = _url;
       
   482             }
   397         }
   483         }
   398         if (typeof this.namespaceUrl === "undefined") {
   484         if (typeof this.namespaceUrl === "undefined") {
   399             this.namespaceUrl = (typeof this.url !== "undefined" ? this.url : this.namespaceUrl);
   485             this.namespaceUrl = "http://ldt.iri.centrepompidou.fr/";
   400         }
   486         }
   401         this.directory.namespaces[this.namespace] = this.namespaceUrl;
   487         this.directory.addNamespace(this.namespace, this.namespaceUrl);
   402         this.get();
   488         this.get();
   403     }
   489     }
   404 }
   490 }
   405 
   491 
   406 IriSP.Model.Source.prototype.getNamespaced = function(_id) {
   492 IriSP.Model.Source.prototype.getNamespaced = function(_id) {
   419         }
   505         }
   420     }
   506     }
   421 }
   507 }
   422     
   508     
   423 IriSP.Model.Source.prototype.unNamespace = function(_id) {
   509 IriSP.Model.Source.prototype.unNamespace = function(_id) {
   424     return _id.replace(this.namespace + ':', '');
   510     if (typeof _id !== "undefined") {
       
   511         return _id.replace(this.namespace + ':', '');
       
   512     }
   425 }
   513 }
   426 
   514 
   427 IriSP.Model.Source.prototype.addList = function(_listId, _contents) {
   515 IriSP.Model.Source.prototype.addList = function(_listId, _contents) {
   428     if (typeof this.contents[_listId] === "undefined") {
   516     if (typeof this.contents[_listId] === "undefined") {
   429         this.contents[_listId] = new IriSP.Model.List(this.directory);
   517         this.contents[_listId] = new IriSP.Model.List(this.directory);
   430     }
   518     }
   431     this.contents[_listId].addElements(_contents);
   519     this.contents[_listId].addElements(_contents);
   432 }
   520 }
   433 
   521 
   434 IriSP.Model.Source.prototype.getList = function(_listId) {
   522 IriSP.Model.Source.prototype.getList = function(_listId, _global) {
   435     if (typeof this.contents[_listId] === "undefined") {
   523     _global = (typeof _global !== "undefined" && _global);
       
   524     if (_global || typeof this.contents[_listId] === "undefined") {
   436         return this.directory.getGlobalList().filter(function(_e) {
   525         return this.directory.getGlobalList().filter(function(_e) {
   437             return (_e.elType === _listId);
   526             return (_e.elementType === _listId);
   438         });
   527         });
   439     } else {
   528     } else {
   440         return this.contents[_listId];
   529         return this.contents[_listId];
   441     }
   530     }
   442 }
   531 }
   513 
   602 
   514 IriSP.Model.Source.prototype.deSerialize = function(_data) {
   603 IriSP.Model.Source.prototype.deSerialize = function(_data) {
   515     this.serializer.deSerialize(_data, this);
   604     this.serializer.deSerialize(_data, this);
   516 }
   605 }
   517 
   606 
   518 IriSP.Model.Source.prototype.getAnnotations = function() {
   607 IriSP.Model.Source.prototype.getAnnotations = function(_global) {
   519     return this.getList("annotation");
   608     _global = (typeof _global !== "undefined" && _global);
   520 }
   609     return this.getList("annotation", _global);
   521 
   610 }
   522 IriSP.Model.Source.prototype.getMedias = function() {
   611 
   523     return this.getList("media");
   612 IriSP.Model.Source.prototype.getMedias = function(_global) {
   524 }
   613     _global = (typeof _global !== "undefined" && _global);
   525 
   614     return this.getList("media", _global);
   526 IriSP.Model.Source.prototype.getAnnotationTypes = function() {
   615 }
   527     return this.getList("annotationType");
   616 
   528 }
   617 IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) {
   529 
   618     _global = (typeof _global !== "undefined" && _global);
   530 IriSP.Model.Source.prototype.getAnnotationTypeByTitle = function(_title) {
   619     return this.getList("annotationType", _global);
   531     var _res = this.getAnnotationTypes().searchByTitle(_title);
   620 }
   532     if (_res.length) {
   621 
   533         return _res[0];
   622 IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) {
   534     }
   623     _global = (typeof _global !== "undefined" && _global);
   535 }
   624     var _res = new IriSP.Model.List(this.directory),
   536 
   625         _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title);
   537 IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title) {
   626     _annTypes.forEach(function(_annType) {
   538     var _annType = this.getAnnotationTypeByTitle(_title);
   627         _res.addElements(_annType.getAnnotations(_global));
   539     if (typeof _annType !== "undefined") {
   628     })
   540         return _annType.getAnnotations();
   629     return _res;
   541     }
       
   542 }
   630 }
   543 
   631 
   544 IriSP.Model.Source.prototype.getDuration = function() {
   632 IriSP.Model.Source.prototype.getDuration = function() {
   545     var _m = this.currentMedia;
   633     var _m = this.currentMedia;
   546     if (typeof _m !== "undefined") {
   634     if (typeof _m !== "undefined") {
   557 IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source();
   645 IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source();
   558 
   646 
   559 IriSP.Model.RemoteSource.prototype.get = function() {
   647 IriSP.Model.RemoteSource.prototype.get = function() {
   560     this.status = IriSP.Model._SOURCE_STATUS_WAITING;
   648     this.status = IriSP.Model._SOURCE_STATUS_WAITING;
   561     var _this = this;
   649     var _this = this;
   562     IriSP.jQuery.getJSON(this.url, function(_result) {
   650     this.serializer.loadData(this.url, function(_result) {
   563         _this.deSerialize(_result);
   651         _this.deSerialize(_result);
   564         _this.handleCallbacks();
   652         _this.handleCallbacks();
   565     });
   653     });
   566 }
   654 }
   567 
   655 
   571     this.remoteSources = {};
   659     this.remoteSources = {};
   572     this.elements = {};
   660     this.elements = {};
   573     this.namespaces = {};
   661     this.namespaces = {};
   574 }
   662 }
   575 
   663 
       
   664 IriSP.Model.Directory.prototype.addNamespace = function(_namespace, _url) {
       
   665     this.namespaces[_namespace] = _url;
       
   666 }
       
   667 
   576 IriSP.Model.Directory.prototype.remoteSource = function(_properties) {
   668 IriSP.Model.Directory.prototype.remoteSource = function(_properties) {
   577     var _config = IriSP._({ directory: this }).extend(_properties);
   669     var _config = IriSP._({ directory: this }).extend(_properties);
   578     if (typeof this.remoteSources[_properties.url] === "undefined") {
   670     if (typeof this.remoteSources[_properties.url] === "undefined") {
   579         this.remoteSources[_properties.url] = new IriSP.Model.RemoteSource(_config);
   671         this.remoteSources[_properties.url] = new IriSP.Model.RemoteSource(_config);
   580     }
   672     }