Security fix and preparation for release 3.2.3 - please update!
This commit is contained in:
parent
c29947b6fd
commit
835a5e9091
|
@ -624,6 +624,26 @@ class Helper
|
|||
return self::checkIdentifier($id, 'PPN');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not $url is a valid URL using HTTP or HTTPS scheme.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidHttpUrl($url)
|
||||
{
|
||||
if (!GeneralUtility::isValidUrl($url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parsed = parse_url($url);
|
||||
$scheme = $parsed['scheme'] ?? '';
|
||||
$schemeNormalized = strtolower($scheme);
|
||||
|
||||
return $schemeNormalized === 'http' || $schemeNormalized === 'https';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load value from user's session.
|
||||
*
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
namespace Kitodo\Dlf\Plugin\Eid;
|
||||
|
||||
use Kitodo\Dlf\Common\Helper;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Http\Response;
|
||||
|
@ -26,7 +27,6 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|||
*/
|
||||
class PageViewProxy
|
||||
{
|
||||
|
||||
/**
|
||||
* The main method of the eID script
|
||||
*
|
||||
|
@ -37,29 +37,29 @@ class PageViewProxy
|
|||
*/
|
||||
public function main(ServerRequestInterface $request)
|
||||
{
|
||||
// header parameter for getUrl(); allowed values 0,1,2; default 0
|
||||
$header = (int) $request->getQueryParams()['header'];
|
||||
$header = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($header, 0, 2, 0);
|
||||
|
||||
// the URI to fetch data or header from
|
||||
$url = (string) $request->getQueryParams()['url'];
|
||||
if (!GeneralUtility::isValidUrl($url)) {
|
||||
if (!Helper::isValidHttpUrl($url)) {
|
||||
throw new \InvalidArgumentException('No valid url passed!', 1580482805);
|
||||
}
|
||||
|
||||
// fetch the requested data or header
|
||||
$fetchedData = GeneralUtility::getUrl($url, $header);
|
||||
// get and verify the uHash
|
||||
$uHash = (string) $request->getQueryParams()['uHash'];
|
||||
if (!hash_equals(GeneralUtility::hmac($url, 'PageViewProxy'), $uHash)) {
|
||||
throw new \InvalidArgumentException('No valid uHash passed!', 1643796565);
|
||||
}
|
||||
|
||||
// fetch the requested data
|
||||
$fetchedData = GeneralUtility::getUrl($url);
|
||||
|
||||
// Fetch header data separately to get "Last-Modified" info
|
||||
if ($header === 0) {
|
||||
$fetchedHeaderString = GeneralUtility::getUrl($url, 2);
|
||||
if (!empty($fetchedHeaderString)) {
|
||||
$fetchedHeader = explode("\n", $fetchedHeaderString);
|
||||
foreach ($fetchedHeader as $headerline) {
|
||||
if (stripos($headerline, 'Last-Modified:') !== false) {
|
||||
$lastModified = trim(substr($headerline, strpos($headerline, ':') + 1));
|
||||
break;
|
||||
}
|
||||
$fetchedHeaderString = GeneralUtility::getUrl($url, 2);
|
||||
if (!empty($fetchedHeaderString)) {
|
||||
$fetchedHeader = explode("\n", $fetchedHeaderString);
|
||||
foreach ($fetchedHeader as $headerline) {
|
||||
if (stripos($headerline, 'Last-Modified:') !== false) {
|
||||
$lastModified = trim(substr($headerline, strpos($headerline, ':') + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ class PageViewProxy
|
|||
$response = $response->withHeader('Access-Control-Max-Age', '86400');
|
||||
$response = $response->withHeader('Content-Type', finfo_buffer(finfo_open(FILEINFO_MIME), $fetchedData));
|
||||
}
|
||||
if ($header === 0 && !empty($lastModified)) {
|
||||
if (!empty($lastModified)) {
|
||||
$response = $response->withHeader('Last-Modified', $lastModified);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ class PageView extends \Kitodo\Dlf\Common\AbstractPlugin
|
|||
'parameter' => $GLOBALS['TSFE']->id,
|
||||
'forceAbsoluteUrl' => !empty($this->conf['forceAbsoluteUrl']) ? 1 : 0,
|
||||
'forceAbsoluteUrl.' => ['scheme' => !empty($this->conf['forceAbsoluteUrl']) && !empty($this->conf['forceAbsoluteUrlHttps']) ? 'https' : 'http'],
|
||||
'additionalParams' => '&eID=tx_dlf_pageview_proxy&url=' . urlencode($image['url']),
|
||||
'additionalParams' => '&eID=tx_dlf_pageview_proxy&url=' . urlencode($image['url']) . '&uHash=' . GeneralUtility::hmac($image['url'], 'PageViewProxy'),
|
||||
];
|
||||
$image['url'] = $this->cObj->typoLink_URL($linkConf);
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ class PageView extends \Kitodo\Dlf\Common\AbstractPlugin
|
|||
'parameter' => $GLOBALS['TSFE']->id,
|
||||
'forceAbsoluteUrl' => !empty($this->conf['forceAbsoluteUrl']) ? 1 : 0,
|
||||
'forceAbsoluteUrl.' => ['scheme' => !empty($this->conf['forceAbsoluteUrl']) && !empty($this->conf['forceAbsoluteUrlHttps']) ? 'https' : 'http'],
|
||||
'additionalParams' => '&eID=tx_dlf_pageview_proxy&url=' . urlencode($fulltext['url']),
|
||||
'additionalParams' => '&eID=tx_dlf_pageview_proxy&url=' . urlencode($fulltext['url']) . '&uHash=' . GeneralUtility::hmac($fulltext['url'], 'PageViewProxy'),
|
||||
];
|
||||
$fulltext['url'] = $this->cObj->typoLink_URL($linkConf);
|
||||
}
|
||||
|
|
|
@ -175,6 +175,7 @@
|
|||
<label index="tt_content.dlf_toolbox">DLF: Toolbox</label>
|
||||
<label index="tt_content.dlf_validator">DLF: Validator</label>
|
||||
<label index="config.metadataFormats">Default metadata namespaces</label>
|
||||
<label index="config.enableInternalProxy">Enable internal page view proxy?: (default is "FALSE")</label>
|
||||
<label index="config.useragent">DLF User-Agent: (default is "Kitodo.Presentation")</label>
|
||||
<label index="config.forceAbsoluteUrl">Force all links to pages and resources to be absolute?: Only needed for some multi-domain environments; requires a fully qualified Entry Point in Site Configuration (default is "FALSE")</label>
|
||||
<label index="config.forceAbsoluteUrlHttps">Use HTTPS for absolute links?: requires a valid Entry Point with "https://..." in Site Configuration (default is "FALSE")</label>
|
||||
|
@ -360,6 +361,7 @@
|
|||
<label index="tt_content.dlf_toolbox">DLF: Werkzeugkasten</label>
|
||||
<label index="tt_content.dlf_validator">DLF: Validator</label>
|
||||
<label index="config.metadataFormats">Standard-Namensräume für Metadaten</label>
|
||||
<label index="config.enableInternalProxy">Internen Proxy für Werkansicht aktivieren? (Standard ist "FALSE")</label>
|
||||
<label index="config.useragent">DLF User-Agent: (Standard ist "Kitodo.Presentation")</label>
|
||||
<label index="config.forceAbsoluteUrl">Verwende nur absolute Links für Seiten und Ressourcen?: Wird nur in speziellen Multi-Domain-Umgebungen benötigt; erfordert einen voll qualifizierten Einstiegspunkt in der Seitenkonfiguration (Standard ist "FALSE")</label>
|
||||
<label index="config.forceAbsoluteUrlHttps">Verwende HTTPS for absolute Links?: erfordert einen Einstiegspunkt mit "https://..." in der Seitenkonfiguration (Standard ist "FALSE")</label>
|
||||
|
|
|
@ -9,17 +9,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Right know the image manipulation uses an own ol.Map object based on a webgl renderer. This is due to the fact
|
||||
* that other parts of the viewer application are using vector geometries and ol3 does only support full vector
|
||||
* renderering with the canvas and dom renderer yet. In contrast the image manipulation tool is only working
|
||||
* with a webgl renderer. Therefore it uses an own ol.Map object which is overlaid and synchronized with the
|
||||
* base ol.Map object.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object=} options Control options.
|
||||
* {Array.<ol.layer.Layer>} layers
|
||||
* {Element} target
|
||||
* {ol.View} view
|
||||
* {ol.Map} map
|
||||
*/
|
||||
dlfViewerImageManipulationControl = function(options) {
|
||||
|
@ -32,30 +24,12 @@ dlfViewerImageManipulationControl = function(options) {
|
|||
dlfUtils.parseDataDic($('#tx-dlf-tools-imagetools')) :
|
||||
{'imagemanipulation-on':'Activate image manipulation', 'imagemanipulation-off':'Deactivate image manipulation', 'saturation':'Saturation', 'hue':'Hue', 'brightness':'Brightness', 'contrast':'Contrast', 'reset':'Reset', 'invert':'Color inverting', 'parentContainer':'.tx-dlf-imagemanipulationtool'};
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.layer.Layer>}
|
||||
* @private
|
||||
*/
|
||||
this.layers = options.layers;
|
||||
|
||||
/**
|
||||
* @type {ol.Map}
|
||||
* @private
|
||||
*/
|
||||
this.baseMap_ = options.map;
|
||||
|
||||
/**
|
||||
* @type {ol.Map|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.map_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {ol.View}
|
||||
* @private
|
||||
*/
|
||||
this.view_ = options.view;
|
||||
|
||||
/**
|
||||
* @type {Element}
|
||||
* @private
|
||||
|
@ -73,6 +47,12 @@ dlfViewerImageManipulationControl = function(options) {
|
|||
*/
|
||||
this.toolContainerEl_ = dlfUtils.exists(options.toolContainer) ? options.toolContainer : $(this.dic['parentContainer'])[0];
|
||||
|
||||
/**
|
||||
* @type {HTMLCanvasElement}
|
||||
*
|
||||
*/
|
||||
this.canvas_ = this.baseMap_.getTargetElement().querySelector('canvas');
|
||||
|
||||
//
|
||||
// Append open/close behavior to toolbox
|
||||
//
|
||||
|
@ -95,8 +75,8 @@ dlfViewerImageManipulationControl = function(options) {
|
|||
var FILTERS_DEFAULT_ = {
|
||||
'brightness': 1,
|
||||
'contrast': 1,
|
||||
'hue': 0,
|
||||
'saturation': 0
|
||||
'hue-rotate': 0,
|
||||
'saturate': 0
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -105,47 +85,14 @@ dlfViewerImageManipulationControl = function(options) {
|
|||
*/
|
||||
this.filters_ = $.extend({}, FILTERS_DEFAULT_);
|
||||
|
||||
/**
|
||||
* Is filter updated
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.filterUpdated_ = false;
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
this.handler_ = {
|
||||
'postcomposeImageFilter': $.proxy(function (event) {
|
||||
var webglContext = event['glContext'],
|
||||
canvas = $('#' + this.map_.getTargetElement().id + ' canvas.ol-unselectable')[0];
|
||||
|
||||
if (webglContext !== undefined && webglContext !== null) {
|
||||
var gl = webglContext.getGL();
|
||||
|
||||
if (this.filterUpdated_) {
|
||||
|
||||
glif.reset();
|
||||
|
||||
for (var filter in this.filters_) {
|
||||
glif.addFilter(filter, this.filters_[String(filter)]);
|
||||
};
|
||||
|
||||
this.filterUpdated_ = false;
|
||||
}
|
||||
|
||||
glif.apply(gl, canvas);
|
||||
|
||||
// for showing openlayers that the program changed
|
||||
// if missing openlayers will produce errors because it
|
||||
// expected other shaders in the webgl program
|
||||
webglContext.useProgram(undefined);
|
||||
}
|
||||
}, this),
|
||||
'resetFilter': $.proxy(function(event) {
|
||||
'resetFilter': $.proxy(function() {
|
||||
// reset the checked filters
|
||||
if (this.filters_.hasOwnProperty('invert')) {
|
||||
if (this.filters_['invert']) {
|
||||
$('#invert-filter').click();
|
||||
}
|
||||
|
||||
|
@ -162,30 +109,47 @@ dlfViewerImageManipulationControl = function(options) {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Set filter style property on map canvas.
|
||||
*
|
||||
* @param {string} filters
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.setCssFilter_ = function (filters) {
|
||||
this.canvas_.style.filter = filters;
|
||||
this.canvas_.style.webkitFilter = filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.applyFilters_ = function () {
|
||||
var filters = '';
|
||||
|
||||
for (var filter in this.filters_) {
|
||||
if (!this.filters_.hasOwnProperty(filter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var cssValue = this.valueToCss_(filter, this.filters_[filter]);
|
||||
if (cssValue === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
filters += filter + '(' + cssValue + ') ';
|
||||
}
|
||||
|
||||
this.setCssFilter_(filters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Activates the image manipulation tool
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.activate = function(){
|
||||
// Apply filters from last time
|
||||
this.applyFilters_();
|
||||
|
||||
//
|
||||
// Toggle maps
|
||||
//
|
||||
$.when($(this.baseMap_.getTargetElement())
|
||||
// fadeOut the base map container
|
||||
.hide())
|
||||
// fadeIn image map container
|
||||
.done($.proxy(function(){
|
||||
if (!dlfUtils.exists(this.map_)) {
|
||||
// create map container and map object if not exists yet
|
||||
this.createMap_();
|
||||
}
|
||||
|
||||
// Show map
|
||||
$(this.map_.getTargetElement()).show();
|
||||
|
||||
// trigger open event
|
||||
$(this).trigger("activate-imagemanipulation", this.map_);
|
||||
}, this));
|
||||
$(this).trigger("activate-imagemanipulation", this.baseMap_);
|
||||
|
||||
//
|
||||
// Toggle toolbox controls
|
||||
|
@ -199,10 +163,6 @@ dlfViewerImageManipulationControl.prototype.activate = function(){
|
|||
this.createFilters_();
|
||||
}
|
||||
$(this.sliderContainer_).show().addClass('open');
|
||||
|
||||
// add postcompose listener to layers
|
||||
if (this.map_ !== undefined)
|
||||
this.map_.on('postcompose', this.handler_.postcomposeImageFilter);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -230,7 +190,7 @@ dlfViewerImageManipulationControl.prototype.createFilters_ = function() {
|
|||
[1, 0, 2, 0.01], this.dic['contrast'], function(v) {
|
||||
return parseInt(v * 100 - 100);
|
||||
}),
|
||||
saturationSlider = this.createSlider_('slider-saturation', 'horizontal', 'saturation',
|
||||
saturationSlider = this.createSlider_('slider-saturation', 'horizontal', 'saturate',
|
||||
[0, -1, 1, 0.01], this.dic['saturation'], function(v) {
|
||||
return parseInt(v * 100);
|
||||
}),
|
||||
|
@ -238,7 +198,7 @@ dlfViewerImageManipulationControl.prototype.createFilters_ = function() {
|
|||
[1, 0, 2, 0.1], this.dic['brightness'],function(v) {
|
||||
return parseInt(v * 100 - 100);
|
||||
}),
|
||||
hueSlider = this.createSlider_('slider-hue', 'horizontal', 'hue',
|
||||
hueSlider = this.createSlider_('slider-hue', 'horizontal', 'hue-rotate',
|
||||
[0, -180, 180, 5], this.dic['hue'], function(v) {
|
||||
return parseInt(v);
|
||||
});
|
||||
|
@ -252,19 +212,10 @@ dlfViewerImageManipulationControl.prototype.createFilters_ = function() {
|
|||
$(this.sliderContainer_).append($('<div class="checkbox"><label><input type="checkbox" id="' + elFilterId + '">' +
|
||||
this.dic['invert'] + '</label></div>'));
|
||||
$('#' + elFilterId).on('click', $.proxy(function(event) {
|
||||
if (event.target.checked === true && !this.filters_.hasOwnProperty('invert')) {
|
||||
// if checked add the invert filter to the filters
|
||||
this.filters_['invert'] = true;
|
||||
} else {
|
||||
// remove invert filter
|
||||
if (this.filters_.hasOwnProperty('invert')) {
|
||||
delete this.filters_['invert'];
|
||||
}
|
||||
}
|
||||
var invert = event.target.checked;
|
||||
|
||||
// update filter chain
|
||||
this.filterUpdated_ = true;
|
||||
this.layers[0].changed();
|
||||
this.setFilter_('invert', invert);
|
||||
}, this));
|
||||
|
||||
// button for reset to default state
|
||||
|
@ -273,72 +224,6 @@ dlfViewerImageManipulationControl.prototype.createFilters_ = function() {
|
|||
$(resetBtn).on('click', this.handler_.resetFilter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the map object used from the image manipulation tool and bind it to the baseMap
|
||||
* @private
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.createMap_ = function() {
|
||||
var mapEl_ = $('<div id="tx-dlf-map-manipulate" class="tx-dlf-map"></div>');
|
||||
$(this.baseMap_.getTargetElement().parentElement).append(mapEl_);
|
||||
|
||||
this.map_ = new ol.Map({
|
||||
layers: this.layers,
|
||||
target: mapEl_[0].id,
|
||||
controls: [],
|
||||
interactions: [
|
||||
new ol.interaction.DragRotate(),
|
||||
new ol.interaction.DragPan(),
|
||||
new ol.interaction.DragZoom(),
|
||||
new ol.interaction.PinchRotate(),
|
||||
new ol.interaction.PinchZoom(),
|
||||
new ol.interaction.MouseWheelZoom(),
|
||||
new ol.interaction.KeyboardPan(),
|
||||
new ol.interaction.KeyboardZoom(),
|
||||
new ol.interaction.DragRotateAndZoom()
|
||||
],
|
||||
// necessary for proper working of the keyboard events
|
||||
keyboardEventTarget: document,
|
||||
view: this.view_,
|
||||
renderer: 'webgl'
|
||||
});
|
||||
|
||||
// couple map behavior with baseMap
|
||||
var adjustViews = function(sourceView, destMap) {
|
||||
var rotateDiff = sourceView.getRotation() !== destMap.getView().getRotation();
|
||||
var resDiff = sourceView.getResolution() !== destMap.getView().getResolution();
|
||||
var centerDiff = sourceView.getCenter() !== destMap.getView().getCenter();
|
||||
|
||||
if (rotateDiff || resDiff || centerDiff) {
|
||||
destMap.zoomTo(sourceView.getCenter(),sourceView.getZoom(), 50);
|
||||
destMap.getView().rotate(sourceView.getRotation());
|
||||
}
|
||||
|
||||
},
|
||||
adjustViewHandler = function(event) {
|
||||
adjustViews(event.target, this);
|
||||
};
|
||||
|
||||
// when deactivate / activate adjust both map centers / zoom
|
||||
$(this).on("activate-imagemanipulation", $.proxy(function(event, map) {
|
||||
// pass change events for resolution and rotation to image manipulation map
|
||||
// created through external view controls
|
||||
this.baseMap_.getView().on('change:resolution', adjustViewHandler, this.map_);
|
||||
this.baseMap_.getView().on('change:rotation', adjustViewHandler, this.map_);
|
||||
|
||||
// adjust the view of both maps
|
||||
adjustViews(this.baseMap_.getView(), this.map_);
|
||||
}, this));
|
||||
$(this).on("deactivate-imagemanipulation", $.proxy(function(event, map) {
|
||||
// pass change events for resolution and rotation to image manipulation map
|
||||
// created through external view controls
|
||||
this.baseMap_.getView().un('change:resolution', adjustViewHandler, this.map_);
|
||||
this.baseMap_.getView().un('change:rotation', adjustViewHandler, this.map_);
|
||||
|
||||
// adjust the view of both maps
|
||||
adjustViews(this.map_.getView(), this.baseMap_);
|
||||
}, this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Functions creates a slider + behavior.
|
||||
*
|
||||
|
@ -366,7 +251,6 @@ dlfViewerImageManipulationControl.prototype.createSlider_ = function(className,
|
|||
*/
|
||||
var update = $.proxy(function(event, ui){
|
||||
var value = ui['value'],
|
||||
layer = this.layers[0],
|
||||
element = valueEl[0],
|
||||
labelValue = dlfUtils.exists(opt_labelFn) ? opt_labelFn(value) : value + '%';
|
||||
|
||||
|
@ -382,9 +266,7 @@ dlfViewerImageManipulationControl.prototype.createSlider_ = function(className,
|
|||
element.innerHTML = labelValue;
|
||||
|
||||
// update filters.
|
||||
this.filters_[key] = value;
|
||||
this.filterUpdated_ = true;
|
||||
layer.changed();
|
||||
this.setFilter_(key, value);
|
||||
}, this);
|
||||
|
||||
$(sliderEl).slider({
|
||||
|
@ -410,12 +292,7 @@ dlfViewerImageManipulationControl.prototype.createSlider_ = function(className,
|
|||
* Deactivates the image manipulation control
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.deactivate = function(){
|
||||
|
||||
// toggle maps
|
||||
if (dlfUtils.exists(this.map_)) {
|
||||
$(this.map_.getTargetElement()).hide();
|
||||
}
|
||||
$(this.baseMap_.getTargetElement()).show();
|
||||
this.setCssFilter_("");
|
||||
|
||||
// toggle view of image manipulation control element
|
||||
$(this.anchor_).removeClass('active')
|
||||
|
@ -424,10 +301,6 @@ dlfViewerImageManipulationControl.prototype.deactivate = function(){
|
|||
|
||||
$(this.sliderContainer_).hide().removeClass('open');
|
||||
|
||||
// remove postcompose listener to map
|
||||
if (this.map_ !== undefined)
|
||||
this.map_.un('postcompose', this.handler_.postcomposeImageFilter);
|
||||
|
||||
// trigger close event for trigger map adjust behavior
|
||||
$(this).trigger("deactivate-imagemanipulation");
|
||||
};
|
||||
|
@ -440,3 +313,39 @@ dlfViewerImageManipulationControl.prototype.deactivate = function(){
|
|||
dlfViewerImageManipulationControl.prototype.isActive = function() {
|
||||
return $(this.anchor_).hasClass('active');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} filter The filter to set
|
||||
* @param {string} value The value to set the filter to
|
||||
* @private
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.setFilter_ = function (filter, value) {
|
||||
this.filters_[filter] = value;
|
||||
this.applyFilters_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert filter value to its CSS representation.
|
||||
*
|
||||
* @param {string} filter
|
||||
* @param {number} value
|
||||
* @private
|
||||
* @return {string}
|
||||
*/
|
||||
dlfViewerImageManipulationControl.prototype.valueToCss_ = function (filter, value) {
|
||||
switch (filter) {
|
||||
case 'contrast':
|
||||
case 'brightness':
|
||||
return (value * 100).toString() + '%';
|
||||
|
||||
case 'saturate':
|
||||
return ((value + 1) * 100).toString() + '%';
|
||||
|
||||
case 'hue-rotate':
|
||||
return value + 'deg';
|
||||
|
||||
case 'invert':
|
||||
return value ? '100%' : '0%';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,18 +191,12 @@ dlfViewer.prototype.addCustomControls = function() {
|
|||
//
|
||||
// Add image manipulation tool if container is added.
|
||||
//
|
||||
// It is important to know that the image manipulation tool uses a webgl renderer as basis. Therefor the
|
||||
// application has as first to check if the renderer is active. Further it has to check if cors supported through
|
||||
// image.
|
||||
//
|
||||
if ($('#tx-dlf-tools-imagetools').length > 0 && dlfUtils.isWebGLEnabled() && this.isCorsEnabled) {
|
||||
if ($('#tx-dlf-tools-imagetools').length > 0) {
|
||||
|
||||
// should be called if cors is enabled
|
||||
imageManipulationControl = new dlfViewerImageManipulationControl({
|
||||
controlTarget: $('.tx-dlf-tools-imagetools')[0],
|
||||
layers: dlfUtils.createOl3Layers(images, '*'),
|
||||
map: this.map,
|
||||
view: dlfUtils.createOl3View(images)
|
||||
});
|
||||
|
||||
// bind behavior of both together
|
||||
|
@ -218,11 +212,6 @@ dlfViewer.prototype.addCustomControls = function() {
|
|||
// set on object scope
|
||||
this.imageManipulationControl = imageManipulationControl;
|
||||
|
||||
} else if ($('#tx-dlf-tools-imagetools').length > 0) {
|
||||
|
||||
// hide the element because the functionality is not supported through missing webgl or cors support.
|
||||
$('#tx-dlf-tools-imagetools').addClass('deactivate');
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -385,17 +374,7 @@ dlfViewer.prototype.init = function(controlNames) {
|
|||
if (this.imageUrls.length <= 0)
|
||||
throw new Error('Missing image source objects.');
|
||||
|
||||
/**
|
||||
* Is cors enabled. Important information for correct renderer and layer initialization
|
||||
* @type {boolean}
|
||||
*/
|
||||
if (this.useInternalProxy) {
|
||||
this.isCorsEnabled = true;
|
||||
} else {
|
||||
this.isCorsEnabled = dlfUtils.isCorsEnabled(this.imageUrls);
|
||||
}
|
||||
|
||||
this.initLayer(this.imageUrls, this.isCorsEnabled)
|
||||
this.initLayer(this.imageUrls)
|
||||
.done($.proxy(function(layers){
|
||||
|
||||
var controls = controlNames.length > 0 || controlNames[0] === ""
|
||||
|
@ -483,11 +462,10 @@ dlfViewer.prototype.init = function(controlNames) {
|
|||
* Function generate the ol3 layer objects for given image sources. Returns a promise.
|
||||
*
|
||||
* @param {Array.<{url: *, mimetype: *}>} imageSourceObjs
|
||||
* @param {boolean} isCorsEnabled
|
||||
* @return {jQuery.Deferred.<function(Array.<ol.layer.Layer>)>}
|
||||
* @private
|
||||
*/
|
||||
dlfViewer.prototype.initLayer = function(imageSourceObjs, isCorsEnabled) {
|
||||
dlfViewer.prototype.initLayer = function(imageSourceObjs) {
|
||||
|
||||
// use deferred for async behavior
|
||||
var deferredResponse = new $.Deferred(),
|
||||
|
@ -498,12 +476,11 @@ dlfViewer.prototype.initLayer = function(imageSourceObjs, isCorsEnabled) {
|
|||
resolveCallback = $.proxy(function(imageSourceData, layers) {
|
||||
this.images = imageSourceData;
|
||||
deferredResponse.resolve(layers);
|
||||
}, this),
|
||||
origin = isCorsEnabled ? '*' : undefined;
|
||||
}, this);
|
||||
|
||||
dlfUtils.fetchImageData(imageSourceObjs)
|
||||
.done(function(imageSourceData) {
|
||||
resolveCallback(imageSourceData, dlfUtils.createOl3Layers(imageSourceData, origin));
|
||||
resolveCallback(imageSourceData, dlfUtils.createOl3Layers(imageSourceData));
|
||||
});
|
||||
|
||||
return deferredResponse;
|
||||
|
|
|
@ -716,72 +716,6 @@ dlfUtils.isNullEmptyUndefinedOrNoNumber = function (val) {
|
|||
return val === null || val === undefined || val === '' || isNaN(val);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array.<{url: *, mimetype: *}>} imageObjs
|
||||
* @return {boolean}
|
||||
*/
|
||||
dlfUtils.isCorsEnabled = function (imageObjs) {
|
||||
// fix for proper working with ie
|
||||
if (!window.location.origin) {
|
||||
window.location.origin = window.location.protocol + '//' + window.location.hostname +
|
||||
(window.location.port ? ':' + window.location.port : '');
|
||||
}
|
||||
|
||||
// fetch data from server
|
||||
// with access control allowed
|
||||
var response = true;
|
||||
|
||||
imageObjs.forEach(function (imageObj) {
|
||||
var url = imageObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.ZOOMIFY
|
||||
? imageObj.url.replace('ImageProperties.xml', 'TileGroup0/0-0-0.jpg')
|
||||
:
|
||||
imageObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIIF
|
||||
? dlfViewerSource.IIIF.getMetdadataURL(imageObj.url)
|
||||
: imageObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIP
|
||||
? dlfViewerSource.IIP.getMetdadataURL(imageObj.url)
|
||||
: imageObj.url;
|
||||
|
||||
url = window.location.origin + window.location.pathname + '?eID=tx_dlf_pageview_proxy&url=' + encodeURIComponent(url) + '&header=2';
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
async: false
|
||||
}).done(function (data, type) {
|
||||
response = type === 'success' && data.indexOf('Access-Control-Allow-Origin') !== -1;
|
||||
}).fail(function (data, type) {
|
||||
response = false;
|
||||
});
|
||||
});
|
||||
return response;
|
||||
};
|
||||
|
||||
/**
|
||||
* Functions checks if WebGL is enabled in the browser
|
||||
* @return {boolean}
|
||||
*/
|
||||
dlfUtils.isWebGLEnabled = function () {
|
||||
if (!!window.WebGLRenderingContext) {
|
||||
var canvas = document.createElement("canvas"),
|
||||
rendererNames = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"],
|
||||
context = false;
|
||||
|
||||
for (var i = 0; i < rendererNames.length; i++) {
|
||||
try {
|
||||
context = canvas.getContext(rendererNames[i]);
|
||||
if (context && typeof context.getParameter === "function") {
|
||||
// WebGL is enabled;
|
||||
return true;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
// WebGL not supported
|
||||
return false;
|
||||
}
|
||||
|
||||
// WebGL not supported
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Element} element
|
||||
* @return {Object}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# cat=Basic; type=user[Kitodo\Dlf\Hooks\ConfigurationForm->checkMetadataFormats]; label=LLL:EXT:dlf/Resources/Private/Language/Labels.xml:config.metadataFormats
|
||||
metadataFormats = 0
|
||||
# cat=Basic; type=boolean; label=LLL:EXT:dlf/Resources/Private/Language/Labels.xml:config.enableInternalProxy
|
||||
enableInternalProxy = 0
|
||||
# cat=Basic; type=string; label=LLL:EXT:dlf/Resources/Private/Language/Labels.xml:config.useragent
|
||||
useragent = Kitodo.Presentation
|
||||
# cat=Basic; type=boolean; label=LLL:EXT:dlf/Resources/Private/Language/Labels.xml:config.forceAbsoluteUrl
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
$EM_CONF[$_EXTKEY] = [
|
||||
'title' => 'Kitodo.Presentation',
|
||||
'description' => 'Base plugins, modules, services and API of the Digital Library Framework. It is part of the community-based Kitodo Digitization Suite.',
|
||||
'version' => '3.2.2',
|
||||
'version' => '3.2.3',
|
||||
'category' => 'misc',
|
||||
'constraints' => [
|
||||
'depends' => [
|
||||
|
|
|
@ -220,7 +220,12 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['dlf/Classes/Common/MetsDocument.php']
|
|||
// Register AJAX eID handlers.
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['tx_dlf_search_suggest'] = \Kitodo\Dlf\Plugin\Eid\SearchSuggest::class . '::main';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['tx_dlf_search_in_document'] = \Kitodo\Dlf\Plugin\Eid\SearchInDocument::class . '::main';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['tx_dlf_pageview_proxy'] = \Kitodo\Dlf\Plugin\Eid\PageViewProxy::class . '::main';
|
||||
|
||||
$extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
|
||||
if (!empty($extConf) && $extConf['enableInternalProxy']) {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['tx_dlf_pageview_proxy'] = \Kitodo\Dlf\Plugin\Eid\PageViewProxy::class . '::main';
|
||||
}
|
||||
|
||||
// Use Caching Framework for Solr queries
|
||||
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_dlf_solr'])) {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_dlf_solr'] = [];
|
||||
|
|
Loading…
Reference in New Issue