@europeana/portal
Version:
Europeana Portal
433 lines (350 loc) • 16.1 kB
JavaScript
exports.ids = [64];
exports.modules = {
/***/ 315:
/***/ (function(module, exports, __webpack_require__) {
// style-loader: Adds some css to the DOM by adding a <style> tag
// load the styles
var content = __webpack_require__(386);
if(content.__esModule) content = content.default;
if(typeof content === 'string') content = [[module.i, content, '']];
if(content.locals) module.exports = content.locals;
// add CSS to SSR context
var add = __webpack_require__(13).default
module.exports.__inject__ = function (context) {
add("39464350", content, true, context)
};
/***/ }),
/***/ 385:
/***/ (function(module, __webpack_exports__, __webpack_require__) {
;
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_vue_style_loader_index_js_ref_7_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_7_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_sass_loader_dist_cjs_js_ref_7_oneOf_1_2_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_2ad20123_lang_scss_scoped_true___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(315);
/* harmony import */ var _node_modules_vue_style_loader_index_js_ref_7_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_7_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_sass_loader_dist_cjs_js_ref_7_oneOf_1_2_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_2ad20123_lang_scss_scoped_true___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_ref_7_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_7_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_sass_loader_dist_cjs_js_ref_7_oneOf_1_2_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_2ad20123_lang_scss_scoped_true___WEBPACK_IMPORTED_MODULE_0__);
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _node_modules_vue_style_loader_index_js_ref_7_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_7_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_sass_loader_dist_cjs_js_ref_7_oneOf_1_2_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_2ad20123_lang_scss_scoped_true___WEBPACK_IMPORTED_MODULE_0__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _node_modules_vue_style_loader_index_js_ref_7_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_7_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_sass_loader_dist_cjs_js_ref_7_oneOf_1_2_node_modules_vue_loader_lib_index_js_vue_loader_options_index_vue_vue_type_style_index_0_id_2ad20123_lang_scss_scoped_true___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));
/***/ }),
/***/ 386:
/***/ (function(module, exports, __webpack_require__) {
// Imports
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(12);
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
// Module
___CSS_LOADER_EXPORT___.push([module.i, "[data-v-2ad20123] .mirador-thumbnail-nav-canvas:focus{outline:2px solid #0a72cc !important}[data-v-2ad20123] .mirador-thumb-navigation{height:100px !important}", ""]);
// Exports
module.exports = ___CSS_LOADER_EXPORT___;
/***/ }),
/***/ 543:
/***/ (function(module, __webpack_exports__, __webpack_require__) {
;
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./src/pages/iiif/index.vue?vue&type=template&id=2ad20123&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_vm._ssrNode("<div id=\"viewer\" data-v-2ad20123></div>")])}
var staticRenderFns = []
// CONCATENATED MODULE: ./src/pages/iiif/index.vue?vue&type=template&id=2ad20123&scoped=true&
// EXTERNAL MODULE: external "lodash/uniq"
var uniq_ = __webpack_require__(57);
var uniq_default = /*#__PURE__*/__webpack_require__.n(uniq_);
// CONCATENATED MODULE: ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./src/pages/iiif/index.vue?vue&type=script&lang=js&
//
//
//
//
//
//
/* harmony default export */ var iiifvue_type_script_lang_js_ = ({
name: 'IIIFPage',
layout: 'minimal',
asyncData({
query
}) {
return {
uri: query.uri,
searchQuery: query.query
};
},
data() {
return {
manifest: null,
MIRADOR_BUILD_PATH: 'https://cdn.jsdelivr.net/npm/mirador@3.0.0/dist',
page: null,
imageToCanvasMap: {},
mirador: null,
showAnnotations: false,
miradorStoreManifestJsonUnsubscriber: () => {}
};
},
head() {
return {
title: this.$pageHeadTitle('IIIF'),
script: [{
src: `${this.MIRADOR_BUILD_PATH}/mirador.min.js`
}]
};
},
computed: {
miradorViewerOptions() {
// Doc: https://github.com/ProjectMirador/mirador/blob/v3.0.0/src/config/settings.js
const options = {
id: 'viewer',
windows: [{
manifestId: this.uri,
thumbnailNavigationPosition: 'far-bottom'
}],
window: {
allowClose: false,
allowFullscreen: true,
allowMaximize: false,
allowTopMenuButton: false,
allowWindowSideBar: false,
sideBarOpen: false,
panels: {
info: false,
attribution: false,
canvas: false,
annotations: true,
search: true
},
defaultSideBarPanel: this.searchQuery ? 'search' : 'annotations'
},
workspace: {
showZoomControls: true,
type: 'mosaic'
},
workspaceControlPanel: {
enabled: false
},
requests: {
postprocessors: [this.postprocessMiradorRequest]
}
};
return options;
}
},
mounted() {
this.$nextTick(() => {
this.mirador = window.Mirador.viewer(this.miradorViewerOptions);
this.miradorStoreManifestJsonUnsubscriber = this.mirador.store.subscribe(this.miradorStoreManifestJsonListener);
});
},
methods: {
miradorStoreManifestJsonListener() {
const miradorWindow = Object.values(this.mirador.store.getState().windows)[0]; // only takes one window into account at the moment
if (miradorWindow) {
const miradorManifest = this.mirador.store.getState().manifests[miradorWindow.manifestId];
if (miradorManifest) {
this.manifest = miradorManifest.json;
if (miradorWindow.canvasId && miradorWindow.canvasId !== this.page) {
this.memoiseImageToCanvasMap();
this.page = miradorWindow.canvasId;
this.fetchImageData(this.uri, this.page);
}
}
}
},
postprocessMiradorRequest(url, action) {
switch (action.type) {
case 'mirador/RECEIVE_MANIFEST':
this.postprocessMiradorManifest(url, action);
break;
case 'mirador/RECEIVE_ANNOTATION':
if (action.annotationJson.resources.length > 0) {
const windowId = Object.keys(this.mirador.store.getState().windows)[0];
if (!this.showAnnotations) {
if (this.searchQuery) {
const companionWindowId = Object.keys(this.mirador.store.getState().companionWindows)[0];
const searchId = `${this.manifest.service['@id']}?q=${this.searchQuery}`;
const actionSearch = window.Mirador.actions.fetchSearch(windowId, companionWindowId, searchId, this.searchQuery);
this.mirador.store.dispatch(actionSearch);
}
const action = window.Mirador.actions.toggleWindowSideBar(windowId);
this.mirador.store.dispatch(action);
this.showAnnotations = true;
this.miradorViewerOptions.window.allowWindowSideBar = true;
const actionShow = window.Mirador.actions.updateConfig(this.miradorViewerOptions);
this.mirador.store.dispatch(actionShow);
}
}
this.postprocessMiradorAnnotation(url, action);
break;
case 'mirador/RECEIVE_SEARCH':
this.postprocessMiradorSearch(url, action);
break;
}
},
postprocessMiradorManifest(url, action) {
this.addTextGranularityFilterToManifest(action.manifestJson);
},
postprocessMiradorAnnotation(url, action) {
this.coerceResourcesOnToCanvases(action.annotationJson);
this.dereferenceAnnotationResources(action.annotationJson);
},
postprocessMiradorSearch(url, action) {
this.filterSearchHitsByTextGranularity(action.searchJson);
this.coerceResourcesOnToCanvases(action.searchJson);
this.coerceSearchHitsToBeforeMatchAfter(action.searchJson);
},
addTextGranularityFilterToManifest(manifestJson, textGranularity = 'Line') {
const europeanaIiifPattern = /^https?:\/\/iiif\.europeana\.eu\/presentation\/[^/]+\/[^/]+\/manifest$/;
if (!europeanaIiifPattern.test(manifestJson['@id'])) {
return;
} // Add textGranularity filter to "otherContent" URIs
for (const sequence of manifestJson.sequences) {
for (const canvas of sequence.canvases || []) {
const otherContent = canvas.otherContent || [];
for (let i = 0; i < otherContent.length; i = i + 1) {
const otherContentLink = otherContent[i];
const paramSeparator = otherContentLink.includes('?') ? '&' : '?';
otherContent[i] = `${otherContentLink}${paramSeparator}textGranularity=${textGranularity}`;
}
}
} // Add textGranularity filter to search service URI
//
// NOTE: this does not work, due to Mirador not expecting a service URI
// to already contain '?' with parameters.
// https://github.com/ProjectMirador/mirador/blob/v3.0.0/src/components/SearchPanelControls.js#L91
//
// If it in future becomes possible to use this, then `filterSearchHitsByTextGranularity`
// becomes redundant and may be removed, as pre-filtering on the
// service side is preferrable.
//
// if ((manifestJson.service || {}).profile === 'http://iiif.io/api/search/1/search') {
// const paramSeparator = manifestJson.service['@id'].includes('?') ? '&' : '?';
// manifestJson.service['@id'] = `${manifestJson.service['@id']}${paramSeparator}textGranularity=${textGranularity}`;
// }
},
filterSearchHitsByTextGranularity(searchJson, textGranularity = 'Line') {
searchJson.resources = searchJson.resources.filter(resource => !resource.dcType || resource.dcType === textGranularity);
const filteredResourceIds = searchJson.resources.map(resource => resource['@id']);
searchJson.hits = searchJson.hits.filter(hit => hit.annotations.some(anno => filteredResourceIds.includes(anno)));
},
coerceResourcesOnToCanvases(json) {
json.resources = json.resources.map(this.coerceResourceOnImagesToCanvases);
},
memoiseImageToCanvasMap() {
this.imageToCanvasMap = this.manifest.sequences.reduce((memo, sequence) => {
for (const canvas of sequence.canvases) {
for (const image of canvas.images) {
memo[image.resource['@id']] = canvas['@id'];
}
}
return memo;
}, {});
},
canvasForImage(imageId) {
const splitImageId = imageId.split('#');
if (this.imageToCanvasMap[splitImageId[0]]) {
return [this.imageToCanvasMap[splitImageId[0]], splitImageId[1]].join('#');
} else {
return null;
}
},
// HACK to force `on` attribute to canvas ID, from invalid targetting of image ID
//
// TODO: remove when API output updated to use canvas ID.
// Affects annotation lists for:
// - full pages of annotations linked to from otherContent in Presentation manifests
// - lists of annotations with search hits
coerceResourceOnImagesToCanvases(resource) {
if (Array.isArray(resource.on)) {
for (let i = 0; i < resource.on.length; i = i + 1) {
const canvas = this.canvasForImage(resource.on[i]);
if (canvas) {
resource.on[i] = canvas;
}
}
} else {
const canvas = this.canvasForImage(resource.on);
if (canvas) {
resource.on = canvas;
}
}
return resource;
},
// HACK to flatten oa:TextQuoteSelector hit selectors to before/match/after
// hits, as Mirador 3.0.0 does not support oa:TextQuoteSelector style.
coerceSearchHitsToBeforeMatchAfter(searchJson) {
const hits = [];
for (const hit of searchJson.hits || []) {
if (hit.selectors) {
for (const selector of hit.selectors) {
hits.push({
'@type': hit['@type'],
annotations: hit.annotations,
before: selector.prefix,
after: selector.suffix,
match: selector.exact
});
}
} else {
hits.push(hit);
}
}
searchJson.hits = hits;
},
fetchAnnotationResourcesFulltext(annotationJson) {
const urls = annotationJson.resources.filter(resource => !resource.resource.chars && resource.resource['@id']).map(resource => resource.resource['@id'].split('#')[0]);
const fulltext = {}; // TODO: error handling
const fetches = uniq_default()(urls).map(url => this.$axios.get(url).then(response => response.data).then(data => {
if (data.type === 'FullTextResource') {
fulltext[url] = data.value;
}
}));
return Promise.all(fetches).then(() => fulltext);
},
async dereferenceAnnotationResources(annotationJson) {
const fulltext = await this.fetchAnnotationResourcesFulltext(annotationJson);
for (const resource of annotationJson.resources) {
if (resource.resource.chars || !resource.resource['@id']) {
continue;
}
const url = resource.resource['@id'].split('#')[0];
if (!fulltext[url]) {
continue;
}
const fragment = resource.resource['@id'].split('#')[1];
resource.resource.chars = fulltext[url];
if (fragment) {
const charMatch = fragment.match(/char=(\d+),(\d+)$/);
if (charMatch) {
resource.resource.chars = resource.resource.chars.slice(Number(charMatch[1]), Number(charMatch[2]) + 1);
}
}
}
},
fetchImageData(url, pageId) {
if (!this.manifest) {
return;
}
const page = this.manifest.sequences[0].canvases.filter(canvas => canvas['@id'] === pageId);
if (page && page[0]) {
window.parent.postMessage({
'event': 'updateDownloadLink',
'id': page[0].images[0].resource['@id']
}, window.location.origin);
}
}
}
});
// CONCATENATED MODULE: ./src/pages/iiif/index.vue?vue&type=script&lang=js&
/* harmony default export */ var pages_iiifvue_type_script_lang_js_ = (iiifvue_type_script_lang_js_);
// EXTERNAL MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
var componentNormalizer = __webpack_require__(3);
// CONCATENATED MODULE: ./src/pages/iiif/index.vue
function injectStyles (context) {
var style0 = __webpack_require__(385)
if (style0.__inject__) style0.__inject__(context)
}
/* normalize component */
var component = Object(componentNormalizer["a" /* default */])(
pages_iiifvue_type_script_lang_js_,
render,
staticRenderFns,
false,
injectStyles,
"2ad20123",
"46332adb"
)
/* harmony default export */ var iiif = __webpack_exports__["default"] = (component.exports);
/***/ })
};;
//# sourceMappingURL=index.js.map