53 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			53 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| chrome.runtime.onMessage.addListener(
 | |
|     function (request, sender, sendResponse) {
 | |
|         if (!request.action) return;
 | |
|         // console.log("Recieved request:",request);
 | |
|         switch (request.action) {
 | |
|             case ACTION_EXTRACT:
 | |
|                 let data = extract(request.itemsSelector, request.fieldSelectors);
 | |
|                 if (sendResponse) sendResponse(data);
 | |
|                 break;
 | |
|             case ACTION_GOTO_URL:
 | |
|                 window.location.replace(request.url);
 | |
|                 if (sendResponse) sendResponse(request.url);
 | |
|                 break;
 | |
|             case ACTION_REPORT_IN:
 | |
|                 if (sendResponse) sendResponse(request.action);
 | |
|                 break;
 | |
|             case ACTION_QUERY_URL:
 | |
|                 if (sendResponse) sendResponse(window.location.href);
 | |
|                 break;
 | |
|             default:
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| );
 | |
| 
 | |
| function extract(itemsSelector, fieldSelectors) {
 | |
|     // since some elements may be loaded asynchronously.
 | |
|     // if one field is never found, we should return undefined,
 | |
|     // so that senders can detect to retry until elements loaded.
 | |
|     // If user writes wrong selectors, the task retries infinitely.
 | |
|     let fieldFound = {};
 | |
|     let items = Array.from(document.querySelectorAll(itemsSelector));
 | |
|     // items may not loaded yet, tell the sender to retry.
 | |
|     if (!items.length) return MSG_ELEMENT_NOT_FOUND;
 | |
|     let results = items.map(
 | |
|         item => {
 | |
|             return fieldSelectors.map(
 | |
|                 selector => {
 | |
|                     let [cls, attr] = selector.split('@').slice(0, 2);
 | |
|                     let fieldVals = Array.from(item.querySelectorAll(cls));
 | |
|                     if (!fieldVals.length) {
 | |
|                         return;
 | |
|                     }
 | |
|                     fieldFound[selector] = true;
 | |
|                     return fieldVals.map(find => attr ? find[attr] : find.textContent.trim()).join('\n')
 | |
|                 }
 | |
|             )
 | |
|         }
 | |
|     );
 | |
|     // if it exists a field, which is not found in any row, the sender should retry.
 | |
|     let shouldWait = fieldSelectors.reduce((p, c) => p || !fieldFound[c], false);
 | |
|     return shouldWait ? MSG_ELEMENT_NOT_FOUND : results
 | |
| } |