diff --git a/dist/client/manifesto.bundle.js b/dist/client/manifesto.bundle.js index cd91b21b..35f47edb 100644 --- a/dist/client/manifesto.bundle.js +++ b/dist/client/manifesto.bundle.js @@ -255,12 +255,12 @@ var Manifesto; IIIFResourceType.prototype.sequence = function () { return new IIIFResourceType(IIIFResourceType.SEQUENCE.toString()); }; - IIIFResourceType.ANNOTATION = new IIIFResourceType("oa:annotation"); - IIIFResourceType.CANVAS = new IIIFResourceType("sc:canvas"); - IIIFResourceType.COLLECTION = new IIIFResourceType("sc:collection"); - IIIFResourceType.MANIFEST = new IIIFResourceType("sc:manifest"); - IIIFResourceType.RANGE = new IIIFResourceType("sc:range"); - IIIFResourceType.SEQUENCE = new IIIFResourceType("sc:sequence"); + IIIFResourceType.ANNOTATION = new IIIFResourceType("annotation"); + IIIFResourceType.CANVAS = new IIIFResourceType("canvas"); + IIIFResourceType.COLLECTION = new IIIFResourceType("collection"); + IIIFResourceType.MANIFEST = new IIIFResourceType("manifest"); + IIIFResourceType.RANGE = new IIIFResourceType("range"); + IIIFResourceType.SEQUENCE = new IIIFResourceType("sequence"); return IIIFResourceType; }(Manifesto.StringValue)); Manifesto.IIIFResourceType = IIIFResourceType; @@ -708,7 +708,7 @@ var Manifesto; return _this; } ManifestResource.prototype.getIIIFResourceType = function () { - return new Manifesto.IIIFResourceType(this.getProperty('@type')); + return new Manifesto.IIIFResourceType(Manifesto.Utils.normaliseType(this.getProperty('type'))); }; ManifestResource.prototype.getLabel = function () { return Manifesto.TranslationCollection.parse(this.getProperty('label'), this.options.locale); @@ -1030,12 +1030,7 @@ var Manifesto; return []; }; IIIFResource.prototype.getIIIFResourceType = function () { - var type = this.getProperty('type'); - if (type) { - return new Manifesto.IIIFResourceType(type); - } - type = this.getProperty('@type'); - return new Manifesto.IIIFResourceType(type); + return new Manifesto.IIIFResourceType(Manifesto.Utils.normaliseType(this.getProperty('type'))); }; IIIFResource.prototype.getLogo = function () { var logo = this.getProperty('logo'); @@ -1070,19 +1065,13 @@ var Manifesto; return this.defaultTree; }; IIIFResource.prototype.isCollection = function () { - if (this.getIIIFResourceType().toString().toLowerCase() === 'collection') { - return true; - } - else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { return true; } return false; }; IIIFResource.prototype.isManifest = function () { - if (this.getIIIFResourceType().toString().toLowerCase() === 'manifest') { - return true; - } - else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { return true; } return false; @@ -1183,7 +1172,7 @@ var Manifesto; if (this.__jsonld.structures && this.__jsonld.structures.length) { for (var i = 0; i < this.__jsonld.structures.length; i++) { var r = this.__jsonld.structures[i]; - if (r['@id'] === id) { + if (r['@id'] === id || r.id === id) { return r; } } @@ -1215,25 +1204,26 @@ var Manifesto; else { parentRange.members.push(range); } - if (r.ranges) { - for (var i = 0; i < r.ranges.length; i++) { - this._parseRanges(r.ranges[i], path + '/' + i, range); - } - } if (r.members) { - var _loop_1 = function (i) { + for (var i = 0; i < r.members.length; i++) { var child = r.members[i]; - // only add to members if not already parsed from backwards-compatible ranges/canvases arrays - if (r.members.en().where(function (m) { return m.id === child.id; }).first()) { - return "continue"; + // todo: use constants + if (child['@type'] && child['@type'].toLowerCase() === 'sc:range' || child['type'] && child['type'].toLowerCase() === 'range') { + this._parseRanges(child, path + '/' + i, range); } - if (child['@type'].toLowerCase() === 'sc:range') { - this_1._parseRanges(child, path + '/' + i, range); + else if (child['@type'] && child['@type'].toLowerCase() === 'sc:canvas' || child['type'] && child['type'].toLowerCase() === 'canvas') { + // store the ids on the __jsonld object to be used by Range.getCanvasIds() + if (!range.canvases) { + range.canvases = []; + } + var id_1 = child['@id'] || child.id; + range.canvases.push(id_1); } - }; - var this_1 = this; - for (var i = 0; i < r.members.length; i++) { - _loop_1(i); + } + } + else if (r.ranges) { + for (var i = 0; i < r.ranges.length; i++) { + this._parseRanges(r.ranges[i], path + '/' + i, range); } } }; @@ -1443,8 +1433,8 @@ var Manifesto; __extends(Range, _super); function Range(jsonld, options) { var _this = _super.call(this, jsonld, options) || this; - _this._canvases = null; _this._ranges = null; + _this.canvases = null; _this.members = []; return _this; } @@ -1452,14 +1442,17 @@ var Manifesto; if (this.__jsonld.canvases) { return this.__jsonld.canvases; } - return []; - }; - Range.prototype.getCanvases = function () { - if (this._canvases) { - return this._canvases; + else if (this.canvases) { + return this.canvases; } - return this._canvases = this.members.en().where(function (m) { return m.isCanvas(); }).toArray(); + return []; }; + // getCanvases(): ICanvas[] { + // if (this._canvases) { + // return this._canvases; + // } + // return this._canvases = this.members.en().where(m => m.isCanvas()).toArray(); + // } Range.prototype.getRanges = function () { if (this._ranges) { return this._ranges; @@ -1576,7 +1569,9 @@ var Manifesto; Sequence.prototype.getCanvasById = function (id) { for (var i = 0; i < this.getTotalCanvases(); i++) { var canvas = this.getCanvasByIndex(i); - if (canvas.id === id) { + // normalise canvas id + var canvasId = Manifesto.Utils.normaliseUrl(canvas.id); + if (Manifesto.Utils.normaliseUrl(id) === canvasId) { return canvas; } } @@ -2166,10 +2161,23 @@ var Manifesto; Utils.generateTreeNodeIds(n, i); } }; + Utils.normaliseType = function (type) { + type = type.toLowerCase(); + if (type.indexOf(':') !== -1) { + var split = type.split(':'); + return split[1]; + } + return type; + }; + Utils.normaliseUrl = function (url) { + url = url.substr(url.indexOf('://')); + if (url.indexOf('#') !== -1) { + url = url.split('#')[0]; + } + return url; + }; Utils.normalisedUrlsMatch = function (url1, url2) { - var url1norm = url1.substr(url1.indexOf('://')); - var url2norm = url1.substr(url1.indexOf('://')); - return url1norm === url2norm; + return Utils.normaliseUrl(url1) === Utils.normaliseUrl(url2); }; Utils.isImageProfile = function (profile) { if (Utils.normalisedUrlsMatch(profile.toString(), Manifesto.ServiceProfile.STANFORDIIIFIMAGECOMPLIANCE0.toString()) || diff --git a/dist/client/manifesto.js b/dist/client/manifesto.js index df652b70..6c13cff2 100644 --- a/dist/client/manifesto.js +++ b/dist/client/manifesto.js @@ -182,12 +182,12 @@ var Manifesto; IIIFResourceType.prototype.sequence = function () { return new IIIFResourceType(IIIFResourceType.SEQUENCE.toString()); }; - IIIFResourceType.ANNOTATION = new IIIFResourceType("oa:annotation"); - IIIFResourceType.CANVAS = new IIIFResourceType("sc:canvas"); - IIIFResourceType.COLLECTION = new IIIFResourceType("sc:collection"); - IIIFResourceType.MANIFEST = new IIIFResourceType("sc:manifest"); - IIIFResourceType.RANGE = new IIIFResourceType("sc:range"); - IIIFResourceType.SEQUENCE = new IIIFResourceType("sc:sequence"); + IIIFResourceType.ANNOTATION = new IIIFResourceType("annotation"); + IIIFResourceType.CANVAS = new IIIFResourceType("canvas"); + IIIFResourceType.COLLECTION = new IIIFResourceType("collection"); + IIIFResourceType.MANIFEST = new IIIFResourceType("manifest"); + IIIFResourceType.RANGE = new IIIFResourceType("range"); + IIIFResourceType.SEQUENCE = new IIIFResourceType("sequence"); return IIIFResourceType; }(Manifesto.StringValue)); Manifesto.IIIFResourceType = IIIFResourceType; @@ -635,7 +635,7 @@ var Manifesto; return _this; } ManifestResource.prototype.getIIIFResourceType = function () { - return new Manifesto.IIIFResourceType(this.getProperty('@type')); + return new Manifesto.IIIFResourceType(Manifesto.Utils.normaliseType(this.getProperty('type'))); }; ManifestResource.prototype.getLabel = function () { return Manifesto.TranslationCollection.parse(this.getProperty('label'), this.options.locale); @@ -957,12 +957,7 @@ var Manifesto; return []; }; IIIFResource.prototype.getIIIFResourceType = function () { - var type = this.getProperty('type'); - if (type) { - return new Manifesto.IIIFResourceType(type); - } - type = this.getProperty('@type'); - return new Manifesto.IIIFResourceType(type); + return new Manifesto.IIIFResourceType(Manifesto.Utils.normaliseType(this.getProperty('type'))); }; IIIFResource.prototype.getLogo = function () { var logo = this.getProperty('logo'); @@ -997,19 +992,13 @@ var Manifesto; return this.defaultTree; }; IIIFResource.prototype.isCollection = function () { - if (this.getIIIFResourceType().toString().toLowerCase() === 'collection') { - return true; - } - else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { return true; } return false; }; IIIFResource.prototype.isManifest = function () { - if (this.getIIIFResourceType().toString().toLowerCase() === 'manifest') { - return true; - } - else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { return true; } return false; @@ -1110,7 +1099,7 @@ var Manifesto; if (this.__jsonld.structures && this.__jsonld.structures.length) { for (var i = 0; i < this.__jsonld.structures.length; i++) { var r = this.__jsonld.structures[i]; - if (r['@id'] === id) { + if (r['@id'] === id || r.id === id) { return r; } } @@ -1142,25 +1131,26 @@ var Manifesto; else { parentRange.members.push(range); } - if (r.ranges) { - for (var i = 0; i < r.ranges.length; i++) { - this._parseRanges(r.ranges[i], path + '/' + i, range); - } - } if (r.members) { - var _loop_1 = function (i) { + for (var i = 0; i < r.members.length; i++) { var child = r.members[i]; - // only add to members if not already parsed from backwards-compatible ranges/canvases arrays - if (r.members.en().where(function (m) { return m.id === child.id; }).first()) { - return "continue"; + // todo: use constants + if (child['@type'] && child['@type'].toLowerCase() === 'sc:range' || child['type'] && child['type'].toLowerCase() === 'range') { + this._parseRanges(child, path + '/' + i, range); } - if (child['@type'].toLowerCase() === 'sc:range') { - this_1._parseRanges(child, path + '/' + i, range); + else if (child['@type'] && child['@type'].toLowerCase() === 'sc:canvas' || child['type'] && child['type'].toLowerCase() === 'canvas') { + // store the ids on the __jsonld object to be used by Range.getCanvasIds() + if (!range.canvases) { + range.canvases = []; + } + var id_1 = child['@id'] || child.id; + range.canvases.push(id_1); } - }; - var this_1 = this; - for (var i = 0; i < r.members.length; i++) { - _loop_1(i); + } + } + else if (r.ranges) { + for (var i = 0; i < r.ranges.length; i++) { + this._parseRanges(r.ranges[i], path + '/' + i, range); } } }; @@ -1370,8 +1360,8 @@ var Manifesto; __extends(Range, _super); function Range(jsonld, options) { var _this = _super.call(this, jsonld, options) || this; - _this._canvases = null; _this._ranges = null; + _this.canvases = null; _this.members = []; return _this; } @@ -1379,14 +1369,17 @@ var Manifesto; if (this.__jsonld.canvases) { return this.__jsonld.canvases; } - return []; - }; - Range.prototype.getCanvases = function () { - if (this._canvases) { - return this._canvases; + else if (this.canvases) { + return this.canvases; } - return this._canvases = this.members.en().where(function (m) { return m.isCanvas(); }).toArray(); + return []; }; + // getCanvases(): ICanvas[] { + // if (this._canvases) { + // return this._canvases; + // } + // return this._canvases = this.members.en().where(m => m.isCanvas()).toArray(); + // } Range.prototype.getRanges = function () { if (this._ranges) { return this._ranges; @@ -1503,7 +1496,9 @@ var Manifesto; Sequence.prototype.getCanvasById = function (id) { for (var i = 0; i < this.getTotalCanvases(); i++) { var canvas = this.getCanvasByIndex(i); - if (canvas.id === id) { + // normalise canvas id + var canvasId = Manifesto.Utils.normaliseUrl(canvas.id); + if (Manifesto.Utils.normaliseUrl(id) === canvasId) { return canvas; } } @@ -2093,10 +2088,23 @@ var Manifesto; Utils.generateTreeNodeIds(n, i); } }; + Utils.normaliseType = function (type) { + type = type.toLowerCase(); + if (type.indexOf(':') !== -1) { + var split = type.split(':'); + return split[1]; + } + return type; + }; + Utils.normaliseUrl = function (url) { + url = url.substr(url.indexOf('://')); + if (url.indexOf('#') !== -1) { + url = url.split('#')[0]; + } + return url; + }; Utils.normalisedUrlsMatch = function (url1, url2) { - var url1norm = url1.substr(url1.indexOf('://')); - var url2norm = url1.substr(url1.indexOf('://')); - return url1norm === url2norm; + return Utils.normaliseUrl(url1) === Utils.normaliseUrl(url2); }; Utils.isImageProfile = function (profile) { if (Utils.normalisedUrlsMatch(profile.toString(), Manifesto.ServiceProfile.STANFORDIIIFIMAGECOMPLIANCE0.toString()) || diff --git a/dist/manifesto.d.ts b/dist/manifesto.d.ts index b7b54e6c..b5adf5dc 100644 --- a/dist/manifesto.d.ts +++ b/dist/manifesto.d.ts @@ -364,15 +364,14 @@ declare namespace Manifesto { declare namespace Manifesto { class Range extends ManifestResource implements IRange { - _canvases: ICanvas[] | null; - _ranges: IRange[] | null; + private _ranges; + canvases: string[] | null; + members: IManifestResource[]; parentRange: Range; path: string; - members: IManifestResource[]; treeNode: ITreeNode; constructor(jsonld?: any, options?: IManifestoOptions); getCanvasIds(): string[]; - getCanvases(): ICanvas[]; getRanges(): IRange[]; getViewingDirection(): ViewingDirection | null; getViewingHint(): ViewingHint | null; @@ -529,6 +528,8 @@ declare namespace Manifesto { static getInexactLocale(locale: string): string; static getLocalisedValue(resource: any, locale: string): string | null; static generateTreeNodeIds(treeNode: ITreeNode, index?: number): void; + static normaliseType(type: string): string; + static normaliseUrl(url: string): string; static normalisedUrlsMatch(url1: string, url2: string): boolean; static isImageProfile(profile: Manifesto.ServiceProfile): boolean; static isLevel0ImageProfile(profile: Manifesto.ServiceProfile): boolean; @@ -817,8 +818,8 @@ declare namespace Manifesto { declare namespace Manifesto { interface IRange extends IManifestResource { + canvases: string[] | null; getCanvasIds(): string[]; - getCanvases(): ICanvas[]; getRanges(): IRange[]; getTree(treeRoot: ITreeNode): ITreeNode; getViewingDirection(): ViewingDirection | null; diff --git a/dist/server/manifesto.js b/dist/server/manifesto.js index ae94cb7c..8ccfd049 100644 --- a/dist/server/manifesto.js +++ b/dist/server/manifesto.js @@ -254,12 +254,12 @@ var Manifesto; IIIFResourceType.prototype.sequence = function () { return new IIIFResourceType(IIIFResourceType.SEQUENCE.toString()); }; - IIIFResourceType.ANNOTATION = new IIIFResourceType("oa:annotation"); - IIIFResourceType.CANVAS = new IIIFResourceType("sc:canvas"); - IIIFResourceType.COLLECTION = new IIIFResourceType("sc:collection"); - IIIFResourceType.MANIFEST = new IIIFResourceType("sc:manifest"); - IIIFResourceType.RANGE = new IIIFResourceType("sc:range"); - IIIFResourceType.SEQUENCE = new IIIFResourceType("sc:sequence"); + IIIFResourceType.ANNOTATION = new IIIFResourceType("annotation"); + IIIFResourceType.CANVAS = new IIIFResourceType("canvas"); + IIIFResourceType.COLLECTION = new IIIFResourceType("collection"); + IIIFResourceType.MANIFEST = new IIIFResourceType("manifest"); + IIIFResourceType.RANGE = new IIIFResourceType("range"); + IIIFResourceType.SEQUENCE = new IIIFResourceType("sequence"); return IIIFResourceType; }(Manifesto.StringValue)); Manifesto.IIIFResourceType = IIIFResourceType; @@ -707,7 +707,7 @@ var Manifesto; return _this; } ManifestResource.prototype.getIIIFResourceType = function () { - return new Manifesto.IIIFResourceType(this.getProperty('@type')); + return new Manifesto.IIIFResourceType(Manifesto.Utils.normaliseType(this.getProperty('type'))); }; ManifestResource.prototype.getLabel = function () { return Manifesto.TranslationCollection.parse(this.getProperty('label'), this.options.locale); @@ -1029,12 +1029,7 @@ var Manifesto; return []; }; IIIFResource.prototype.getIIIFResourceType = function () { - var type = this.getProperty('type'); - if (type) { - return new Manifesto.IIIFResourceType(type); - } - type = this.getProperty('@type'); - return new Manifesto.IIIFResourceType(type); + return new Manifesto.IIIFResourceType(Manifesto.Utils.normaliseType(this.getProperty('type'))); }; IIIFResource.prototype.getLogo = function () { var logo = this.getProperty('logo'); @@ -1069,19 +1064,13 @@ var Manifesto; return this.defaultTree; }; IIIFResource.prototype.isCollection = function () { - if (this.getIIIFResourceType().toString().toLowerCase() === 'collection') { - return true; - } - else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { return true; } return false; }; IIIFResource.prototype.isManifest = function () { - if (this.getIIIFResourceType().toString().toLowerCase() === 'manifest') { - return true; - } - else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { return true; } return false; @@ -1182,7 +1171,7 @@ var Manifesto; if (this.__jsonld.structures && this.__jsonld.structures.length) { for (var i = 0; i < this.__jsonld.structures.length; i++) { var r = this.__jsonld.structures[i]; - if (r['@id'] === id) { + if (r['@id'] === id || r.id === id) { return r; } } @@ -1214,25 +1203,26 @@ var Manifesto; else { parentRange.members.push(range); } - if (r.ranges) { - for (var i = 0; i < r.ranges.length; i++) { - this._parseRanges(r.ranges[i], path + '/' + i, range); - } - } if (r.members) { - var _loop_1 = function (i) { + for (var i = 0; i < r.members.length; i++) { var child = r.members[i]; - // only add to members if not already parsed from backwards-compatible ranges/canvases arrays - if (r.members.en().where(function (m) { return m.id === child.id; }).first()) { - return "continue"; + // todo: use constants + if (child['@type'] && child['@type'].toLowerCase() === 'sc:range' || child['type'] && child['type'].toLowerCase() === 'range') { + this._parseRanges(child, path + '/' + i, range); } - if (child['@type'].toLowerCase() === 'sc:range') { - this_1._parseRanges(child, path + '/' + i, range); + else if (child['@type'] && child['@type'].toLowerCase() === 'sc:canvas' || child['type'] && child['type'].toLowerCase() === 'canvas') { + // store the ids on the __jsonld object to be used by Range.getCanvasIds() + if (!range.canvases) { + range.canvases = []; + } + var id_1 = child['@id'] || child.id; + range.canvases.push(id_1); } - }; - var this_1 = this; - for (var i = 0; i < r.members.length; i++) { - _loop_1(i); + } + } + else if (r.ranges) { + for (var i = 0; i < r.ranges.length; i++) { + this._parseRanges(r.ranges[i], path + '/' + i, range); } } }; @@ -1442,8 +1432,8 @@ var Manifesto; __extends(Range, _super); function Range(jsonld, options) { var _this = _super.call(this, jsonld, options) || this; - _this._canvases = null; _this._ranges = null; + _this.canvases = null; _this.members = []; return _this; } @@ -1451,14 +1441,17 @@ var Manifesto; if (this.__jsonld.canvases) { return this.__jsonld.canvases; } - return []; - }; - Range.prototype.getCanvases = function () { - if (this._canvases) { - return this._canvases; + else if (this.canvases) { + return this.canvases; } - return this._canvases = this.members.en().where(function (m) { return m.isCanvas(); }).toArray(); + return []; }; + // getCanvases(): ICanvas[] { + // if (this._canvases) { + // return this._canvases; + // } + // return this._canvases = this.members.en().where(m => m.isCanvas()).toArray(); + // } Range.prototype.getRanges = function () { if (this._ranges) { return this._ranges; @@ -1575,7 +1568,9 @@ var Manifesto; Sequence.prototype.getCanvasById = function (id) { for (var i = 0; i < this.getTotalCanvases(); i++) { var canvas = this.getCanvasByIndex(i); - if (canvas.id === id) { + // normalise canvas id + var canvasId = Manifesto.Utils.normaliseUrl(canvas.id); + if (Manifesto.Utils.normaliseUrl(id) === canvasId) { return canvas; } } @@ -2165,10 +2160,23 @@ var Manifesto; Utils.generateTreeNodeIds(n, i); } }; + Utils.normaliseType = function (type) { + type = type.toLowerCase(); + if (type.indexOf(':') !== -1) { + var split = type.split(':'); + return split[1]; + } + return type; + }; + Utils.normaliseUrl = function (url) { + url = url.substr(url.indexOf('://')); + if (url.indexOf('#') !== -1) { + url = url.split('#')[0]; + } + return url; + }; Utils.normalisedUrlsMatch = function (url1, url2) { - var url1norm = url1.substr(url1.indexOf('://')); - var url2norm = url1.substr(url1.indexOf('://')); - return url1norm === url2norm; + return Utils.normaliseUrl(url1) === Utils.normaliseUrl(url2); }; Utils.isImageProfile = function (profile) { if (Utils.normalisedUrlsMatch(profile.toString(), Manifesto.ServiceProfile.STANFORDIIIFIMAGECOMPLIANCE0.toString()) || diff --git a/src/IIIFResource.ts b/src/IIIFResource.ts index a57dfd92..f6da860c 100644 --- a/src/IIIFResource.ts +++ b/src/IIIFResource.ts @@ -40,15 +40,7 @@ namespace Manifesto { } getIIIFResourceType(): IIIFResourceType { - - let type: string = this.getProperty('type'); - - if (type) { - return new IIIFResourceType(type); - } - - type = this.getProperty('@type'); - return new IIIFResourceType(type); + return new IIIFResourceType(Utils.normaliseType(this.getProperty('type'))); } getLogo(): string | null { @@ -91,18 +83,14 @@ namespace Manifesto { } isCollection(): boolean { - if (this.getIIIFResourceType().toString().toLowerCase() === 'collection') { // todo: use constant - return true; - } else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.COLLECTION.toString()) { return true; } return false; } isManifest(): boolean { - if (this.getIIIFResourceType().toString().toLowerCase() === 'manifest') { // todo: use constant - return true; - } else if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { + if (this.getIIIFResourceType().toString() === Manifesto.IIIFResourceType.MANIFEST.toString()) { return true; } return false; diff --git a/src/IIIFResourceType.ts b/src/IIIFResourceType.ts index 3f82eaa9..a97a6868 100644 --- a/src/IIIFResourceType.ts +++ b/src/IIIFResourceType.ts @@ -1,11 +1,11 @@ namespace Manifesto { export class IIIFResourceType extends StringValue{ - public static ANNOTATION = new IIIFResourceType("oa:annotation"); - public static CANVAS = new IIIFResourceType("sc:canvas"); - public static COLLECTION = new IIIFResourceType("sc:collection"); - public static MANIFEST = new IIIFResourceType("sc:manifest"); - public static RANGE = new IIIFResourceType("sc:range"); - public static SEQUENCE = new IIIFResourceType("sc:sequence"); + public static ANNOTATION = new IIIFResourceType("annotation"); + public static CANVAS = new IIIFResourceType("canvas"); + public static COLLECTION = new IIIFResourceType("collection"); + public static MANIFEST = new IIIFResourceType("manifest"); + public static RANGE = new IIIFResourceType("range"); + public static SEQUENCE = new IIIFResourceType("sequence"); // todo: use getters when ES3 target is no longer required. diff --git a/src/IRange.ts b/src/IRange.ts index e50e344d..739862ae 100644 --- a/src/IRange.ts +++ b/src/IRange.ts @@ -1,7 +1,7 @@ namespace Manifesto { export interface IRange extends IManifestResource { + canvases: string[] | null; getCanvasIds(): string[]; - getCanvases(): ICanvas[]; getRanges(): IRange[]; getTree(treeRoot: ITreeNode): ITreeNode; getViewingDirection(): ViewingDirection | null; diff --git a/src/Manifest.ts b/src/Manifest.ts index c11aeea7..d037fe08 100644 --- a/src/Manifest.ts +++ b/src/Manifest.ts @@ -72,7 +72,7 @@ namespace Manifesto { if (this.__jsonld.structures && this.__jsonld.structures.length) { for (let i = 0; i < this.__jsonld.structures.length; i++) { const r = this.__jsonld.structures[i]; - if (r['@id'] === id){ + if (r['@id'] === id || r.id === id) { return r; } } @@ -111,26 +111,29 @@ namespace Manifesto { parentRange.members.push(range); } - if (r.ranges) { - for (let i = 0; i < r.ranges.length; i++) { - this._parseRanges(r.ranges[i], path + '/' + i, range); - } - } - if (r.members) { for (let i = 0; i < r.members.length; i++) { const child: any = r.members[i]; - // only add to members if not already parsed from backwards-compatible ranges/canvases arrays - if (r.members.en().where(m => m.id === child.id).first()) { - continue; - } - - if (child['@type'].toLowerCase() === 'sc:range'){ + // todo: use constants + if (child['@type'] && child['@type'].toLowerCase() === 'sc:range' || child['type'] && child['type'].toLowerCase() === 'range'){ this._parseRanges(child, path + '/' + i, range); - } + } else if (child['@type'] && child['@type'].toLowerCase() === 'sc:canvas' || child['type'] && child['type'].toLowerCase() === 'canvas') { + // store the ids on the __jsonld object to be used by Range.getCanvasIds() + if (!range.canvases) { + range.canvases = []; + } + + const id: string = child['@id'] || child.id; + + range.canvases.push(id); + } } - } + } else if (r.ranges) { + for (let i = 0; i < r.ranges.length; i++) { + this._parseRanges(r.ranges[i], path + '/' + i, range); + } + } } getAllRanges(): IRange[] { diff --git a/src/ManifestResource.ts b/src/ManifestResource.ts index bb0fa2ae..f3342bcc 100644 --- a/src/ManifestResource.ts +++ b/src/ManifestResource.ts @@ -9,7 +9,7 @@ namespace Manifesto { } getIIIFResourceType(): IIIFResourceType { - return new IIIFResourceType(this.getProperty('@type')); + return new IIIFResourceType(Utils.normaliseType(this.getProperty('type'))); } getLabel(): TranslationCollection { diff --git a/src/Range.ts b/src/Range.ts index 108bbb53..c9148d8e 100644 --- a/src/Range.ts +++ b/src/Range.ts @@ -1,35 +1,39 @@ namespace Manifesto { export class Range extends ManifestResource implements IRange{ - _canvases: ICanvas[] | null = null; - _ranges: IRange[] | null = null; - parentRange: Range; - path: string; - members: IManifestResource[] = []; - treeNode: ITreeNode; + private _ranges: IRange[] | null = null; + public canvases: string[] | null = null; + public members: IManifestResource[] = []; + public parentRange: Range; + public path: string; + public treeNode: ITreeNode; constructor(jsonld?: any, options?: IManifestoOptions){ super(jsonld, options); } getCanvasIds(): string[] { + if (this.__jsonld.canvases) { return this.__jsonld.canvases; + } else if (this.canvases) { + return this.canvases; } return []; } - getCanvases(): ICanvas[] { - if (this._canvases){ - return this._canvases; - } + // getCanvases(): ICanvas[] { + // if (this._canvases) { + // return this._canvases; + // } - return this._canvases = this.members.en().where(m => m.isCanvas()).toArray(); - } + // return this._canvases = this.members.en().where(m => m.isCanvas()).toArray(); + // } getRanges(): IRange[] { - if (this._ranges){ + + if (this._ranges) { return this._ranges; } diff --git a/src/Sequence.ts b/src/Sequence.ts index 6ef8eadd..a43a44f1 100644 --- a/src/Sequence.ts +++ b/src/Sequence.ts @@ -31,7 +31,10 @@ namespace Manifesto { for (let i = 0; i < this.getTotalCanvases(); i++) { const canvas = this.getCanvasByIndex(i); - if (canvas.id === id){ + // normalise canvas id + const canvasId: string = Utils.normaliseUrl(canvas.id); + + if (Utils.normaliseUrl(id) === canvasId){ return canvas; } } diff --git a/src/StringValue.ts b/src/StringValue.ts index 7fa2f66b..424982bf 100644 --- a/src/StringValue.ts +++ b/src/StringValue.ts @@ -4,7 +4,7 @@ namespace Manifesto { public value: string = ""; constructor(value?: string) { - if (value){ + if (value) { this.value = value.toLowerCase(); } } diff --git a/src/Utils.ts b/src/Utils.ts index 8d6726b7..1ee7243a 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -93,11 +93,29 @@ namespace Manifesto { } } - static normalisedUrlsMatch(url1: string, url2: string): boolean { - const url1norm: string = url1.substr(url1.indexOf('://')); - const url2norm: string = url1.substr(url1.indexOf('://')); + static normaliseType(type: string): string { + type = type.toLowerCase(); - return url1norm === url2norm; + if (type.indexOf(':') !== -1) { + const split: string[] = type.split(':'); + return split[1]; + } + + return type; + } + + static normaliseUrl(url: string): string { + url = url.substr(url.indexOf('://')); + + if (url.indexOf('#') !== -1) { + url = url.split('#')[0]; + } + + return url; + } + + static normalisedUrlsMatch(url1: string, url2: string): boolean { + return Utils.normaliseUrl(url1) === Utils.normaliseUrl(url2); } static isImageProfile(profile: Manifesto.ServiceProfile): boolean { diff --git a/test/chemistdruggist.js b/test/chemistdruggist.js index f382d8c3..41d0cb27 100644 --- a/test/chemistdruggist.js +++ b/test/chemistdruggist.js @@ -18,9 +18,9 @@ describe('#loadsChemistDruggist', function() { }); describe('#hasIIIFResourceType', function() { - it('has a IIIFResourceType property of "sc:collection"', function () { + it('has a IIIFResourceType property of "collection"', function () { var type = collection.getIIIFResourceType(); - type.toString().should.equal('sc:collection'); + type.toString().should.equal('collection'); expect(collection.isManifest()).to.equal(false); expect(collection.isCollection()).to.equal(true); }); diff --git a/test/fixtures/lunchroom-manners.json b/test/fixtures/lunchroom-manners.json new file mode 100644 index 00000000..048799e2 --- /dev/null +++ b/test/fixtures/lunchroom-manners.json @@ -0,0 +1,211 @@ +{ + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners", + "type": "Manifest", + "label": "Lunchroom manners", + "description": "Beginning Reponsibility: Lunchroom Manners [motion picture] Coronet Films", + "sequences": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/sequence/1", + "type": "Sequence", + "canvases": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1", + "type": "Canvas", + "label": "Beginning Reponsibility: Lunchroom Manners [motion picture] Coronet Films", + "description": "Lunchroom manners are taught by following a boy through his lunchroom experience", + "height": 360, + "width": 480, + "duration": 660, + "content": [ + { + "id": "...", + "type": "AnnotationPage", + "items": [ + { + "id": "...", + "type": "Annotation", + "motivation": "painting", + "body": [ + { + "type": "Choice", + "choiceHint": "user", + "items": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/high/lunchroom_manners_1024kb.mp4", + "type": "Video", + "label": "High" + }, + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/medium/lunchroom_manners_512kb.mp4", + "type": "Video", + "label": "Medium" + }, + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/low/lunchroom_manners_256kb.mp4", + "type": "Video", + "label": "Low" + } + ] + }, + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/lunchroom_manners.vtt", + "type": "Text", + "format": "text/vtt", + "language": "en" + } + ], + "target": "http://dlib.indiana.edu/iiif_av/canvas/1" + } + ] + } + ] + } + ] + } + ], + "structures": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/1", + "type": "Range", + "label": "Getting Ready for Lunch", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/2", + "type": "Range", + "label": "Washing Hands", + "members": [ + { + "type": "Range", + "label": "Using Soap", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=157,160", + "type": "Canvas" + } + ] + }, + { + "type": "Range", + "label": "", + "viewingHint": "no-table-of-contents", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=160,165", + "type": "Canvas" + } + ] + }, + { + "type": "Range", + "label": "Rinsing Well", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=165,178", + "type": "Canvas" + } + ] + } + ] + } + ] + }, + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/3", + "type": "Range", + "label": "In the Lunchroom", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/4", + "type": "Range", + "label": "At the Counter", + "members": [ + { + "type": "Range", + "label": "Getting Tray", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=227,245", + "type": "Canvas" + } + ] + }, + { + "type": "Range", + "label": "Choosing Food", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=258,288", + "type": "Canvas" + } + ] + }, + { + "type": "Range", + "label": "There will be Cake", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=301,308", + "type": "Canvas" + } + ] + } + ] + }, + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/5", + "type": "Range", + "label": "At the Table", + "members": [ + { + "type": "Range", + "label": "Sitting Quietly", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=323,333", + "type": "Canvas" + } + ] + }, + { + "type": "Range", + "label": "Eating Neatly", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=362,378", + "type": "Canvas" + } + ] + } + ] + }, + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/6", + "type": "Range", + "label": "Leavning the Lunchroom", + "members": [ + { + "type": "Range", + "label": "Cleaning Up", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=448,492", + "type": "Canvas" + } + ] + }, + { + "type": "Range", + "label": "Putting Things Away", + "members": [ + { + "id": "http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=511,527", + "type": "Canvas" + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/test/fixtures/manifests.js b/test/fixtures/manifests.js index 1f724e1d..e8840ce6 100644 --- a/test/fixtures/manifests.js +++ b/test/fixtures/manifests.js @@ -12,6 +12,7 @@ module.exports = { "herbal": "http://localhost:3001/herbal.json", "horriblemurders": "http://localhost:3001/horriblemurders.json", "illustrationsofchina": "http://localhost:3001/illustrationsofchina.json", + "lunchroommanners": "http://localhost:3001/lunchroom-manners.json", "members": "http://localhost:3001/members.json", "memberscollection": "http://localhost:3001/members-collection.json", "membersranges": "http://localhost:3001/members-ranges.json", diff --git a/test/https.js b/test/https.js index 728e5946..f739fad4 100644 --- a/test/https.js +++ b/test/https.js @@ -6,12 +6,12 @@ require('./shared'); var manifest, sequence; -describe('#loadsRiksarkivetHTTPS', function() { - this.timeout(20000); - it('loads successfully', function (done) { - manifesto.loadManifest(manifests.https).then(function(data) { - manifest = manifesto.create(data); - done(); - }); - }); -}); \ No newline at end of file +// describe('#loadsRiksarkivetHTTPS', function() { +// this.timeout(20000); +// it('loads successfully', function (done) { +// manifesto.loadManifest(manifests.https).then(function(data) { +// manifest = manifesto.create(data); +// done(); +// }); +// }); +// }); \ No newline at end of file diff --git a/test/lunchroommanners.js b/test/lunchroommanners.js new file mode 100644 index 00000000..1c43dd5e --- /dev/null +++ b/test/lunchroommanners.js @@ -0,0 +1,29 @@ +var expect = require('chai').expect; +var manifesto = require('../dist/server/manifesto'); +var should = require('chai').should(); +var manifests = require('./fixtures/manifests'); +require('./shared'); + +var manifest, topRange; + +describe('#loadsMembersRanges', function() { + it('loads successfully', function (done) { + manifesto.loadManifest(manifests.lunchroommanners).then(function(data) { + manifest = manifesto.create(data); + done(); + }); + }); +}); + +describe('#hasRanges', function() { + it('has ranges', function () { + topRange = manifest.getTopRanges()[0]; + topRange.members.length.should.equal(2); + var washingHands = topRange.members[0].members[0]; + expect(washingHands.id).to.equal("http://dlib.indiana.edu/iiif_av/lunchroom_manners/range/2"); + var usingSoap = washingHands.members[0]; + var canvasid = usingSoap.canvases[0]; + expect(canvasid).to.equal("http://dlib.indiana.edu/iiif_av/lunchroom_manners/canvas/1#t=157,160"); + // get sequence and use .getCanvasById trimming http/s and hash fragment + }); +}); \ No newline at end of file diff --git a/test/nested.js b/test/nested.js index 39d5c13d..fb3ea25f 100644 --- a/test/nested.js +++ b/test/nested.js @@ -1,86 +1,86 @@ -// nested collections - -var expect = require('chai').expect; -var manifesto = require('../dist/server/manifesto'); -var should = require('chai').should(); -var manifests = require('./fixtures/manifests'); -require('./shared'); - -var collection, manifest, firstCollection, secondCollection; - -describe('#loadsTopNestedManifest', function() { - it('loads successfully', function (done) { - manifesto.loadManifest(manifests['nested-top']).then(function(data) { - collection = manifesto.create(data); - done(); - }); - }); -}); - -describe('#hasIIIFResourceType', function() { - it('has a IIIFResourceType property of "sc:collection"', function () { - var type = collection.getIIIFResourceType(); - type.toString().should.equal('sc:collection'); - }); -}); - -describe('#hasCollectionCount', function() { - it('has a collection count of 1', function () { - collection.getTotalCollections().should.equal(1); - }); -}); - -describe('#hasLabel', function() { - it('has a label', function() { - Manifesto.TranslationCollection.getValue(collection.getLabel()).should.equal('Villanova Digital Library'); - }); -}); - -describe('#firstCollectionHasLabel', function() { - it('has a first collection with a label', function(done) { - collection.getCollectionByIndex(0).then(function(data) { - firstCollection = data; - Manifesto.TranslationCollection.getValue(firstCollection.getLabel()).should.equal('Dime Novel and Popular Literature'); - done(); - }); - }); -}); - -describe('#firstCollectionHasEmptyManifestCount', function() { - it('has a first collection which contains 0 manifests', function () { - firstCollection.getTotalManifests().should.equal(0); - }); -}); - -describe('#getTree', function() { - it('has a tree', function () { - var tree = collection.getDefaultTree(); - expect(tree).to.exist; - }); -}); - -describe('#secondLevelCollectionHasLabel', function() { - it('has a second-level collection with a label', function (done) { - firstCollection.getCollectionByIndex(0).then(function(data) { - secondCollection = data; - Manifesto.TranslationCollection.getValue(secondCollection.getLabel()).should.equal('Covers and Illustrations'); - done(); - }); - }); -}); - -describe('#secondCollectionHasManifestCount', function() { - it('has a second-level collection which contains 9 manifests', function () { - secondCollection.getTotalManifests().should.equal(9); - }); -}); - -describe('#canAccessManifestFromSecondCollection', function() { - it('can access a deeply-nested manifest', function (done) { - secondCollection.getManifestByIndex(0).then(function(data) { - manifest = data; - Manifesto.TranslationCollection.getValue(manifest.getLabel()).should.equal('Wunder der Vererbung'); - done(); - }); - }); +// nested collections + +var expect = require('chai').expect; +var manifesto = require('../dist/server/manifesto'); +var should = require('chai').should(); +var manifests = require('./fixtures/manifests'); +require('./shared'); + +var collection, manifest, firstCollection, secondCollection; + +describe('#loadsTopNestedManifest', function() { + it('loads successfully', function (done) { + manifesto.loadManifest(manifests['nested-top']).then(function(data) { + collection = manifesto.create(data); + done(); + }); + }); +}); + +describe('#hasIIIFResourceType', function() { + it('has a IIIFResourceType property of "collection"', function () { + var type = collection.getIIIFResourceType(); + type.toString().should.equal('collection'); + }); +}); + +describe('#hasCollectionCount', function() { + it('has a collection count of 1', function () { + collection.getTotalCollections().should.equal(1); + }); +}); + +describe('#hasLabel', function() { + it('has a label', function() { + Manifesto.TranslationCollection.getValue(collection.getLabel()).should.equal('Villanova Digital Library'); + }); +}); + +describe('#firstCollectionHasLabel', function() { + it('has a first collection with a label', function(done) { + collection.getCollectionByIndex(0).then(function(data) { + firstCollection = data; + Manifesto.TranslationCollection.getValue(firstCollection.getLabel()).should.equal('Dime Novel and Popular Literature'); + done(); + }); + }); +}); + +describe('#firstCollectionHasEmptyManifestCount', function() { + it('has a first collection which contains 0 manifests', function () { + firstCollection.getTotalManifests().should.equal(0); + }); +}); + +describe('#getTree', function() { + it('has a tree', function () { + var tree = collection.getDefaultTree(); + expect(tree).to.exist; + }); +}); + +describe('#secondLevelCollectionHasLabel', function() { + it('has a second-level collection with a label', function (done) { + firstCollection.getCollectionByIndex(0).then(function(data) { + secondCollection = data; + Manifesto.TranslationCollection.getValue(secondCollection.getLabel()).should.equal('Covers and Illustrations'); + done(); + }); + }); +}); + +describe('#secondCollectionHasManifestCount', function() { + it('has a second-level collection which contains 9 manifests', function () { + secondCollection.getTotalManifests().should.equal(9); + }); +}); + +describe('#canAccessManifestFromSecondCollection', function() { + it('can access a deeply-nested manifest', function (done) { + secondCollection.getManifestByIndex(0).then(function(data) { + manifest = data; + Manifesto.TranslationCollection.getValue(manifest.getLabel()).should.equal('Wunder der Vererbung'); + done(); + }); + }); }); \ No newline at end of file