develop screenshot chrome extension - javascript

i saw a lot of answers here but no one is what i'm looking for.
i want to take screenshot from chrome extension just for the screen i see at the first time without scrolling the page.
and "alert" the created file base64 path.
i have all the right permissions:
"permissions": [
"activeTab",
"tabs" ,
"storage",
"unlimitedStorage",
"browsingData",
"notifications",
"http://*/*",
"https://*/*",
"file://*/*",
"background" // added after i got the answer
],
"background": { // added after i got the answer
"scripts": [
"js/background.js"
]
},
in my manifest.json
i also have the code:
$(document).ready(function() {
alert("1");
chrome.tabs.captureVisibleTab(null, {}, function (image) {
alert("2");
});
});
i got 1 all the time but 2 i never get and i don't know why. please help..
thanks ..
UPDATE
that's the missing part (background.js)
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
chrome.tabs.captureVisibleTab(
null,
{},
function(dataUrl){
sendResponse({imgSrc:dataUrl});
}); //remember that captureVisibleTab() is a statement
return true;
}
);
and then :
chrome.tabs.captureVisibleTab(null, {}, function (image) {
// alert("2");
alert(response.imgSrc);
});

You can't do extension API call in content script.Try to use use message passing if you really want to trigger this function in content script.
And please note that the permission requirement of tabs.captureVisibleTab() has been updated since chrome rev.246766.
Extension need to have '< all_urls >' permission, or been granted the
'activeTab' permission to be allowed to use tabs.captureVisibleTab().
Developer doc doesn't mention it.
manifest.json
"permissions": [
"activeTab",
"tabs" ,
"storage",
"unlimitedStorage",
"browsingData",
"notifications",
"http://*/*",
"https://*/*",
"file://*/*",
"<all_urls>"
]
Try to execute this code below in background page and screenshot capturing will work as expected.
chrome.tabs.captureVisibleTab(null,{},function(dataUri){
console.log(dataUri);
});
screenshot

It actually does not work on Google pages as on the Extensions page, were it looks very natural to test your extension while developing.
(Should be a way to test that before taking the snapshot, I think...)

Related

Communication between background.js and content-script? Response is UNDEFINED

From content-script:
chrome.runtime.sendMessage({ type: "getFormatOption" }, function (response) {
return response === 'csv';
});
I have inspected in console: the value, which is used in SendResponse() from background.js method is OK. The problem is that response is always UNDEFINED. What am I doing wrong?
background.js:
chrome.runtime.onMessage.addListener(
function (message, sender, sendResponse) {
switch (message.type) {
case 'getFormatOption':
var response = $('input[name=csvOrEnter_radio]:checked', '#csvOrEnter_form').val();
console.log('formatOption: ' + response);
sendResponse(response);
break;
case 'getFilteringStrategy':
var response = $('input[name=filteringStrategy_radio]:checked', '#filteringStrategy_form').val();
console.log('filteringStrategy: ' + response);
sendResponse(response);
break;
default:
console.error('Unrecognised message: ', message);
}
}
);
The idea that I take some values from radiobuttons from my plugin popup.html.
Manifest:
{
// default for the latest version of Chrome extensions
"manifest_version": 2,
// extension related general info
"name": "FB Interest Search Tool",
"short_name": "FB Interest Search Tool",
"description": "FB Interest Search Tool",
"version": "1.0.0",
"default_locale": "en",
// sets path to popup files
"browser_action": {
"default_icon": "img/128.png",
"default_popup": "popups/popup.html",
"default_title": "FB Interest Search Tool"
},
// sets path to content scripts and when they are injected onto the page
"content_scripts": [
{
"matches": [ "http://*/*", "https://*/*" ],
"css": [ "styles/styles.css" ],
"js": [
"bower_components/jquery.min.js",
"bower_components/jquery.cookie.js"
]
}
],
// sets path to background scripts
"background": {
"scripts": [
"bower_components/jquery.min.js",
"bower_components/jquery.cookie.js",
"bg/background.js",
"content-scripts/rewriteStorage.js"
]
},
"permissions": [
"activeTab",
"http://*/",
"https://*/",
"file:///*/*",
"<all_urls>",
"tabs",
"storage",
"unlimitedStorage",
"storage",
"cookies"
],
"web_accessible_resources": [ "styles/commentblocker_on.css" ]
}
Problem 1: it's called background.js.
I'm not even remotely joking. Well maybe a little.
Since it's included BOTH in the popup and as a background script, there are 2 message listeners registered. And only one can answer:
Note: If multiple pages are listening for onMessage events, only the first to call sendResponse() for a particular event will succeed in sending the response. All other responses to that event will be ignored.
Guess which gets to answer first? My bets are on the background, since it registered the listener first.
While you still see the listener execute in the popup if you try to debug, its sendResponse is ignored because the background already answered.
This one's easy to fix: make a copy, call it popup.js, and keep only relevant logic in both. Don't include the same file in both places unless you're 100% certain code needs to run in both.
Problem 2: Popup is mortal.
When the popup is closed — it's dead, Jim. It simply does not exist: neither the listener, nor the radiobuttons. Therefore, it cannot answer the message.
Fixing this requires reworking the architecture. The only 2 places that can provide storage you can query at any time are:
Background page. It needs to hold the state in a way other than selected element, and the popup needs to inform about the change of state.
chrome.storage API. Both the popup and the content script can read/write to it.
For options, the second one is preferable.

Auto start chrome extension

I am trying to make a chrome extension that redirects to a other page when it's loaded. For example, if it's google.nl, go to google.nl?example I managed to get that working, but only when i press the extension button. I want to run the script from the background.js but i get the error:
Uncaught TypeError: Cannot read property 'onBeforeRequest' of undefined
Why do i wan't to reload? Well i don't. it's just to test. The original plan is reading the URL and put the open graph data in my extension.
manifest (part)
"content_scripts": [{
"matches": [
"<all_urls>"
],
"js": ["background.js"]
}],
"permissions": [
"tabs",
"activeTab",
"webRequest"
],
"background": {
"scripts": ["background.js"]
}
background.js
chrome.webRequest.onBeforeRequest.addListener(function(a) {
if (a.url.indexOf("http://www.google.com/") >= 0) {
reloadExtensions();
chrome.tabs.get(a.tabId, function(b) {
if ((b.selected == false)) {
chrome.tabs.remove(a.tabId)
}
});
return {redirectUrl: chrome.extension.getURL("close.html")}
}
return {cancel: false}
}, {urls: ["http://reload.extensions/"],types: ["main_frame"]}, ["blocking"]);
iirc the docs say you need to put all the URL's you want to redirect in the permissions array.
If you don't you will see the following error
Checkout Catblock example https://developer.chrome.com/extensions/samples#search:webrequest by removing
I don't think you need the content script parts at all, in fact I suspect that is where you are seeing the error.

chrome.webRequest.onBeforeRequest.addListener Cannot read property 'onBeforeRequest' of undefined

I'm trying to build my own chrome extension and I'm trying to add an event handler using onBeforeRequest.
My manifest.json:
{
"manifest_version": 2,
"name": "My extension",
"description": "some descrpition",
"version": "1.0",
"permissions": [
"activeTab",
"tabs",
"webRequest",
"webNavigation",
"management",
"http://*/*",
"https://*/*"
],
"background": {
"scripts": [
"js/jquery-2.1.4.min.js",
"js/background.js"
],
"persistent": true
},
"browser_action": {
"default_icon": "imgs/img.png",
"default_title": "extension"
},
"icons" : {
"64" : "imgs/vergrootglas.png"
}
}
My background.js:
function callback(param1,param2,param3){
alert(param1);
alert(param2);
alert(param3);
}
//alert("test");
chrome.webRequest.onBeforeRequest.addListener(callback);
I got this loaded into my chrome. But everytime I get this message in my console:
Uncaught TypeError: Cannot read property 'onBeforeRequest' of
undefined
I can't figure out what I'm oding wrong, I've found this:
https://developer.chrome.com/extensions/webRequest
But the example of the code seems to be quite the same as what I do.
What am I missing here?
The comments above don't make sense to me. There is a background script above and it seems to have appropriate permissions... Some extra comments that might help...
You need to add a background page in the manifest file and the appropriate permissions in the manifest so the background page can access the webRequest APIs. See this example: chrome.webRequest not working?
As Mihai mentioned, if you need to have the content script perform the action, check this page out: https://developer.chrome.com/extensions/messaging
Add this to your content script (you can change greeting to action and hello to which action the background script should perform):
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
Add this to your background page (you can do if statements and peform different actions based on the message):
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
I just ran into a similar issue, except the problem for me was unrelated to permissions and it was in fact a Webpack issue.
My background script was accidentally being bundled with my content script. Background js was exporting certain constants that content script was using, causing methods restricted to background file (such as chrome.webRequest) to be called as part of content script, hence the cannot read property of undefined…

Chrome Extension: how to change JS url before he starts loading

I wanna change src of js javascript before he starts loading using a Chrome Extension.
Manifest.json
{
"name":"Inject DOM",
"version":"1",
"manifest_version":2,
"permissions": [
"webRequest",
"webNavigation",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"run_at": "document_end",
"matches": ["http://www.example.com/*"],
"js": ["inject_this.js"]
}
]
}
inject_this.js
I execute this code in various functions scenarios
var element = event.srcElement;
if(/production_path/.test(element.src)){
element.src = element.src.replace(/production_url/gi, "dev_path");
}
Scenario A
document.addEventListener('DOMNodeInserted', nodeInsertedCallback);
Scenario B
Executing this scenario into inject_this.js throw this TypeError:
Uncaught TypeError: Cannot read property 'onBeforeRequest' of undefined
Executing this in another js doesn't work
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
if(/production_url/.test(details.url)){
return {
redirectUrl: details.usl.replace(/production_url/gi, "dev_url")
}
}
},
{urls: ["<all_urls>"]},
["blocking"]);
Where do i put this snippet code ?
Scenario C
document.addEventListener('beforeload', doBeforeLoad , true);
but every time script.src is changed too late, the resource is loaded.
How can I change javascript url before he starts loading?
Your solution B should work.
Two conditions need to be met for this to work:
This code should go to a background script / event page.
You need appropriate permissions: "webRequest", "webRequestBlocking"
You probably also should not use it on <all_urls>, since your extension seems to be specific to a single site (from your manifest). Doing it on all URLs is going to slow your Chrome down and may lead to breaking other sites, consider using a restrictive match pattern like "http://www.example.com/*production_url*"

Chrome extension that acts only when clicked on certain webpages

I'm trying to get my Chrome extension to pop up an alert when the user is on http://google.com/ and clicks on the extension icon.
I have the following manifest:
{
"manifest_version": 2,
"name": "One Megahurt",
"version": "0.1",
"permissions": [
"activeTab"
],
"background": {
"scripts": ["bg.js"],
"persistent": false
},
"browser_action": {
"default_icon": "icon.png"
}
}
and this is bg.js:
chrome.browserAction.onClicked.addListener(function(tab) {
alert('Test!');
})
This code will allow popup an alert on any website, as I don't have any restrictions on which websites this works on. I tried using
if(tab.url === "https://google.com/")
between the first and second lines, but that didn't work.
I'm not sure if I should even be using a background script rather than a content script. I looked in Google's examples and tried using the implementation in "Page action by URL", but that didn't work for me either.
Any help would be appreciated. I should note that I don't really care about the specific issues with the URL--google.com is merely an example. I want to learn to use this for other projects and websites.
EDIT: Adding urls to permissions doesn't restrict which websites the alert pops up on, either.
I ended up using page actions for my solution, per Felix King's suggestion. In retrospect, this was the best solution to use because it doesn't load the extension on every page and cause browser slowdowns (as far as I know).
In addition to adding domains to permissions in the manifest, add a the following code to a background.js.
// 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 URL matches one of the following ...
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlMatches: 'http://google.com/' }, // use https if necessary or add another line to match for both
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlMatches: 'http://facebook.com/*' },
}) // continue with more urls if needed
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction()]
}
]);
});
});
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, { file: "script.js" });
});
Key sections to add in manifest.js are:
"background": {
"scripts": ["res/background.js"],
"persistent": false
}
&
"permissions": [
"declarativeContent", "tabs", "activeTab", "http://google.com", "http://facebook.com/*"
]
I don't have much experience with this, but looking at the example manifests that I've seen, they usually have the a list of domains under permissions. I'm betting that if you used:
"permissions": ["http://www.google.com/", "https://www.google.com/", https://google.com, https://google.com],
it would only run the code on the permissible pages.
Pulled example from:
http://developer.chrome.com/extensions/overview
More detailed info here:
http://developer.chrome.com/extensions/declare_permissions

Categories

Resources