switched from executeScript() to message-based communication between scripts so the content script can be executed repeatedly

This commit is contained in:
eclipse 2025-11-03 17:45:17 +01:00
parent 24f52b4b77
commit 89f4b2f9a6
3 changed files with 52 additions and 57 deletions

View File

@ -18,6 +18,7 @@ function onFailure(error) {
console.log(`background.js: onFailure(): Promise rejected with error '${error}'`); console.log(`background.js: onFailure(): Promise rejected with error '${error}'`);
} }
// actually download an attached file
async function downloadFile(url, filename, saveAs=false) { async function downloadFile(url, filename, saveAs=false) {
console.log(`background.js: downloadFile(): url is '${url}' and filename is '${filename}'`); console.log(`background.js: downloadFile(): url is '${url}' and filename is '${filename}'`);
return browser.downloads.download({ return browser.downloads.download({
@ -27,57 +28,43 @@ async function downloadFile(url, filename, saveAs=false) {
}); });
} }
// sequentially initiate download for each attached file
async function downloadAllFiles(urlsAndFilenames) { async function downloadAllFiles(urlsAndFilenames) {
console.log(`background.js: downloadAllFiles(): started with ${JSON.stringify(urlsAndFilenames)}`);
const currentDate = getCurrentDate(); const currentDate = getCurrentDate();
for (let i = 0; i < urlsAndFilenames.length; i++) { for (let i = 0; i < urlsAndFilenames.length; i++) {
// prefix filename // prefix filename
let prefixedFilename = currentDate + " " + urlsAndFilenames[i].filename; let prefixedFilename = currentDate + " " + urlsAndFilenames[i].filename;
console.log(`background.js: downloadAllFiles(): i is ${i}`); console.log(`background.js: downloadAllFiles(): i is ${i}`);
if ( i == 0 ) {
await downloadFile(urlsAndFilenames[i].url, prefixedFilename, true).then(onSuccess, onFailure); await downloadFile(urlsAndFilenames[i].url, prefixedFilename, true).then(onSuccess, onFailure);
} else {
downloadFile(urlsAndFilenames[i].url, prefixedFilename, true).then(onSuccess, onFailure);
}
} }
} }
function handlePageactionClick(tab, onClickData) { // page action handler
console.log("background.js: handlePageactionClick(): executing content script"); function handlePageactionClick(tab) {
console.log("background.js: handlePageactionClick(): sending message");
// get base url // get base url
browser.tabs.query( browser.tabs.query({
{
currentWindow: true, currentWindow: true,
active: true active: true
} })
) .then(tabs => {
.then(
tabs => {
console.log(`background.js: handlePageactionClick(): tab query returned ${JSON.stringify(tabs)}`); console.log(`background.js: handlePageactionClick(): tab query returned ${JSON.stringify(tabs)}`);
baseUrl = tabs[0].url; baseUrl = tabs[0].url;
} })
)
// execute content script // send message to content script which will trigger said content script
browser.scripting.executeScript( browser.tabs.sendMessage(
{ tab.id,
files: [ "/contentscript.js" ], "pageAction was clicked"
target:
{
tabId: tab.id,
allFrames: false
}
}
) )
.then(results => { .then(message => {
console.log(`background.js: handlePageactionClick(): content script execution successful with results '${JSON.stringify(results)}'`); console.log(`background.js: received a response from contentscript.js with content ${JSON.stringify(message.urlsAndFilenames)}`);
results.forEach(r => downloadAllFiles(r.result)); downloadAllFiles(message.urlsAndFilenames);
}) })
.catch(error => .catch(error =>
console.error(`background.js: handlePageactionClick(): The following error occured while executing a content script: ${error}`) console.error(`background.js: handlePageactionClick(): The following error occured while handling a page action: ${error}`)
) )
} }

View File

@ -1,14 +1,27 @@
console.log("contentscript.js started!"); console.log("contentscript.js started!");
//
function handleReceivedMessage(message) {
// log received message
console.log(`contentscript.js received a message with content ${message}`);
// execute script regardless of message content
const urlsAndFilenames = extractUrlsAndFilenames();
clickPrintButton();
console.log(`contentscript.js: URLs and filenames extracted -> ${JSON.stringify(urlsAndFilenames)}`);
// return data as the resolved Promise's payload
return Promise.resolve({ urlsAndFilenames: urlsAndFilenames });
};
// extract URL and filename for each mail attachment
function extractUrlsAndFilenames() { function extractUrlsAndFilenames() {
console.log("contentscript.js: this is extractFileUrlsAndNames()"); console.log("contentscript.js: this is extractFileUrlsAndNames()");
// get the correct frame // get the correct frame
let frame = document.querySelector("iframe.js-mail-content"); let frame = document.querySelector("iframe.js-mail-content");
// get all divs containing attachments // get all divs containing attachments
let divs = frame.contentWindow.document.body.querySelectorAll( let divs = frame.contentWindow.document.body.querySelectorAll("div.samoware-mail-message__attach__item[attachment-ref]");
"div.samoware-mail-message__attach__item[attachment-ref]"
);
// loop over divs and extract attachment information // loop over divs and extract attachment information
let urlsAndFilenames = []; let urlsAndFilenames = [];
@ -26,22 +39,10 @@ function extractUrlsAndFilenames() {
return urlsAndFilenames; return urlsAndFilenames;
} }
// trigger a click event on samoware's print button
function clickPrintButton() { function clickPrintButton() {
let printElement = document.querySelector( let printElement = document.querySelector('li[ng-click="printMessage(selectedMessage)"]');
'li[ng-click="printMessage(selectedMessage)"]'
);
printElement.click(); printElement.click();
} }
const urlsAndFilenames = extractUrlsAndFilenames(); browser.runtime.onMessage.addListener(handleReceivedMessage);
console.log(
`contentscript.js: URLs and filenames extracted -> ${JSON.stringify(
urlsAndFilenames
)}`
);
clickPrintButton();
console.log(`contentscript.js: clicked the print button`);
// this last statement is important it's evaluation value is the return value for the background script
urlsAndFilenames;

View File

@ -3,7 +3,7 @@
"name": "samoware-multisave", "name": "samoware-multisave",
"version": "1.0", "version": "1.0",
"description": "When using the groupware CommuniGate with the web application Samoware, this browser extension saves all attachments from the currently opened email to a directory of the user's choosing, prefixing each entry's filename with the current date. Yep, it's quite specific.", "description": "When using the groupware CommuniGate in combination with the web application Samoware, this browser extension saves all attachments from the currently opened email to a directory of the user's choosing, prefixing each entry's filename with the current date, while also raising a print dialog for the mail body. Yep, it's quite specific.",
"icons": { "icons": {
"48": "icons/samovar-48.png", "48": "icons/samovar-48.png",
@ -34,5 +34,12 @@
"scripts": [ "scripts": [
"background.js" "background.js"
] ]
},
"content_scripts": [
{
"matches": ["https://communigate.aip.de/*"],
"js": ["contentscript.js"]
} }
]
} }