From 0fee384bd449f3d35d0d5e93553229310f8992a1 Mon Sep 17 00:00:00 2001 From: Mick Ryan Date: Mon, 1 Jul 2019 14:24:26 -0700 Subject: [PATCH] Fix: Chrome Print Preview Fix (#1030) Add listener that is fired once the iframe has loaded it's content for printing. This enables chrome to show an accurate print preview. --- src/lib/viewers/image/ImageViewer.js | 28 ++++++++++++----- .../image/__tests__/ImageViewer-test.js | 31 ++++++++++++++----- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/lib/viewers/image/ImageViewer.js b/src/lib/viewers/image/ImageViewer.js index 9da815cb1..0bc698a74 100644 --- a/src/lib/viewers/image/ImageViewer.js +++ b/src/lib/viewers/image/ImageViewer.js @@ -291,20 +291,32 @@ class ImageViewer extends ImageBaseViewer { * @return {void} */ print() { + const browserName = Browser.getName(); + + /** + * Called async to ensure resource is loaded for print preview. Then removes listener to prevent + * multiple handlers. + * + * @return {void} + */ + const defaultPrintHandler = () => { + if (browserName === 'Explorer' || browserName === 'Edge') { + this.printframe.contentWindow.document.execCommand('print', false, null); + } else { + this.printframe.contentWindow.print(); + } + + this.printframe.removeEventListener('load', defaultPrintHandler); + this.emit('printsuccess'); + }; + this.printframe = util.openContentInsideIframe(this.imageEl.outerHTML); + this.printframe.addEventListener('load', defaultPrintHandler); this.printframe.contentWindow.focus(); this.printImage = this.printframe.contentDocument.querySelector('img'); this.printImage.style.display = 'block'; this.printImage.style.margin = '0 auto'; - - if (Browser.getName() === 'Explorer' || Browser.getName() === 'Edge') { - this.printframe.contentWindow.document.execCommand('print', false, null); - } else { - this.printframe.contentWindow.print(); - } - - this.emit('printsuccess'); } /** diff --git a/src/lib/viewers/image/__tests__/ImageViewer-test.js b/src/lib/viewers/image/__tests__/ImageViewer-test.js index 81217cf62..3750137be 100644 --- a/src/lib/viewers/image/__tests__/ImageViewer-test.js +++ b/src/lib/viewers/image/__tests__/ImageViewer-test.js @@ -353,6 +353,7 @@ describe('lib/viewers/image/ImageViewer', () => { stubs.focus = sandbox.stub(); stubs.print = sandbox.stub(); stubs.mockIframe = { + addEventListener() {}, contentWindow: { document: { execCommand: stubs.execCommand @@ -362,7 +363,8 @@ describe('lib/viewers/image/ImageViewer', () => { }, contentDocument: { querySelector: sandbox.stub().returns(containerEl.querySelector('img')) - } + }, + removeEventListener() {} }; stubs.openContentInsideIframe = sandbox.stub(util, 'openContentInsideIframe').returns(stubs.mockIframe); @@ -377,25 +379,40 @@ describe('lib/viewers/image/ImageViewer', () => { expect(stubs.focus).to.be.called; }); - it('should execute the print command if the browser is Explorer', () => { + it('should execute the print command if the browser is Explorer', (done) => { stubs.getName.returns('Explorer'); + stubs.mockIframe.addEventListener = (type, callback) => { + callback(); + expect(stubs.execCommand).to.be.calledWith('print', false, null); + + done(); + }; image.print(); - expect(stubs.execCommand).to.be.calledWith('print', false, null); }); - it('should execute the print command if the browser is Edge', () => { + it('should execute the print command if the browser is Edge', (done) => { stubs.getName.returns('Edge'); + stubs.mockIframe.addEventListener = (type, callback) => { + callback(); + expect(stubs.execCommand).to.be.calledWith('print', false, null); + + done(); + }; image.print(); - expect(stubs.execCommand).to.be.calledWith('print', false, null); }); - it('should call the contentWindow print for other browsers', () => { + it('should call the contentWindow print for other browsers', (done) => { stubs.getName.returns('Chrome'); + stubs.mockIframe.addEventListener = (type, callback) => { + callback(); + expect(stubs.print).to.be.called; + + done(); + }; image.print(); - expect(stubs.print).to.be.called; }); });