wait for elements

This commit is contained in:
2020-01-10 15:35:18 +08:00
parent 4656e4ff64
commit c504942144
5 changed files with 38 additions and 19 deletions

View File

@ -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"

View File

@ -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);
}

View File

@ -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
View 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");

View File

@ -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
}
}
}