Pankaj Shinde Pankaj Shinde - 19 days ago 5
Javascript Question

How can prevent my code from running an increasing number of times each time I click a button?

how can I close instance of chrome extension by clicking browserAction button..?

I am working on chrome extension, in which I want to activate the extension by clicking on browserAction button and when I click it again I want to close the actual instance of that extension so that I can start it again fresh by clicking browserAction icon again.

https://gist.github.com/p10shinde/fb24e5c01d435d138a9bcfdb5b1734aa

add jquery.js

background.js

var actvTabId;
var toggle = false;


chrome.browserAction.onClicked.addListener(function(tab)
{

ws = new WebSocket("ws://127.0.0.1:1234/");

toggle = !toggle;

chrome.tabs.getSelected(null, function(tab)
{
actvTabId = tab.id

if(toggle)
{
chrome.browserAction.setBadgeBackgroundColor({ tabId : actvTabId,color: "green" });
chrome.browserAction.setBadgeText({tabId : actvTabId,text: 'R'});

chrome.tabs.query({active:true}, function(tabs)
{
for(var i=0;i<tabs.length;i++)
{
if(tabs[i].selected == true)
{
//sending to active tab (myscript) from back
try
{
//send to active tab to myscript from backgrund
chrome.tabs.sendMessage(tabs[i].id, {from : 'btn_record2',msg : 'dontremove'}, function(response) {});
alert('sent');
}
catch(e){}
}
}
});


chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
if ( request.from =='btn_record_myscript' )
{
if(typeof(request) != 'undefined')
{
var msg = {cmd : request.command,trgt : request.target , val : request.value};
//sending to java desktop app (can comment)
//ws.send(JSON.stringify(msg));
alert('sent to java');
}
}
});
}
else
{
ws.close();
chrome.browserAction.setBadgeBackgroundColor({tabId : actvTabId, color: "red" });
chrome.browserAction.setBadgeText({tabId : actvTabId,text: ''});
}






ws.onopen = function opn() {

console.log('Connection Successfull.');

};

ws.onmessage = function (evt) {

console.log("From Server : "+evt.data);
};

ws.onclose = function() {
// alert("Closed!");
console.log('closed');
ws.close();
};

ws.onerror = function(err) {
//alert("Error: " + err);
console.log('Connection Failed. Check if server is up and running.');
};

});

});


myScript.js

var typed = '';
var events = [];

chrome.extension.onMessage.addListener(function (message,sender, sendResponse)
{
if(message.from === 'btn_record2')
{
alert('gotchaa');
if(message.msg == 'remove')
{
alert("1");
monitorEvents({'main' : document, 'actn':'rem'});
alert('removed');
}
else if(message.msg == 'dontremove')
{
alert("2");
monitorEvents({'main' : document, 'actn':'add'});
alert('added');
}

}

function monitorEvents(element)
{
//handler
var log = function(e)
{
if(typeof(e.toElement) != 'undefined' )
{
if(e.type == 'click' || e.type == 'change')
{
console.log(e);
var ele = document.getElementsByTagName(e.target.nodeName);
var target_lcl = createXPathFromElement(ele[0]);

chrome.runtime.sendMessage({from : 'btn_record_myscript',command : e.type,target:target_lcl,value:''});

if(typeof(e.toElement.href) != 'undefined')
monitorEvents(document);
}
}
else
{
if(e.type == 'change')
console.log(e);

var ele = document.getElementsByTagName(e.target.nodeName);
var target_lcl = createXPathFromElement(ele[0]);
typed = e.target.value;
chrome.runtime.sendMessage({from : 'btn_record_myscript', command : 'type' , target : target_lcl , value : typed});
}

}


for(var i in element.main)
{
if(i.startsWith("on"))
events.push(i.substr(2));
}

events.forEach(function(eventName)
{
if(element.actn == 'add')
{
element.main.addEventListener(eventName, log,false);
}
else if(element.actn == 'rem')
{
element.main.removeEventListener(eventName, log,false);
}
});
}
});


////new xpath element (is being used)
//dont bother about this function
function createXPathFromElement(elm)
{
var allNodes = document.getElementsByTagName('*');
for (var segs = []; elm && elm.nodeType == 1; elm = elm.parentNode)
{
if (elm.hasAttribute('id')) {
var uniqueIdCount = 0;
for (var n=0;n < allNodes.length;n++) {
if (allNodes[n].hasAttribute('id') && allNodes[n].id == elm.id) uniqueIdCount++;
if (uniqueIdCount > 1) break;
};
if ( uniqueIdCount == 1) {
segs.unshift('id("' + elm.getAttribute('id') + '")');
return segs.join('/');
} else {
segs.unshift(elm.localName.toLowerCase() + '[@id="' + elm.getAttribute('id') + '"]');
}
} else if (elm.hasAttribute('class')) {
segs.unshift(elm.localName.toLowerCase() + '[@class="' + elm.getAttribute('class') + '"]');
} else {
for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling) {
if (sib.localName == elm.localName) i++; };
segs.unshift(elm.localName.toLowerCase() + '[' + i + ']');
};
};
return segs.length ? '/' + segs.join('/') : null;
};


manifest.json

{
"name": "WindowFetchDOMExtension",
"version": "1.0.0",
"manifest_version": 2,
"description" : "This extension fetches the DOM of current page.",
"icons": { "48": "bear.png"},

"browser_action": {
"default_icon": { "16": "bear.png", "32": "bear.png" },
"default_title": "WindowFetch DOM"
},
"permissions": ["tabs"],
"background": {
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["jquery.js","myScript.js"]
}]
}


Added information describing the problem from OP comment:

It's a single extension. When I turn it on, it captures click events. When I click the browserAction icon again, it should stop listening to click events. Now here is problem: when I click start it again, it listens two times for that event. If I turn it off and on again then it would listen 4 times for a single click event.

Answer

Insted below,

chrome.extension.onMessage.addListener(function (message,sender, sendResponse)
    {
        if(message.from === 'btn_record2')
        {...}
    });

I have used chrome.extension.onMessage.addListener(dostuff); and inside

function dostuff(message,sender, sendResponse)
        {
        chrome.extension.onMessage.removeListener(dostuff);
         //rest code below
        }

to remove previous listener and it solved my problem.

Avoid using anonymous functions.

Comments