From 7e782c633ab2fa01b6ae51e0237e1bda88142474 Mon Sep 17 00:00:00 2001 From: jebbs Date: Sat, 29 Sep 2018 14:37:24 +0800 Subject: [PATCH] better task tab management --- scripts/extract.js | 88 +++++++++++++++++++++++++++++--------------- scripts/extractor.js | 16 ++++++-- 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/scripts/extract.js b/scripts/extract.js index 395aefc..12df97e 100644 --- a/scripts/extract.js +++ b/scripts/extract.js @@ -14,39 +14,29 @@ async function extract(itemsSelector, fieldSelectors, ...args) { } /** - * Extract data from current tab / multiple urls. - * @param {string} itemsSelector items selectors for selecting items (data rows) - * @param {Array} fieldSelectors fields selectors for selecting fields (data columns) under each item - * @param {...any} args url list / url templates, page numers, either [from, to, interval] or [...pages] + * Extract data from current page / multiple urls. + * getData(tab, itemsSelector:string, fieldSelectors:string[]) + * getData(tab, itemsSelector:string, fieldSelectors:string[], url:string, from:number, to:number, interval:number) + * getData(tab, itemsSelector:string, fieldSelectors:string, url:string, pages:number[]) + * getData(tab, itemsSelector:string, fieldSelectors:string[], urls:string[]) + * getData(tab, itemsSelector:string, fieldSelectors:string[], urls:ExtractResult) + * getData(itemsSelector:string, fieldSelectors:string[]) + * getData(itemsSelector:string, fieldSelectors:string[], url:string, from:number, to:number, interval:number) + * getData(itemsSelector:string, fieldSelectors:string, url:string, pages:number[]) + * getData(itemsSelector:string, fieldSelectors:string[], urls:string[]) + * getData(itemsSelector:string, fieldSelectors:string[], urls:ExtractResult) + * @param {...any} args */ -async function getData(itemsSelector, fieldSelectors, ...args) { - if (!testArgs(itemsSelector, fieldSelectors, ...args)) +async function getData(...args) { + let tab; + if (typeof args[0] !== 'string') tab = args.shift(); + if (!testArgs(...args)) throw new Error(`Invalid call arguments.\n\n${signitures}\n\n`); - let urls = []; - if (args.length) { - let arg = args.shift(); - if (arg instanceof Array) { - urls = arg; - } else if (arg instanceof ExtractResult) { - urls = arg.squash().filter(v => !!v); - } else { - let urlTempl = arg; - if (urlTempl) { - if (args[0] instanceof Array) { - urls = args[0].map(p => urlTempl.replace("${page}", p)); - } else if (args.length >= 3) { - let from = args.shift(); - let to = args.shift(); - let interval = args.shift(); - for (let i = from; i <= to; i += interval) { - urls.push(urlTempl.replace("${page}", i)); - } - } - } - } - } + itemsSelector = args.shift(); + fieldSelectors = args.shift(); + let urls = parseUrls(...args); let data = []; - let tab = await getActiveTab(true) || await getActiveTab(false); + if (!tab) tab = await getActiveTab(true) || await getActiveTab(false); if (!tab) throw new Error("Cannot find active tab."); return new Promise((resolve, reject) => { let pms; @@ -73,6 +63,33 @@ async function getData(itemsSelector, fieldSelectors, ...args) { }); } +function parseUrls(...args) { + if (!args.length) return []; + let arg = args.shift(); + if (arg instanceof Array) { + return arg; + } else if (arg instanceof ExtractResult) { + return arg.squash().filter(v => !!v); + } else { + let urlTempl = arg; + if (urlTempl) { + if (args[0] instanceof Array) { + return args[0].map(p => urlTempl.replace("${page}", p)); + } else if (args.length >= 3) { + let urls = []; + let from = args.shift(); + let to = args.shift(); + let interval = args.shift(); + for (let i = from; i <= to; i += interval) { + urls.push(urlTempl.replace("${page}", i)); + } + return urls; + } + } + } + return []; +} + function redirectTab(tab, url) { let curUrl = ""; return queryUrl(tab) @@ -170,6 +187,17 @@ function sendMessage(tab, req, cond, interval) { }); } +async function createTab(url, active) { + return new Promise((resolve, reject) => { + chrome.tabs.create({ + 'url': url, + 'active': active + }, function (tab) { + resolve(tab); + }) + }) +} + async function getActiveTab(currentWindow) { return new Promise((resolve, reject) => { chrome.tabs.query({ diff --git a/scripts/extractor.js b/scripts/extractor.js index 7d2b15f..5b9a38f 100644 --- a/scripts/extractor.js +++ b/scripts/extractor.js @@ -1,6 +1,7 @@ class Extractor { constructor() { this._tasks = []; + this._tab = undefined; this._results = {}; } /** @@ -38,12 +39,20 @@ class Extractor { console.log('No task to run.'); return; } + let firstTaskArgs = this._tasks[0]; + if (firstTaskArgs.length > 2) { + // task specifies target urls, create new tab with first url for it + let urls = parseUrls(...firstTaskArgs.slice(2, firstTaskArgs.length)); + this._tab = await createTab(urls[0], false); + } else { + this._tab = await getActiveTab(false); + } return this._tasks.reduce((pms, args, i, tasks) => { return pms.then( result => { - if (result === undefined) return getData(...args); + if (result === undefined) return getData(this._tab, ...args); this._results[tasks[i - 1]] = result; - return getData(...args, result); + return getData(this._tab, ...args, result); }); }, Promise.resolve(undefined)).then( result => { @@ -68,11 +77,12 @@ class Extractor { console.log(`No result cache for task (id ${taskid}). \nMake sure call ".start()" before ".restart()"?`); return; } + this._tab = await createTab(parseUrls(cache)[0], false) return this._tasks.slice(taskid - 1).reduce((pms, args, i, tasks) => { return pms.then( result => { this._results[tasks[i - 1]] = result; - return getData(...args, result); + return getData(this._tab, ...args, result); }); }, Promise.resolve(cache)).then( result => {