Add a waitOnEventOrTimeout
helper function that allows waiting for an event or a timeout, whichever occurs first
This commit is contained in:
parent
28ce3b6185
commit
0c4985546a
@ -14,7 +14,8 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
binarySearchFirstItem, EventBus, getPDFFileNameFromURL
|
||||
binarySearchFirstItem, EventBus, getPDFFileNameFromURL, waitOnEventOrTimeout,
|
||||
WaitOnType
|
||||
} from '../../web/ui_utils';
|
||||
import { createObjectURL, isNodeJS } from '../../src/shared/util';
|
||||
|
||||
@ -259,4 +260,118 @@ describe('ui_utils', function() {
|
||||
expect(count).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('waitOnEventOrTimeout', function() {
|
||||
let eventBus;
|
||||
|
||||
beforeAll(function(done) {
|
||||
eventBus = new EventBus();
|
||||
done();
|
||||
});
|
||||
|
||||
afterAll(function() {
|
||||
eventBus = null;
|
||||
});
|
||||
|
||||
it('should reject invalid parameters', function(done) {
|
||||
let invalidTarget = waitOnEventOrTimeout({
|
||||
target: 'window',
|
||||
name: 'DOMContentLoaded',
|
||||
}).then(function() {
|
||||
throw new Error('Should reject invalid parameters.');
|
||||
}, function(reason) {
|
||||
expect(reason instanceof Error).toEqual(true);
|
||||
});
|
||||
|
||||
let invalidName = waitOnEventOrTimeout({
|
||||
target: eventBus,
|
||||
name: '',
|
||||
}).then(function() {
|
||||
throw new Error('Should reject invalid parameters.');
|
||||
}, function(reason) {
|
||||
expect(reason instanceof Error).toEqual(true);
|
||||
});
|
||||
|
||||
let invalidDelay = waitOnEventOrTimeout({
|
||||
target: eventBus,
|
||||
name: 'pagerendered',
|
||||
delay: -1000,
|
||||
}).then(function() {
|
||||
throw new Error('Should reject invalid parameters.');
|
||||
}, function(reason) {
|
||||
expect(reason instanceof Error).toEqual(true);
|
||||
});
|
||||
|
||||
Promise.all([invalidTarget, invalidName, invalidDelay]).then(done,
|
||||
done.fail);
|
||||
});
|
||||
|
||||
it('should resolve on event, using the DOM', function(done) {
|
||||
if (isNodeJS()) {
|
||||
pending('Document in not supported in Node.js.');
|
||||
}
|
||||
let button = document.createElement('button');
|
||||
|
||||
let buttonClicked = waitOnEventOrTimeout({
|
||||
target: button,
|
||||
name: 'click',
|
||||
delay: 10000,
|
||||
});
|
||||
// Immediately dispatch the expected event.
|
||||
button.click();
|
||||
|
||||
buttonClicked.then(function(type) {
|
||||
expect(type).toEqual(WaitOnType.EVENT);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should resolve on timeout, using the DOM', function(done) {
|
||||
if (isNodeJS()) {
|
||||
pending('Document in not supported in Node.js.');
|
||||
}
|
||||
let button = document.createElement('button');
|
||||
|
||||
let buttonClicked = waitOnEventOrTimeout({
|
||||
target: button,
|
||||
name: 'click',
|
||||
delay: 10,
|
||||
});
|
||||
// Do *not* dispatch the event, and wait for the timeout.
|
||||
|
||||
buttonClicked.then(function(type) {
|
||||
expect(type).toEqual(WaitOnType.TIMEOUT);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should resolve on event, using the EventBus', function(done) {
|
||||
let pageRendered = waitOnEventOrTimeout({
|
||||
target: eventBus,
|
||||
name: 'pagerendered',
|
||||
delay: 10000,
|
||||
});
|
||||
// Immediately dispatch the expected event.
|
||||
eventBus.dispatch('pagerendered');
|
||||
|
||||
pageRendered.then(function(type) {
|
||||
expect(type).toEqual(WaitOnType.EVENT);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should resolve on timeout, using the EventBus', function(done) {
|
||||
let pageRendered = waitOnEventOrTimeout({
|
||||
target: eventBus,
|
||||
name: 'pagerendered',
|
||||
delay: 10,
|
||||
});
|
||||
// Do *not* dispatch the event, and wait for the timeout.
|
||||
|
||||
pageRendered.then(function(type) {
|
||||
expect(type).toEqual(WaitOnType.TIMEOUT);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { PDFJS } from 'pdfjs-lib';
|
||||
import { createPromiseCapability, PDFJS } from 'pdfjs-lib';
|
||||
|
||||
const CSS_UNITS = 96.0 / 72.0;
|
||||
const DEFAULT_SCALE_VALUE = 'auto';
|
||||
@ -453,6 +453,62 @@ function cloneObj(obj) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const WaitOnType = {
|
||||
EVENT: 'event',
|
||||
TIMEOUT: 'timeout',
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Object} WaitOnEventOrTimeoutParameters
|
||||
* @property {Object} target - The event target, can for example be:
|
||||
* `window`, `document`, a DOM element, or an {EventBus} instance.
|
||||
* @property {string} name - The name of the event.
|
||||
* @property {number} delay - The delay, in milliseconds, after which the
|
||||
* timeout occurs (if the event wasn't already dispatched).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows waiting for an event or a timeout, whichever occurs first.
|
||||
* Can be used to ensure that an action always occurs, even when an event
|
||||
* arrives late or not at all.
|
||||
*
|
||||
* @param {WaitOnEventOrTimeoutParameters}
|
||||
* @returns {Promise} A promise that is resolved with a {WaitOnType} value.
|
||||
*/
|
||||
function waitOnEventOrTimeout({ target, name, delay = 0, }) {
|
||||
if (typeof target !== 'object' || !(name && typeof name === 'string') ||
|
||||
!(Number.isInteger(delay) && delay >= 0)) {
|
||||
return Promise.reject(
|
||||
new Error('waitOnEventOrTimeout - invalid paramaters.'));
|
||||
}
|
||||
let capability = createPromiseCapability();
|
||||
|
||||
function handler(type) {
|
||||
if (target instanceof EventBus) {
|
||||
target.off(name, eventHandler);
|
||||
} else {
|
||||
target.removeEventListener(name, eventHandler);
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
capability.resolve(type);
|
||||
}
|
||||
|
||||
let eventHandler = handler.bind(null, WaitOnType.EVENT);
|
||||
if (target instanceof EventBus) {
|
||||
target.on(name, eventHandler);
|
||||
} else {
|
||||
target.addEventListener(name, eventHandler);
|
||||
}
|
||||
|
||||
let timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT);
|
||||
let timeout = setTimeout(timeoutHandler, delay);
|
||||
|
||||
return capability.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Promise that is resolved when DOM window becomes visible.
|
||||
*/
|
||||
@ -618,4 +674,6 @@ export {
|
||||
normalizeWheelEventDelta,
|
||||
animationStarted,
|
||||
localized,
|
||||
WaitOnType,
|
||||
waitOnEventOrTimeout,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user