Merge pull request #8157 from Snuffleupagus/api-RenderTask-cancel-Error

[api-minor] Reject the `RenderTask` with an actual `Error`, instead of just a `string`, when rendering is cancelled
This commit is contained in:
Yury Delendik 2017-04-04 09:38:47 -05:00 committed by GitHub
commit 31f8875614
12 changed files with 106 additions and 20 deletions

View File

@ -69,6 +69,7 @@
"no-redeclare": "error", "no-redeclare": "error",
"no-self-assign": "error", "no-self-assign": "error",
"no-self-compare": "error", "no-self-compare": "error",
"no-throw-literal": "error",
"no-unused-expressions": "error", "no-unused-expressions": "error",
"no-unused-labels": "error", "no-unused-labels": "error",
"no-useless-call": "error", "no-useless-call": "error",

View File

@ -67,7 +67,8 @@ var DEFINES = {
CHROME: false, CHROME: false,
MINIFIED: false, MINIFIED: false,
SINGLE_FILE: false, SINGLE_FILE: false,
COMPONENTS: false COMPONENTS: false,
PDFJS_NEXT: false,
}; };
function createStringSource(filename, content) { function createStringSource(filename, content) {
@ -675,7 +676,7 @@ gulp.task('minified', ['minified-pre'], function (done) {
gulp.task('firefox-pre', ['buildnumber', 'locale'], function () { gulp.task('firefox-pre', ['buildnumber', 'locale'], function () {
console.log(); console.log();
console.log('### Building Firefox extension'); console.log('### Building Firefox extension');
var defines = builder.merge(DEFINES, {FIREFOX: true}); var defines = builder.merge(DEFINES, { FIREFOX: true, PDFJS_NEXT: true, });
var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR + '/content/', var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR + '/content/',
FIREFOX_EXTENSION_DIR = 'extensions/firefox/', FIREFOX_EXTENSION_DIR = 'extensions/firefox/',
@ -786,7 +787,7 @@ gulp.task('firefox', ['firefox-pre'], function (done) {
gulp.task('mozcentral-pre', ['buildnumber', 'locale'], function () { gulp.task('mozcentral-pre', ['buildnumber', 'locale'], function () {
console.log(); console.log();
console.log('### Building mozilla-central extension'); console.log('### Building mozilla-central extension');
var defines = builder.merge(DEFINES, {MOZCENTRAL: true}); var defines = builder.merge(DEFINES, { MOZCENTRAL: true, PDFJS_NEXT: true, });
var MOZCENTRAL_DIR = BUILD_DIR + 'mozcentral/', var MOZCENTRAL_DIR = BUILD_DIR + 'mozcentral/',
MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/extensions/pdfjs/', MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/extensions/pdfjs/',
@ -859,7 +860,7 @@ gulp.task('mozcentral', ['mozcentral-pre']);
gulp.task('chromium-pre', ['buildnumber', 'locale'], function () { gulp.task('chromium-pre', ['buildnumber', 'locale'], function () {
console.log(); console.log();
console.log('### Building Chromium extension'); console.log('### Building Chromium extension');
var defines = builder.merge(DEFINES, {CHROME: true}); var defines = builder.merge(DEFINES, { CHROME: true, PDFJS_NEXT: true, });
var CHROME_BUILD_DIR = BUILD_DIR + '/chromium/', var CHROME_BUILD_DIR = BUILD_DIR + '/chromium/',
CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + '/content/'; CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + '/content/';

View File

@ -60,6 +60,7 @@ var FontFaceObject = displayFontLoader.FontFaceObject;
var FontLoader = displayFontLoader.FontLoader; var FontLoader = displayFontLoader.FontLoader;
var CanvasGraphics = displayCanvas.CanvasGraphics; var CanvasGraphics = displayCanvas.CanvasGraphics;
var Metadata = displayMetadata.Metadata; var Metadata = displayMetadata.Metadata;
var RenderingCancelledException = displayDOMUtils.RenderingCancelledException;
var getDefaultSetting = displayDOMUtils.getDefaultSetting; var getDefaultSetting = displayDOMUtils.getDefaultSetting;
var DOMCanvasFactory = displayDOMUtils.DOMCanvasFactory; var DOMCanvasFactory = displayDOMUtils.DOMCanvasFactory;
var DOMCMapReaderFactory = displayDOMUtils.DOMCMapReaderFactory; var DOMCMapReaderFactory = displayDOMUtils.DOMCMapReaderFactory;
@ -2065,7 +2066,7 @@ var RenderTask = (function RenderTaskClosure() {
/** /**
* Cancels the rendering task. If the task is currently rendering it will * Cancels the rendering task. If the task is currently rendering it will
* not be cancelled until graphics pauses with a timeout. The promise that * not be cancelled until graphics pauses with a timeout. The promise that
* this object extends will resolved when cancelled. * this object extends will be rejected when cancelled.
*/ */
cancel: function RenderTask_cancel() { cancel: function RenderTask_cancel() {
this._internalRenderTask.cancel(); this._internalRenderTask.cancel();
@ -2147,7 +2148,14 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
cancel: function InternalRenderTask_cancel() { cancel: function InternalRenderTask_cancel() {
this.running = false; this.running = false;
this.cancelled = true; this.cancelled = true;
this.callback('cancelled');
if ((typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PDFJS_NEXT')) ||
getDefaultSetting('pdfjsNext')) {
this.callback(new RenderingCancelledException(
'Rendering cancelled, page ' + this.pageNumber, 'canvas'));
} else {
this.callback('cancelled');
}
}, },
operatorListChanged: function InternalRenderTask_operatorListChanged() { operatorListChanged: function InternalRenderTask_operatorListChanged() {

View File

@ -176,6 +176,19 @@ var CustomStyle = (function CustomStyleClosure() {
return CustomStyle; return CustomStyle;
})(); })();
var RenderingCancelledException = (function RenderingCancelledException() {
function RenderingCancelledException(msg, type) {
this.message = msg;
this.type = type;
}
RenderingCancelledException.prototype = new Error();
RenderingCancelledException.prototype.name = 'RenderingCancelledException';
RenderingCancelledException.constructor = RenderingCancelledException;
return RenderingCancelledException;
})();
var hasCanvasTypedArrays; var hasCanvasTypedArrays;
if (typeof PDFJSDev === 'undefined' || if (typeof PDFJSDev === 'undefined' ||
!PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {
@ -308,6 +321,8 @@ function getDefaultSetting(id) {
return globalSettings ? globalSettings.externalLinkRel : DEFAULT_LINK_REL; return globalSettings ? globalSettings.externalLinkRel : DEFAULT_LINK_REL;
case 'enableStats': case 'enableStats':
return !!(globalSettings && globalSettings.enableStats); return !!(globalSettings && globalSettings.enableStats);
case 'pdfjsNext':
return !!(globalSettings && globalSettings.pdfjsNext);
default: default:
throw new Error('Unknown default setting: ' + id); throw new Error('Unknown default setting: ' + id);
} }
@ -338,6 +353,7 @@ exports.isExternalLinkTargetSet = isExternalLinkTargetSet;
exports.isValidUrl = isValidUrl; exports.isValidUrl = isValidUrl;
exports.getFilenameFromUrl = getFilenameFromUrl; exports.getFilenameFromUrl = getFilenameFromUrl;
exports.LinkTarget = LinkTarget; exports.LinkTarget = LinkTarget;
exports.RenderingCancelledException = RenderingCancelledException;
exports.hasCanvasTypedArrays = hasCanvasTypedArrays; exports.hasCanvasTypedArrays = hasCanvasTypedArrays;
exports.getDefaultSetting = getDefaultSetting; exports.getDefaultSetting = getDefaultSetting;
exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL; exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;

View File

@ -251,6 +251,13 @@
PDFJS.isEvalSupported = (PDFJS.isEvalSupported === undefined ? PDFJS.isEvalSupported = (PDFJS.isEvalSupported === undefined ?
true : PDFJS.isEvalSupported); true : PDFJS.isEvalSupported);
/**
* Opt-in to backwards incompatible API changes. NOTE:
* If the `PDFJS_NEXT` build flag is set, it will override this setting.
* @var {boolean}
*/
PDFJS.pdfjsNext = (PDFJS.pdfjsNext === undefined) ? false : PDFJS.pdfjsNext;
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) { if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) {
var savedOpenExternalLinksInNewWindow = PDFJS.openExternalLinksInNewWindow; var savedOpenExternalLinksInNewWindow = PDFJS.openExternalLinksInNewWindow;
delete PDFJS.openExternalLinksInNewWindow; delete PDFJS.openExternalLinksInNewWindow;

View File

@ -62,6 +62,8 @@
exports.removeNullCharacters = sharedUtil.removeNullCharacters; exports.removeNullCharacters = sharedUtil.removeNullCharacters;
exports.shadow = sharedUtil.shadow; exports.shadow = sharedUtil.shadow;
exports.createBlob = sharedUtil.createBlob; exports.createBlob = sharedUtil.createBlob;
exports.RenderingCancelledException =
displayDOMUtils.RenderingCancelledException;
exports.getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl; exports.getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl;
exports.addLinkAttributes = displayDOMUtils.addLinkAttributes; exports.addLinkAttributes = displayDOMUtils.addLinkAttributes;
})); }));

View File

@ -52,5 +52,7 @@ exports.createObjectURL = pdfjsSharedUtil.createObjectURL;
exports.removeNullCharacters = pdfjsSharedUtil.removeNullCharacters; exports.removeNullCharacters = pdfjsSharedUtil.removeNullCharacters;
exports.shadow = pdfjsSharedUtil.shadow; exports.shadow = pdfjsSharedUtil.shadow;
exports.createBlob = pdfjsSharedUtil.createBlob; exports.createBlob = pdfjsSharedUtil.createBlob;
exports.RenderingCancelledException =
pdfjsDisplayDOMUtils.RenderingCancelledException;
exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl; exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl;
exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes; exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes;

View File

@ -263,6 +263,8 @@ var Driver = (function DriverClosure() { // eslint-disable-line no-unused-vars
PDFJS.cMapUrl = '../external/bcmaps/'; PDFJS.cMapUrl = '../external/bcmaps/';
PDFJS.enableStats = true; PDFJS.enableStats = true;
PDFJS.imageResourcesPath = '/web/images/'; PDFJS.imageResourcesPath = '/web/images/';
// Opt-in to using the latest API.
PDFJS.pdfjsNext = true;
// Set the passed options // Set the passed options
this.inflight = options.inflight; this.inflight = options.inflight;

View File

@ -17,19 +17,24 @@
(function (root, factory) { (function (root, factory) {
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
define('pdfjs-test/unit/api_spec', ['exports', 'pdfjs/shared/util', define('pdfjs-test/unit/api_spec', ['exports', 'pdfjs/shared/util',
'pdfjs/display/global', 'pdfjs/display/api'], factory); 'pdfjs/display/dom_utils', 'pdfjs/display/global', 'pdfjs/display/api'],
factory);
} else if (typeof exports !== 'undefined') { } else if (typeof exports !== 'undefined') {
factory(exports, require('../../src/shared/util.js'), factory(exports, require('../../src/shared/util.js'),
require('../../src/display/global.js'), require('../../src/display/dom_utils.js'),
require('../../src/display/api.js')); require('../../src/display/global.js'),
require('../../src/display/api.js'));
} else { } else {
factory((root.pdfjsTestUnitApiSpec = {}), root.pdfjsSharedUtil, factory((root.pdfjsTestUnitApiSpec = {}), root.pdfjsSharedUtil,
root.pdfjsDisplayGlobal, root.pdfjsDisplayApi); root.pdfjsDisplayDOMUtils, root.pdfjsDisplayGlobal, root.pdfjsDisplayApi);
} }
}(this, function (exports, sharedUtil, displayGlobal, displayApi) { }(this, function (exports, sharedUtil, displayDOMUtils, displayGlobal,
displayApi) {
var PDFJS = displayGlobal.PDFJS; var PDFJS = displayGlobal.PDFJS;
var createPromiseCapability = sharedUtil.createPromiseCapability; var createPromiseCapability = sharedUtil.createPromiseCapability;
var DOMCanvasFactory = displayDOMUtils.DOMCanvasFactory;
var RenderingCancelledException = displayDOMUtils.RenderingCancelledException;
var PDFDocumentProxy = displayApi.PDFDocumentProxy; var PDFDocumentProxy = displayApi.PDFDocumentProxy;
var InvalidPDFException = sharedUtil.InvalidPDFException; var InvalidPDFException = sharedUtil.InvalidPDFException;
var MissingPDFException = sharedUtil.MissingPDFException; var MissingPDFException = sharedUtil.MissingPDFException;
@ -42,6 +47,16 @@ var FontType = sharedUtil.FontType;
describe('api', function() { describe('api', function() {
var basicApiUrl = new URL('../pdfs/basicapi.pdf', window.location).href; var basicApiUrl = new URL('../pdfs/basicapi.pdf', window.location).href;
var basicApiFileLength = 105779; // bytes var basicApiFileLength = 105779; // bytes
var CanvasFactory;
beforeAll(function(done) {
CanvasFactory = new DOMCanvasFactory();
done();
});
afterAll(function () {
CanvasFactory = null;
});
function waitSome(callback) { function waitSome(callback) {
var WAIT_TIMEOUT = 10; var WAIT_TIMEOUT = 10;
@ -1000,6 +1015,26 @@ describe('api', function() {
done.fail(reason); done.fail(reason);
}); });
}); });
it('cancels rendering of page', function(done) {
var viewport = page.getViewport(1);
var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
var renderTask = page.render({
canvasContext: canvasAndCtx.context,
viewport: viewport,
});
renderTask.cancel();
renderTask.promise.then(function() {
done.fail('shall cancel rendering');
}).catch(function (error) {
expect(error instanceof RenderingCancelledException).toEqual(true);
expect(error.type).toEqual('canvas');
CanvasFactory.destroy(canvasAndCtx);
done();
});
});
}); });
describe('Multiple PDFJS instances', function() { describe('Multiple PDFJS instances', function() {
// Regression test for https://github.com/mozilla/pdf.js/issues/6205 // Regression test for https://github.com/mozilla/pdf.js/issues/6205
@ -1022,15 +1057,16 @@ describe('api', function() {
pdfDocuments.push(pdf); pdfDocuments.push(pdf);
return pdf.getPage(1); return pdf.getPage(1);
}).then(function(page) { }).then(function(page) {
var c = document.createElement('canvas'); var viewport = page.getViewport(1.2);
var v = page.getViewport(1.2); var canvasAndCtx = CanvasFactory.create(viewport.width,
c.width = v.width; viewport.height);
c.height = v.height;
return page.render({ return page.render({
canvasContext: c.getContext('2d'), canvasContext: canvasAndCtx.context,
viewport: v, viewport: viewport,
}).then(function() { }).then(function() {
return c.toDataURL(); var data = canvasAndCtx.canvas.toDataURL();
CanvasFactory.destroy(canvasAndCtx);
return data;
}); });
}); });
} }

View File

@ -60,6 +60,8 @@ function initializePDFJS(callback) {
// Configure the worker. // Configure the worker.
displayGlobal.PDFJS.workerSrc = '../../src/worker_loader.js'; displayGlobal.PDFJS.workerSrc = '../../src/worker_loader.js';
// Opt-in to using the latest API.
displayGlobal.PDFJS.pdfjsNext = true;
callback(); callback();
}); });

View File

@ -117,6 +117,7 @@ function configure(PDFJS) {
PDFJS.cMapUrl = '../external/bcmaps/'; PDFJS.cMapUrl = '../external/bcmaps/';
PDFJS.cMapPacked = true; PDFJS.cMapPacked = true;
PDFJS.workerSrc = '../src/worker_loader.js'; PDFJS.workerSrc = '../src/worker_loader.js';
PDFJS.pdfjsNext = true;
} else { } else {
PDFJS.cMapUrl = '../web/cmaps/'; PDFJS.cMapUrl = '../web/cmaps/';
PDFJS.cMapPacked = true; PDFJS.cMapPacked = true;

View File

@ -441,7 +441,9 @@ var PDFPageView = (function PDFPageViewClosure() {
self.paintTask = null; self.paintTask = null;
} }
if (error === 'cancelled') { if (((typeof PDFJSDev === 'undefined' ||
!PDFJSDev.test('PDFJS_NEXT')) && error === 'cancelled') ||
error instanceof pdfjsLib.RenderingCancelledException) {
self.error = null; self.error = null;
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
@ -632,7 +634,13 @@ var PDFPageView = (function PDFPageViewClosure() {
var cancelled = false; var cancelled = false;
var ensureNotCancelled = function () { var ensureNotCancelled = function () {
if (cancelled) { if (cancelled) {
throw 'cancelled'; if ((typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('PDFJS_NEXT')) || pdfjsLib.PDFJS.pdfjsNext) {
throw new pdfjsLib.RenderingCancelledException(
'Rendering cancelled, page ' + self.id, 'svg');
} else {
throw 'cancelled'; // eslint-disable-line no-throw-literal
}
} }
}; };