52 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
		
			1.8 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 interval for detecting
 | |
|  * @param {string} log messages logged to console.
 | |
|  * @return {Promise} a promise of the response.
 | |
|  */
 | |
| function sendMessage(tab, req, log, cond, interval) {
 | |
|     interval = interval || 500;
 | |
|     return new Promise((resolve, reject) => {
 | |
| 
 | |
|         loop();
 | |
| 
 | |
|         async function loop() {
 | |
|             // console.log("request for", req.action);
 | |
|             let tabAvailable = await getTabByID(tab.id);
 | |
|             if (!tabAvailable) {
 | |
|                 reject("Task interrupted due to the target tab is closed.");
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             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) console.log(log, flag ? '(OK)' : '(failed)');
 | |
|                 if (flag) {
 | |
|                     resolve(r);
 | |
|                 } else {
 | |
|                     setTimeout(() => {
 | |
|                         loop();
 | |
|                     }, interval);
 | |
|                 }
 | |
|             });
 | |
|         }
 | |
|     });
 | |
| }
 | |
| 
 | |
| chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
 | |
|     if (!message.action || !message.action.startsWith(EXT_NAME)) {
 | |
|         return;
 | |
|     }
 | |
|     sendResponse("Calling from user pages is not allowed.");
 | |
|     return;
 | |
| });
 |