I'm trying to switch my extension from MV2 to MV3 and I'm stuck on the DOMParser using the Offscreen document
Service_Worker :
*const OFFSCREEN_DOCUMENT_PATH = "/background/offscreen.html";
let creating;
async function fetchEntries(feed) {
//Check feed
const chk = await fetch(feed.url)
if (!chk.ok) {
console.log("error fetchEntries");
chrome.notifications.create("errfetch",{
"type": "basic",
"iconUrl": "assets/logo_color.svg",
"title": "Attention",
"message": chrome.i18n.getMessage("errfeed") + feed.name + chrome.i18n.getMessage("errfeed2"),
})
const entries = [];
return entries;
} else {
const htmlString = await (await fetch(feed.url)).text();
const xml = await getParsed(htmlString);
console.log("xml : " + xml) <-- *this is an [object][Object]*
for (const el of xml.querySelectorAll("entry, item")) { <-- don't work
entries.push(parse(el, feed));
return entries
}
}
};
async function getParsed(htmlString) {
await setupOffscreenDocument(OFFSCREEN_DOCUMENT_PATH);
const parsing = await chrome.runtime.sendMessage({
type: 'getParsedDOM',
target: 'offscreen',
data: htmlString
});
await closeOffscreenDocument();
console.log("parsing : " + parsing);
return parsing;
}
async function setupOffscreenDocument(path) {
if (!(await hasDocument())) {
// create offscreen document
if (creating) {
await creating;
} else {
creating = chrome.offscreen.createDocument({
url: path,
reasons: ['DOM_PARSER'],
justification: 'Parse DOM'
});
await creating;
creating = null;
}
}
}
async function hasDocument() {
const matchedClients = await clients.matchAll();
return matchedClients.some(
(c) => c.url === chrome.runtime.getURL(OFFSCREEN_DOCUMENT_PATH)
);
}
async function closeOffscreenDocument() {
if (!(await hasDocument())) {
return;
}
await chrome.offscreen.closeDocument();
}*
offscreen.js :
chrome.runtime.onMessage.addListener(handleMessages);
async function handleMessages(message, sender, sendResponse) {
if (message.target !== 'offscreen') {
return false;
}
if (message.type !== 'getParsedDOM') {
console.warn(`Unexpected message type received: '${message.type}'.`);
return;
}
await getParsed(message.data).then((result) => {
sendResponse(result); <-- *result is a [XML objectdocument]*
})
return true;
}
async function getParsed(data) {
return new Promise((resolve, reject) => {
const parser = new DOMParser();
const xml = parser.parseFromString(data, 'text/xml');
resolve(xml);
(err) => reject(err)
});
}
the offscreen document does send an [XMLObjectdocument] to the service_worker, but the service_worker receives an [object object] that I can't process. So how to pass an [XML Objectdocument] from offscreen to service_worker ?
You can't send DOM across threads. Move all of the code that parses the XML into the offscreen document i.e. querySelectorAll and your parse() function, and finally return the resultant array/object with JSON-compatible data inside (strings, numbers, boolean, null).