Apply changes from IIIF feature branch - add IIIF Annotation tool

The tool is not usable without yet without the changes to the PageView plugin
This commit is contained in:
Lutz Helm 2019-04-05 09:42:04 +02:00
parent f51c7cc7a1
commit 04f5eb8bc9
7 changed files with 720 additions and 0 deletions

View File

@ -0,0 +1,79 @@
<?php
namespace Kitodo\Dlf\Plugin\Tools;
/**
* (c) Kitodo. Key to digital objects e.V. <contact@kitodo.org>
*
* This file is part of the Kitodo and TYPO3 projects.
*
* @license GNU General Public License version 3 or later.
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/
use Kitodo\Dlf\Common\AbstractPlugin;
use Kitodo\Dlf\Common\Helper;
/**
* Tool 'Annotation selection' for the plugin 'DLF: Toolbox' of the 'dlf' extension.
* Allows the display of IIIF annotations.
*
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
* @author Alexander Bigga <alexander.bigga@slub-dresden.de>
* @author Lutz Helm <helm@ub.uni-leipzig.de>
* @package TYPO3
* @subpackage dlf
* @access public
*/
class AnnotationTool extends AbstractPlugin {
public $scriptRelPath = 'Classes/Plugin/Tools/AnnotationTool.php';
/**
* The main method of the PlugIn
*
* @access public
*
* @param string $content: The PlugIn content
* @param array $conf: The PlugIn configuration
*
* @return string The content that is displayed on the website
*/
public function main($content, $conf) {
$this->init($conf);
// Merge configuration with conf array of toolbox.
$this->conf = Helper::array_merge_recursive_overrule($this->cObj->data['conf'], $this->conf);
// Load current document.
$this->loadDocument();
if ($this->doc === NULL || $this->doc->numPages < 1) {
// Quit without doing anything if required variables are not set.
return $content;
} else {
if (!empty($this->piVars['logicalPage'])) {
$this->piVars['page'] = $this->doc->getPhysicalPage($this->piVars['logicalPage']);
// The logical page parameter should not appear again
unset($this->piVars['logicalPage']);
}
// Set default values if not set.
// $this->piVars['page'] may be integer or string (physical structure @ID)
if ((int) $this->piVars['page'] > 0 || empty($this->piVars['page'])) {
$this->piVars['page'] = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange((int) $this->piVars['page'], 1, $this->doc->numPages, 1);
} else {
$this->piVars['page'] = array_search($this->piVars['page'], $this->doc->physicalStructure);
}
$this->piVars['double'] = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->piVars['double'], 0, 1, 0);
}
// Load template file.
$this->getTemplate();
$annotationContainers = $this->doc->physicalStructureInfo[$this->doc->physicalStructure[$this->piVars['page']]]['annotationContainers'];
if ($annotationContainers != null && sizeof($annotationContainers)>0) {
$markerArray['###ANNOTATION_SELECT###'] = '<a class="select switchoff" id="tx-dlf-tools-annotations" title="" data-dic="annotations-on:'
.$this->pi_getLL('annotations-on', '', TRUE).';annotations-off:'
.$this->pi_getLL('annotations-off', '', TRUE).'">&nbsp;</a>';
// TODO selector for different motivations
} else {
$markerArray['###ANNOTATION_SELECT###'] = '<span class="no-annotations">'.$this->pi_getLL('annotations-not-available', '', TRUE).'</span>';
}
$content .= $this->cObj->substituteMarkerArray($this->template, $markerArray);
return $this->pi_wrapInBaseClass($content);
}
}

View File

@ -129,6 +129,61 @@
</config>
</TCEforms>
</rootline>
<originalIiifMetadata>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:dlf/plugins/metadata/locallang.xml:tt_content.pi_flexform.originalIiifMetadata</label>
<onChange>reload</onChange>
<config>
<type>check</type>
<default>0</default>
</config>
</TCEforms>
</originalIiifMetadata>
<iiifMetadataWrap>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:dlf/plugins/metadata/locallang.xml:tt_content.pi_flexform.iiifMetadataWrap</label>
<displayCond>FIELD:originalIiifMetadata:=:1</displayCond>
<config>
<type>text</type>
<default>key.wrap = &lt;dt&gt;|&lt;/dt&gt;&#13;value.required = 1&#13;value.wrap = &lt;dd&gt;|&lt;/dd&gt;</default>
</config>
</TCEforms>
</iiifMetadataWrap>
<displayIiifDescription>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:dlf/plugins/metadata/locallang.xml:tt_content.pi_flexform.displayIiifDescription</label>
<displayCond>FIELD:originalIiifMetadata:=:1</displayCond>
<config>
<type>check</type>
<default>1</default>
</config>
</TCEforms>
</displayIiifDescription>
<displayIiifRights>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:dlf/plugins/metadata/locallang.xml:tt_content.pi_flexform.displayIiifRights</label>
<displayCond>FIELD:originalIiifMetadata:=:1</displayCond>
<config>
<type>check</type>
<default>1</default>
</config>
</TCEforms>
</displayIiifRights>
<displayIiifLinks>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:dlf/plugins/metadata/locallang.xml:tt_content.pi_flexform.displayIiifLinks</label>
<displayCond>FIELD:originalIiifMetadata:=:1</displayCond>
<config>
<type>check</type>
<default>1</default>
</config>
</TCEforms>
</displayIiifLinks>
<separator>
<TCEforms>
<exclude>1</exclude>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!--
* (c) Kitodo. Key to digital objects e.V. <contact@kitodo.org>
*
* This file is part of the Kitodo and TYPO3 projects.
*
* @license GNU General Public License version 3 or later.
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
-->
<T3locallang>
<meta type="array">
<type>module</type>
<description>Language labels for tool Annotation</description>
</meta>
<data type="array">
<languageKey index="default" type="array">
<label index="annotations-on">Display Annotations</label>
<label index="annotations-off">Hide Annotations</label>
<label index="annotations-not-available">No Annotations available</label>
</languageKey>
<languageKey index="de" type="array">
<label index="annotations-on">Annotationen anzeigen</label>
<label index="annotations-off">Annotationen verbergen</label>
<label index="annotations-not-available">Keine Annotationen vorhanden</label>
</languageKey>
</data>
</T3locallang>

View File

@ -142,6 +142,7 @@
<label index="tx_dlf_mail.mail">Address</label>
<label index="tx_dlf_mail.name">Name</label>
<label index="tx_dlf_toolbox.fulltexttool">Fulltext</label>
<label index="tx_dlf_toolbox.annotationstool">IIIF Annotations</label>
<label index="tx_dlf_toolbox.imagedownloadtool">Image Download</label>
<label index="tx_dlf_toolbox.imagemanipulationtool">Image Manipulation</label>
<label index="tx_dlf_toolbox.pdfdownloadtool">PDF Download</label>
@ -309,6 +310,7 @@
<label index="tx_dlf_mail.mail">Adresse</label>
<label index="tx_dlf_mail.name">Name</label>
<label index="tx_dlf_toolbox.fulltexttool">Volltext</label>
<label index="tx_dlf_toolbox.annotationstool">IIIF-Annotationen</label>
<label index="tx_dlf_toolbox.imagedownloadtool">Bild-Download</label>
<label index="tx_dlf_toolbox.imagemanipulationtool">Bildbearbeitung</label>
<label index="tx_dlf_toolbox.pdfdownloadtool">PDF-Download</label>

View File

@ -0,0 +1,350 @@
/**
* (c) Kitodo. Key to digital objects e.V. <contact@kitodo.org>
*
* This file is part of the Kitodo and TYPO3 projects.
*
* @license GNU General Public License version 3 or later.
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/
/**
* This is necessary to support the scrolling of the element into the viewport
* in case of text hover on the map.
*
* @param elem
* @param speed
* @returns {jQuery}
*/
if (jQuery.fn.scrollTo === undefined) {
jQuery.fn.scrollTo = function(elem, speed) {
var manualOffsetTop = $(elem).parent().height() / 2;
$(this).animate({
scrollTop: $(this).scrollTop() - $(this).offset().top + $(elem).offset().top - manualOffsetTop
}, speed == undefined ? 1000 : speed);
return this;
};
}
class DlfAnnotationControl {
constructor(map, image, annotationContainers) {
this.map = map;
this.image = image;
this.annotationContainers = annotationContainers.annotationContainers;
this.canvas = annotationContainers.canvas;
this.annotationData;
this.dic = $('#tx-dlf-tools-annotations').length > 0 && $('#tx-dlf-tools-annotations').attr('data-dic') ?
dlfUtils.parseDataDic($('#tx-dlf-tools-annotations')) :
{'annotations-on':'Display Annotations','annotations-off':'Hide Annotations'};
this.layers_ = {
annotationList: new ol.layer.Vector({
'source': new ol.source.Vector(),
'style': dlfViewerOL3Styles.defaultStyle()
}),
annotation: new ol.layer.Vector({
'source': new ol.source.Vector(),
'style': dlfViewerOL3Styles.invisibleStyle()
}),
select: new ol.layer.Vector({
'source': new ol.source.Vector(),
'style': dlfViewerOL3Styles.selectStyle()
}),
hoverAnnotationList: new ol.layer.Vector({
'source': new ol.source.Vector(),
'style': dlfViewerOL3Styles.hoverStyle()
}),
hoverAnnotation: new ol.layer.Vector({
'source': new ol.source.Vector(),
'style': dlfViewerOL3Styles.textlineStyle()
}),
};
this.handlers = {
mapClick: $.proxy(function(event){
var feature = this.map.forEachFeatureAtPixel(event['pixel'], function(feature, layer) {
if (feature.get('type') === 'annotationList') {
return feature;
}
});
if (feature === undefined) {
this.layers_.select.getSource().clear();
this.selectedFeature_ = undefined;
this.showAnnotationText(undefined);
return;
};
if (this.selectedFeature_) {
// remove old clicks
this.layers_.select.getSource().removeFeature(this.selectedFeature_);
}
if (feature) {
// remove hover for preventing an adding of styles
this.layers_.hoverAnnotationList.getSource().clear();
// add feature
this.layers_.select.getSource().addFeature(feature);
}
this.selectedFeature_ = feature;
if (dlfUtils.exists(feature)) {
this.showAnnotationText([feature]);
}
}, this),
mapHover: $.proxy(function(event){
// hover in case of dragging
if (event['dragging']) {
return;
};
var hoverSourceAnnotation = this.layers_.hoverAnnotation.getSource(),
hoverSourceAnnotationList = this.layers_.hoverAnnotationList.getSource(),
selectSource = this.layers_.select.getSource(),
map_ = this.map,
annotationListFeature,
annotationFeature;
map_.forEachFeatureAtPixel(event['pixel'], function(feature, layer) {
if (feature.get('type') === 'annotationList') {
annotationListFeature = feature;
}
if (feature.get('type') === 'annotation') {
annotationFeature = feature;
}
});
// Handle AnnotationList elements
var activeSelectAnnotationListEl = selectSource.getFeatures().length > 0 ?
selectSource.getFeatures()[0] : undefined,
activeHoverAnnotationListEl = hoverSourceAnnotationList.getFeatures().length > 0 ?
hoverSourceAnnotationList.getFeatures()[0] : undefined,
isFeatureEqualSelectFeature = activeSelectAnnotationListEl !== undefined && annotationListFeature !== undefined &&
activeSelectAnnotationListEl.getId() === annotationListFeature.getId() ? true : false,
isFeatureEqualToOldHoverFeature = activeHoverAnnotationListEl !== undefined && annotationListFeature !== undefined &&
activeHoverAnnotationListEl.getId() === annotationListFeature.getId() ? true : false;
if (!isFeatureEqualToOldHoverFeature && !isFeatureEqualSelectFeature) {
// remove old AnnotationList hover features
hoverSourceAnnotationList.clear();
if (annotationListFeature) {
// add AnnotationList feature to hover
hoverSourceAnnotationList.addFeature(annotationListFeature);
}
}
// Handle Annotation elements
var activeHoverAnnotationListEl = hoverSourceAnnotation.getFeatures().length > 0 ?
hoverSourceAnnotation.getFeatures()[0] : undefined,
isFeatureEqualToOldHoverFeature = activeHoverAnnotationListEl !== undefined && annotationFeature !== undefined &&
activeHoverAnnotationListEl.getId() === annotationFeature.getId() ? true : false;
if (!isFeatureEqualToOldHoverFeature) {
if (activeHoverAnnotationListEl) {
// remove highlight effect on annotation view
var oldTargetElem = $('#' + activeHoverAnnotationListEl.getId());
if (oldTargetElem.hasClass('highlight') ) {
oldTargetElem.removeClass('highlight');
}
// remove old Annotation hover features
hoverSourceAnnotation.clear();
}
if (annotationFeature) {
// add highlight effect to annotation view
var targetElem = $('#' + annotationFeature.getId());
if (targetElem.length > 0 && !targetElem.hasClass('highlight')) {
targetElem.addClass('highlight');
$('#tx-dlf-annotationselection').scrollTo(targetElem, 50);
hoverSourceAnnotation.addFeature(annotationFeature);
}
}
}
}, this)
};
var anchorEl = $('#tx-dlf-tools-annotations');
if (anchorEl.length > 0){
var toogleAnnotations = $.proxy(function(event) {
event.preventDefault();
if ($(event.target).hasClass('active')){
this.deactivate();
return;
}
this.activate();
}, this);
anchorEl.on('click', toogleAnnotations);
anchorEl.on('touchstart', toogleAnnotations);
}
this.selectedFeature_ = undefined;
// set initial title of annotation element
$("#tx-dlf-tools-annotations")
.text(this.dic['annotations-on'])
.attr('title', this.dic['annotations-on']);
// if annotation is activated via cookie than run activation methode
if (dlfUtils.getCookie("tx-dlf-pageview-annotation-select") == 'enabled') {
// activate the annotation behavior
this.activate(anchorEl);
}
}
showAnnotationText(featuresParam) {
var features = featuresParam === undefined ? this.annotationData : featuresParam;
if (features !== undefined) {
$('#tx-dlf-annotationselection').children().remove();
for (var i = 0; i < features.length; i++) {
var feature = features[i],
annotations = feature.get('annotations'),
labelEl;
if (feature.get('label') != '') {
labelEl = $('<span class="annotation-list-label"/>');
labelEl.text(feature.get('label'));
$('#tx-dlf-annotationselection').append(labelEl);
}
for (var j=0; j<annotations.length; j++) {
var span = $('<span class="annotation" id="' + annotations[j].getId() + '"/>');
span.text(annotations[j].get('content'));
$('#tx-dlf-annotationselection').append(span);
$('#tx-dlf-annotationselection').append(' ');
}
$('#tx-dlf-annotationselection').append('<br /><br />');
}
}
}
activate() {
var controlEl = $('#tx-dlf-tools-annotations');
// Fetch annotation lists from server if the method is called for the first time
if (this.annotationData === undefined) {
this.annotationData = this.fetchAnnotationContainersFromServer(this.annotationContainers, this.image, this.canvas);
if (this.annotationData !== undefined) {
this.layers_.annotationList.getSource().addFeatures(this.annotationData);
for (var dataIndex = 0; dataIndex < this.annotationData.length; dataIndex++) {
this.layers_.annotation.getSource().addFeatures(this.annotationData[dataIndex].getAnnotations());
}
if (this.annotationData.length >0)
{
this.showAnnotationText(this.annotationData);
}
}
}
// now activate the annotation overlay and map behavior
this.enableAnnotationSelect();
dlfUtils.setCookie("tx-dlf-pageview-annotation-select", 'enabled');
$(controlEl).addClass('active');
// trigger event
$(this).trigger("activate-annotations", this);
}
deactivate() {
var controlEl = $('#tx-dlf-tools-annotations');
// deactivate annotations
this.disableAnnotationSelect();
dlfUtils.setCookie("tx-dlf-pageview-annotation-select", 'disabled');
$(controlEl).removeClass('active');
// trigger event
$(this).trigger("deactivate-annotations", this);
};
disableAnnotationSelect() {
// register event listeners
this.map.un('click', this.handlers.mapClick);
this.map.un('pointermove', this.handlers.mapHover);
// remove layers
for (var key in this.layers_) {
if (this.layers_.hasOwnProperty(key)) {
this.map.removeLayer(this.layers_[key]);
}
};
var className = 'fulltext-visible';
$("#tx-dlf-tools-annotations").removeClass(className)
.text(this.dic['annotations-on'])
.attr('title', this.dic['annotations-on']);
$('#tx-dlf-annotationselection').removeClass(className);
$('#tx-dlf-annotationselection').hide();
$('body').removeClass(className);
};
enableAnnotationSelect(textBlockFeatures, textLineFeatures) {
// register event listeners
this.map.on('click', this.handlers.mapClick);
this.map.on('pointermove', this.handlers.mapHover);
// add layers to map
for (var key in this.layers_) {
if (this.layers_.hasOwnProperty(key)) {
this.map.addLayer(this.layers_[key]);
}
};
// show annotation container
var className = 'fulltext-visible';
$("#tx-dlf-tools-annotations").addClass(className)
.text(this.dic['annotations-off'])
.attr('title', this.dic['annotations-off']);
$('#tx-dlf-annotationselection').addClass(className);
$('#tx-dlf-annotationselection').show();
$('body').addClass(className);
}
fetchAnnotationContainersFromServer(annotationContainers, image, canvas, optOffset) {
var annotationListData = [],
parser;
parser = new DlfIiifAnnotationParser(image, canvas.width, canvas.height, optOffset);
annotationContainers.forEach(function(annotationList){
var responseJson;
var request = $.ajax({
url: annotationList.uri,
async: false
});
responseJson = request.responseJSON != null ? request.responseJSON : request.responseText != null ? $.parseJSON(request.responseText) : null;
if (responseJson.label === undefined) {
responseJson.label = annotationList.label;
}
annotationListData.push(parser.parseAnnotationList(responseJson, canvas.id));
});
return annotationListData;
}
}

View File

@ -0,0 +1,204 @@
/**
* (c) Kitodo. Key to digital objects e.V. <contact@kitodo.org>
*
* This file is part of the Kitodo and TYPO3 projects.
*
* @license GNU General Public License version 3 or later.
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/
/**
* @constructor
* @param {Object=} opt_imageObj
* @param {number=} opt_width
* @param {number=} opt_height
* @param {number=} opt_offset
*/
var DlfIiifAnnotationParser = function(opt_imageObj, opt_width, opt_height, opt_offset) {
// get width and height either from image info.json or from canvas information
/**
* @type {Object|undefined}
* @private
*/
this.image_ = dlfUtils.exists(opt_imageObj) ? opt_imageObj : undefined;
/**
* @type {number|undefined}
* @private
*/
this.width_ = dlfUtils.exists(opt_width) ? opt_width : undefined;
/**
* @type {number|undefined}
* @private
*/
this.height_ = dlfUtils.exists(opt_height) ? opt_height : undefined;
/**
* @type {number|undefined}
* @private
*/
this.offset_ = dlfUtils.exists(opt_offset) ? opt_offset : undefined;
};
/**
* @param {number} width
* @param {number} height
* @param {number} hpos
* @param {number} vpos
* @private
*/
DlfIiifAnnotationParser.prototype.generateId_ = function(width, height, hpos, vpos) {
var heigt_ = isNaN(height) ? '0' : height;
return '' + width + '_' + heigt_ + '_' + hpos + '_' + vpos;
};
/**
* Create an OpenLayers Feature from a IIIF Annotation
* @param {Object} annotation
* @return {ol.Feature}
* @private
*/
DlfIiifAnnotationParser.prototype.parseAnnotation = function(annotation) {
var geometry = this.parseGeometry(annotation),
xywh = this.getXYWHForAnnotation(annotation)
id = this.generateId_(xywh.width, xywh.height, xywh.x1, xywh.y1),
feature = new ol.Feature(geometry);
feature.setId(id);
feature.setProperties({
'type': 'annotation',
'width': xywh.width,
'height': xywh.height,
'x1': xywh.x1,
'y1': xywh.y1,
'x2': xywh.x2,
'y2': xywh.y2,
'content': annotation.resource.chars
});
return feature;
};
DlfIiifAnnotationParser.prototype.parseAnnotationList = function(annotationList, currentCanvas) {
var minX, maxX, minY, maxY, annotationFeatures = [];
for (var i = 0; i < annotationList.resources.length; i++) {
var annotation = annotationList.resources[i];
var onCanvas = DlfIiifAnnotationParser.getTargetIdentifierWithoutFragment(annotation.on);
if (currentCanvas != onCanvas) continue;
var feature = this.parseAnnotation(annotation);
// Determine the dimension of the AnnotationList
minX = minX === undefined ? feature.get('x1') : minX > feature.get('x1') ? feature.get('x1') : minX;
maxX = maxX === undefined ? feature.get('x2') : maxX < feature.get('x2') ? feature.get('x2') : maxX;
minY = minY === undefined ? feature.get('y1') : minY > feature.get('y1') ? feature.get('y1') : minY;
maxY = maxY === undefined ? feature.get('y2') : maxY < feature.get('y2') ? feature.get('y2') : maxY;
annotationFeatures.push(feature);
};
var width = maxX - minX,
height = maxY - minY,
listCoordinatesWithoutScale = [[[minX, minY], [maxX, minY], [maxX, maxY], [minX, maxY], [minX, minY]]],
annotationListId = this.generateId_(width, height, minX, minY),
scale = this.image_.width / this.width_,
coordinatesRescale = [];
for (var i = 0; i < listCoordinatesWithoutScale[0].length; i++) {
coordinatesRescale.push([( scale * listCoordinatesWithoutScale[0][i][0]),
0 - (scale * listCoordinatesWithoutScale[0][i][1])]);
};
listGeometry = new ol.geom.Polygon([coordinatesRescale]);
listFeature = new ol.Feature(listGeometry);
listFeature.setId(annotationListId);
listFeature.setProperties({
'type': 'annotationList',
'label': annotationList.label != null ? annotationList.label : '',
'width': maxX - minX + 1,
'height': maxY - minY + 1,
'x1': minX,
'y1': minY,
'x2': maxX,
'y2': maxY,
'annotations': annotationFeatures
});
listFeature.getAnnotations = function() {
return annotationFeatures;
};
return listFeature;
};
DlfIiifAnnotationParser.prototype.parseGeometry = function(annotation) {
var xywh = this.getXYWHForAnnotation(annotation),
coordinatesWithoutScale = [[[xywh.x1, xywh.y1], [xywh.x2, xywh.y1], [xywh.x2, xywh.y2], [xywh.x1, xywh.y2], [xywh.x1, xywh.y1]]];
if (isNaN(xywh.width) || isNaN(xywh.height))
return undefined;
// return geometry without rescale
if (!dlfUtils.exists(this.image_) || !dlfUtils.exists(this.width_))
return new ol.geom.Polygon(coordinatesWithoutScale);
// rescale coordinates
var scale = this.image_.width / this.width_,
offset = dlfUtils.exists(this.offset_) ? this.offset_ : 0,
coordinatesRescale = [];
for (var i = 0; i < coordinatesWithoutScale[0].length; i++) {
coordinatesRescale.push([offset + ( scale * coordinatesWithoutScale[0][i][0]),
0 - (scale * coordinatesWithoutScale[0][i][1])]);
};
return new ol.geom.Polygon([coordinatesRescale]);
};
/**
* Get position and dimension from the fragment identifier of the on-uri or from the canvas dimension
* @param {Object} annotation
* @return {Object}
* @private
*/
DlfIiifAnnotationParser.prototype.getXYWHForAnnotation = function (annotation) {
var fragmentPos = annotation.on.indexOf("#xywh="),
xywh = fragmentPos > -1 ? annotation.on.substr(fragmentPos+6).split(",") : undefined;
if (xywh === undefined) return {
x1: 0,
y1: 0,
width: this.width,
height: this.height,
x2: this.width - 1,
y2: this.height - 1
};
return {
x1: parseInt(xywh[0]),
y1: parseInt(xywh[1]),
width: parseInt(xywh[2]),
height: parseInt(xywh[3]),
x2: parseInt(xywh[0]) + parseInt(xywh[2]) - 1,
y2: parseInt(xywh[1]) + parseInt(xywh[3]) - 1
};
};
/**
* Remove any fragment from the uri
* @param {string} uri
* @return {string|null}
* @private
*/
DlfIiifAnnotationParser.getTargetIdentifierWithoutFragment = function(uri) {
if (uri == null) {
return null;
}
return uri.split("#")[0];
}

View File

@ -49,6 +49,8 @@ if (!defined('DEVLOG_SEVERITY_ERROR')) {
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['dlf/Classes/Plugin/Toolbox.php']['tools'] = [];
\Kitodo\Dlf\Hooks\ExtensionManagementUtility::addPItoST43($_EXTKEY, \Kitodo\Dlf\Plugin\Tools\FulltextTool::class, '_fulltexttool', '', TRUE);
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['dlf/Classes/Plugin/Toolbox.php']['tools'][\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getCN($_EXTKEY).'_fulltexttool'] = 'LLL:EXT:dlf/Resources/Private/Language/Labels.xml:tx_dlf_toolbox.fulltexttool';
\Kitodo\Dlf\Hooks\ExtensionManagementUtility::addPItoST43($_EXTKEY, \Kitodo\Dlf\Plugin\Tools\AnnotationTool::class, '_annotationstool', '', TRUE);
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['dlf/Classes/Plugin/Toolbox.php']['tools'][\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getCN($_EXTKEY).'_annotationstool'] = 'LLL:EXT:dlf/Resources/Private/Language/Labels.xml:tx_dlf_toolbox.annotationstool';
\Kitodo\Dlf\Hooks\ExtensionManagementUtility::addPItoST43($_EXTKEY, \Kitodo\Dlf\Plugin\Tools\ImageDownloadTool::class, '_imagedownloadtool', '', TRUE);
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['dlf/Classes/Plugin/Toolbox.php']['tools'][\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getCN($_EXTKEY).'_imagedownloadtool'] = 'LLL:EXT:dlf/Resources/Private/Language/Labels.xml:tx_dlf_toolbox.imagedownloadtool';
\Kitodo\Dlf\Hooks\ExtensionManagementUtility::addPItoST43($_EXTKEY, \Kitodo\Dlf\Plugin\Tools\ImageManipulationTool::class, '_imagemanipulationtool', '', TRUE);