diff --git a/src/lib/viewers/image/ImageBaseViewer.js b/src/lib/viewers/image/ImageBaseViewer.js index 47f4e4886..d9c04fd89 100644 --- a/src/lib/viewers/image/ImageBaseViewer.js +++ b/src/lib/viewers/image/ImageBaseViewer.js @@ -13,9 +13,6 @@ const CSS_CLASS_ZOOMABLE = 'zoomable'; const CSS_CLASS_PANNABLE = 'pannable'; class ImageBaseViewer extends BaseViewer { - /** @property {string} - Url used to download an image representation */ - downloadUrl; - /** @inheritdoc */ constructor(options) { super(options); @@ -323,8 +320,9 @@ class ImageBaseViewer extends BaseViewer { // eslint-disable-next-line console.error(err); - const genericDownloadError = new PreviewError(ERROR_CODE.CONTENT_DOWNLOAD, __('error_refresh'), err.message); - super.handleDownloadError(err instanceof PreviewError ? err : genericDownloadError, imgUrl); + // Display a generic error message but log the real one + const error = new PreviewError(ERROR_CODE.CONTENT_DOWNLOAD, __('error_refresh'), {}, err.message); + super.handleDownloadError(error, imgUrl); } /** diff --git a/src/lib/viewers/image/ImageViewer.js b/src/lib/viewers/image/ImageViewer.js index 3745507e6..9da815cb1 100644 --- a/src/lib/viewers/image/ImageViewer.js +++ b/src/lib/viewers/image/ImageViewer.js @@ -57,12 +57,12 @@ class ImageViewer extends ImageBaseViewer { const { representation, viewer } = this.options; const template = representation.content.url_template; - this.downloadUrl = this.createContentUrlWithAuthParams(template, viewer.ASSET); + const downloadUrl = this.createContentUrlWithAuthParams(template, viewer.ASSET); this.bindDOMListeners(); return this.getRepStatus() .getPromise() - .then(this.handleAssetAndRepLoad) + .then(() => this.handleAssetAndRepLoad(downloadUrl)) .catch(this.handleAssetError); } @@ -72,17 +72,11 @@ class ImageViewer extends ImageBaseViewer { * @override * @return {void} */ - handleAssetAndRepLoad() { + handleAssetAndRepLoad(downloadUrl) { this.startLoadTimer(); + this.imageEl.src = downloadUrl; - return util - .fetchRepresentationAsBlob(this.downloadUrl) - .then((blob) => { - const srcUrl = URL.createObjectURL(blob); - this.imageEl.src = srcUrl; - super.handleAssetAndRepLoad(); - }) - .catch(this.handleImageDownloadError); + super.handleAssetAndRepLoad(); } /** @@ -380,7 +374,7 @@ class ImageViewer extends ImageBaseViewer { * @return {void} */ handleImageDownloadError(err) { - this.handleDownloadError(err, this.downloadUrl); + this.handleDownloadError(err, this.imageEl.src); } /** diff --git a/src/lib/viewers/image/MultiImageViewer.js b/src/lib/viewers/image/MultiImageViewer.js index b984421d2..e860f8832 100644 --- a/src/lib/viewers/image/MultiImageViewer.js +++ b/src/lib/viewers/image/MultiImageViewer.js @@ -3,7 +3,7 @@ import PageControls from '../../PageControls'; import './MultiImage.scss'; import { ICON_FULLSCREEN_IN, ICON_FULLSCREEN_OUT } from '../../icons/icons'; import { CLASS_INVISIBLE, CLASS_MULTI_IMAGE_PAGE, CLASS_IS_SCROLLABLE } from '../../constants'; -import { pageNumberFromScroll, fetchRepresentationAsBlob } from '../../util'; +import { pageNumberFromScroll } from '../../util'; const PADDING_BUFFER = 100; const CSS_CLASS_IMAGE = 'bp-images'; @@ -148,15 +148,7 @@ class MultiImageViewer extends ImageBaseViewer { // Set page number. Page is index + 1. this.singleImageEls[index].setAttribute('data-page-number', index + 1); this.singleImageEls[index].classList.add(CLASS_MULTI_IMAGE_PAGE); - - this.downloadUrl = imageUrl; - - fetchRepresentationAsBlob(imageUrl) - .then((blob) => { - const srcUrl = URL.createObjectURL(blob); - this.singleImageEls[index].src = srcUrl; - }) - .catch(this.handleMultiImageDownloadError); + this.singleImageEls[index].src = imageUrl; } /** @inheritdoc */ @@ -275,18 +267,17 @@ class MultiImageViewer extends ImageBaseViewer { * @return {void} */ handleMultiImageDownloadError(err) { - if (this.isDestroyed()) { - return; - } - this.singleImageEls.forEach((el, index) => { this.unbindImageListeners(index); }); + // Since we're using the src to get the hostname, we can always use the src of the first page + const { src } = this.singleImageEls[0]; + // Clear any images we may have started to load. this.singleImageEls = []; - this.handleDownloadError(err, this.downloadUrl); + this.handleDownloadError(err, src); } /** diff --git a/src/lib/viewers/image/__tests__/ImageViewer-test.js b/src/lib/viewers/image/__tests__/ImageViewer-test.js index 8984d407e..81217cf62 100644 --- a/src/lib/viewers/image/__tests__/ImageViewer-test.js +++ b/src/lib/viewers/image/__tests__/ImageViewer-test.js @@ -236,8 +236,6 @@ describe('lib/viewers/image/ImageViewer', () => { image.wrapperEl.style.height = '50px'; sandbox.stub(image, 'getRepStatus').returns({ getPromise: () => Promise.resolve() }); - sandbox.stub(util, 'fetchRepresentationAsBlob').returns(Promise.resolve(imageUrl)); - sandbox.stub(URL, 'createObjectURL').returns(imageUrl); image.setup(); image.load(imageUrl).catch(() => {}); }); @@ -275,18 +273,21 @@ describe('lib/viewers/image/ImageViewer', () => { }); }); - it('should increase scale when the image is rotated', () => { + it('should zoom the width & height when the image rotated', () => { sandbox.stub(image, 'isRotated').returns(true); - sandbox.stub(image, 'getTransformWidthAndHeight').returns({ - width: 100, - height: 100 - }); - stubs.setScale = sandbox.stub(image, 'setScale'); + image.imageEl.style.transform = 'rotate(90deg)'; + image.imageEl.style.width = '200px'; + image.imageEl.setAttribute('originalWidth', '150'); + image.imageEl.setAttribute('originalHeight', '100'); + image.imageEl.src = imageUrl; + const origImageSize = image.imageEl.getBoundingClientRect(); image.zoomIn(); - - expect(stubs.setScale).to.be.calledWith(undefined, 120); + const newImageSize = image.imageEl.getBoundingClientRect(); + expect(newImageSize.width).gt(origImageSize.width); + expect(newImageSize.height).gt(origImageSize.height); expect(stubs.adjustZoom).to.be.called; + image.imageEl.style.transform = ''; }); it('should reset dimensions and adjust padding when called with reset', () => { @@ -598,13 +599,11 @@ describe('lib/viewers/image/ImageViewer', () => { done(); }) ); - sandbox.stub(URL, 'URL.createObjectURL(blob)').returns(url); - image.handleAssetAndRepLoad(url).then(() => { - expect(imageEl.src).to.be.equal(url); - }); + image.handleAssetAndRepLoad(url); expect(startLoadTimer).to.be.called; + expect(imageEl.url).to.be.equal(url); expect(loadBoxAnnotations).to.be.called; expect(createAnnotator).to.be.called; }); diff --git a/src/lib/viewers/image/__tests__/MultiImageViewer-test.js b/src/lib/viewers/image/__tests__/MultiImageViewer-test.js index fa89dc9eb..39e1b35c9 100644 --- a/src/lib/viewers/image/__tests__/MultiImageViewer-test.js +++ b/src/lib/viewers/image/__tests__/MultiImageViewer-test.js @@ -210,17 +210,11 @@ describe('lib/viewers/image/MultiImageViewer', () => { expect(stubs.bindImageListeners).to.be.called; }); - it('should set the download URL and fetch the page as a blob', () => { - stubs.fetchRepresentationAsBlob = sandbox - .stub(util, 'fetchRepresentationAsBlob') - .returns(Promise.resolve('foo')); + it('should set the image source', () => { multiImage.singleImageEls = [stubs.singleImageEl]; - const repUrl = 'file/100/content/{page}.png'; - multiImage.setupImageEls(repUrl, 0); - - expect(multiImage.downloadUrl).to.be.equal(repUrl); - expect(stubs.fetchRepresentationAsBlob).to.be.called; + multiImage.setupImageEls('file/100/content/{page}.png', 0); + expect(multiImage.singleImageEls[0].src).to.be.equal('file/100/content/{page}.png'); }); it('should set the page number for each image el', () => { @@ -410,22 +404,13 @@ describe('lib/viewers/image/MultiImageViewer', () => { sandbox.stub(multiImage, 'unbindImageListeners'); }); - it('should do nothing if the viewer is already destroyed', () => { - sandbox.stub(multiImage, 'isDestroyed').returns(true); - multiImage.downloadUrl = multiImage.singleImageEls[0]; - multiImage.handleMultiImageDownloadError('err'); - - expect(multiImage.handleDownloadError).to.not.be.called; - expect(multiImage.unbindImageListeners).to.not.be.called; - }); - it('unbind the image listeners, clear the image Els array, and handle the download error', () => { - multiImage.downloadUrl = multiImage.singleImageEls[0]; + const { src } = multiImage.singleImageEls[0]; multiImage.handleMultiImageDownloadError('err'); expect(multiImage.singleImageEls).to.deep.equal([]); - expect(multiImage.handleDownloadError).to.be.calledWith('err', multiImage.downloadUrl); + expect(multiImage.handleDownloadError).to.be.calledWith('err', src); expect(multiImage.unbindImageListeners).to.be.calledTwice; }); }); diff --git a/test/integration/sanity/DeletedReps.e2e.test.js b/test/integration/sanity/DeletedReps.e2e.test.js index 6a17e691d..72bbfb04a 100644 --- a/test/integration/sanity/DeletedReps.e2e.test.js +++ b/test/integration/sanity/DeletedReps.e2e.test.js @@ -3,9 +3,7 @@ describe('Previewing a file with deleted representations', () => { const token = Cypress.env('ACCESS_TOKEN'); const fileIdDoc = Cypress.env('FILE_ID_DOC'); - const fileIdImage = Cypress.env('FILE_ID_IMAGE'); const fileIdPresentation = Cypress.env('FILE_ID_PRESENTATION'); - const fileIdTiff = Cypress.env('FILE_ID_TIFF'); const REPS_ERROR = 'error_deleted_reps'; @@ -55,16 +53,8 @@ describe('Previewing a file with deleted representations', () => { { viewer: 'Presentation', fileId: fileIdPresentation - }, - { - viewer: 'Image', - fileId: fileIdImage - }, - { - viewer: 'MultiImage', - fileId: fileIdTiff } - ].forEach((test) => { + ].forEach((test) => { it(test.viewer, () => { helpers.checkDeletedRepError();