77 lines
2.8 KiB
JavaScript
77 lines
2.8 KiB
JavaScript
|
|
/**
|
|
* Sending a message to target tab repeatedly until the response is not undefined.
|
|
* @param {object} tab the table where to send the message
|
|
* @param {object} req the request data.
|
|
* @param {function} dataChecker (reulst:any, err:error, tryCount:number) => any.
|
|
* Check and decide what value finally returns.
|
|
* Return undefined to make 'sendMessage' retry.
|
|
* Return MSG_USER_ABORT to cancel this promise.
|
|
* @param {number} interval retry interval, default: 500ms.
|
|
* @param {number} limit retry limit, default: 0, no limit.
|
|
* @param {string} log messages logged to console.
|
|
* @return {Promise} a promise of the response.
|
|
*/
|
|
function sendMessage(tab, req, log, dataChecker, interval, limit = 0) {
|
|
interval = interval || 500;
|
|
limit = limit && !isNaN(limit) ? limit : 0;
|
|
let count = 0;
|
|
return new Promise((resolve, reject) => {
|
|
|
|
loop();
|
|
|
|
async function loop() {
|
|
logger.debug("Request for", req.action);
|
|
let tabAvailable = await getTabByID(tab.id);
|
|
if (!tabAvailable) {
|
|
reject("Task interrupted due to the target tab is closed.");
|
|
return;
|
|
}
|
|
|
|
if (limit && count >= limit) {
|
|
reject(`sendMessage loop limit ${limit} reached.`);
|
|
return;
|
|
}
|
|
count++;
|
|
chrome.tabs.sendMessage(tab.id, req, async r => {
|
|
// check error but do nothing.
|
|
// do not interrupt promise chains even if error, or the task always fail when:
|
|
// a tab is newly created, and the content scripts won't have time to initialize
|
|
let err = chrome.runtime.lastError;
|
|
let result = r;
|
|
if (dataChecker) {
|
|
result = await dataChecker(r, err, count);
|
|
if (MSG_USER_ABORT.isEqual(result)) {
|
|
reject(MSG_USER_ABORT.message);
|
|
}
|
|
}
|
|
let flag = result !== undefined && result !== null;
|
|
if (log) logger.info(log, flag ? '(OK)' : '(failed)');
|
|
if (flag) {
|
|
resolve(result);
|
|
} else {
|
|
setTimeout(() => {
|
|
loop();
|
|
}, interval);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
|
if (!request.action || !request.action.startsWith(EXT_NAME)) {
|
|
return;
|
|
}
|
|
switch (request.action) {
|
|
case ACTION_UPLOAD_STATE:
|
|
sendResponse('recieved!');
|
|
__EXTRACTOR_STATE__ = request.state;
|
|
logger.info(`State (${request.name}) recieved. To load it: some_var = new Extractor().load()`);
|
|
break;
|
|
default:
|
|
sendResponse("Request not supported.");
|
|
break;
|
|
}
|
|
});
|