2

I've been having some issues having my different scripts in my extension communicating with each other. the main stuff like sending the array from as.js -> background.js -> popup.js works but im having issues sending the data from background.js -> as.js for the file download. any insight would be helpful aswell as any tips on where i can improve the existing working code.

Thanks, Sam

Code:

manifest.json

{
    "manifest_version": 3,
    "name": "Helper",
    "description": "Desc",
    "version": "0.1",
    "icons": {
        "16": "./icons/16.png",
        "48": "./icons/48.png",
        "128": "./icons/128.png"
    },
    "background": {
        "service_worker": "./scripts/background.js"
    },
    "action": {
        "default_icon": {
            "16": "./icons/16.png",
            "48": "./icons/48.png",
            "128": "./icons/128.png"
        },
        "default_title": "Test Extension",
        "default_popup": "./popup.html"
    },
    
    "content_scripts": [
        {
            "matches": [
                "https://www.website.com/*"
            ],
            "js": [
                "./scripts/jquery-3.6.0.min.js", "./scripts/fileSaver.js", "./scripts/as.js"
            ],
            "run_at": "document_idle"
        }
    ],
    "optional_permissions": [
        "activeTab",
        "tabs",
        "storage"
      ]
    
}

background.js

const data = []

chrome.runtime.onConnect.addListener(function (port) {

    console.assert(port.name === "mh");

    port.onMessage.addListener(function (msg) {

        if (msg.links === undefined) {

            switch (msg.type) {
                case "getData":

                    port.postMessage({
                        'data': data
                    });

                    break;
                case "text":

                    port.postMessage({
                        dlData: data
                    });

                    break;
            }
            
        } else {

            if (Array.isArray(msg.links)) {

                data.length = 0

                msg.links.forEach(e => {
                    data.push(e)
                });

            }
        }

    });

});

as.js (The Part that actually does stuff to the page)

//
// Random Unrelated Stuff...
//

var port = chrome.runtime.connect({
        name: "mh"
    });

    port.postMessage({
        links: data
    });

    port.onMessage.addListener(function (da) { // <--- This is the point where the code stops working.

        console.log('hello')

        console.log(da)

        toTextFile('download', da.dlData)

    });


function toTextFile(fileName, data) {

    var blob = new Blob(
        [`${data.join("\n")}`], {
            type: "text/plain;charset=utf-8"
        }
    );

    saveAs(blob, `${fileName}.txt`);

}

popup.html

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css">
    <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous">

    <style>
        #copy {
            background-color: rgb(135, 135, 135);
            border-radius: 5px;
        }

        #text-copy {
            text-align: center;
            padding-left: 5px;
            padding-top: 5px;
            padding-left: 5px;
            padding-bottom: 5px;
            font-size: x-small;
            color: rgb(7, 7, 7);

        }

        .popup {
            padding-left: 20px;
            padding-right: 20px;
            padding-top: 10px;
        }
    </style>
</head>

<div class="hero is-transparent" style="height: 400px; width: 400px; background-color: rgb(30, 30, 30);">

    <div class="popup">


        <div class="field is-grouped">
            <p class="control">
                <p class="title is-3" style="color: rgb(123, 123, 123);" href="#">Image URL's &nbsp;&nbsp;</p>
            </p>
            <p class="control">
                <button class="button is-dark">
                    <i class="fal fa-clipboard"></i>
                </button>
            </p>
            <p class="control">
                <button class="button is-dark" id="download">
                    <i class="fal fa-arrow-alt-to-bottom"></i>
                </button>
            </p>

        </div>


        <div id="copy">
        </div>

    </div>

    <script src="scripts/jquery-3.6.0.min.js"></script>
    <script src="scripts/popup.js"></script>

</div>



</html>

popup.js

getData()

async function getData() {

    // Request Data
    var port = chrome.runtime.connect({ name: "mh" });
    port.postMessage({ type: 'getData' });


    // Download Button
    var dl = document.getElementById("download")
    dl.addEventListener('click', port.postMessage({ type: 'text' }));

    
    // Process da Links
    port.onMessage.addListener(function (msg) {

        if (!msg.data) return;

        if (Array.isArray(msg.data)) {

            var data = msg.data.join('<br>').replace(/"/g, '')

            var p = document.createElement('p');

            p.innerHTML = `${data}`;
            p.setAttribute("id", "text-copy");

            document.getElementById('copy').appendChild(p);


        } 
    

    });


}
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
SamJones
  • 71
  • 4
  • 2
    Ports are closed after 5 minutes in MV3. Don't use ports. Use [one-time messages](https://developer.chrome.com/extensions/messaging). – wOxxOm Feb 01 '22 at 19:26
  • 1
    @wOxxOm I think i remember getting an error like 'The port closed before a response was received' or something like that, is this avoidable and if so how? – SamJones Feb 01 '22 at 21:56
  • 1
    Simply don't use ports. See also [this](https://stackoverflow.com/a/59915897). BTW you don't need the background script for this task judging by the posted code. – wOxxOm Feb 01 '22 at 22:00
  • 1
    Can i use `chrome.runtime.sendMessage()` or do i have to use tabs? – SamJones Feb 01 '22 at 22:29
  • 1
    Content script uses runtime, the popup uses tabs. See the article I've linked for more info. – wOxxOm Feb 01 '22 at 23:06
  • would i be able to use `chrome.runtime.onMessage` in popup.js? I'm trying it rn but im the only request im not getting anything – SamJones Feb 02 '22 at 18:25
  • i cant currently find an alternative to onMessage under tabs – SamJones Feb 02 '22 at 18:31
  • See the article I've linked. The onMessage listener is always in runtime. Your popup sends a message, the content script is listening using onMessage. – wOxxOm Feb 02 '22 at 18:41

0 Answers0