wait for elements
This commit is contained in:
@ -16,7 +16,8 @@
|
||||
},
|
||||
"background": {
|
||||
"scripts": [
|
||||
"scripts/shared.js",
|
||||
"scripts/shared/tools.js",
|
||||
"scripts/shared/common.js",
|
||||
"scripts/background/messaging.js",
|
||||
"scripts/background/result.js",
|
||||
"scripts/background/signiture.js",
|
||||
@ -29,7 +30,8 @@
|
||||
"content_scripts": [{
|
||||
"matches": ["*://*/*"],
|
||||
"js": [
|
||||
"scripts/shared.js",
|
||||
"scripts/shared/tools.js",
|
||||
"scripts/shared/common.js",
|
||||
"scripts/content/content.js"
|
||||
],
|
||||
"run_at": "document_idle"
|
||||
|
||||
@ -105,7 +105,7 @@ function extractTabData(tab, itemsSelector, fieldSelectors) {
|
||||
itemsSelector: itemsSelector,
|
||||
fieldSelectors: fieldSelectors
|
||||
}
|
||||
let cond = r => r !== undefined;
|
||||
let cond = r => !MSG_ELEMENT_NOT_FOUND.isEqual(r);
|
||||
return sendMessage(tab, req, 'Extract data from the tab...', cond);
|
||||
}
|
||||
|
||||
|
||||
@ -24,26 +24,30 @@
|
||||
);
|
||||
|
||||
function extract(itemsSelector, fieldSelectors) {
|
||||
// let fieldNotFound = false;
|
||||
// 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));
|
||||
if (!items.length) return [];
|
||||
// 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);
|
||||
// TODO: close tab to cancel task tip
|
||||
// if (fieldNotFound) return;
|
||||
let fieldVals = Array.from(item.querySelectorAll(cls));
|
||||
// if (!fieldVals.length) {
|
||||
// fieldNotFound = true;
|
||||
// return;
|
||||
// }
|
||||
if (!fieldVals.length) {
|
||||
return;
|
||||
}
|
||||
fieldFound[selector] = true;
|
||||
return fieldVals.map(find => attr ? find[attr] : find.textContent.trim()).join('\n')
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
// return fieldNotFound ? [] : results
|
||||
return results;
|
||||
// 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
|
||||
}
|
||||
8
scripts/shared/common.js
Normal file
8
scripts/shared/common.js
Normal file
@ -0,0 +1,8 @@
|
||||
const EXT_NAME = "DataExtracter";
|
||||
|
||||
const ACTION_EXTRACT = `${EXT_NAME}:Extract`;
|
||||
const ACTION_GOTO_URL = `${EXT_NAME}:GoToTUL`;
|
||||
const ACTION_REPORT_IN = `${EXT_NAME}:ReportIn`;
|
||||
const ACTION_QUERY_URL = `${EXT_NAME}:QueryURL`;
|
||||
|
||||
const MSG_ELEMENT_NOT_FOUND = new ConstMessage(1, "No element found for at least one selector, maybe it's not loaded yet");
|
||||
@ -1,8 +1,13 @@
|
||||
const EXT_NAME = "DataExtracter";
|
||||
const ACTION_EXTRACT = `${EXT_NAME}:Extract`;
|
||||
const ACTION_GOTO_URL = `${EXT_NAME}:GoToTUL`;
|
||||
const ACTION_REPORT_IN = `${EXT_NAME}:ReportIn`;
|
||||
const ACTION_QUERY_URL = `${EXT_NAME}:QueryURL`;
|
||||
class ConstMessage {
|
||||
constructor(id, message) {
|
||||
this.id = id;
|
||||
this.message = message;
|
||||
}
|
||||
isEqual(err) {
|
||||
if (!err || !err.id) return false;
|
||||
return this.id == err.id;
|
||||
}
|
||||
}
|
||||
|
||||
function saveFile(data, mimeType, fileName) {
|
||||
fileName = fileName || document.title || "result";
|
||||
@ -34,4 +39,4 @@ function saveFile(data, mimeType, fileName) {
|
||||
} else {
|
||||
location.href = url
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user