import { Resources } from '../../resources/resources';
import { checkBrowserCompatibility } from '../../view/helpers';
import { GalleryRenderOptions, Events, DragDropMimeType, parseDragData, getBarcodeUrl, getSnapshotUrl, getThumbnailUrl } from './components';
import { default as Ps } from 'perfect-scrollbar';
import 'perfect-scrollbar/css/perfect-scrollbar.css';
import $ from 'jquery';
// find the currently visible images for horizontal scrolling and loads them
function loadVisibleX() {
var rail = $(this.element).find(".ps__rail-x");
var left = -Infinity;
var right = Infinity;
if (rail && rail.position()) {
left = rail.position().left;
right = left + rail.width();
}
if (left === 0 && right === 0) {
left = -Infinity;
right = Infinity;
}
var self = this;
$(this.element).find("li.lazy").each(function () {
var el = $(this);
var elLeft = el.position().left;
var elRight = elLeft + el.width();
if (!(elLeft > right || elRight < left)) {
loadImage.call(self, el);
}
});
}
// find the currently visible images for vertical scrolling and loads them
function loadVisibleY() {
var rail = $(this.element).find(".ps__rail-y");
var top = -Infinity;
var bottom = Infinity;
if (rail && rail.position()) {
top = rail.position().top;
bottom = top + rail.height();
}
if (top === bottom) {
top = -Infinity;
bottom = Infinity;
}
var self = this;
$(this.element).find("li.lazy").each(function () {
var el = $(this);
var elTop = el.position().top;
var elBottom = elTop + el.height();
if (!(elTop > bottom || elBottom < top)) {
loadImage.call(self, el);
}
});
}
// lazy loading background images
function loadImage(li) {
var self = this;
li.removeClass("lazy");
var div = li.find("div[data-img]");
var src = div.data("img");
var rot = div.data("rotation");
$("<img />").bind("load", function () {
li.removeClass("loading");
div.css("background-image", "url(\"" + src + "\")");
if (self.mode === "vertical") {
div.css("width", "100%");
}
else {
div.css("width", self.thumbnailWidth + "px");
}
div.css("height", self.thumbnailHeight + "px");
div.css("margin", "0 auto");
if (rot) {
var w = this.width;
var h = this.height;
var rad = rot / (180 / Math.PI);
var factorWidth = w / (w * Math.abs(Math.cos(rad)) + h * Math.abs(Math.sin(rad)));
var factorHeight = h / (w * Math.abs(Math.sin(rad)) + h * Math.abs(Math.cos(rad)));
div.css("transform", "rotate(" + rot + "deg) scale(" + Math.min(factorWidth, factorHeight) + ")");
}
}).bind("error", function () {
li.removeClass("loading");
div.addClass("no-image");
div.html(Resources.translate("Failed to load image"));
if (self.mode === "vertical") {
div.css("width", "100%");
}
else {
div.css("width", self.thumbnailWidth + "px");
}
div.css("height", self.thumbnailHeight + "px");
div.css("margin", "0 auto");
div.css("padding-top", (self.thumbnailHeight / 3) + "px");
var a = li.find("a");
var serverUrl = a.data("server");
var path = a.data("path");
self.fireEvent(Events.SlideInfoError, { serverUrl: serverUrl, path: path });
}).attr("src", src);
var showBarcodeNormal = this.renderOptions == GalleryRenderOptions.All;
if (!showBarcodeNormal) {
return;
}
var a = li.find("a");
var serverUrl = a.data("server");
var path = a.data("path");
this.context.getImageInfo.call(
this.context,
serverUrl,
path,
function (sessionId, imageInfo) {
var hasBarcode = imageInfo.AssociatedImageTypes.indexOf("Barcode") > -1;
if (!hasBarcode) {
return;
}
// load barcode if it exists
var barcodeImage = li.find("img.barcode");
if (barcodeImage.length !== 0) {
barcodeImage.bind("error", function () {
barcodeImage.hide();
});
barcodeImage.attr("src", barcodeImage.data("src"));
barcodeImage.css("width", Math.round(self.thumbnailWidth * 0.4) + "px");
barcodeImage.css("display", "block");
barcodeImage.removeClass("hidden");
}
},
function () {
}
);
}
function imageClick(element, fromUserInteraction) {
var $el = $(element);
var alreadySelected = $el.parent().hasClass("selected");
if (alreadySelected) {
$el.parent().removeClass("selected");
this.fireEvent(Events.SlideDeSelected, { serverUrl: $el.data("server"), path: $el.data("path"), index: $el.parent().index(), userInteraction: fromUserInteraction === true });
}
if (!this.multiSelect) {
$(this.element).find("ul li").removeClass("selected");
}
if (!alreadySelected) {
$el.parent().addClass("selected");
this.fireEvent(Events.SlideSelected, { serverUrl: $el.data("server"), path: $el.data("path"), index: $el.parent().index(), userInteraction: fromUserInteraction === true });
}
}
function printMessage(message) {
var style = " style=' ";
if (this.thumbnailHeight > 0) {
style += "height: " + this.thumbnailHeight + "px!important; ";
}
style += "' ";
this.element.innerHTML = "<ul><li class='empty-message' " + style + "><span>" + message + "</span></li></ul>";
}
function renderImages(serverUrl, sessionId, images, doneCb, append) {
var _this = this;
if (images.length === 0) {
printMessage.call(_this, Resources.translate("No images found"));
if (typeof doneCb === "function") {
doneCb();
}
return;
}
// var showBarcodeNormal = this.renderOptions == GalleryRenderOptions.All;
var showBarcodeOnly = this.renderOptions == GalleryRenderOptions.Barcode;
var imagesObj = [];
for (var i = 0; i < images.length; i++) {
var img = { path: images[i], hasBarcode: true, rotation: 0 };
// if (typeof images[i] === 'object' && images[i].hasOwnProperty('path')) {
if (typeof images[i] === 'object' && Object.prototype.hasOwnProperty.call(images[i], 'path')) {
img.path = images[i].path;
}
// if (typeof images[i] === 'object' && images[i].hasOwnProperty('rotation')) {
if (typeof images[i] === 'object' && Object.prototype.hasOwnProperty.call(images[i], 'rotation')) {
img.rotation = images[i].rotation;
}
// if (typeof images[i] === 'object' && images[i].hasOwnProperty('snapshotParameters')) {
if (typeof images[i] === 'object' && Object.prototype.hasOwnProperty.call(images[i], 'snapshotParameters')) {
img.snapshotParameters = images[i].snapshotParameters;
}
img.hasBarcode = true;
imagesObj.push(img);
}
if (showBarcodeOnly) {
this.context.getImagesInfo({
serverUrl: serverUrl, images: imagesObj.map(function (r) { return r.path; }), success: function (sessionId, imagesInfo) {
for (var i = 0; i < imagesInfo.length; i++) {
var hasBarcode = imagesInfo[i].AssociatedImageTypes.indexOf("Barcode") > -1;
for (var j = 0; j < imagesObj.length; j++) {
if (imagesObj[j].path == imagesInfo[i].Filename) {
imagesObj[j].hasBarcode = hasBarcode;
break;
}
}
}
continueRenderImages.call(_this, serverUrl, sessionId, imagesObj, doneCb, append);
},
failure: function () {
continueRenderImages.call(_this, serverUrl, sessionId, imagesObj, doneCb, append);
}
});
}
else {
continueRenderImages.call(_this, serverUrl, sessionId, imagesObj, doneCb, append);
}
}
function continueRenderImages(serverUrl, sessionId, imagesObj, doneCb, append) {
var _this = this;
var showBarcodeNormal = this.renderOptions == GalleryRenderOptions.All;
var showBarcodeOnly = this.renderOptions == GalleryRenderOptions.Barcode;
var loadingImgMarginX = Math.floor(_this.thumbnailWidth / 3);
var loadingImgMarginY = Math.floor(_this.thumbnailHeight / 3);
var imageStyle = "margin: " + loadingImgMarginY + "px " + (_this.mode === "horizontal" || _this.mode === "grid" ? loadingImgMarginX + "px" : "auto") + "; width: " + loadingImgMarginX + "px; height: " + loadingImgMarginY + "px;";
var aStyle = "";
var listStyle = "";
var liStyle = "";
var tw = _this.thumbnailWidth,
th = _this.thumbnailHeight;
if (_this.mode === "horizontal") {
listStyle = " style='width: " + (imagesObj.length * _this.thumbnailWidth) + "px; height: " + _this.thumbnailHeight + "px; overflow: hidden;' ";
aStyle = " style='max-width: " + _this.thumbnailWidth + "px;' ";
tw = 0;
}
else if (_this.mode === "vertical") {
th = 0;
}
else if (_this.mode === "grid") {
listStyle = " style='grid-template-columns: repeat(auto-fit, minmax(" + (_this.thumbnailWidth + 32) + "px, 1fr))' ";
// aStyle = " style='width: " + (_this.thumbnailWidth + 32) + "px;height: " + (_this.thumbnailHeight + 32) + "px;' ";
aStyle = " style='width: auto;height: " + (_this.thumbnailHeight + 32) + "px;' ";
tw = 0;
}
var html = "<ul" + listStyle + ">";
$(_this.element).find("ul li.emptyli").remove();
if (append === true) {
html = "";
}
for (var i = 0; i < imagesObj.length; i++) {
var path = imagesObj[i].path;
var extrastyle = '';
var extradata = '';
var thumbUrl = getThumbnailUrl(serverUrl, sessionId, path, 0, tw, th);
// if (imagesObj[i].hasOwnProperty('snapshotParameters')) {
if (Object.prototype.hasOwnProperty.call(imagesObj[i], 'snapshotParameters')) {
thumbUrl = getSnapshotUrl(serverUrl, sessionId, path, imagesObj[i].snapshotParameters, tw, th, "jpg");
}
// else if (imagesObj[i].hasOwnProperty('rotation')) {v
else if (Object.prototype.hasOwnProperty.call(imagesObj[i], 'rotation')) {
var rInt = parseInt(imagesObj[i].rotation);
if (!isNaN(rInt) && rInt != 0) {
extrastyle = 'transform:rotate(' + rInt + 'deg);';
extradata = 'data-rotation="' + rInt + '"';
}
}
var barcodeUrl = getBarcodeUrl(serverUrl, sessionId, path, _this.barcodeRotation ? _this.barcodeRotation : 0);
html +=
"<li draggable='true' class='lazy loading'" + liStyle + "><a " + aStyle + " data-server='" + serverUrl + "' data-path='" + path + "' href='#'>";
if (_this.showFileName) {
if (typeof _this.filenameCallback === "function") {
html += "<span>" + _this.filenameCallback(serverUrl, path) + "</span>";
}
else {
html += "<span>" + path.split('/').pop() + "</span>";
}
}
html += "<div " + extradata + " data-img='" + (showBarcodeOnly ? barcodeUrl : thumbUrl) + "' style=' " + imageStyle + extrastyle + "'></div>";
if (showBarcodeNormal) {
html += '<img class="barcode hidden" data-src="' + barcodeUrl + '" />';
}
html += '</a>';
if (typeof _this.additionalHtmlCallback === "function") {
html += _this.additionalHtmlCallback(imagesObj[i]);
}
html += '</li>';
}
// if (this.mode === "grid") {
// for (var p = 0; p < 10; p++) {
// html += "<li class='emptyli' " + liStyle + " ></li>";
// }
// }
if (append !== true) {
html += "</ul>";
}
if (append === true) {
$(_this.element).find("ul").append(html);
}
else {
_this.element.innerHTML = html;
}
$(_this.element).find("ul li:not(.emptyli)").each(function (index, element) {
element.addEventListener("dragstart", dragstart.bind(this, element), false);
});
if (_this.mode === "horizontal") {
// fix width once loaded
var horUl = $(_this.element).find("ul");
var horWidth = horUl.outerWidth(true) - horUl.width();
$(_this.element).find("ul li").each(function () {
horWidth += $(this).outerWidth(true) + 2;
});
horUl.css("width", horWidth + "px");
horUl.css("height", "");
horUl.css("overflow", "");
}
$(_this.element).find("ul li a").click(function (ev) {
ev.preventDefault();
imageClick.call(_this, this, true);
});
if (append !== true) {
_this.ps = new Ps(_this.element, { useBothWheelAxes: true, wheelPropagation: true, swipePropagation: true });
}
else {
_this.ps.update();
}
// bind scroll events for lazy loading
if (_this.mode === "horizontal") {
$(_this.element).on('ps-scroll-x', function () {
clearTimeout(_this.lazyLoadTimeOut);
_this.lazyLoadTimeOut = setTimeout(loadVisibleX.bind(_this), 500);
});
loadVisibleX.call(_this);
}
else {
$(_this.element).on('ps-scroll-y', function () {
clearTimeout(_this.lazyLoadTimeOut);
_this.lazyLoadTimeOut = setTimeout(loadVisibleY.bind(_this), 500);
});
loadVisibleY.call(_this);
}
if (typeof doneCb === "function") {
doneCb();
}
}
/**
* A private function which load slides from one server only
* @param {string} serverUrl - The URL of the PMA.core server to get images from
* @param {string[]|Object[]} images - An array of strings that contains the paths of the images to load or an array of objects that contains the path and rotation of the images as desribed below
* @param {string} images.path - The path of the image to load
* @param {string} images.rotation - The rotation of the image in degrees
* @param {Components~snapshotParameters} images.snapshotParameters - Optional snapshot parameters to show
* @param {function} [doneCb] - Called when image loading is complete
* @ignore
*/
function loadSlides(serverUrl, images, doneCb) {
if (this.ps) {
this.ps.destroy();
}
var _this = this;
_this.context.getSession(serverUrl, function (sessionId) {
renderImages.call(_this, serverUrl, sessionId, images, doneCb);
});
}
function refresh() {
if (this.lastLoadedImages.length > 0) {
for (var i = 0; i < this.lastLoadedImages.length; i++) {
renderImages.call(this, this.lastLoadedImages[i].serverUrl, this.lastLoadedImages[i].sessionId, this.lastLoadedImages[i].images, null);
}
}
}
function ondragover(ev) {
ev.preventDefault();
var types = ev.dataTransfer.types;
let hasData = false;
if (types) {
if (types.indexOf) {
hasData = types.indexOf("application/x-fancytree-node") > -1 || types.indexOf(DragDropMimeType) > -1;
}
else if (types.contains) {
// in IE and EDGE types is DOMStringList
hasData = types.contains("application/x-fancytree-node") || types.contains(DragDropMimeType);
}
// var nodeData = PMA.UI.Components.parseDragData(ev.dataTransfer);
if (hasData) {
if (ev.altKey) {
ev.dataTransfer.dropEffect = "move";
}
else {
ev.dataTransfer.dropEffect = "copy";
}
return;
}
ev.dataTransfer.dropEffect = "none";
}
}
function ondrop(ev) {
ev.preventDefault();
var self = this;
var nodeData = parseDragData(ev.dataTransfer);
var append = ev.altKey == false;
if (nodeData && nodeData.path && nodeData.serverUrl && nodeData.source !== "gallery") {
if (nodeData.isFolder) {
this.context.getSlides({
serverUrl: nodeData.serverUrl,
path: nodeData.path,
success: function (sessionId, files) {
if (files == null || files.length == 0) {
self.fireEvent(Events.Dropped, { serverUrl: nodeData.serverUrl, path: nodeData.path, isFolder: true, append: append && self.lastLoadedImages.length > 1 });
return;
}
self.lastLoadedImages.push([{ serverUrl: nodeData.serverUrl, sessionId: sessionId, images: files }]);
renderImages.call(self, nodeData.serverUrl, sessionId, files, function () {
self.fireEvent(Events.Dropped, { serverUrl: nodeData.serverUrl, path: nodeData.path, isFolder: true, append: append && self.lastLoadedImages.length > 1 });
}, append && self.lastLoadedImages.length > 1);
},
failure: function () {
console.error("Error loading slides from directory");
}
});
}
else {
var imageArray = [{ serverUrl: nodeData.serverUrl, path: nodeData.path }];
self.context.getSession(nodeData.serverUrl, function (sessionId) {
self.lastLoadedImages.push({ serverUrl: nodeData.serverUrl, sessionId: sessionId, images: imageArray });
renderImages.call(self, nodeData.serverUrl, sessionId, imageArray, function () {
self.fireEvent(Events.Dropped, { serverUrl: nodeData.serverUrl, path: nodeData.path, isFolder: false, append: append && self.lastLoadedImages.length > 1 });
}, append && self.lastLoadedImages.length > 1);
});
return;
}
}
}
function initializeDropZone() {
if (this.element) {
this.element.addEventListener("drop", ondrop.bind(this), false);
this.element.addEventListener("dragover", ondragover.bind(this), false);
}
}
function dragstart(element, ev) {
var link = $(element).find("a");
if (link) {
var d = JSON.stringify({
serverUrl: link.data("server"),
path: link.data("path"),
isFolder: false,
source: "gallery"
});
ev.dataTransfer.setData("text", d);
ev.dataTransfer.setData(DragDropMimeType, d);
}
}
/**
* Function that returns a string to be displayed on top of a thumbnail
* @callback Gallery~callback
* @param {string} serverUrl - The serverUrl of the image
* @param {string} filename - The virtual path of the image
* @returns {string}
*/
/**
* Function that returns a string to be displayed on below a thumbnail
* @callback Gallery~additionalHtmlCallback
* @param {object} image - The image object used to render this thumbnail
* @returns {string}
*/
export
/**
* Represents a UI component that shows image thumbnails. Provides events to handle click and multiple selection, as well as built-in lazy loading functionality.
* @memberof PMA.UI.Components
* @alias Gallery
* @param {Context} context
* @param {object} options - Configuration options
* @param {string|HTMLElement} options.element - The element that hosts the gallery. It can be either a valid CSS selector or an HTMLElement instance.
* @param {Number} options.thumbnailWidth - The desired width of the displayed thumbnails.
* @param {Number} options.thumbnailHeight - The desired height of the displayed thumbnails.
* @param {string} [options.mode="horizontal"] - "horizontal", "vertical" or "grid"
* @param {Gallery~callback} [options.filenameCallback] - Callback to override the displayed name of each image.
* @param {Gallery~additionalHtmlCallback} [options.additionalHtmlCallback] - Callback to provide additional HTML to render on top of the thumbnail.
* @param {boolean} [options.showFileName=false] - Whether or not to print each image's name
* @param {GalleryRenderOptions} [options.renderOptions = PMA.UI.Components.GalleryRenderOptions.All] - Whether to render thumbnail only, barcode only or both
* @param {Number} [options.barcodeRotation=0] - Rotation of the barcode in steps of 90 degrees
* @param {boolean} [options.multiSelect=false] - Whether or not to allow multiple files to be selected
* @fires PMA.UI.Components.Events.SlideInfoError
* @fires PMA.UI.Components.Events.SlideSelected
* @fires PMA.UI.Components.Events.SlideDeSelected
* @fires PMA.UI.Components.Events.Dropped
* @tutorial 03-gallery
* @tutorial 04-tree
*/
class Gallery {
constructor(context, options) {
if (!checkBrowserCompatibility()) {
return;
}
if (options.element instanceof HTMLElement) {
this.element = options.element;
}
else if (typeof options.element == "string") {
var el = document.querySelector(options.element);
if (!el) {
console.error("Invalid selector for element");
}
else {
this.element = el;
}
}
else {
console.error("Invalid element");
return;
}
if (isNaN(options.thumbnailHeight) || isNaN(options.thumbnailWidth) || options.thumbnailHeight <= 0 || options.thumbnailWidth <= 0) {
console.error("thumbnailWidth & thumbnailHeight must be positive integers");
return;
}
this.listeners = {};
this.listeners[Events.SlideDeSelected] = [];
this.listeners[Events.SlideSelected] = [];
this.listeners[Events.SlideInfoError] = [];
this.listeners[Events.Dropped] = [];
this.filenameCallback = options.filenameCallback;
this.additionalHtmlCallback = options.additionalHtmlCallback;
this.multiSelect = options.multiSelect === true;
this.lazyLoadTimeOut = 0;
this.showFileName = options.showFileName === true;
this.barcodeRotation = options.barcodeRotation;
this.context = context;
this.thumbnailWidth = options.thumbnailWidth;
this.thumbnailHeight = options.thumbnailHeight;
// a helper array that holds the last loaded images as objects { serverUrl, sessionId, imageArray }
this.lastLoadedImages = [];
if (options.mode !== "horizontal" && options.mode !== "vertical" && options.mode !== "grid") {
options.mode = "horizontal";
}
this.renderOptions = options.renderOptions ? options.renderOptions : GalleryRenderOptions.All;
// for backwards compatibility keep the showBarcode option
if (options.showBarcode === false) {
this.renderOptions = GalleryRenderOptions.Thumbnail;
}
this.mode = options.mode;
$(this.element).addClass("pma-ui-gallery");
if (this.mode === "vertical") {
$(this.element).addClass("vertical");
}
else if (this.mode === "grid") {
$(this.element).addClass("grid");
}
printMessage.call(this, Resources.translate("No images found"));
initializeDropZone.call(this);
}
/**
* Attaches an event listener
* @param {PMA.UI.Components.Events} eventName - The name of the event to listen to
* @param {function} callback - The function to call when the event occurs
*/
listen(eventName, callback) {
// if (!this.listeners.hasOwnProperty(eventName)) {
if (!Object.prototype.hasOwnProperty.call(this.listeners, eventName)) {
console.error(eventName + " is not a valid event");
}
this.listeners[eventName].push(callback);
}
// fires an event
fireEvent(eventName, eventArgs) {
// if (!this.listeners.hasOwnProperty(eventName)) {
if (!Object.prototype.hasOwnProperty.call(this.listeners, eventName)) {
console.error(eventName + " does not exist");
return;
}
for (var i = 0, max = this.listeners[eventName].length; i < max; i++) {
this.listeners[eventName][i].call(this, eventArgs);
}
}
/**
* Loads the thumbnails of all the images found directly under a given directory
* @param {string} serverUrl - The URL of the PMA.core server to get images from
* @param {string} directory - The path of a directory to load images from
* @param {function} [doneCb] - Called when image loading is complete
*/
loadDirectory(serverUrl, directory, doneCb) {
if (this.ps) {
this.ps.destroy();
}
var _this = this;
this.lastLoadedImages = [];
printMessage.call(_this, Resources.translate("<i class='fa fa-spinner fa-spin'></i> Loading"));
this.context.getSlides({
serverUrl: serverUrl,
path: directory,
success: function (sessionId, files) {
_this.lastLoadedImages = [{ serverUrl: serverUrl, sessionId: sessionId, images: files }];
renderImages.call(_this, serverUrl, sessionId, files, doneCb);
},
failure: function (error) {
_this.element.innerHTML = error.Message;
_this.fireEvent(Events.SlideInfoError, { serverUrl: serverUrl, path: directory, message: error.Message });
}
});
}
/**
* Loads the thumbnails of all the provided images
* @param {Object[]} images - An array of image objects containing the path, rotation and server url for each image to load
* @param {string} images.serverUrl - The URL of the PMA.core server to load this image from
* @param {string} images.path - The path of the image to load
* @param {string} images.rotation - The rotation of the image in degrees
* @param {function} doneCb - Called when image loading is complete
*/
loadSlides(images, doneCb) {
if (typeof images === "string") {
// the old deprecated function is used if the first parameter is of type string, corresponding to the server url
// loadSlides = function(serverUrl, images, doneCb)
loadSlides.call(this, arguments[0], arguments[1], arguments[2]);
return;
}
if (this.ps) {
this.ps.destroy();
}
var servers = {};
var serverUrls = [];
var _this = this;
if (!images || images.length == 0) {
// call with empty parameters to clear all
renderImages.call(this, "", "", [], doneCb);
return;
}
for (var i = 0; i < images.length; i++) {
if (images[i].serverUrl) {
// if (!servers.hasOwnProperty(images[i].serverUrl)) {
if (!Object.prototype.hasOwnProperty.call(servers, images[i].serverUrl)) {
servers[images[i].serverUrl] = [];
serverUrls.push(images[i].serverUrl);
}
servers[images[i].serverUrl].push({ path: images[i].path, rotation: images[i].rotation });
}
}
_this.lastLoadedImages = [];
var c = 0;
var getSessionFunc = (function (serverUrl, imageArray, gallery, cb, count, done) {
gallery.context.getSession(serverUrl, function (sessionId) {
_this.lastLoadedImages.push({ serverUrl: serverUrl, sessionId: sessionId, images: imageArray });
renderImages.call(gallery, serverUrl, sessionId, imageArray, function () {
if (done && typeof cb === "function") {
cb();
}
}, count != 0);
});
});
for (i = 0; i < serverUrls.length; i++) {
getSessionFunc(serverUrls[i], servers[serverUrls[i]], _this, doneCb, c, ++c >= serverUrls.length);
}
}
/**
* Selects or deselects a slide
* @param {Number} index - The index of the slide to select
* @fires PMA.UI.Components.Events.SlideSelected
* @fires PMA.UI.Components.Events.SlideDeSelected
*/
selectSlide(index) {
if (index === undefined || index === null) {
$(this.element).find("ul li").removeClass("selected");
return;
}
var el = $(this.element).find("ul li:nth-child(" + (index + 1) + ") a")[0];
imageClick.call(this, el, false);
}
/**
* Highlights or unhighlights a slide
* @param {Number} index - The index of the slide to highlight
* @param {boolean} highlight - True to highlight, otherwise false
*/
highlightSlide(index, highlight) {
if (index === undefined || index === null) {
$(this.element).find("ul li").removeClass("selected");
return;
}
var el = $(this.element).find("ul li:nth-child(" + (index + 1) + ") a");
if (highlight === true) {
el.parent().addClass("selected");
}
else {
el.parent().removeClass("selected");
}
}
/**
* Slide information
* @typedef {Object} Gallery~slide
* @property {string} server - The URL of the PMA.core server this slide has been loaded from
* @property {string} path - The path of the slide
* @property {Number} index - The index of the slide in the gallery
*/
/**
* Returns the first of the currently selected slides, or null
* @return {Gallery~slide}
*/
getSelectedSlide() {
var el = $(this.element).find("ul li.selected a:first-child");
if (el.length === 0) {
return null;
}
else {
return { server: el.data("server"), path: el.data("path"), index: el.parent().index() };
}
}
/**
* Returns the currently selected slides, or null
* @return {Gallery~slide[]}
*/
getSelectedSlides() {
var el = $(this.element).find("ul li.selected a:first-child");
if (el.length === 0) {
return null;
}
else {
var result = [];
el.each(function () {
result.push({ server: $(this).data("server"), path: $(this).data("path"), index: $(this).parent().index() });
});
return result;
}
}
/**
* Returns all the currently loaded slides
* @return {Gallery~slide[]}
*/
getSlides() {
var el = $(this.element).find("ul li a:first-child");
if (el.length === 0) {
return null;
}
else {
var result = [];
el.each(function () {
result.push({ server: $(this).data("server"), path: $(this).data("path"), index: $(this).parent().index() });
});
return result;
}
}
/**
* Sets the render options
* @param {PMA.UI.Components.GalleryRenderOptions} option - The render option to set
*/
setRenderOptions(option) {
if (option && this.renderOptions != option) {
this.renderOptions = option;
refresh.call(this);
}
}
/**
* Toggles the mode of the gallery
* @param {String} mode - The mode to set, one of "horizontal", "vertical" or "grid"
*/
setMode(mode) {
if (this.mode !== mode) {
this.mode = mode;
$(this.element).removeClass("vertical grid");
if (this.mode === "vertical") {
$(this.element).addClass("vertical");
}
else if (this.mode === "grid") {
$(this.element).addClass("grid");
}
refresh.call(this);
}
}
}