diff -r 0b710028f3d3 -r 60ca7678f074 integration/js/model.js --- a/integration/js/model.js Mon Aug 26 13:06:12 2013 +0200 +++ b/integration/js/model.js Tue Oct 01 16:16:07 2013 +0200 @@ -1,6 +1,8 @@ -/* TODO: Separate Project-specific data from Source */ + +/* js is where data is stored in a standard form, whatever the serializer */ -/* model.js is where data is stored in a standard form, whatever the serializer */ +//TODO: Separate Project-specific data from Source + IriSP.Model = (function (ns) { function pad(n, x, b) { @@ -31,23 +33,32 @@ String.fromCharCode(768), String.fromCharCode(769), String.fromCharCode(770), String.fromCharCode(771), String.fromCharCode(807), "{", "}", "(", ")", "[", "]", "【", "】", "、", "・", "‥", "。", "「", "」", "『", "』", "〜", ":", "!", "?", " ", ",", " ", ";", "(", ")", ".", "*", "+", "\\", "?", "|", "{", "}", "[", "]", "^", "#", "/" - ] + ]; -var Model = { - _SOURCE_STATUS_EMPTY : 0, - _SOURCE_STATUS_WAITING : 1, - _SOURCE_STATUS_READY : 2, - getUID : function() { +var Model = {}, + _SOURCE_STATUS_EMPTY = Model._SOURCE_STATUS_EMPTY = 0, + _SOURCE_STATUS_WAITING = Model._SOURCE_STATUS_WAITING = 1, + _SOURCE_STATUS_READY = Model._SOURCE_STATUS_READY = 2, + extendPrototype = Model.extendPrototype = function(toClass, fromClass) { + var fromP = fromClass.prototype, + toP = toClass.prototype; + for (var k in fromP) { + if (fromP.hasOwnProperty(k)) { + toP[k] = fromP[k]; + } + } + }, + getUID = Model.getUID = function() { return uidbase + pad(4, (++uidincrement % 0x10000), 16) + "-" + rand16(4) + "-" + rand16(6) + rand16(6); }, - isLocalURL : function(url) { + isLocalURL = Model.isLocalURL = function(url) { var matches = url.match(/^(\w+:)\/\/([^/]+)/); if (matches) { - return(matches[1] === document.location.protocol && matches[2] === document.location.host) + return(matches[1] === document.location.protocol && matches[2] === document.location.host); } return true; }, - regexpFromTextOrArray : function(_textOrArray, _testOnly, _iexact) { + regexpFromTextOrArray = Model.regexpFromTextOrArray = function(_textOrArray, _testOnly, _iexact) { var _testOnly = _testOnly || false, _iexact = _iexact || false; function escapeText(_text) { @@ -67,10 +78,10 @@ } return new RegExp( _source, _flags); }, - fullTextRegexps: function(_text) { + fullTextRegexps = Model.fullTextRegexps = function(_text) { var remsrc = "[\\" + removeChars.join("\\") + "]", remrx = new RegExp(remsrc,"gm"), - txt = _text.toLowerCase().replace(remrx,"") + txt = _text.toLowerCase().replace(remrx,""), res = [], charsrx = ns._(charsub).map(function(c) { return new RegExp(c); @@ -88,7 +99,7 @@ } return "(" + src + ")"; }, - isoToDate : function(_str) { + isoToDate = Model.isoToDate = function(_str) { // http://delete.me.uk/2005/03/iso8601.html 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})))?)?)?)?"; var d = _str.match(new RegExp(regexp)); @@ -113,28 +124,27 @@ _res.setTime(Number(time)); return _res; }, - dateToIso : function(_d) { + dateToIso = Model.dateToIso = function(_d) { var d = _d ? new Date(_d) : new Date(); return d.getUTCFullYear()+'-' + pad(2, d.getUTCMonth()+1)+'-' + pad(2, d.getUTCDate())+'T' + pad(2, d.getUTCHours())+':' + pad(2, d.getUTCMinutes())+':' - + pad(2, d.getUTCSeconds())+'Z' - } -} + + pad(2, d.getUTCSeconds())+'Z' ; + }; /* - * Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) + * List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) */ -Model.List = function(_directory) { +var List = Model.List = function(_directory) { Array.call(this); this.directory = _directory; this.idIndex = []; this.__events = {}; if (typeof _directory == "undefined") { console.trace(); - throw "Error : new Model.List(directory): directory is undefined"; + throw "Error : new List(directory): directory is undefined"; } var _this = this; this.on("clear-search", function() { @@ -144,116 +154,116 @@ _element.found = undefined; }); _this.trigger("search-cleared"); - }) -} + }); +}; -Model.List.prototype = new Array(); +List.prototype = new Array(); -Model.List.prototype.hasId = function(_id) { +List.prototype.hasId = function(_id) { return ns._(this.idIndex).include(_id); -} +}; /* On recent browsers, forEach and map are defined and do what we want. * Otherwise, we'll use the Underscore.js functions */ if (typeof Array.prototype.forEach === "undefined") { - Model.List.prototype.forEach = function(_callback) { + List.prototype.forEach = function(_callback) { var _this = this; ns._(this).forEach(function(_value, _key) { _callback(_value, _key, _this); }); - } -} + }; +}; if (typeof Array.prototype.map === "undefined") { - Model.List.prototype.map = function(_callback) { + List.prototype.map = function(_callback) { var _this = this; return ns._(this).map(function(_value, _key) { return _callback(_value, _key, _this); }); - } -} + }; +}; -Model.List.prototype.pluck = function(_key) { +List.prototype.pluck = function(_key) { return this.map(function(_value) { return _value[_key]; }); -} +}; -/* We override Array's filter function because it doesn't return an Model.List +/* We override Array's filter function because it doesn't return an List */ -Model.List.prototype.filter = function(_callback) { +List.prototype.filter = function(_callback) { var _this = this, - _res = new Model.List(this.directory); + _res = new List(this.directory); _res.addElements(ns._(this).filter(function(_value, _key) { return _callback(_value, _key, _this); })); return _res; -} +}; -Model.List.prototype.slice = function(_start, _end) { - var _res = new Model.List(this.directory); +List.prototype.slice = function(_start, _end) { + var _res = new List(this.directory); _res.addElements(Array.prototype.slice.call(this, _start, _end)); return _res; -} +}; -Model.List.prototype.splice = function(_start, _end) { - var _res = new Model.List(this.directory); +List.prototype.splice = function(_start, _end) { + var _res = new List(this.directory); _res.addElements(Array.prototype.splice.call(this, _start, _end)); this.idIndex.splice(_start, _end); return _res; -} +}; /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy - * and won't return a new Model.List + * and won't return a new List */ -Model.List.prototype.sortBy = function(_callback) { +List.prototype.sortBy = function(_callback) { var _this = this, - _res = new Model.List(this.directory); + _res = new List(this.directory); _res.addElements(ns._(this).sortBy(function(_value, _key) { return _callback(_value, _key, _this); })); return _res; -} +}; /* Title and Description are basic information for (almost) all element types, * here we can search by these criteria */ -Model.List.prototype.searchByTitle = function(_text, _iexact) { +List.prototype.searchByTitle = function(_text, _iexact) { var _iexact = _iexact || false, - _rgxp = Model.regexpFromTextOrArray(_text, true, _iexact); + _rgxp = regexpFromTextOrArray(_text, true, _iexact); return this.filter(function(_element) { return _rgxp.test(_element.title); }); -} +}; -Model.List.prototype.searchByDescription = function(_text, _iexact) { +List.prototype.searchByDescription = function(_text, _iexact) { var _iexact = _iexact || false, - _rgxp = Model.regexpFromTextOrArray(_text, true, _iexact); + _rgxp = regexpFromTextOrArray(_text, true, _iexact); return this.filter(function(_element) { return _rgxp.test(_element.description); }); -} +}; -Model.List.prototype.searchByTextFields = function(_text, _iexact) { +List.prototype.searchByTextFields = function(_text, _iexact) { var _iexact = _iexact || false, - _rgxp = Model.regexpFromTextOrArray(_text, true, _iexact); + _rgxp = regexpFromTextOrArray(_text, true, _iexact); return this.filter(function(_element) { var keywords = (_element.keywords || _element.getTagTexts() || []).join(", "); return _rgxp.test(_element.description) || _rgxp.test(_element.title) || _rgxp.test(keywords); }); -} +}; -Model.List.prototype.search = function(_text) { +List.prototype.search = function(_text) { if (!_text) { this.trigger("clear-search"); return this; } this.searching = true; this.trigger("search", _text); - var rxsource = Model.fullTextRegexps(_text) - rgxp = new RegExp(rxsource,"im"), - this.regexp = new RegExp(rxsource,"gim"); + var rxsource = fullTextRegexps(_text), + rgxp = new RegExp(rxsource,"im"); + this.regexp = new RegExp(rxsource,"gim"); var res = this.filter(function(_element, _k) { var titlematch = rgxp.test(_element.title), descmatch = rgxp.test(_element.description), @@ -264,23 +274,23 @@ }); this.trigger(res.length ? "found" : "not-found",res); return res; -} +}; -Model.List.prototype.getTitles = function() { +List.prototype.getTitles = function() { return this.map(function(_el) { return _el.title; }); -} +}; -Model.List.prototype.addId = function(_id) { - var _el = this.directory.getElement(_id) +List.prototype.addId = function(_id) { + var _el = this.directory.getElement(_id); if (!this.hasId(_id) && typeof _el !== "undefined") { this.idIndex.push(_id); Array.prototype.push.call(this, _el); } -} +}; -Model.List.prototype.push = function(_el) { +List.prototype.push = function(_el) { if (typeof _el === "undefined") { return; } @@ -291,24 +301,24 @@ } else { this[_index] = _el; } -} +}; -Model.List.prototype.addIds = function(_array) { +List.prototype.addIds = function(_array) { var _l = _array.length, _this = this; ns._(_array).forEach(function(_id) { _this.addId(_id); }); -} +}; -Model.List.prototype.addElements = function(_array) { +List.prototype.addElements = function(_array) { var _this = this; ns._(_array).forEach(function(_el) { _this.push(_el); }); -} +}; -Model.List.prototype.removeId = function(_id, _deleteFromDirectory) { +List.prototype.removeId = function(_id, _deleteFromDirectory) { var _deleteFromDirectory = _deleteFromDirectory || false, _index = (ns._(this.idIndex).indexOf(_id)); if (_index !== -1) { @@ -317,61 +327,61 @@ if (_deleteFromDirectory) { delete this.directory.elements[_id]; } -} +}; -Model.List.prototype.removeElement = function(_el, _deleteFromDirectory) { +List.prototype.removeElement = function(_el, _deleteFromDirectory) { var _deleteFromDirectory = _deleteFromDirectory || false; this.removeId(_el.id); -} +}; -Model.List.prototype.removeIds = function(_list, _deleteFromDirectory) { +List.prototype.removeIds = function(_list, _deleteFromDirectory) { var _deleteFromDirectory = _deleteFromDirectory || false, _this = this; ns._(_list).forEach(function(_id) { _this.removeId(_id); }); -} +}; -Model.List.prototype.removeElements = function(_list, _deleteFromDirectory) { +List.prototype.removeElements = function(_list, _deleteFromDirectory) { var _deleteFromDirectory = _deleteFromDirectory || false, _this = this; ns._(_list).forEach(function(_el) { _this.removeElement(_el); }); -} +}; -Model.List.prototype.on = function(_event, _callback) { +List.prototype.on = function(_event, _callback) { if (typeof this.__events[_event] === "undefined") { this.__events[_event] = []; } this.__events[_event].push(_callback); -} +}; -Model.List.prototype.off = function(_event, _callback) { +List.prototype.off = function(_event, _callback) { if (typeof this.__events[_event] !== "undefined") { this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) { return _fn === _callback; }); } -} +}; -Model.List.prototype.trigger = function(_event, _data) { +List.prototype.trigger = function(_event, _data) { var _list = this; ns._(this.__events[_event]).each(function(_callback) { _callback.call(_list, _data); }); -} +}; /* A simple time management object, that helps converting millisecs to seconds and strings, * without the clumsiness of the original Date object. */ -Model.Time = function(_milliseconds) { +var Time = Model.Time = function(_milliseconds) { this.milliseconds = 0; this.setMilliseconds(_milliseconds); -} +}; -Model.Time.prototype.setMilliseconds = function(_milliseconds) { +Time.prototype.setMilliseconds = function(_milliseconds) { var _ante = this.milliseconds; switch(typeof _milliseconds) { case "string": @@ -389,51 +399,51 @@ if (this.milliseconds === NaN) { this.milliseconds = _ante; } -} +}; -Model.Time.prototype.setSeconds = function(_seconds) { +Time.prototype.setSeconds = function(_seconds) { this.milliseconds = 1000 * _seconds; -} +}; -Model.Time.prototype.getSeconds = function() { +Time.prototype.getSeconds = function() { return this.milliseconds / 1000; -} +}; -Model.Time.prototype.getHMS = function() { +Time.prototype.getHMS = function() { var _totalSeconds = Math.abs(Math.floor(this.getSeconds())); return { hours : Math.floor(_totalSeconds / 3600), minutes : (Math.floor(_totalSeconds / 60) % 60), seconds : _totalSeconds % 60, milliseconds: this.milliseconds % 1000 - } -} + }; +}; -Model.Time.prototype.add = function(_milliseconds) { - this.milliseconds += new Model.Time(_milliseconds).milliseconds; -} +Time.prototype.add = function(_milliseconds) { + this.milliseconds += new Time(_milliseconds).milliseconds; +}; -Model.Time.prototype.valueOf = function() { +Time.prototype.valueOf = function() { return this.milliseconds; -} +}; -Model.Time.prototype.toString = function(showCs) { +Time.prototype.toString = function(showCs) { var _hms = this.getHMS(), _res = ''; if (_hms.hours) { - _res += _hms.hours + ':' + _res += _hms.hours + ':'; } _res += pad(2, _hms.minutes) + ':' + pad(2, _hms.seconds); if (showCs) { - _res += "." + Math.floor(_hms.milliseconds / 100) + _res += "." + Math.floor(_hms.milliseconds / 100); } return _res; -} +}; -/* Model.Reference handles references between elements +/* Reference handles references between elements */ -Model.Reference = function(_source, _idRef) { +var Reference = Model.Reference = function(_source, _idRef) { this.source = _source; this.id = _idRef; if (typeof _idRef === "object") { @@ -442,107 +452,107 @@ this.isList = false; } this.refresh(); -} +}; -Model.Reference.prototype.refresh = function() { +Reference.prototype.refresh = function() { if (this.isList) { - this.contents = new Model.List(this.source.directory); + this.contents = new List(this.source.directory); this.contents.addIds(this.id); } else { this.contents = this.source.getElement(this.id); } -} +}; -Model.Reference.prototype.getContents = function() { +Reference.prototype.getContents = function() { if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) { this.refresh(); } return this.contents; -} +}; -Model.Reference.prototype.isOrHasId = function(_idRef) { +Reference.prototype.isOrHasId = function(_idRef) { if (this.isList) { - return (ns._(this.id).indexOf(_idRef) !== -1) + return (ns._(this.id).indexOf(_idRef) !== -1); } else { return (this.id == _idRef); } -} +}; /* */ -Model.Element = function(_id, _source) { +var BaseElement = Model.Element = function(_id, _source) { this.elementType = 'element'; this.title = ""; this.description = ""; - this.__events = {} + this.__events = {}; if (typeof _source === "undefined") { return; } if (typeof _id === "undefined" || !_id) { - _id = Model.getUID(); + _id = getUID(); } this.id = _id; this.source = _source; if (_source !== this) { this.source.directory.addElement(this); } -} +}; -Model.Element.prototype.toString = function() { +BaseElement.prototype.toString = function() { return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : ''); -} +}; -Model.Element.prototype.setReference = function(_elementType, _idRef) { - this[_elementType] = new Model.Reference(this.source, _idRef); -} +BaseElement.prototype.setReference = function(_elementType, _idRef) { + this[_elementType] = new Reference(this.source, _idRef); +}; -Model.Element.prototype.getReference = function(_elementType) { +BaseElement.prototype.getReference = function(_elementType) { if (typeof this[_elementType] !== "undefined") { return this[_elementType].getContents(); } -} +}; -Model.Element.prototype.getRelated = function(_elementType, _global) { +BaseElement.prototype.getRelated = function(_elementType, _global) { _global = (typeof _global !== "undefined" && _global); var _this = this; return this.source.getList(_elementType, _global).filter(function(_el) { var _ref = _el[_this.elementType]; return _ref && _ref.isOrHasId(_this.id); }); -} +}; -Model.Element.prototype.on = function(_event, _callback) { +BaseElement.prototype.on = function(_event, _callback) { if (typeof this.__events[_event] === "undefined") { this.__events[_event] = []; } this.__events[_event].push(_callback); -} +}; -Model.Element.prototype.off = function(_event, _callback) { +BaseElement.prototype.off = function(_event, _callback) { if (typeof this.__events[_event] !== "undefined") { this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) { return _fn === _callback; }); } -} +}; -Model.Element.prototype.trigger = function(_event, _data) { +BaseElement.prototype.trigger = function(_event, _data) { var _element = this; ns._(this.__events[_event]).each(function(_callback) { _callback.call(_element, _data); }); -} +}; /* */ -Model.Playable = function(_id, _source) { - Model.Element.call(this, _id, _source); +var Playable = Model.Playable = function(_id, _source) { + BaseElement.call(this, _id, _source); if (typeof _source === "undefined") { return; } this.elementType = 'playable'; - this.currentTime = new Model.Time(); + this.currentTime = new Time(); this.volume = .5; this.paused = true; this.muted = false; @@ -557,14 +567,14 @@ this.on("timeupdate", function(_time) { _this.currentTime = _time; _this.getAnnotations().filter(function(_a) { - return (_a.end <= _time || _a.begin > _time) && _a.playing + return (_a.end <= _time || _a.begin > _time) && _a.playing; }).forEach(function(_a) { _a.playing = false; _a.trigger("leave"); _this.trigger("leave-annotation",_a); }); _this.getAnnotations().filter(function(_a) { - return _a.begin <= _time && _a.end > _time && !_a.playing + return _a.begin <= _time && _a.end > _time && !_a.playing; }).forEach(function(_a) { _a.playing = true; _a.trigger("enter"); @@ -573,188 +583,188 @@ }); this.on("loadedmetadata", function() { _this.loadedMetadata = true; - }) -} + }); +}; -Model.Playable.prototype = new Model.Element(); +extendPrototype(Playable, BaseElement); -Model.Playable.prototype.getCurrentTime = function() { +Playable.prototype.getCurrentTime = function() { return this.currentTime; -} +}; -Model.Playable.prototype.getVolume = function() { +Playable.prototype.getVolume = function() { return this.volume; -} +}; -Model.Playable.prototype.getPaused = function() { +Playable.prototype.getPaused = function() { return this.paused; -} +}; -Model.Playable.prototype.getMuted = function() { +Playable.prototype.getMuted = function() { return this.muted; -} +}; -Model.Playable.prototype.setCurrentTime = function(_time) { +Playable.prototype.setCurrentTime = function(_time) { this.trigger("setcurrenttime",_time); -} +}; -Model.Playable.prototype.setVolume = function(_vol) { +Playable.prototype.setVolume = function(_vol) { this.trigger("setvolume",_vol); -} +}; -Model.Playable.prototype.setMuted = function(_muted) { +Playable.prototype.setMuted = function(_muted) { this.trigger("setmuted",_muted); -} +}; -Model.Playable.prototype.play = function() { +Playable.prototype.play = function() { this.trigger("setplay"); -} +}; -Model.Playable.prototype.pause = function() { +Playable.prototype.pause = function() { this.trigger("setpause"); -} +}; -Model.Playable.prototype.show = function() {} +Playable.prototype.show = function() {}; -Model.Playable.prototype.hide = function() {} +Playable.prototype.hide = function() {}; /* */ -Model.Media = function(_id, _source) { - Model.Playable.call(this, _id, _source); +var Media = Model.Media = function(_id, _source) { + Playable.call(this, _id, _source); this.elementType = 'media'; - this.duration = new Model.Time(); + this.duration = new Time(); this.video = ''; var _this = this; -} +}; -Model.Media.prototype = new Model.Playable(); +extendPrototype(Media, Playable); /* Default functions to be overriden by players */ -Model.Media.prototype.setDuration = function(_durationMs) { +Media.prototype.setDuration = function(_durationMs) { this.duration.setMilliseconds(_durationMs); -} +}; -Model.Media.prototype.getAnnotations = function() { +Media.prototype.getAnnotations = function() { return this.getRelated("annotation"); -} +}; -Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) { +Media.prototype.getAnnotationsByTypeTitle = function(_title) { var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); if (_annTypes.length) { return this.getAnnotations().filter(function(_annotation) { return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; }); } else { - return new Model.List(this.source.directory) + return new List(this.source.directory); } -} +}; /* */ -Model.Tag = function(_id, _source) { - Model.Element.call(this, _id, _source); +var Tag = Model.Tag = function(_id, _source) { + BaseElement.call(this, _id, _source); this.elementType = 'tag'; -} +}; -Model.Tag.prototype = new Model.Element(); +extendPrototype(Tag, BaseElement); -Model.Tag.prototype.getAnnotations = function() { +Tag.prototype.getAnnotations = function() { return this.getRelated("annotation"); -} +}; /* */ -Model.AnnotationType = function(_id, _source) { - Model.Element.call(this, _id, _source); +var AnnotationType = Model.AnnotationType = function(_id, _source) { + BaseElement.call(this, _id, _source); this.elementType = 'annotationType'; -} +}; -Model.AnnotationType.prototype = new Model.Element(); +extendPrototype(AnnotationType, BaseElement); -Model.AnnotationType.prototype.getAnnotations = function() { +AnnotationType.prototype.getAnnotations = function() { return this.getRelated("annotation"); -} +}; /* Annotation * */ -Model.Annotation = function(_id, _source) { - Model.Element.call(this, _id, _source); +var Annotation = Model.Annotation = function(_id, _source) { + BaseElement.call(this, _id, _source); this.elementType = 'annotation'; - this.begin = new Model.Time(); - this.end = new Model.Time(); - this.tag = new Model.Reference(_source, []); + this.begin = new Time(); + this.end = new Time(); + this.tag = new Reference(_source, []); this.playing = false; var _this = this; this.on("click", function() { _this.getMedia().setCurrentTime(_this.begin); }); -} +}; -Model.Annotation.prototype = new Model.Element(); +extendPrototype(Annotation, BaseElement); -Model.Annotation.prototype.setBegin = function(_beginMs) { +Annotation.prototype.setBegin = function(_beginMs) { this.begin.setMilliseconds(Math.max(0,_beginMs)); this.trigger("change-begin"); if (this.end < this.begin) { this.setEnd(this.begin); } -} +}; -Model.Annotation.prototype.setEnd = function(_endMs) { +Annotation.prototype.setEnd = function(_endMs) { this.end.setMilliseconds(Math.min(_endMs, this.getMedia().duration.milliseconds)); this.trigger("change-end"); if (this.end < this.begin) { this.setBegin(this.end); } -} +}; -Model.Annotation.prototype.setDuration = function(_durMs) { +Annotation.prototype.setDuration = function(_durMs) { this.setEnd(_durMs + this.begin.milliseconds); -} +}; -Model.Annotation.prototype.setMedia = function(_idRef) { +Annotation.prototype.setMedia = function(_idRef) { this.setReference("media", _idRef); -} +}; -Model.Annotation.prototype.getMedia = function() { +Annotation.prototype.getMedia = function() { return this.getReference("media"); -} +}; -Model.Annotation.prototype.setAnnotationType = function(_idRef) { +Annotation.prototype.setAnnotationType = function(_idRef) { this.setReference("annotationType", _idRef); -} +}; -Model.Annotation.prototype.getAnnotationType = function() { +Annotation.prototype.getAnnotationType = function() { return this.getReference("annotationType"); -} +}; -Model.Annotation.prototype.setTags = function(_idRefs) { +Annotation.prototype.setTags = function(_idRefs) { this.setReference("tag", _idRefs); -} +}; -Model.Annotation.prototype.getTags = function() { +Annotation.prototype.getTags = function() { return this.getReference("tag"); -} +}; -Model.Annotation.prototype.getTagTexts = function() { +Annotation.prototype.getTagTexts = function() { return this.getTags().getTitles(); -} +}; -Model.Annotation.prototype.getDuration = function() { - return new Model.Time(this.end.milliseconds - this.begin.milliseconds) -} +Annotation.prototype.getDuration = function() { + return new Time(this.end.milliseconds - this.begin.milliseconds); +}; /* */ -Model.MashedAnnotation = function(_mashup, _annotation) { - Model.Element.call(this, _mashup.id + "_" + _annotation.id, _annotation.source); +var MashedAnnotation = Model.MashedAnnotation = function(_mashup, _annotation) { + BaseElement.call(this, _mashup.id + "_" + _annotation.id, _annotation.source); this.elementType = 'mashedAnnotation'; this.annotation = _annotation; - this.begin = new Model.Time(); - this.end = new Model.Time(); - this.duration = new Model.Time(); + this.begin = new Time(); + this.end = new Time(); + this.duration = new Time(); this.title = this.annotation.title; this.description = this.annotation.description; this.color = this.annotation.color; @@ -768,66 +778,66 @@ this.on("leave", function() { _this.annotation.trigger("leave"); }); -} +}; -Model.MashedAnnotation.prototype = new Model.Element(null); +extendPrototype(MashedAnnotation, BaseElement); -Model.MashedAnnotation.prototype.getMedia = function() { +MashedAnnotation.prototype.getMedia = function() { return this.annotation.getReference("media"); -} +}; -Model.MashedAnnotation.prototype.getAnnotationType = function() { +MashedAnnotation.prototype.getAnnotationType = function() { return this.annotation.getReference("annotationType"); -} +}; -Model.MashedAnnotation.prototype.getTags = function() { +MashedAnnotation.prototype.getTags = function() { return this.annotation.getReference("tag"); -} +}; -Model.MashedAnnotation.prototype.getTagTexts = function() { +MashedAnnotation.prototype.getTagTexts = function() { return this.annotation.getTags().getTitles(); -} +}; -Model.MashedAnnotation.prototype.getDuration = function() { +MashedAnnotation.prototype.getDuration = function() { return this.annotation.getDuration(); -} +}; -Model.MashedAnnotation.prototype.setBegin = function(_begin) { +MashedAnnotation.prototype.setBegin = function(_begin) { this.begin.setMilliseconds(_begin); this.duration.setMilliseconds(this.annotation.getDuration()); this.end.setMilliseconds(_begin + this.duration); -} +}; /* */ -Model.Mashup = function(_id, _source) { - Model.Playable.call(this, _id, _source); +var Mashup = Model.Mashup = function(_id, _source) { + Playable.call(this, _id, _source); this.elementType = 'mashup'; - this.duration = new Model.Time(); - this.segments = new Model.List(_source.directory); + this.duration = new Time(); + this.segments = new List(_source.directory); this.loaded = false; var _this = this; this._updateTimes = function() { _this.updateTimes(); _this.trigger("change"); - } + }; this.on("add", this._updateTimes); this.on("remove", this._updateTimes); -} +}; -Model.Mashup.prototype = new Model.Playable(); +extendPrototype(Mashup, Playable); -Model.Mashup.prototype.updateTimes = function() { +Mashup.prototype.updateTimes = function() { var _time = 0; this.segments.forEach(function(_segment) { _segment.setBegin(_time); _time = _segment.end; }); this.duration.setMilliseconds(_time); -} +}; -Model.Mashup.prototype.addAnnotation = function(_annotation, _defer) { - var _mashedAnnotation = new Model.MashedAnnotation(this, _annotation), +Mashup.prototype.addAnnotation = function(_annotation, _defer) { + var _mashedAnnotation = new MashedAnnotation(this, _annotation), _defer = _defer || false; this.segments.push(_mashedAnnotation); _annotation.on("change-begin", this._updateTimes); @@ -835,33 +845,33 @@ if (!_defer) { this.trigger("add"); } -} +}; -Model.Mashup.prototype.addAnnotationById = function(_elId, _defer) { +Mashup.prototype.addAnnotationById = function(_elId, _defer) { var _annotation = this.source.getElement(_elId), _defer = _defer || false; if (typeof _annotation !== "undefined") { this.addAnnotation(_annotation, _defer); } -} +}; -Model.Mashup.prototype.addAnnotations = function(_segments) { +Mashup.prototype.addAnnotations = function(_segments) { var _this = this; ns._(_segments).forEach(function(_segment) { _this.addAnnotation(_segment, true); }); this.trigger("add"); -} +}; -Model.Mashup.prototype.addAnnotationsById = function(_segments) { +Mashup.prototype.addAnnotationsById = function(_segments) { var _this = this; ns._(_segments).forEach(function(_segment) { _this.addAnnotationById(_segment, true); }); this.trigger("add"); -} +}; -Model.Mashup.prototype.removeAnnotation = function(_annotation, _defer) { +Mashup.prototype.removeAnnotation = function(_annotation, _defer) { var _defer = _defer || false; _annotation.off("change-begin", this._updateTimes); _annotation.off("change-end", this._updateTimes); @@ -869,9 +879,9 @@ if (!_defer) { this.trigger("remove"); } -} +}; -Model.Mashup.prototype.removeAnnotationById = function(_annId, _defer) { +Mashup.prototype.removeAnnotationById = function(_annId, _defer) { var _defer = _defer || false; var _annotation = this.source.getElement(_annId); @@ -881,72 +891,72 @@ if (!_defer) { this.trigger("remove"); } -} +}; -Model.Mashup.prototype.setAnnotations = function(_segments) { +Mashup.prototype.setAnnotations = function(_segments) { while (this.segments.length) { this.removeAnnotation(this.segments[0].annotation, true); } this.addAnnotations(_segments); -} +}; -Model.Mashup.prototype.setAnnotationsById = function(_segments) { +Mashup.prototype.setAnnotationsById = function(_segments) { while (this.segments.length) { this.removeAnnotation(this.segments[0].annotation, true); } this.addAnnotationsById(_segments); -} +}; -Model.Mashup.prototype.hasAnnotation = function(_annotation) { +Mashup.prototype.hasAnnotation = function(_annotation) { return !!ns._(this.segments).find(function(_s) { - return _s.annotation === _annotation + return _s.annotation === _annotation; }); -} +}; -Model.Mashup.prototype.getAnnotation = function(_annotation) { +Mashup.prototype.getAnnotation = function(_annotation) { return ns._(this.segments).find(function(_s) { - return _s.annotation === _annotation + return _s.annotation === _annotation; }); -} +}; -Model.Mashup.prototype.getAnnotationById = function(_id) { +Mashup.prototype.getAnnotationById = function(_id) { return ns._(this.segments).find(function(_s) { - return _s.annotation.id === _id + return _s.annotation.id === _id; }); -} +}; -Model.Mashup.prototype.getAnnotations = function() { +Mashup.prototype.getAnnotations = function() { return this.segments; -} +}; -Model.Mashup.prototype.getOriginalAnnotations = function() { - var annotations = new Model.List(this.source.directory); +Mashup.prototype.getOriginalAnnotations = function() { + var annotations = new List(this.source.directory); this.segments.forEach(function(_s) { annotations.push(_s.annotation); }); return annotations; -} +}; -Model.Mashup.prototype.getMedias = function() { - var medias = new Model.List(this.source.directory); +Mashup.prototype.getMedias = function() { + var medias = new List(this.source.directory); this.segments.forEach(function(_annotation) { - medias.push(_annotation.getMedia()) - }) + medias.push(_annotation.getMedia()); + }); return medias; -} +}; -Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) { +Mashup.prototype.getAnnotationsByTypeTitle = function(_title) { var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); if (_annTypes.length) { return this.getAnnotations().filter(function(_annotation) { return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; }); } else { - return new Model.List(this.source.directory) + return new List(this.source.directory); } -} +}; -Model.Mashup.prototype.getAnnotationAtTime = function(_time) { +Mashup.prototype.getAnnotationAtTime = function(_time) { var _list = this.segments.filter(function(_annotation) { return _annotation.begin <= _time && _annotation.end > _time; }); @@ -955,143 +965,146 @@ } else { return undefined; } -} +}; -Model.Mashup.prototype.getMediaAtTime = function(_time) { +Mashup.prototype.getMediaAtTime = function(_time) { var _annotation = this.getAnnotationAtTime(_time); if (typeof _annotation !== "undefined") { return _annotation.getMedia(); } else { return undefined; } -} +}; /* */ -Model.Source = function(_config) { - Model.Element.call(this, false, this); - this.status = Model._SOURCE_STATUS_EMPTY; +var Source = Model.Source = function(_config) { + BaseElement.call(this, false, this); + this.status = _SOURCE_STATUS_EMPTY; this.elementType = "source"; if (typeof _config !== "undefined") { var _this = this; ns._(_config).forEach(function(_v, _k) { _this[_k] = _v; - }) + }); this.callbackQueue = []; this.contents = {}; this.get(); } -} +}; -Model.Source.prototype = new Model.Element(); +extendPrototype(Source, BaseElement); -Model.Source.prototype.addList = function(_listId, _contents) { +Source.prototype.addList = function(_listId, _contents) { if (typeof this.contents[_listId] === "undefined") { - this.contents[_listId] = new Model.List(this.directory); + this.contents[_listId] = new List(this.directory); } this.contents[_listId].addElements(_contents); -} +}; -Model.Source.prototype.getList = function(_listId, _global) { +Source.prototype.getList = function(_listId, _global) { _global = (typeof _global !== "undefined" && _global); if (_global) { return this.directory.getGlobalList().filter(function(_e) { return (_e.elementType === _listId); }); } else { - return this.contents[_listId] || new IriSP.Model.List(this.directory); + if (typeof this.contents[_listId] === "undefined") { + this.contents[_listId] = new List(this.directory); + } + return this.contents[_listId]; } -} +}; -Model.Source.prototype.forEach = function(_callback) { +Source.prototype.forEach = function(_callback) { var _this = this; ns._(this.contents).forEach(function(_value, _key) { _callback.call(_this, _value, _key); - }) -} + }); +}; -Model.Source.prototype.getElement = function(_elId) { +Source.prototype.getElement = function(_elId) { return this.directory.getElement(_elId); -} +}; -Model.Source.prototype.get = function() { - this.status = Model._SOURCE_STATUS_WAITING; +Source.prototype.get = function() { + this.status = _SOURCE_STATUS_WAITING; this.handleCallbacks(); -} +}; /* We defer the callbacks calls so they execute after the queue is cleared */ -Model.Source.prototype.deferCallback = function(_callback) { +Source.prototype.deferCallback = function(_callback) { var _this = this; ns._.defer(function() { _callback.call(_this); }); -} +}; -Model.Source.prototype.handleCallbacks = function() { - this.status = Model._SOURCE_STATUS_READY; +Source.prototype.handleCallbacks = function() { + this.status = _SOURCE_STATUS_READY; while (this.callbackQueue.length) { this.deferCallback(this.callbackQueue.splice(0,1)[0]); } -} -Model.Source.prototype.onLoad = function(_callback) { - if (this.status === Model._SOURCE_STATUS_READY) { +}; +Source.prototype.onLoad = function(_callback) { + if (this.status === _SOURCE_STATUS_READY) { this.deferCallback(_callback); } else { this.callbackQueue.push(_callback); } -} +}; -Model.Source.prototype.serialize = function() { +Source.prototype.serialize = function() { return this.serializer.serialize(this); -} +}; -Model.Source.prototype.deSerialize = function(_data) { +Source.prototype.deSerialize = function(_data) { this.serializer.deSerialize(_data, this); -} +}; -Model.Source.prototype.getAnnotations = function(_global) { +Source.prototype.getAnnotations = function(_global) { _global = (typeof _global !== "undefined" && _global); return this.getList("annotation", _global); -} +}; -Model.Source.prototype.getMedias = function(_global) { +Source.prototype.getMedias = function(_global) { _global = (typeof _global !== "undefined" && _global); return this.getList("media", _global); -} +}; -Model.Source.prototype.getTags = function(_global) { +Source.prototype.getTags = function(_global) { _global = (typeof _global !== "undefined" && _global); return this.getList("tag", _global); -} +}; -Model.Source.prototype.getMashups = function(_global) { +Source.prototype.getMashups = function(_global) { _global = (typeof _global !== "undefined" && _global); return this.getList("mashup", _global); -} +}; -Model.Source.prototype.getAnnotationTypes = function(_global) { +Source.prototype.getAnnotationTypes = function(_global) { _global = (typeof _global !== "undefined" && _global); return this.getList("annotationType", _global); -} +}; -Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) { +Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) { _global = (typeof _global !== "undefined" && _global); - var _res = new Model.List(this.directory), + var _res = new List(this.directory), _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title); _annTypes.forEach(function(_annType) { _res.addElements(_annType.getAnnotations(_global)); - }) + }); return _res; -} +}; -Model.Source.prototype.getDuration = function() { +Source.prototype.getDuration = function() { var _m = this.currentMedia; if (typeof _m !== "undefined") { return this.currentMedia.duration; } -} +}; -Model.Source.prototype.getCurrentMedia = function(_opts) { +Source.prototype.getCurrentMedia = function(_opts) { if (typeof this.currentMedia === "undefined") { if (_opts.is_mashup) { var _mashups = this.getMashups(); @@ -1106,28 +1119,28 @@ } } return this.currentMedia; -} +}; -Model.Source.prototype.merge = function(_source) { +Source.prototype.merge = function(_source) { var _this = this; _source.forEach(function(_value, _key) { _this.getList(_key).addElements(_value); }); -} +}; /* */ -Model.RemoteSource = function(_config) { - Model.Source.call(this, _config); -} +var RemoteSource = Model.RemoteSource = function(_config) { + Source.call(this, _config); +}; -Model.RemoteSource.prototype = new Model.Source(); +extendPrototype(RemoteSource, Source); -Model.RemoteSource.prototype.get = function() { - this.status = Model._SOURCE_STATUS_WAITING; +RemoteSource.prototype.get = function() { + this.status = _SOURCE_STATUS_WAITING; var _this = this, urlparams = this.url_params || {}, - dataType = (Model.isLocalURL(this.url) ? "json" : "jsonp"); + dataType = (isLocalURL(this.url) ? "json" : "jsonp"); urlparams.format = dataType; ns.jQuery.ajax({ url: this.url, @@ -1139,51 +1152,50 @@ _this.handleCallbacks(); } }); -} +}; /* */ -Model.Directory = function() { +var Directory = Model.Directory = function() { this.remoteSources = {}; this.elements = {}; -} +}; -Model.Directory.prototype.remoteSource = function(_properties) { +Directory.prototype.remoteSource = function(_properties) { if (typeof _properties !== "object" || typeof _properties.url === "undefined") { - throw "Error : Model.Directory.remoteSource(configuration): configuration.url is undefined"; + throw "Error : Directory.remoteSource(configuration): configuration.url is undefined"; } var _config = ns._({ directory: this }).extend(_properties); _config.url_params = _config.url_params || {}; var _hash = _config.url + "?" + ns.jQuery.param(_config.url_params); if (typeof this.remoteSources[_hash] === "undefined") { - this.remoteSources[_hash] = new Model.RemoteSource(_config); + this.remoteSources[_hash] = new RemoteSource(_config); } return this.remoteSources[_hash]; -} +}; -Model.Directory.prototype.newLocalSource = function(_properties) { +Directory.prototype.newLocalSource = function(_properties) { var _config = ns._({ directory: this }).extend(_properties), - _res = new Model.Source(_config); + _res = new Source(_config); return _res; -} +}; -Model.Directory.prototype.getElement = function(_id) { +Directory.prototype.getElement = function(_id) { return this.elements[_id]; -} +}; -Model.Directory.prototype.addElement = function(_element) { +Directory.prototype.addElement = function(_element) { this.elements[_element.id] = _element; -} +}; -Model.Directory.prototype.getGlobalList = function() { - var _res = new Model.List(this); +Directory.prototype.getGlobalList = function() { + var _res = new List(this); _res.addIds(ns._(this.elements).keys()); return _res; -} - +}; return Model; })(IriSP); -/* END model.js */ +/* END js */