@ -39,6 +39,7 @@
var scratchCanvas = null ;
var scratchCanvas = null ;
function renderPage ( pdfDocument , pageNumber , size , wrapper ) {
function renderPage ( pdfDocument , pageNumber , size , wrapper ) {
var activeServiceOnEntry = activeService ;
if ( ! scratchCanvas ) {
if ( ! scratchCanvas ) {
scratchCanvas = document . createElement ( 'canvas' ) ;
scratchCanvas = document . createElement ( 'canvas' ) ;
}
}
@ -69,9 +70,7 @@
} ;
} ;
return pdfPage . render ( renderContext ) . promise ;
return pdfPage . render ( renderContext ) . promise ;
} ) . then ( function ( ) {
} ) . then ( function ( ) {
if ( ! activeService ) {
activeServiceOnEntry . throwIfInactive ( ) ;
return Promise . reject ( new Error ( 'cancelled' ) ) ;
}
if ( ( 'toBlob' in scratchCanvas ) &&
if ( ( 'toBlob' in scratchCanvas ) &&
! pdfjsLib . PDFJS . disableCreateObjectURL ) {
! pdfjsLib . PDFJS . disableCreateObjectURL ) {
scratchCanvas . toBlob ( function ( blob ) {
scratchCanvas . toBlob ( function ( blob ) {
@ -98,6 +97,8 @@
PDFPrintService . prototype = {
PDFPrintService . prototype = {
layout : function ( ) {
layout : function ( ) {
this . throwIfInactive ( ) ;
var pdfDocument = this . pdfDocument ;
var pdfDocument = this . pdfDocument ;
var printContainer = this . printContainer ;
var printContainer = this . printContainer ;
var body = document . querySelector ( 'body' ) ;
var body = document . querySelector ( 'body' ) ;
@ -139,15 +140,18 @@
} ,
} ,
destroy : function ( ) {
destroy : function ( ) {
if ( activeService !== this ) {
// |activeService| cannot be replaced without calling destroy() first,
// so if it differs then an external consumer has a stale reference to
// us.
return ;
}
this . printContainer . textContent = '' ;
this . printContainer . textContent = '' ;
this . wrappers = null ;
this . wrappers = null ;
if ( this . pageStyleSheet && this . pageStyleSheet . parentNode ) {
if ( this . pageStyleSheet && this . pageStyleSheet . parentNode ) {
this . pageStyleSheet . parentNode . removeChild ( this . pageStyleSheet ) ;
this . pageStyleSheet . parentNode . removeChild ( this . pageStyleSheet ) ;
this . pageStyleSheet = null ;
this . pageStyleSheet = null ;
}
}
if ( activeService !== this ) {
return ; // no need to clean up shared resources
}
activeService = null ;
activeService = null ;
if ( scratchCanvas ) {
if ( scratchCanvas ) {
scratchCanvas . width = scratchCanvas . height = 0 ;
scratchCanvas . width = scratchCanvas . height = 0 ;
@ -164,10 +168,7 @@
renderPages : function ( ) {
renderPages : function ( ) {
var pageCount = this . pagesOverview . length ;
var pageCount = this . pagesOverview . length ;
var renderNextPage = function ( resolve , reject ) {
var renderNextPage = function ( resolve , reject ) {
if ( activeService !== this ) {
this . throwIfInactive ( ) ;
reject ( new Error ( 'cancelled' ) ) ;
return ;
}
if ( ++ this . currentPage >= pageCount ) {
if ( ++ this . currentPage >= pageCount ) {
renderProgress ( pageCount , pageCount ) ;
renderProgress ( pageCount , pageCount ) ;
resolve ( ) ;
resolve ( ) ;
@ -181,6 +182,16 @@
} . bind ( this ) ;
} . bind ( this ) ;
return new Promise ( renderNextPage ) ;
return new Promise ( renderNextPage ) ;
} ,
} ,
get active ( ) {
return this === activeService ;
} ,
throwIfInactive : function ( ) {
if ( ! this . active ) {
throw new Error ( 'This print request was cancelled or completed.' ) ;
}
} ,
} ;
} ;
@ -200,7 +211,22 @@
if ( ! activeService ) {
if ( ! activeService ) {
console . error ( 'Expected print service to be initialized.' ) ;
console . error ( 'Expected print service to be initialized.' ) ;
}
}
activeService . renderPages ( ) . then ( startPrint , abort ) ;
var activeServiceOnEntry = activeService ;
activeService . renderPages ( ) . then ( function ( ) {
activeServiceOnEntry . throwIfInactive ( ) ;
return startPrint ( activeServiceOnEntry ) ;
} ) . catch ( function ( ) {
// Ignore any error messages.
} ) . then ( function ( ) {
// aborts acts on the "active" print request, so we need to check
// whether the print request (activeServiceOnEntry) is still active.
// Without the check, an unrelated print request (created after aborting
// this print request while the pages were being generated) would be
// aborted.
if ( activeServiceOnEntry . active ) {
abort ( ) ;
}
} ) ;
}
}
} ;
} ;
@ -210,17 +236,21 @@
window . dispatchEvent ( event ) ;
window . dispatchEvent ( event ) ;
}
}
function startPrint ( ) {
function startPrint ( activeServiceOnEntry ) {
// Push window.print in the macrotask queue to avoid being affected by
return new Promise ( function ( resolve ) {
// the deprecation of running print() code in a microtask, see
// Push window.print in the macrotask queue to avoid being affected by
// https://github.com/mozilla/pdf.js/issues/7547.
// the deprecation of running print() code in a microtask, see
setTimeout ( function ( ) {
// https://github.com/mozilla/pdf.js/issues/7547.
if ( ! activeService ) {
setTimeout ( function ( ) {
return ; // Print task cancelled by user.
if ( ! activeServiceOnEntry . active ) {
}
resolve ( ) ;
print . call ( window ) ;
return ;
setTimeout ( abort , 20 ) ; // Tidy-up
}
} , 0 ) ;
print . call ( window ) ;
// Delay promise resolution in case print() was not synchronous.
setTimeout ( resolve , 20 ) ; // Tidy-up.
} , 0 ) ;
} ) ;
}
}
function abort ( ) {
function abort ( ) {