Extractor.watch() improvements
- only watch current window - stop watch on window close - don't ask user to confirm when fails
This commit is contained in:
		| @ -1,5 +1,6 @@ | ||||
| import { Actions, Request } from "../common"; | ||||
| import { sendMessage } from "./messaging"; | ||||
| import { logger } from "./common"; | ||||
|  | ||||
| /** | ||||
|  * redirect tab to url. | ||||
| @ -41,7 +42,7 @@ export function redirectTab(tab: chrome.tabs.Tab, url: string) { | ||||
|  * @param {Array<string>} fieldSelectors fields selectors for selecting fields (data columns) under each item | ||||
|  * @returns {Promise<string[]>} a promise of extracted data | ||||
|  */ | ||||
| export function extractTabData(tab, itemsSelector, fieldSelectors) { | ||||
| export function extractTabData(tab: chrome.tabs.Tab, itemsSelector: string, fieldSelectors: string[], askOnfail?: boolean) { | ||||
|     let req = { | ||||
|         action: Actions.EXTRACT, | ||||
|         itemsSelector: itemsSelector, | ||||
| @ -49,7 +50,13 @@ export function extractTabData(tab, itemsSelector, fieldSelectors) { | ||||
|     } | ||||
|     let checker = (result, err, tryCount) => { | ||||
|         if (!result || !result.length) { | ||||
|             if (tryCount % 20 == 0 && confirm('No data found in current page. \n\nContinue to next page?')) { | ||||
|             if ( | ||||
|                 tryCount % 20 == 0 && ( | ||||
|                     !askOnfail || | ||||
|                     confirm('No data found in current page. \n\nContinue to next page?') | ||||
|                 ) | ||||
|             ) { | ||||
|                 logger.warn(`Failed after ${tryCount} tries: ${tab.url}`) | ||||
|                 return []; | ||||
|             } else { | ||||
|                 return undefined; | ||||
| @ -135,6 +142,25 @@ export async function findIncognitoWindow(): Promise<chrome.windows.Window> { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export async function getCurrentWindow(): Promise<chrome.windows.Window> { | ||||
|     return new Promise((resolve, reject) => { | ||||
|         chrome.windows.getCurrent( | ||||
|             (windows: chrome.windows.Window) => { | ||||
|                 return resolve(windows); | ||||
|             } | ||||
|         ); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export async function getWindowByID(id: number) { | ||||
|     return new Promise<chrome.windows.Window>((resolve, reject) => { | ||||
|         chrome.windows.get(id, function (window) { | ||||
|             chrome.runtime.lastError; | ||||
|             resolve(window); | ||||
|         }) | ||||
|     }) | ||||
| } | ||||
|  | ||||
| export async function CreateIncognitoWindow() { | ||||
|     return new Promise((resolve, reject) => { | ||||
|         chrome.windows.create( | ||||
|  | ||||
| @ -31,7 +31,7 @@ export function sendMessage<T>( | ||||
|         loop(); | ||||
|  | ||||
|         async function loop() { | ||||
|             logger.debug("Request for", req.action); | ||||
|             logger.debug("Request for", Actions[req.action]); | ||||
|             let tabAvailable = await getTabByID(tab.id); | ||||
|             if (!tabAvailable) { | ||||
|                 reject("Task interrupted due to the target tab is closed."); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { parseUrls } from "./tools"; | ||||
| import { queryUrl, redirectTab, scrollToBottom, extractTabData } from "./actions"; | ||||
| import { queryUrl, redirectTab, scrollToBottom, extractTabData, findIncognitoWindow, getCurrentWindow, getWindowByID } from "./actions"; | ||||
| import { testArgs, signitures } from "./signiture"; | ||||
| import { ExtractResult } from "./result"; | ||||
| import { messageSubscribers, ActionSubscriber } from "./messaging"; | ||||
| @ -14,6 +14,7 @@ export class Task { | ||||
|     private _fieldSelectors: string[]; | ||||
|     private _urls: string[] = []; | ||||
|     private _running = false; | ||||
|     private _listeners: ActionSubscriber[] = []; | ||||
|  | ||||
|     constructor(options: any, ...arg: any); | ||||
|     constructor(options: any, itemsSelector: string, fieldSelectors: string[]); | ||||
| @ -56,15 +57,46 @@ export class Task { | ||||
|     } | ||||
|     stop() { | ||||
|         this._running = false; | ||||
|         messageSubscribers.removeListener(Actions.REPORT_NEW_PAGE, this.listener); | ||||
|         let listener: ActionSubscriber; | ||||
|         while (listener = this._listeners.pop()) { | ||||
|             messageSubscribers.removeListener(Actions.REPORT_NEW_PAGE, listener); | ||||
|         } | ||||
|     watch() { | ||||
|     } | ||||
|     async watch() { | ||||
|         if (this._running) { | ||||
|             logger.info("The task is running. Please wait..."); | ||||
|             return; | ||||
|         } | ||||
|         this._running = true; | ||||
|         messageSubscribers.addListener(Actions.REPORT_NEW_PAGE, this.listener); | ||||
|         let window = await findIncognitoWindow() || await getCurrentWindow(); | ||||
|         if (!window) { | ||||
|             logger.info("No window to watch..."); | ||||
|             return; | ||||
|         } | ||||
|         let listener: ActionSubscriber = async (request, sender, sendResponse) => { | ||||
|             let findWindow = await getWindowByID(window.id); | ||||
|             if (!findWindow) { | ||||
|                 // stop watch on window close. | ||||
|                 messageSubscribers.removeListener(Actions.REPORT_NEW_PAGE, listener); | ||||
|                 return; | ||||
|             } | ||||
|             // only watch current window. | ||||
|             if (sender.tab.windowId != window.id) return; | ||||
|             let pm = this.makeOptionalTasks(sender.tab); | ||||
|             return pm.then( | ||||
|                 () => extractTabData(sender.tab, this._itemsSelector, this._fieldSelectors, false) | ||||
|             ).then( | ||||
|                 results => { | ||||
|                     if (results && results.length) { | ||||
|                         this.saveResult(results, sender.tab.url); | ||||
|                     } | ||||
|                 } | ||||
|             ).catch( | ||||
|                 e => logger.error(e) | ||||
|             ) | ||||
|         } | ||||
|         this._listeners.push(listener); | ||||
|         messageSubscribers.addListener(Actions.REPORT_NEW_PAGE, listener); | ||||
|     } | ||||
|     async execute(tab: chrome.tabs.Tab, upstreamData?: ExtractResult): Promise<void> { | ||||
|         if (!tab) return Promise.reject("No tab to execute the task."); | ||||
| @ -108,21 +140,6 @@ export class Task { | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|     private listener: ActionSubscriber = (request, sender, sendResponse) => { | ||||
|         sendResponse('recieved!'); | ||||
|         let pm = this.makeOptionalTasks(sender.tab); | ||||
|         return pm.then( | ||||
|             () => extractTabData(sender.tab, this._itemsSelector, this._fieldSelectors) | ||||
|         ).then( | ||||
|             results => { | ||||
|                 if (results && results.length) { | ||||
|                     this.saveResult(results, sender.tab.url); | ||||
|                 } | ||||
|             } | ||||
|         ).catch( | ||||
|             e => logger.error(e) | ||||
|         ) | ||||
|     } | ||||
|     private makeOptionalTasks(tab: chrome.tabs.Tab): Promise<any> { | ||||
|         let pm: Promise<any>; | ||||
|         if (this._options["scrollToBottom"]) { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user