-1

I'm trying to develop a chrome extension, it has to inject the script using OnUpdated and OnActivated Event Listener.

My script is injecting properly but the problem is that how I can communicate with my background/service_worker script using my injected script

This is image of my injected script which contain some kind of buttons Injected Script

I've tried to access these element into content-script send message to background/service_worker but these elements aren't accessible in my content-script

When I try to access element without injected script these elements are passing message correctly between content-script to background/service-worker Web page

This is the Manifest MV3 Manifest.json

"content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "css": [
        "css/all.min.css",
        "css/camera.css"
      ],
      "js": [
        "js/content-script.js"
      ],
      "run_at": "document_end",
      "all_frames": false
    }
  ],
  "web_accessible_resources": [
    {
      "resources": [
        "*"
      ],
      "matches": [
        "<all_urls>"
      ],
      "use_dynamic_url": true
    }
  ]

This is my content-script.js

var startRecording = document.getElementById('start-recording');
var stopRecording = document.getElementById('rec-stop'); 

if(startRecording){
    startRecording.addEventListener('click',()=> {
        chrome.runtime.sendMessage({recording_started: true}, function(response){
            console.log(response.result);
        })
    })
}
if(stopRecording){
    stopRecording.addEventListener('click',()=>{
        console.log('im stop')       
    })
}

startRecording is accessing element from non injected script which is working and
stopRecordingis accessing element from injected script which is not working well

and after all this is my service_worker.js which i'm using to listening messages from content script

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log('Service Workder ',message);
    if(message.recording_started){
        sendResponse({result: 'hello Im going from service worker'});
    }
    if(message.notification){
        sendResponse({result: 'Notification from service worker'});
    }
})

Basically my problem is to accessing the element of injected script in content-script and pass message to service_worker.js when injected element is clicked

This is how I'm injecting my script

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 
    if(changeInfo.status == 'complete' && tab.status == 'complete' && tab.url !== 'undefined'){
        chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
            if(tabs[0].url?.includes('chrome://')) return undefined;
            var currentId = tabs[0].id;
            chrome.scripting.executeScript({
                target: {tabId: currentId, allFrames: false},
                files: ['js/camera.js'],
            });
        });
    }
})

Maybe I'm using the wrong method for message passing You should suggest me a better way to passing message between injected script and content-script Thanks

Ra Zi
  • 17
  • 1
  • 6
  • Add ` "background": { "service_worker": "background.js" }` to manifest.json. – Norio Yamamoto Jan 07 '23 at 01:11
  • This is already added into manifest.json that’s why my not injected elements are working but injected elements are not working – Ra Zi Jan 07 '23 at 01:32
  • Debug using DevTools. – Norio Yamamoto Jan 07 '23 at 01:39
  • 1
    Show us how you inject or declare your scripts, which file name is injected and how and where. – wOxxOm Jan 07 '23 at 09:20
  • Assuming the "injected script" means a DOM `script` element, you need to use DOM messaging to communicate with the content script, then the content script can communicate with the background script. Example: [Access global js variables from js injected by a chrome extension](https://stackoverflow.com/a/46870005) – wOxxOm Jan 07 '23 at 11:56
  • @wOxxOm I've updated How I'm injected the script – Ra Zi Jan 07 '23 at 14:33
  • Looks like there's something wrong in camera.js so maybe you can show it too. – wOxxOm Jan 07 '23 at 14:38

2 Answers2

0

Based on the limited code provided and your explanation, if stopRecording is added via the injected script, then it does not appear that your codes actually adds the stopRecording element. Upon the user clicking "startRecording", you should be injecting the stopRecording element first into the DOM before attempting to "getElementId" and assign an onclick event to it. Inside the startRecording onClick event you should be adding code that replaces the startRecording Button with the stopRecording button and then looking for 'rec-stop':

 var startRecording = document.getElementById('start-recording');
 
 if(startRecording){
    startRecording.addEventListener('click',()=> {
    //Replace startRecording Button with stopRecording Button
    const stopRecordingElement = document.createElement("div");
    stopRecordingElement.id = "rec-stop";
    //Add any image or styling to button
    startRecording.replaceWith(stopRecordingElement);
    //Now that the DOM has the 'rec-stop' element you can call
    var stopRecording = document.getElementById('rec-stop'); 
    if(stopRecording){
       stopRecording.addEventListener('click',()=>{
          console.log('im stop')       
       })
    }
    chrome.runtime.sendMessage({recording_started: true}, 
        function(response){
            console.log(response.result);
        })
    })
 }
  • Thanks for recommending this scenario but the problem is that startRecording button will not be available on all the chrome tabs after starting recording my camera will be injected into chrome tabs where user can pause/stop the camera..... same like loom – Ra Zi Jan 07 '23 at 14:19
-2

I've tried to access my injected elements into my non-injected js files They are working properly for me

Thanks everyone for helping me

Ra Zi
  • 17
  • 1
  • 6