68 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
 | |
| /**
 | |
|  * Repeatedly sending a message to target tab until the response is detected good.
 | |
|  * @param {object} tab the table where to send the message
 | |
|  * @param {object} req the request data.
 | |
|  * @param {function} cond success condition function, r:any=>boolean
 | |
|  * @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, cond, interval, limit = 0) {
 | |
|     interval = interval || 500;
 | |
|     limit = limit && !isNaN(limit) ? limit : 0;
 | |
|     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, 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
 | |
|                 chrome.runtime.lastError;
 | |
| 
 | |
|                 let flag = !cond || cond(r);
 | |
|                 if (log) logger.info(log, flag ? '(OK)' : '(failed)');
 | |
|                 if (flag) {
 | |
|                     resolve(r);
 | |
|                 } 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;
 | |
|     }
 | |
| });
 |