I have a chrome extension that works perfectly when I'm using it in one tab. Then I go to another tab and extension still works, but here's the strange thing that I can't understand. When I come back to first tab and I click on browser action to show the extension or close (if I left it open), nothing happens. I need to click browser action second time and then extension starts working.
Part of my background.js where the browser action button is defined:
chrome.browserAction.onClicked.addListener(function (tab) {
if (page_loaded == true) {
chrome.tabs.query({ active: true, currentWindow: true, highlighted: true }, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, { greeting: "browser_action_clicked" }, function (response) {
if (response.found == 'N') {
chrome.tabs.executeScript(null, { file: "src/injection.js" }, function () {
chrome.tabs.executeScript(null, { file: "src/extension.js" }, function () {
chrome.tabs.executeScript(tab.id, { code: "$('.cheap-watcher' ).animate({ 'right': '0px' }, 'slow');" }, function () {
sidebarActive = true;
});
});
});
}
else {
if (sidebarActive == true) {
chrome.tabs.executeScript(tab.id, { code: "$('.cheap-watcher' ).animate({ 'right': '-370px' }, 'slow');" }, function () {
sidebarActive = false;
});
}
else {
chrome.tabs.executeScript(tab.id, { code: "$('.cheap-watcher' ).animate({ 'right': '0px' }, 'slow');" }, function () {
sidebarActive = true;
});
}
}
});
});
}
});
Did I wrote something wrong? Or is it chrome bug?
Your sidebarActive is stored as a global state variable (and same with page_loaded). So here's what you have as an example:
You click the button on your first tab; sidebar is shown, sidebarActive is set to true.
You do something with the second tab that results, eventually, in sidebarActive being false - no longer reflecting the state of the old tab.
You click the button on your first tab; since sidebarActive is false, you attempt to show the sidebar; however, it is already shown, so it gives an impression of doing "nothing".
However, now sidebarActive is actually in sync with the tab, so subsequent clicks "work".
This will not work at all, since the state is really per-tab. You have to either:
Save the state in the content script, not the background script, or
Save the state per-tab, e.g. as an array indexed by tab IDs: sidebarActive[tab.id]
In this case, you may still need to do some cleanup on the array when tab updates happen.
Related
Here is the relevant part of the code.
I am trying to capture network calls using chrome.debugger API here. Everything is ok but once the page loads or I click a link then after the first action it closes automatically
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.play) {
if (message.captureNtwrk) {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const tab = tabs[0];
tabId = tab.id;
chrome.debugger.attach({ tabId: tabId }, version, onAttach.bind(null, tabId));
});
}
if (message.captureScreen) {
}
if (message.captureEvent) {
}
}
if (message.stop) {
chrome.debugger.detach({ tabId: tabId });
}
});
// Function to run while debugging
const onAttach = (tabId) => {
if (chrome.runtime.lastError) console.log(chrome.runtime.lastError.message);
chrome.debugger.sendCommand({ tabId: tabId }, 'Network.enable');
chrome.debugger.onEvent.addListener(onEvent);
chrome.debugger.onDetach.addListener((source, reason) => {
console.log('Detached: ' + reason);
});
});
You can try disabling other extensions, especially 3rd party extensions added by desktop applications. One particular extension observed, which causes debugger to detach after page navigation is Adobe Acrobat.
am new in creating chrome extensions, I'm developing an extension page action it works in certain urls, I would like to put different text in the popup for each url, i can do it? please help me.
My background.js is thus
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (~tab.url.indexOf('url1.com.br')) {
chrome.pageAction.show(tabId);
}
if (~tab.url.indexOf('url2.com.br')) {
chrome.pageAction.show(tabId);
}
});
OK. First of all, to show page_action icon on specific URLs you can use declarative content.
// When the extension is installed or upgraded ...
chrome.runtime.onInstalled.addListener(function() {
// Replace all rules ...
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// With a new rule ...
chrome.declarativeContent.onPageChanged.addRules([
{
// That fires when a page's on a specific URL
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'url1.com.br' },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'url2.com.br' }
})
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
Don't forget adding a permission for declarative content in manifest.json. Another thing is different texts for different urls.
popup.js
chrome.tabs.query({'active': true, 'currentWindow': true}, function (tabs) {
var dynamicText = "You are here;"+ tabs[0].url;
document.getElementById("textbox").value = dynamicText ;
});
This sample gets the currentWindow's URL and insert it into the element that has textbox id. I hope samples are enough to solve the problem.
I am unable to view the HTML content of web pages when I view source in Google Chrome's dev tools. For example, if I view the source of https://stackoverflow.com/help, the only content I can see is as follows.
<script>
$('#herobox li').click(function () {
StackExchange.using("gps", function () {
StackExchange.gps.track("aboutpage.click", { aboutclick_location: "hero" }, true);
});
window.location.href = '/about';
});
$('#tell-me-more').click(function () {
StackExchange.using("gps", function () {
StackExchange.gps.track("aboutpage.click", { aboutclick_location: "hero" }, true);
});
});
$('#herobox #close').click(function () {
StackExchange.using("gps", function () {
StackExchange.gps.track("hero.action", { hero_action_type: "minimize" }, true);
});
$.cookie("hero", "mini", { path: "/" });
$.ajax({
url: "/hero-mini",
success: function (data) {
$("#herobox").fadeOut("fast", function () {
$("#herobox").replaceWith(data);
$("#herobox-mini").fadeIn("fast");
});
}
});
return false;
});
</script>
I'm not sure if I've inadvertently changed a setting in Chrome, but any help would be greatly appreciated.
I'm using chrome Version 29.0.1547.76.
I have disabled all extensions.
I tried this using a new profile with the same effect.
I'm not behind a proxy.
If you open the DevTools after loading the page, the content of the items listed on the Resources tab may not be populated. This is also true of network requests on the Network tab. To see the fully populated resources on the Resources tab, first open the DevTools, then refresh the page, or navigate to the desired page with the DevTools open. Now select the html resource and it should be populated.
I have made a class that handles load and submit of a html form. See code below
ND.Form = new Class({
//--- Implements options og events.
Implements: [Options, Events],
//--- Options.
options: {
url: '',
injectTo: ''
},
//--- Initialize the class.
initialize: function (panel, options) {
//--- Set options
this.setOptions(options);
this.panel = panel;
this.loadForm();
},
loadForm: function () {
var req = new Request.HTML({
url: this.options.url,
method: 'get',
onSuccess: function (html) {
$(this.options.injectTo).empty();
$(this.options.injectTo).adopt(html);
var formId = $(this.options.injectTo).getFirst('form').get('id');
$(formId).addEvent('submit', function (e) {
e.stop();
this.submitForm(formId);
} .bind(this));
} .bind(this)
}).send();
},
submitForm: function (formId) {
$(formId).set('send', {
onSuccess: function (resp) {
this.panel.loadContent();
if (resp != null) {
$('lbl_error').empty();
$('lbl_error').setStyles({ 'display': 'block', 'color': 'red' }).set('html', resp);
}
}.bind(this),
onFailure: function (resp) {
if (resp != null) {
$('lbl_error').empty();
$('lbl_error').setStyles({ 'display': 'block', 'color': 'red' }).set('html', resp);
}
}
});
$(formId).send();
}
});
And it all works just fine, exept that when i push the save button more than ones the "this.panel.loadContent();" in the "submitForm: function (formId)" fires the same x amount of times I have pushed the button, how can i prevent this ?
/Martin
Starting from mootools 1.3 "set('send')" adds another one event.
So You need to write:
$('myForm').set('send', {
onSuccess: function (html) {},
onFailure: function(xhr){}
}).addEvent('submit', function(e){
e.stop();
this.send();
});
instead of:
$('myForm').addEvent('submit', function(e){
e.stop();
this.set('send', {
onSuccess: function (html) {},
onFailure: function(xhr){}
});
}).send();
Then Request will be sent only once each time when You handle form.
Basically we need to do three things:
Listen for the ‘click’ event on the submit button.
Stop the event from submitting the form.
Send the form using $(formElement).send()
A solution could look something like this:
$('submit').addEvent( 'click', function(evt){
// Stops the submission of the form.
new Event(evt).stop();
// Sends the form to the action path,
// which is 'script.php'
$('myForm').send();
} );
I have used the request.send() method but googled trying to find a way to just replicate the action of a user hitting a form submit button, but with also allowing some javascript logic being performed beforehand. I did not find anything in discussions specifically addressing this. The answer I found is to use the form.submit() method.
I'm using a listener in the background page to know when a tab is loaded:
chrome.tabs.onUpdated.addListener(function (tabId) { })
But the listener is fired twice: when the page has started loading, and when the page has finished.Is there a way to differentiate the two cases?
Luckily have found the solution.
There is an additional parameter that holds the status value:
chrome.tabs.onUpdated.addListener(function (tabId , info) {
if (info.status === 'complete') {
// your code ...
}
});
Status can be either loading or complete.
I wanted a easier way to do this after opening a tab
function createTab (url) {
return new Promise(resolve => {
chrome.tabs.create({url}, async tab => {
chrome.tabs.onUpdated.addListener(function listener (tabId, info) {
if (info.status === 'complete' && tabId === tab.id) {
chrome.tabs.onUpdated.removeListener(listener);
resolve(tab);
}
});
});
});
}
so it would be
let tab = await createTab('http://google.com');