Skip to content

Commit

Permalink
Merge pull request kitodo#6269 from thomaslow/open-page-in-separate-b…
Browse files Browse the repository at this point in the history
…rowser-window-fix-5887

Open media in separate browser window
  • Loading branch information
solth authored Nov 5, 2024
2 parents abc71c5 + 28292df commit 3d32ea1
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* This file is part of the Kitodo project.
*
* It is licensed under GNU General Public License version 3 or later.
*
* For the full copyright and license information, please read the
* GPL3-License.txt file that was distributed with this source code.
*/

package org.kitodo.production.forms.dataeditor;

import java.util.Objects;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

/**
* Bean that is used in externalView.xhtml.
*/
@Named("ExternalView")
@RequestScoped
public class ExternalView {

/**
* Return the shortened ID of the media by removing leading zeros.
*
* @param id the long id of the media file as string
* @return the shortened id of the media file
*/
public static String convertToShortId(String id) {
if (Objects.nonNull(id)) {
return id.replaceFirst("^0+(?!$)", "");
} else {
return "-";
}
}

}
1 change: 1 addition & 0 deletions Kitodo/src/main/resources/messages/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,7 @@ validator={0}-Bilder validieren
value=Wert
video=Video
view=Anzeigen
viewPageInNewWindow=Seite in neuem Browser-Fenster öffnen
visible=Sichtbar
volume=Band
of=von
Expand Down
1 change: 1 addition & 0 deletions Kitodo/src/main/resources/messages/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,7 @@ validator=Validate {0} images
value=Value
video=Video
view=View
viewPageInNewWindow=View page in new browser window
visible=Visible
volume=volume
of=of
Expand Down
2 changes: 2 additions & 0 deletions Kitodo/src/main/resources/messages/messages_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,8 @@ validator=Validar {0}-imágenes
value=Valor
video=Video
view=Ver
# please check google translation below and remove comment if translation is acceptable
viewPageInNewWindow=Ver página en una nueva ventana del navegador
visible=Visible
volume=Banda
of=Desde
Expand Down
23 changes: 23 additions & 0 deletions Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css
Original file line number Diff line number Diff line change
Expand Up @@ -3824,6 +3824,29 @@ kbd {
padding: 0 var(--default-half-size);
}

#externalViewTitle {
color: var(--pure-white);
line-height: 1.5em;
}

#externalViewPanel {
margin: auto 16px;
}

#externalViewPanel, #externalViewPanel_content {
padding: 0;
height: 100%;
overflow: hidden;
}

#externalViewPanel #imagePreviewForm\:mediaDetailMediaContainer {
height: 100%;
}

#externalViewPanel video {
max-height: 90%;
}

/*----------------------------------------------------------------------
Workflow Editor
----------------------------------------------------------------------*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@
update="dialogAddDocStrucTypeDialog">
<f:actionListener binding="#{DataEditorForm.addDocStrucTypeDialog.preparePreselectedViews()}"/>
</p:menuitem>
<p:menuitem value="#{msgs.viewPageInNewWindow}"
rendered="#{
DataEditorForm.structurePanel.selectedLogicalNode.type eq StructurePanel.VIEW_NODE_TYPE and
mediaProvider.hasPreviewVariant(DataEditorForm.galleryPanel.getGalleryMediaContent(DataEditorForm.galleryPanel.lastSelection.key))}"
icon="fa fa-external-link fa-sm"
styleClass="plain"
outcome="externalView"
target="_blank">
<f:param name="processId" value="#{DataEditorForm.process.id}"/>
<f:param name="mediaId" value="#{DataEditorForm.galleryPanel.getGalleryMediaContent(DataEditorForm.galleryPanel.lastSelection.key).id}"/>
<f:param name="mimeType" value="#{DataEditorForm.galleryPanel.getGalleryMediaContent(DataEditorForm.galleryPanel.lastSelection.key).mediaViewMimeType}"/>
<f:param name="cachingUUID" value="#{DataEditorForm.galleryPanel.cachingUUID}"/>
</p:menuitem>
<p:menuitem value="#{msgs.assignToNextElement}"
icon="fa fa-link fa-sm"
styleClass="plain"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,19 @@
update="dialogAddDocStrucTypeDialog">
<f:actionListener binding="#{DataEditorForm.addDocStrucTypeDialog.preparePreselectedViews()}"/>
</p:menuitem>
<p:menuitem value="#{msgs.viewPageInNewWindow}"
rendered="#{
DataEditorForm.structurePanel.selectedLogicalNode.type eq StructurePanel.VIEW_NODE_TYPE and
mediaProvider.hasPreviewVariant(DataEditorForm.galleryPanel.getGalleryMediaContent(DataEditorForm.galleryPanel.lastSelection.key))}"
icon="fa fa-external-link fa-sm"
styleClass="plain"
outcome="externalView"
target="_blank">
<f:param name="processId" value="#{DataEditorForm.process.id}"/>
<f:param name="mediaId" value="#{DataEditorForm.galleryPanel.getGalleryMediaContent(DataEditorForm.galleryPanel.lastSelection.key).id}"/>
<f:param name="mimeType" value="#{DataEditorForm.galleryPanel.getGalleryMediaContent(DataEditorForm.galleryPanel.lastSelection.key).mediaViewMimeType}"/>
<f:param name="cachingUUID" value="#{DataEditorForm.galleryPanel.cachingUUID}"/>
</p:menuitem>
<p:menuitem value="#{msgs.changeDocstructType}"
rendered="#{DataEditorForm.structurePanel.selectedLogicalNode.type eq StructurePanel.STRUCTURE_NODE_TYPE and not DataEditorForm.structurePanel.selectedLogicalNode.data.linked}"
icon="fa fa-pencil fa-sm"
Expand Down
96 changes: 96 additions & 0 deletions Kitodo/src/main/webapp/pages/externalView.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!--
*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* This file is part of the Kitodo project.
*
* It is licensed under GNU General Public License version 3 or later.
*
* For the full copyright and license information, please read the
* GPL3-License.txt file that was distributed with this source code.
*
-->

<ui:composition
template="/WEB-INF/templates/base.xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">

<f:metadata>
<!--@elvariable id="id" type="java.lang.Integer"-->
<f:viewParam name="processId"/>
<!--@elvariable id="mediaId" type="java.lang.String"-->
<f:viewParam name="mediaId"/>
<!--@elvariable id="mimeType" type="java.lang.String"-->
<f:viewParam name="mimeType"/>
<!--@elvariable id="cachingUUID" type="java.lang.String"-->
<f:viewParam name="cachingUUID"/>
</f:metadata>

<ui:define name="search">
<h2 id="externalViewTitle">
<h:outputText rendered="#{fn:startsWith(mimeType, 'audio')}" value="#{msgs.audio} "/>
<h:outputText rendered="#{fn:startsWith(mimeType, 'video')}" value="#{msgs.video} "/>
<h:outputText rendered="#{fn:startsWith(mimeType, 'image')}" value="#{msgs.image} "/>
<h:outputText value="#{ExternalView.convertToShortId(mediaId)}">
<f:convertNumber pattern="#" />
</h:outputText>
</h2>
</ui:define>

<ui:define name="breadcrumbs"></ui:define>
<ui:define name="navigation"></ui:define>

<ui:define name="content">
<p:panel id="externalViewPanel">
<h:form id="imagePreviewForm" style="height: 100%;" styleClass="focusable">
<!-- video and audio -->
<ui:fragment rendered="#{fn:startsWith(mimeType, 'video') or fn:startsWith(mimeType, 'audio')}">
<p:outputPanel id="mediaDetailMediaContainer">
<p:media
styleClass="mediaPreviewItem"
value="#{mediaProvider.mediaView}"
player="#{fn:startsWith(mimeType, 'video') ? 'html-video' : 'html-audio'}"
width="90%"
height="auto">
<f:param name="mediaId" value="#{mediaId}"/>
<f:param name="process" value="#{processId}"/>
<f:param name="sessionId" value="#{cachingUUID}"/>
<f:param name="type" value="#{mimeType}"/>
<f:param name="krsc" value="true"/>
</p:media>
</p:outputPanel>
</ui:fragment>
<!-- image -->
<ui:fragment rendered="#{fn:startsWith(mimeType, 'image')}">
<p:graphicImage
id="mediaPreviewGraphicImage"
value="#{mediaProvider.mediaView}"
styleClass="mediaPreviewItem"
style="display: none;">
<f:param name="mediaId" value="#{mediaId}"/>
<f:param name="process" value="#{processId}"/>
</p:graphicImage>

<div id="map" class="map" style="width: 100%; height: 100%;">
<i class="fa fa-spinner fa-spin"/>
</div>
</ui:fragment>
</h:form>
</p:panel>

<h:outputStylesheet name="webjars/openlayers/6.14.1/ol.css"/>
<h:outputScript library="webjars" name="openlayers/6.14.1/ol.js" />
<h:outputScript name="js/ol_custom.js"/>
<h:outputScript>
$(document).ready(function () {
// load openlayers and show image
metadataEditor.detailMap.update();
});
</h:outputScript>
</ui:define>

</ui:composition>
57 changes: 57 additions & 0 deletions Kitodo/src/test/java/org/kitodo/selenium/MetadataST.java
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,63 @@ public void showPhysicalPageNumberBelowThumbnailTest() throws Exception {
assertFalse(Browser.getDriver().findElements(By.cssSelector(".thumbnail-banner")).isEmpty());
}

/**
* Verifies that an image can be openend in a separate window by clicking on the corresponding
* context menu item of the first logical tree node.
*/
@Test
public void openPageInSeparateWindowTest() throws Exception {
login("kowal");

// remember current window handle
String firstWindowHandle = Browser.getDriver().getWindowHandle();

// open the metadata editor
Pages.getProcessesPage().goTo().editMetadata(MockDatabase.MEDIA_RENAMING_TEST_PROCESS_TITLE);

// wait until structure tree is shown
await().ignoreExceptions().pollDelay(100, TimeUnit.MILLISECONDS).atMost(5, TimeUnit.SECONDS)
.until(() -> Browser.getDriver().findElement(By.id("logicalTree")).isDisplayed());

// right click on first tree node representing image 2
WebElement firstTreeNode = Browser.getDriver().findElement(
By.cssSelector("#logicalTree\\:0_0 .ui-treenode-content")
);
new Actions(Browser.getDriver()).contextClick(firstTreeNode).build().perform();

// wait until menu is visible
await().ignoreExceptions().pollDelay(100, TimeUnit.MILLISECONDS).atMost(5, TimeUnit.SECONDS)
.until(() -> Browser.getDriver().findElement(By.id("contextMenuLogicalTree")).isDisplayed());

// click second menu entry to open new tab
Browser.getDriver().findElement(By.cssSelector(
"#contextMenuLogicalTree .ui-menuitem:nth-child(2) .ui-menuitem-link"
)).click();

// find handle of new tab window
String newWindowHandle = Browser.getDriver().getWindowHandles().stream()
.filter((h) -> !h.equals(firstWindowHandle)).findFirst().get();

// switch to new window
Browser.getDriver().switchTo().window(newWindowHandle);

// wait until preview image is found
await().ignoreExceptions().pollDelay(100, TimeUnit.MILLISECONDS).atMost(5, TimeUnit.SECONDS)
.until(() -> !Browser.getDriver().findElements(By.id("imagePreviewForm:mediaPreviewGraphicImage")).isEmpty());

// check that title contains image number
assertEquals("Bild 2", Browser.getDriver().findElement(By.id("externalViewTitle")).getText());

// check that canvas is visible
assertTrue(Browser.getDriver().findElement(By.cssSelector("#map canvas")).isDisplayed());

// close tab
Browser.getDriver().close();

// switch back to previous window
Browser.getDriver().switchTo().window(firstWindowHandle);
}

/**
* Close metadata editor and logout after every test.
* @throws Exception when page navigation fails
Expand Down

0 comments on commit 3d32ea1

Please sign in to comment.