3

I have Opera sidebar extension
and when extension is fired (sb opened), I need to inject some code with message listener in active tab
code works fine, the problem is that if I close sidebar and open it again, I'll get another listener injected (console will log two times when message is send)...and on another reopen +1..and so on.

I tried to fix this with removing listener, but it doesn't work.
I'm still getting +1 on console for every new extension start (injecting).
And I can't place addListener in removeListener callback. Doesn't work at all
(I guess it doesn't support it in this form)

here is the code I've bee injecting:

chrome.tabs.executeScript({code: 
    "chrome.runtime.onMessage.removeListener(msgL);\
    chrome.runtime.onMessage.addListener(msgL);\
    function msgL(msg) {\
      if (msg.test) console.log('aaaaaaaaaaaaaaaaaaaaaaaaa');\
    }"
  }, function(result) {
    if (!result) console.log(chrome.runtime.lastError);
});

How can I clear previous listener when injecting new one?

Wolf War
  • 1,503
  • 1
  • 15
  • 28

1 Answers1

2

In your code the msgL function is recreated each time so removeListener tries to remove this new instance instead of the previously attached one.

Store the function in the window object (this doesn't seem safe), the injected code would be:

if (window.msgL) chrome.runtime.onMessage.removeListener(window.msgL);
window.msgL = function(msg) {
  if (msg.test) console.log('aaaaaaaaaaaaaaaaaaaaaaaaa');
};
chrome.runtime.onMessage.addListener(window.msgL);

Or keep track of tab IDs with the listener attached in your extension and only add it when needed:

var attachedIDs = {};
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
    var id = tabs[0].id;
    if (!attachedIDs[id]) {
        attachedIDs[id] = true;
        chrome.tabs.executeScript({code: 
            "chrome.runtime.onMessage.addListener(function msgL(msg) {\
              if (msg.test) console.log('aaaaaaaaaaaaaaaaaaaaaaaaa');\
            });"
          }, function(result) {
            if (!result) console.log(chrome.runtime.lastError);
        });
    }
});

This code would save the attachedIDs when run in a persistent background page. Otherwise use sessionStorage API or chrome.storage API to save/restore it.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • If I use window.msgL = function(msg)... I'm getting **Uncaught SyntaxError: Unexpected identifier**. There is no error if i just write **function msgL(msg).....**. So the problem is writing into a window object.Any chance to fix this?...cause I would like to avoid storage usage (using event page) – Wolf War Aug 10 '15 at 06:37
  • started to work when I added **;** after anonymous function in **window.msgL** – Wolf War Aug 10 '15 at 07:53
  • 1
    Good catch, this is now an assignment not a scope. Usually it doesn't matter though, but evidently this is not the case. I'll add it to the answer. – wOxxOm Aug 10 '15 at 08:09