DOMParser in an Extension Service Worker using the Offscreen document - Stack Overflow

I'm trying to switch my extension from MV2 to MV3 and I'm stuck on the DOMParser using the Of

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 ?

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 ?

Share Improve this question asked Nov 20, 2024 at 17:01 BillyBoy1BillyBoy1 335 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 1

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).

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742342618a4425927.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信