3

I'm writing a password manager, and my extension creates a listener on page ready, so after a few urls navigated I have a bunch of listeners. I want to respond to a user clicking a "submit" form button without having more than one listener active at a time, so I'd like to detach the content script.

Right now it listens for form submit, then checks the next page loaded for "incorrect password" or the like, then does some other stuff. Here's the code where I attach the listener:

tabs.on("ready", function(tab) {
    fillLoginAndPass(tab);
    listenForLoginSubmit(tab);
});

function listenForLoginSubmit(tab) {
    // attach submit listener 
    worker = tab.attach({
        contentScriptFile: [data.url("jquery-1.11.1.min.js"), data.url("listener-script.js")]
    });

    worker.port.on("submittedCredentials", function (formSubmitURL, enteredLogin, loginField, enteredPassword, passwordField) {
        tab.on("ready", function() {
            checkLogin(tab, formSubmitURL, enteredLogin, loginField, enteredPassword, passwordField);
        });
    });
}

I've tried using worker.destroy(), but it has no effect - the port.on() script still executes multiple times. Is there another way to do it? Thanks in advance.

Edit

To clarify, this is what my code looks like with worker.destroy():

function listenForLoginSubmit(tab) {
    // attach submit listener 
    worker = tab.attach({
        contentScriptFile: [data.url("jquery-1.11.1.min.js"), data.url("listener-script.js")]       
    });

    worker.on("detach", function() {
        console.log("Worker detached from "+tabs.activeTab.url);
    });

    worker.port.on("submittedCredentials", function (formSubmitURL, enteredLogin, loginField, enteredPassword, passwordField) {
        tab.on("ready", function() {
            checkLogin(tab, formSubmitURL, enteredLogin, loginField, enteredPassword, passwordField);
            worker.destroy();
        });
    });
}

function checkLogin(tab, formSubmitURL, enteredLogin, loginField, enteredPassword, passwordField) {
    console.log("Hello!");
    /* code */
}

And the difference in outputs is:

// without worker.destroy()
/* Log in to wikipedia.org */
console.log: passman: Hello!

/* Log out, return to login page */
/* Log in a second time */
console.log: passman: Hello!
console.log: passman: Hello!
console.log: passman: Worker detached from https://en.wikipedia.org/w/index.php?title=Special:Search&search=&go=Go

// with worker.destroy()
/* Log in to wikipedia.org */
console.log: passman: Hello!
console.log: passman: Worker detached from https://en.wikipedia.org/w/index.php?title=Special:Search&search=&go=Go

/* Log out, return to login page */
/* Log in a second time */
console.log: passman: Hello!
console.log: passman: Worker detached from https://en.wikipedia.org/w/index.php?title=Special:Search&search=&go=Go
console.log: passman: Hello!
console.log: passman: Worker detached from https://en.wikipedia.org/w/index.php?title=Special:Search&search=&go=Go

If I do it a third time, I get 3 "Hello!"s, and so on. Again, thanks for any help you can offer.

Edit 2 The bug report Zer0 links in the comments has the answer. Here it is:

let { off } = require("sdk/event/core");
off(worker.port);
Miryafa
  • 163
  • 1
  • 2
  • 15
  • That's odd; `worker.destroy` should have some effects. I filed the following [bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1031082). – ZER0 Jun 26 '14 at 23:39
  • Try reading this topic it might helpl, maybe, im not sure. : http://stackoverflow.com/questions/22382201/pagemod-attaching-worker-to-same-url-multiple-times – Noitidart Jun 27 '14 at 08:14
  • Thanks for creating a bug report, ZER0. To clarify, worker.destroy() does activate the onDetach: function, but doesn't remove the contentscript. I've edited my question to include that. @Noitidart: Thanks. Unfortunately that didn't work. It seems to be attaching to the page top already, only once per page load. The fact that I'm loading multiple pages causes it to stack up. – Miryafa Jun 27 '14 at 19:40

2 Answers2

0

I have to say I didn't tryed this idea, but as anybody replied, maybe it could help you: As far as I know, the content scripts are added through the worker. So, maybe, you can try by overriding the worker with a new one (with no content scripts):

worker.on("detach", function() {
    worker = tab.attach({
         contentScriptFile: [data.url("jquery-1.11.1.min.js")]       
    });
});

Or, maybe, you can override just that file with a listener-script.js blank file, or code that override the classes defined in that content script. Hope it works or throws new ideas!

gal007
  • 6,911
  • 8
  • 47
  • 70
0

It's past time this question got an accepted answer, and since no one else has written it I will. The bug report Zer0 links in the comments has the answer. Here it is:

let { off } = require("sdk/event/core");
off(worker.port);
Miryafa
  • 163
  • 1
  • 2
  • 15