diff --git a/scripts/content.js b/scripts/content.js index f1d5ee7..10b432f 100644 --- a/scripts/content.js +++ b/scripts/content.js @@ -1,19 +1,22 @@ chrome.runtime.onMessage.addListener( function (request, sender, sendResponse) { + if (!request.from) return; + let [ext, act] = request.from.split(":"); + if (ext.toLowerCase() !== 'dataextracter') return; // console.log(request); - switch (request.from) { - case "DataExtracter:Extract": + switch (act.toLowerCase()) { + case "extract": let data = extractTabData(request.itemsSelector, request.fieldSelectors); if (sendResponse) sendResponse(data); break; - case "DataExtracter:GotoUrl": + case "gotourl": window.location.replace(request.url); if (sendResponse) sendResponse(request.url); break; - case "DataExtracter:ReportIn": + case "reportin": if (sendResponse) sendResponse(request.from); break; - case "DataExtracter:QueryUrl": + case "queryurl": if (sendResponse) sendResponse(window.location.href); break; default: @@ -22,19 +25,7 @@ } ); -function extractTabData(itemsSelector, fieldSelectors) { - return $(itemsSelector).toArray().map( - item => fieldSelectors.map( - selector => { - let [cls, attr] = selector.split('@').slice(0, 2); - return $(item).find(cls).toArray().map(find => attr ? find[attr] : find.textContent.trim()).join('\n') - } - ) - ); -} - -function extract(...args) { - let sig = ` +const sig = ` # DataExtracter Help ---------------------------- @@ -66,7 +57,24 @@ extract(".list-item", ["a.title", "p.content"], "http://sample.com/?pn=\${page}" ### Extract link text and target (use 'selector@attribute') extract('.list-item', ['a.title', 'a.title@href']) + +### Collect links from page(s) & Extract data of each link (only available in console of extension background page) + +extract('body',["a.title", "p.content"], await getData('.list-item', ['.item a@href'],["http://sample.com/abc"])) `.trim(); + +function extractTabData(itemsSelector, fieldSelectors) { + return $(itemsSelector).toArray().map( + item => fieldSelectors.map( + selector => { + let [cls, attr] = selector.split('@').slice(0, 2); + return $(item).find(cls).toArray().map(find => attr ? find[attr] : find.textContent.trim()).join('\n') + } + ) + ); +} + +function extract(...args) { if (!testArgs(...args)) { console.log(sig); return; @@ -90,12 +98,41 @@ extract('.list-item', ['a.title', 'a.title@href']) } function testArgs(...args) { - if (args.length < 2) return false; - if (args.length == 2) - return (args[0] && args[1] && (typeof args[0] == "string") && (args[1] instanceof Array)) - let urls = []; - if (args.length > 2) return (typeof args[2] == "string") && ( - (args[3] instanceof Array) || - (!isNaN(args[3]) && !isNaN(args[4]) && !isNaN(args[5])) - ) + switch (args.length) { + case 0, 1: + return false; + case 2: + return args[0] && args[1] && + (typeof args[0] == "string") && + (args[1] instanceof Array) && + testArrayVals(args[1], v => typeof v == "string"); + case 3: + return args[0] && args[1] && + typeof args[0] == "string" && + args[1] instanceof Array && + testArrayVals(args[1], v => typeof v == "string") && + args[2] instanceof Array && + testArrayVals(args[2], v => typeof v == "string"); + case 4: + return args[0] && args[1] && + typeof args[0] == "string" && + args[1] instanceof Array && + testArrayVals(args[1], v => typeof v == "string") && + typeof args[2] == "string" && + args[3] instanceof Array && + testArrayVals(args[3], v => typeof v == "number"); + case 5: + return args[0] && args[1] && + typeof args[0] == "string" && + args[1] instanceof Array && + testArrayVals(args[1], v => typeof v == "string") && + typeof args[2] == "string" && + !isNaN(args[3]) && !isNaN(args[4]) && !isNaN(args[5]); + default: + return false; + } + + function testArrayVals(arr, tester) { + return arr.reduce((p, c) => p && tester(c), true); + } } \ No newline at end of file diff --git a/scripts/extract.js b/scripts/extract.js index 5eb45b2..6698a72 100644 --- a/scripts/extract.js +++ b/scripts/extract.js @@ -75,10 +75,10 @@ function redirectTab(tab, url) { if (url !== u) { curUrl = u; let req = { - from: "DataExtracter:GotoUrl", + from: "GotoUrl", url: url } - chrome.tabs.sendMessage(tab.id, req); + sendMessage(tab, req); } }) .then(() => queryUrl(tab, curUrl)) @@ -94,13 +94,12 @@ function redirectTab(tab, url) { */ function extractTabData(tab, itemsSelector, fieldSelectors) { let req = { - from: "DataExtracter:Extract", + from: "Extract", itemsSelector: itemsSelector, fieldSelectors: fieldSelectors } - let failMsg = "extractTabData failed after 10 second."; let cond = r => !!r; - return sendMessageAndDetect(tab, req, cond, failMsg); + return sendMessage(tab, req, cond); } /** @@ -110,11 +109,10 @@ function extractTabData(tab, itemsSelector, fieldSelectors) { */ function reportIn(tab) { let req = { - from: "DataExtracter:ReportIn" + from: "ReportIn" } - let failMsg = "reportIn failed after 10 second."; let cond = r => r == req.from; - return sendMessageAndDetect(tab, req, cond, failMsg); + return sendMessage(tab, req, cond); } /** @@ -125,11 +123,10 @@ function reportIn(tab) { */ function queryUrl(tab, urlExcluded) { let req = { - from: "DataExtracter:QueryUrl" + from: "QueryUrl" } - let failMsg = "queryUrl failed after 10 second."; let cond = url => url && (!urlExcluded || (urlExcluded && urlExcluded != url)); - return sendMessageAndDetect(tab, req, cond, failMsg); + return sendMessage(tab, req, cond); } /** @@ -137,27 +134,27 @@ function queryUrl(tab, urlExcluded) { * @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 {string} failMsg message when failed after time out * @param {number} failedTimeOut fail time out * @param {number} detectInterval interval for detecting * @return {Promise} a promise of the response. */ -function sendMessageAndDetect(tab, req, cond, failMsg, failedTimeOut, detectInterval) { +function sendMessage(tab, req, cond, failedTimeOut, detectInterval) { + req.from = "DataExtracter:" + req.from; failedTimeOut = failedTimeOut || 10000; detectInterval = detectInterval || 500; return new Promise((resolve, reject) => { let timeOut; let rejectTimeout = setTimeout(() => { - reject(failMsg); + reject(`${req.from} failed after ${failedTimeOut/1000} seconds.`); clearTimeout(timeOut); }, failedTimeOut); loop(); function loop() { chrome.tabs.sendMessage(tab.id, req, r => { - if (cond(r)) { - resolve(r); + if (!cond || cond(r)) { clearTimeout(rejectTimeout); + resolve(r); } else { timeOut = setTimeout(() => { loop();