check url change before extract data

This commit is contained in:
2020-01-16 15:11:49 +08:00
parent c78f593c70
commit 378883b626
6 changed files with 111 additions and 57 deletions

View File

@ -1,7 +1,11 @@
import { Request, Actions } from "../common";
import { Request, Actions, Response } from "../common";
import { getTabByID } from "./actions";
import { logger } from "./logger";
export type ResponseCheckerSync<T> = (r: Response<T>, err: chrome.runtime.LastError, count: number) => T;
export type ResponseCheckerAsync<T> = (r: Response<T>, err: chrome.runtime.LastError, count: number) => Promise<T>;
export type ResponseChecker<T> = ResponseCheckerSync<T> | ResponseCheckerAsync<T>;
/**
* Sending a message to target tab repeatedly until the response is not undefined.
* @param {object} tab the table where to send the message
@ -19,7 +23,7 @@ export function sendMessage<T>(
tab: chrome.tabs.Tab,
req,
log?: string,
dataChecker?: (r: T, err: chrome.runtime.LastError, count: number) => T | Promise<T>,
dataChecker?: ResponseChecker<T>,
interval?: number,
limit?: number
) {
@ -43,30 +47,34 @@ export function sendMessage<T>(
return;
}
count++;
chrome.tabs.sendMessage(tab.id, req, async (r: T) => {
chrome.tabs.sendMessage(tab.id, req, async (r: Response<T>) => {
// check error but do nothing until dataChecker.
let err = chrome.runtime.lastError;
let result: T = r;
let result: T;
// r could be undefined if the content script is interrupted.
if (r) {
result = r.result;
if (dataChecker) {
let pms: T | Promise<T>;
try {
pms = dataChecker(r, err, count);
} catch (error) {
reject(error);
return;
}
// don't catch if it's not a Promise
if (pms instanceof Promise) {
let checkerError: any;
pms = pms.catch(e => checkerError = e);
result = await pms;
if (checkerError) {
reject(checkerError);
if (dataChecker) {
let pms: T | Promise<T>;
try {
pms = dataChecker(r, err, count);
} catch (error) {
reject(error);
return;
}
} else {
result = pms;
// don't catch if it's not a Promise
if (pms instanceof Promise) {
let checkerError: any;
pms = pms.catch(e => checkerError = e);
result = await pms;
if (checkerError) {
reject(checkerError);
return;
}
} else {
result = pms;
}
}
}
@ -84,7 +92,10 @@ export function sendMessage<T>(
});
}
export type ActionSubscriber = (request: Request, sender: chrome.runtime.MessageSender, sendResponse: (response?: any) => void) => void | Promise<void>;
export type ActionSubscriberSync = (request: Request, sender: chrome.runtime.MessageSender, sendResponse: (response?: any) => void) => void;
export type ActionSubscriberAsync = (request: Request, sender: chrome.runtime.MessageSender, sendResponse: (response?: any) => void) => Promise<void>;
export type ActionSubscriber = ActionSubscriberSync | ActionSubscriberAsync;
class MessageSubscribers {
private listeners: { [key: number]: ActionSubscriber[] } = {};
addListener(action: Actions, subscriber: ActionSubscriber) {