This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Chrome extension delay condition
Im very beginner at extensions and by collecting codes from here and there I created a simple one which collects the tab's url (works for specific website) and using ajax Im sending it to my server in order to store it in my database.
What Im trying to do is to add a timer so the browser button will be disabled (or do nothing) if the previous click occured in less than 5 seconds.
Below is the structure of the extension:
Manifest:
{
"name": "The name",
"icons": { "16": "Big.png",
"48": "Big.png",
"128": "Big.png" },
"version": "1.0",
"manifest_version": 2,
"description": "and the description",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "<all_urls>"]
}
popup.js:
chrome.tabs.getSelected(null,function(tab) {
var Mp=tab.url
if(Mp=='http://www.examplesite.com')
{
var xhr=new XMLHttpRequest();
var Params;
xhr.open("POST", "http://myserver.com/post_from_extension.asp", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
Params='Url=' + tab.url;
xhr.onreadystatechange=function()
{
if(xhr.readyState==4)
{
message.innerHTML=xhr.responseText;
}
}
xhr.send(Params);
}
else
{
message.innerHTML='<span style="font-family: Segoe UI, Tahoma;color: #f00">This is not a valid url</span>';
}
});
popup.html
<!DOCTYPE html>
<html style=''>
<head>
<script src='popup.js'></script>
</head>
<body style="width:400px;">
<div id='message'><span style="font-family: Segoe UI, Tahoma;color: #00f">Sending request</span></div>
</body>
</html>
As a side question, is there any other method to post the url in my database, if not with Ajax?
Thank you for reading me.
I think you should add a background page (script) to your extension - this is a kind of application state. Add this in the manifest:
"background": {
"scripts": ["background.js"]
},
Then in the page you can define an array storing last times when browser action was performed for each tab.
var timers = [];
You can update this array's elements from your popup.js, something like that (in getSelected callback):
chrome.extension.getBackgroundPage().timers[tabId] = new Date();
chrome.browserAction.disable(tabId);
chrome.browserAction.setIcon({path: "icon-disabled.png", tabId: tabId});
Note how you can disable browser action and change its appearence to a disable/grayed one.
When a period passed since the registered time exceeds 5 seconds you should re-enable the button from the background page.
var currentTime = new Date();
if(currentTime - chrome.extension.getBackgroundPage().timers[tabId] > 5000)
{
chrome.browserAction.enable(tabId);
chrome.browserAction.setIcon({path: "icon-enabled.png", tabId: tabId});
}
You can execute this code from setInterval callback and within a cycle through all elements in the timers array.
Related
I need to create Google Chrome Extension that does the following things :
Read an array of urls (it is possible to have 2000 urls)
For each url :
1) I display the page in a tab
2) I extract some html content in the new loaded page
3) I built a new url with the extracted content for send information to my own local service, it saves the information (I suppose, I just need to update the tab with this new url)
After that, it's ok, I just do again the same tasks with the next url.
To begin to do this job, I have created this 3 following files.
Manifest.json
{
"manifest_version": 2,
"name": "Test",
"description": "Test to read pages",
"version": "1.0",
"browser_action": {
"default_title": "test page reader",
"default_popup": "popup.html",
"default_icon": "icon.png"
},
"permissions": [
"activeTab"
]
}
popup.html
This file loads directly the popup.js
<html>
<head>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<div id="test" style="width: 100px; height: 100px; margin-top: 15px;"></div>
</body>
</html>
popup.js
urls = ["http://localhost/page1.php",
"http://localhost/page2.php",
"http://localhost/page3.php"
];
for (i = 0; i < urls.length; i++) {
myUrl = urls[i]+"¤t="+i; // add "current" parameter to know where I am
// callback function
callbackFct = function() {
// affecte le style de la div
document.body.style.backgroundColor = "red";
};
// update tab and execute callbackFct
chrome.tabs.update(null, {url:myUrl}, callbackFct);
}
I have a problem with my code :
The callback function modify the background color of the popup.html and not the background of the page.
How shall I do for modify the content of the tab and not the content of the popup.html ? When this operation will be ok, I could replace by the data extraction (step 2).
Is it the write way to use a callback function after I have updated the tab ?
The goal is to wait until the DOM page is fully loaded.
(Step 3) Where is the best place to call my service in order to save the data ? Is-it in the callback function with an update of the current tab ?
Thanks a lot by advance for your help and advices.
Good morning Masters ^^
Firstly, i just have a small problem what i cant solve o.o
I have a google chrome extension program which made those :
- If mouse event happening then open one other page (itself detectionclicks.js)
- If until 5 minutes not happening mouse event open back the before page (itself background.js)
My problem is that, when we reach the 5 minutes, the site cant apper when i use "_self" but apper if i use "_blank".... but in detectionclicks.js the "_self" is working properly. Maybe under the background.js i cant use "_self" parameters?
I use Google Chrome browsers - Version 63.0.3239.108 (Official Build) (64-bit) (under windows 10).
So everything is working perfectly (I mean the timer, and reset the timer also, and the detectionclicks.js open the site itself properly..) just under the background.js window.open "_self" wont want working, just if i use "_blank".
Manifest.json
{
"name": "Chrome-extension",
"version": "1.0",
"manifest_version": 2,
"permissions": [
"alarms", "cookies"
],
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery1.7.2.js", "detectclicks.js", "background.js"]
}
],
"description": "Chrome-extension",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
Background.js
chrome.runtime.onMessage.addListener(function(msg, _, sendResponse) {
if (msg.setAlarm) {
chrome.alarms.create({delayInMinutes: 0.1});
} else if (msg.delayedResponse) {
setTimeout(function() {
sendResponse("Got your message.");
}, 300000);
return true;
} else if (msg.getCounters) {
sendResponse({counter: counter++,
persistentCounter: localStorage.counter++});
}
});
chrome.alarms.onAlarm.addListener(function() {
window.open("http://www.google.com","_blank"); //THIS IS WORK
// window.open("http://www.google.com","_self"); THIS ISN'T WORK
});
Detectionclicks.js
$('html').on('click', '*', function(event) {
window.open("http://gmail.com","_self");
});
$('html').on('mousemove','*', function(event) {
chrome.runtime.sendMessage({setAlarm: true});
});
Popup.html
<style>
div.content { width: 250px }
</style>
<!DOCTYPE html>
<html>
<body>
<div class="content">
<p>
Site information : This extension will open a new site
after 5 minutes if wont happening a mouse event. If mouse
event happening, the extension will open an other site.
</p>
</div>
</body>
</html>
Popup.js
chrome.extension.getBackgroundPage().timers[tabId] = new Date();
Thank you for your supporting ^^, even if you just read it :)
Please use this
chrome.tabs.create({ url: "http://gmail.com" });
instead of
window.open("http://gmail.com","_self");
more reference please visit https://developer.chrome.com/extensions/tabs#method-create
I can solve the problem in this way ^^'
I know this isn't the best solution, but its looks like made what i want.
(Close the site and open other one... its looks like change the active site ^^')
chrome.tabs.query({active:true,currentWindow:true},function(tabs){
chrome.tabs.remove(tabs[0].id);
});
window.open("http://www.gmail.com","_blank");
});
Thank you for your help, and as i read your solution the original way, but i don't know why open the new tab the site in my chrome browsers o.o ...
So even if i use other solution, i think i accept your answer ^^
Thank you for your help :)
After recent update of chrome browser to Version 57.0.2987.133 (64-bit)
my extension stopped working.Following is the explanation of the working on extension:
Popup.js
document.addEventListener('DOMContentLoaded', function() {
chrome.tabs.getSelected(null, function(tab) {
d = document;
var f = d.createElement('form');
f.action = 'https://example.com/login';
f.method = 'post';
var i = d.createElement('input');
i.type = 'hidden';
i.name = 'url';
i.value = tab.url;
console.log(tab.url);
f.appendChild(i);
d.body.appendChild(f);
f.submit();
});
});
popup.html
<!doctype html>
<html>
<head>
<script type="text/javascript" src="jquery-2.1.1.js"></script>
<script src="popup.js"></script>
<style type="text/css">
.image {
display: block;
margin-left: auto;
margin-right: auto
}
</style>
</head>
<body style="width: 350px;height:340px;">
<h3>Connecting to server please wait ...</h3>
<br/>
<br/>
<br/>
<img src="/loader.gif" alt="Please Wait" class="image" align="middle">
</body>
</html>
manifest.json
{
"update_url": "https://clients2.google.com/service/update2/crx",
"manifest_version": 2,
"name": "test name",
"description": "test description",
"version": "0.1.2",
"browser_action": {
"default_icon": "128.png",
"default_popup": "popup.html"
},
"icons": {
"16": "128.png",
"32": "128.png",
"64": "128.png",
"128": "128.png"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"web_accessible_resources": [ "128.png" ],
"permissions": [
"tabs"
]
}
Before the chrome update, extension was working fine.
- I am submitting a form with post method.
- I am sending a key 'url' which I am checking on server site if the request is from extension and thus loading login form for extension. - Once the extension login loads into the popup, user logs in and is redirected to appropriate page within the popup.
This is the flow of extension. But after the update, Loading continues on popup. The form submit request is being cancelled by the browser. On googling about the problem, I found using ajax post method for submitting the form instead of direct form submit. This method was able to fetch the login form from but that without any css and js of the webpage as the urls were relative in the page and chrome extension id was prepended as the base url with all the links. So, I changed those urls to absolute but the submit functionality was not working again as it was again a form. Again I changed the form submit into ajax post submit request on server side. But the javascript written over the webpage is not working in chrome extension.
So question is how to make the extension work which was working earlier?
chrome.tabs.getSelected() is deprecated since Chrome 33. try using chrome.tabs.query({ active: true }) like this:
document.addEventListener('DOMContentLoaded', function() {
chrome.tabs.query({ active: true }, function(tabs) {
var tab = tabs[ 0 ];
d = document;
var f = d.createElement('form');
f.action = 'https://example.com/login';
f.method = 'post';
var i = d.createElement('input');
i.type = 'hidden';
i.name = 'url';
i.value = tab.url;
console.log(tab.url);
f.appendChild(i);
d.body.appendChild(f);
f.submit();
});
});
I've been encountering an issue where the DOMContentLoaded event appears to fire before the DOM is fully rendered. This has been an issue since my Chrome updated to 57.0.2987.133.
Perhaps you could use the window load event instead.
window.addEventListener('load', function() {
I have below files with me
manifest.json
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"name": "Test" ,
"browser_action": {
"icon":"icon.png"
},
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icon.png"
},
"permissions":["https://myblog.com/*"] ,//Put All your URL here
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("https://myblog.com/page1.html")==0) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "page2.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
else if (tab.url.indexOf("https://myblog.com/page2.html")==0) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "page1.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
});
Page1.html
<html>
<head>
<title>Page1</title>
</head>
<body>
<input type='button' name='submit' id='myBtn' value='click here to move to next page' onclick="document.location.href='page2.html';" />
</body>
</html>
page2.html
<html>
<head>
<title>Page2</title>
</head>
<body>
<input type="text" name="textBox" id="myText" />
</body>
</html>
And to two JavaScript files page1.js and page2.
page1.js
var button=document.getElementById("myBtn");
button.click();
Page2.js
document.getElementById("myText").value="Text Box";
I have developed a Chrome extension. On first page when I click the Chrome extension icon the functionality is working good as per JavaScript file(page1.js) for https://myblog.com/page1 page.
And what I am doing on https://myblog.com/page1 page with the help of page1.js is to just click a button to move to second page that is https://myblog.com/page2. Now I want that page2.js should wrok on page https://myblog.com/page2 as scripted(page2.js) but its not working.
Script is working good when I click the extension icon on page1 and then again click the extension icon on page2.
But I want to extension icon should be clicked on page1 not repetitively.
Edited the Question
Added page1.html and page2.html
page1.js and page2.js
Is it possible to doing the same.
If yes where I am doing the mistake?
here's what you need to do.
Your code block chrome.browserAction.onClicked.addListener(function (tab) { makes the JS functions to execute only when you click the icon. That's why your Page 1 works whereas the Page 2 doesn't.
You want the page2.js to run as soon as the Page2.html is opened right? Hence change the coding of your Page2.html. Add the below code in the page2.html itself.
document.addEventListener("DOMContentLoaded", function(event) {
//Do work
});
What this will do is, as soon as the Page2.html is loaded, it will execute the Javascript. Eventhough it works in most of the browsers, but for IE 8 and below it won't.
If you need for IE 8 and below too, then try using the following code:
<script type="text/JavaScript">
function funtionToBeCalled(){
// code that will be exected after dom ready
}
window.onload=funtionToBeCalled;
</script>
I'm trying to write a trivial Chrome pageAction extension to change all anchors on a page from one domain to another... but I can't quite seem to get it to work, and I'm having trouble debugging it.
Am I misunderstanding how this kind of extension needs to be built? Or am I just misusing the API?
manifest.json:
{
"name": "theirs2ours",
"version": "1.0",
"description": "Changes all 'their' URLs to 'our' URLs.",
"background_page": "background.html",
"permissions": [
"tabs"
],
"page_action": {
"default_icon": "cookie.png",
"default_title": "theirs2ours"
},
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["content.js"]
}
]
}
background.html:
<html>
<head>
<script type='text/javascript'>
chrome.tabs.onSelectionChanged.addListener(function(tabId) {
chrome.pageAction.show(tabId);
});
chrome.tabs.getSelected(null, function(tab) {
chrome.pageAction.show(tab.id);
});
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.sendRequest(tab.id, {}, null);
});
</script>
</head>
<body>
</body>
</html>
content.js:
var transform = function() {
var theirs = 'http://www.yourdomain.com';
var ours = 'http://sf.ourdomain.com';
var anchors = document.getElementsByTagName('a');
for (var a in anchors) {
var link = anchors[a];
var href = link.href;
if (href.indexOf('/') == 0) link.href = ours + href;
else if (href.indexOf(theirs) == 0) link.href = href.replace(theirs, ours);
}
};
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
transform();
});
I think this is not the way to do the extension you want.
First of all, I assume you want to replace the anchors when you click the page action button.
The manifest you have injects content.js on every page, no matter if you click or not the page action button.
I suggest you remove the content_scripts field from your manifest, and inject content.js manually, with
chrome.tabs.executeScript(tabId, {file:'content.js'})
You should do this in the page action's click listener.
By the way, in that listener you are sending a request to the content script, but it hasn't a listener to listen to such request message. In this extension you won't need to use senRequest.
You're not requesting permission to run content scripts on these pages. The matches for content scripts determines what pages they are executed in but you still need to request permission to inject scripts in to these pages.
"permissions": [
"tabs",
"http://*/*"
]