diff --git a/manifest.json b/manifest.json index 9536651..bab72c9 100755 --- a/manifest.json +++ b/manifest.json @@ -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" diff --git a/scripts/background/actions.js b/scripts/background/actions.js index 526baf0..7c25b0e 100644 --- a/scripts/background/actions.js +++ b/scripts/background/actions.js @@ -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); } diff --git a/scripts/content/content.js b/scripts/content/content.js index f6099f3..f8f7d8c 100644 --- a/scripts/content/content.js +++ b/scripts/content/content.js @@ -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 } \ No newline at end of file diff --git a/scripts/shared/common.js b/scripts/shared/common.js new file mode 100644 index 0000000..cd0b5d8 --- /dev/null +++ b/scripts/shared/common.js @@ -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"); diff --git a/scripts/shared.js b/scripts/shared/tools.js similarity index 82% rename from scripts/shared.js rename to scripts/shared/tools.js index 79dcaa5..30cb6eb 100644 --- a/scripts/shared.js +++ b/scripts/shared/tools.js @@ -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 } -} \ No newline at end of file +}