Read in loop, the content of HTML pages with Chrome extension - google-chrome-extension

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]+"&current="+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.

Related

Chrome extension not working after chrome update to Version 57.0.2987.133 (64-bit)

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() {

Performing browser action on two different pages

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>

Chrome extension: managing multiple html pages in an extension

I want to have several html files in my extension so I can open each of them according to some conditions or events. Say I want a.html to be opened when the user chooses an option on the context menu.
I tried the following:
manifest.json:
{
"name": "My extension",
"version": "1.1",
"background": { "page": ["background.html"] },
"incognito": "split",
"permissions": ["tabs", "<all_urls>", "contextMenus"],
"icons": { "16": "images/16.png" },
"manifest_version": 2
}
background.html:
<!DOCTYPE html>
<html>
<head>
<script src="background.js"></script>
<script src='someWindow.js'></script>
</head>
<body>
</body>
</html>
background.js:
var winID;
chrome.contextMenus.onClicked.addListener(function proccess_interested(info, tab){
chrome.tabs.create({active: false}, function(newTab) {
// After the tab has been created, open a window to inject the tab into it.
chrome.windows.create(
{
tabId: newTab.id,
type: "popup",
url: chrome.extension.getURL('a.html'),
focused: true
},function(window){
winID = newWindow.id;
});
});
})
chrome.extension.onMessage.addListener(function(Msg, sender, sendResponse) {
if(Msg.close_comment_win){
chrome.windows.remove(winID, function(){});
}
});
someWindow.js:
function hide_win()
{
chrome.extension.sendMessage({close_win: close}, function(response) {});
}
a.html:
<!DOCTYPE html>
<html>
<head>
<script src='someWindow.js'></script>
head //with tags, can't show it here
body
<input type='button' value=' Cancel ' onclick="hide_win()"></input>
</body>
</html>
The window is opened when context menu is clicked, but when hitting cancel, it's not closed. console.log says: Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:". I guess the reason is that a.html is not part of the extension, even though someWindow.js which triggers sendMessage is part of the extension.
Including a.html in the extension through manifest isn't an option as no more than one background html page can be included.
Of course I get the same when putting chrome.windows.remove(winID, function(){}); directly in hide_win() without using sendMessage.
Any ideas how to get this job done?
Just as the error says, it is against v2's content security policy to have any inline code in extension html pages. Simply move that handler to your js file and it should work fine.

How to make a extension/script/program that will refresh a browser until a certain phrase/keyword is found or is not found?

Is there any program/extension that I can use with browser that will refresh a webpage and search for a certain phrase or text and then stop once the phrase is found or is not found.
For example say I made a site that cycles using a randomizer through the words "One," "Two," and "Three."
This program would refresh the page until the word "Three" is found, If I set it to find that word, and then stop once it is found.
OR
This program would refresh the page until the word "Three" is not found, If I set it to find that word, and then stop once it is not found.
I know that we can use curl and grep to do that, but the page is not loaded on webbrowser. This is not what I want. see if there is solution that we can load on browser as well
If there no such things exists, any idea on how to write this kind of program? use what tool to do that?
You could very easily write an extension to do this. I would suggest instead of refreshing the page every time, you poll the data until you get the desired result then refresh the page once you find it. A short example using jQuery because I am familiar with it:
Manifest.json
{
"name": "Find Text",
"version": "0.1",
"description": "Find Text",
"manifest_version": 2,
"browser_action": {
"default_icon": "on.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs","http://*/*","https://*/*"
],
"background": {
"scripts": ["bgp.js","jquery-1.8.3.min.js"],
"persistent": true
}
}
Popup.html
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 300px; }
</style>
<script src="jquery-1.8.3.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<div>Desired Search Url</div>
<input type="text" id="searchUrl">
<div>Desired Search Text</div>
<input type="text" id="searchText">
<button id="searchButton">Search</button>
</body>
</html>
Popup.js
$(function(){
var tabId;
chrome.tabs.query({active:true,currentWindow:true}, function(tab) {
$('#searchUrl').val(tab[0].url);
tabId = tab[0].id;
});
$('#searchButton').click(function(){
chrome.extension.sendMessage({
url:$('#searchUrl').val(),
text:$('#searchText').val(),
tab:tabId
});
});
});
bgp.js
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
checkUrlForText(message.url,message.text,message.tab);
});
function checkUrlForText(url,text,tab){
var contains;
$.ajax({
url:url,
async:false,
success: function(data){
contains = $(':contains('+text+')',data);
while(contains.length == 0){
$.ajax({
url:url,
async:false,
success: function(dat){
contains = $(':contains('+text+')',dat);
}
});
}
}
});
chrome.tabs.reload(tab);
}
If having it refresh the tab every time is a requirement (the content would change between the time it found what you were looking for and when it refreshes the page) then you should use content scripts to test for the desired value and send a message to the background page if the desired text is not there to refresh the page and start again. Like this:
bgp.js
var contains;
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
checkTabForText(message.text,message.tab);
contains = false;
});
function checkTabForText(text,tab){
chrome.tabs.executeScript(tab,{file:"jquery-1.8.3.min.js"});
chrome.tabs.executeScript(tab,{file:"checkText.js"},function(){
chrome.tabs.sendMessage(tab, {text:text}, function(response){
contains = response.contains;
if(!contains){
chrome.tabs.reload(tab,function(){
checkTabForText(text,tab);
});
}
});
});
}
checkText.js
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
var contains = $(':contains('+message.text+')');
if(contains.length > 0)
sendResponse({contains:true});
else
sendResponse({contains:false});
});

Timer for chrome extension [duplicate]

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.

Resources