chrome - How to display images in popup.html using dom and js - javascript

I am doing a project and I need to display on a chrome extension popup all the images of the current selected tab website, I tried many things but the popup always shows as a small popup with nothing on it.
Here is the code:
Dom.js:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.action == "getDOM")
sendResponse({dom: document.body.getElementsByTagName("img")});
else
sendResponse({}); // Send nothing..
});
Manifest.json:
{
"manifest_version": 2,
"name": "PrintIt",
"version": "1.0",
"description": "Partilha conteudo com redes sociais",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs"
],
"content_scripts": [{
"matches": [
"http://www.google.com/*"
],
"js": [
"dom.js"
]
}]
}
Popup.html:
<html>
<head>
<script>
chrome.tabs.getSelected(null, function(tab) {
// Send a request to the content script.
chrome.tabs.sendRequest(tab.id, {action: "getDOM"}, function(response) {
document.write(response.dom);
});
});
</script>
</head>
<body>
</body>
</html>
I did console.log(response.dom) and i got the folowing errors in estension console:
Port error: Could not establish connection. Receiving end does not exist. miscellaneous_bindings:236
chromeHidden.Port.dispatchOnDisconnect miscellaneous_bindings:236
Error in event handler for 'undefined': Cannot read property 'dom' of
undefined TypeError: Cannot read property 'dom' of undefined
at chrome-extension://cfboppmcojfddlkbpohfnnnkogpeflgk/popup.js:4:23
at miscellaneous_bindings:281:11
at chrome.Event.dispatchToListener (event_bindings:390:21)
at chrome.Event.dispatch_ (event_bindings:376:27)
at chrome.Event.dispatch (event_bindings:396:17)
at Object.chromeHidden.Port.dispatchOnDisconnect (miscellaneous_bindings:239:27) event_bindings:380

I run into the same problem some time ago. It's simply prohibited to place script code inside the popup.html so it's not working. Place your code completely inside of dom.js and everything should be fine.

Related

Chrome extension working on two tabs

I am trying to create a Chrome extension that retrieves some content from the DOM of the current tab, then opens a new tab, and performs an operation on this new tab using the previously retrieved content.
I am attempting to use callbacks to perform this sequence, but I can't figure out a proper way to do it. Now I am able to execute the first script, and get the content from the current tab DOM: what I still can't do is passing this content to the second script, utilities2.js, to be executed on the new tab.
Here's my current code:
popup.html
<!doctype html>
<html>
<head><title>Extension</title></head>
<body>
<button id="clickactivity">Click here</button>
<script src="popup.js"></script>
</body>
</html>
popup.js
function injectTheScript() {
var tempStorage;
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "content_script.js"}, function(results){
tempStorage = results[0];
});
chrome.tabs.create({"url":"http://www.google.com","selected":true}, function(tab) {
});
});
}
document.getElementById('clickactivity').addEventListener('click', injectTheScript);
contentScript.js
function execContentScript() {
var code = document.getElementById('textarea').value;
return code;
}
execContentScript();
manifest.json
{
"manifest_version": 2,
"name": "My extension",
"description": "My extension",
"version": "1.0",
"permissions": ["tabs", "<all_urls>","activeTab"],
"browser_action": {
"default_popup": "popup.html"
}
}
You can store the content in the local storage of Chrome extension and after navigating to next tab, you can get the content from local storage of Chrome.
The following code may help you in this case:
chrome.storage.local.set({key: value}, function() {
console.log('Value is set to ' + value);
});
chrome.storage.local.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
If you want to learn more about the local storage of Chrome, please read from here.
Edit:
I think you don't have idea of background scripts in the Chrome extension. Background scripts which have highest privileges to run the Chrome commands.
The complete workflow will be as follows:
popup.js is included as script
When you click button, injectTheScript function will be called from popup.js
Then it will get the element id from page and then send the request to background.js
Then background.js will save the value to Chrome storage
Then background.js will create new tab
After successful creation of tab, it will execute callback function and get the value from storage of Chrome
The following is the complete code of working extension:
manifest.json
{
"manifest_version": 2,
"name": "My extension",
"description": "My extension",
"version": "1.0",
"permissions": ["tabs", "<all_urls>","activeTab","storage"],
"browser_action": {
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
popup.html
<!doctype html>
<html>
<head><
title>Extension</title>
</head>
<body>
<button id="clickactivity">Click here</button>
<script src="popup.js"></script>
</body>
</html>
popup.js
function injectTheScript() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var code="abc";
//var code = document.getElementById('textarea').value;
chrome.runtime.sendMessage({type: "navigate",value:code}, function(response) {
console.log('code saved to local storage');
});
});
}
document.getElementById('clickactivity').addEventListener('click', injectTheScript);
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.type == "navigate"){
chrome.storage.sync.set({key: request.value}, function() {
console.log('Background got request for saving the code '+request.value+' to local storage');
chrome.tabs.create({"url":"http://www.google.com","selected":true}, function( tab) {
console.log('navigated to new tab');
chrome.storage.sync.get(['key'], function(result) {
console.log('new tab key is '+result.key);
});
});
});
}
});
You don't need utilities2.js and content_script.js.
I've tested the code and it's working according to your requirements.
You can not see the console output if anything is consoled in background page. To see the output on console (for anything in background), open the link chrome://extensions
and click the button Background Page as following
A new window will appear as following

Chrome extension to change DOM with a button in extension popup

i am completely new to chrome extension development.
I am trying to change the DOM (append data to active webpage) when clicked on a button in the extension popup. How is this possible.
the manifest file
{
"manifest_version": 2,
"name": "test 2",
"description": "test ext 2",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://*/*","https://*/*"],
"js": ["jquery.min.js", "main.js"]
}
],
"permissions": [
"activeTab"
]
}
suppose if the popup.html file is
<!doctype html>
<html>
<head>
<title>test extension 2</title>
<script src="popup.js"></script>
</head>
<body>
<a id="button">button</a>
</body>
</html>
and when i click on #button, i want to execute some jquery code in main.js file which will append some data to the active webpage.
Thank you.
Use Programmatic injection. You could register event listener in popup.js and call chrome.tabs.executeScript to inject some js code/file to current active tab. This requires host permissions.
popup.js
document.getElementById('button').addEventListener('click', function() {
chrome.tabs.query({ active: true, currentWindow: true}, function(activeTabs) {
// WAY 1
chrome.tabs.executeScript(activeTabs[0].id, { code: 'YOUR CODE HERE' });
});
});
Use Message Passing. You could call chrome.tabs.sendMessage in popup.js and listen to that via chrome.runtime.onMessage in content.js.
popup.js
// WAY 2 (Replace WAY1 with following line)
chrome.tabs.sendMessage(activeTabs[0].id, { action: 'executeCode' });
content.js
chrome.runtime.onMessage.addListener(function(request) {
if(request.action === 'executeCode') {
// YOUR CODE HERE
}
});
Use Storage. You could call chrome.storage.local.set in popup.js and listen to storage change in content.js via chrome.storage.onChanged.
popup.js
// WAY 3 (Replace WAY1 with following line)
chrome.storage.local.set({ action: 'executeCode' });
content.js
chrome.storage.onChanged.addListener(function(changes) {
var action = changes['action'];
if(action.newValue === 'executeCode') {
// YOUR CODE HERE
}
});

Chrome extension and content scripts can communicate only in "inspect popup" mode

I have this rather simple extention and content script:
manifest.json:
{
"name": "My.First.App.Uses.Native.Api",
"version": "1.0",
"manifest_version": 2,
"description": "My app uses my first Native Api",
"icons": {
"128": "icon-128__2.png"
},
"permissions": [
"nativeMessaging", "activeTab"
],
"browser_action": {"default_popup": "ext-page.htm"},
"content_scripts": [
{
"matches": ["file:///*"],
"js": ["content-script.js"]
}
]
}
ext-script.js:
// Listen for messages that come from the client script.
chrome.runtime.onMessage.addListener(
function( request, sender, sendResponse ) {
if( request.greeting ) {
//connectToNative();
sendResponse( { farewell: request.greeting + ' -> received' } );
}
} );
content-script.js:
var btn = document.getElementById( 'mybutton' );
if( btn ) {
btn.addEventListener( 'click', function() {
var msg = document.getElementById( 'mytext' ).value;
if( msg ) {
chrome.runtime.sendMessage( { greeting: msg }, function( response ) {
console.log( response.farewell );
} );
//port.postMessage({joke: "Knock knock"});
}
else {
alert( "content script could not send message" );
}
} );
}
ext-page.htm:
<!DOCTYPE html>
<html>
<head>
<script src='./ext-script.js'></script>
</head>
<body>
This is a test Extention.
</body>
</html>
A sample page which the content script is injected in :
<html>
<head>
<title>Connecting to a Chrome Extention using Content Script</title>
</head>
<body>
<p>
<!--<input id="btn" type="button" value="open document" />-->
<input id="mytext" type="text" />
<input id="mybutton" name="mybutton" type="button" value="open document" />
</p>
</body>
</html>
My problem:
If I select the extention and "inspect popup" it (meaning start the debug mode), and click mybutton button on my sample page, then I receive a message back from the extension and I can see it in my page's console. What I want is to get that message simply right after clicking that button in my sample page-- of course without debugging the extension. If I do not "inspect popup" the extension, then I receive this error message:
Error in event handler for (unknown): TypeError: Cannot read property 'farewell' of undefined
Thanks!
I think because you're executing your alert inside main.js which is inside your popup, the popup needs to be open. Try inserting your alert inside background.js. Because background.js gets inserted into your sample page as a content_script, the alert should show up right in your sample page.
Instead of in background.js
if( msg ) {
chrome.extension.sendRequest( msg );
}
Do
var msg = document.getElementById( 'mytext' ).value;
if( msg ) {
alert( msg );
}
The docs suggest to have a manifest like this:
{
"manifest_version": 2,
"name": "Test",
"version": "0.1",
"background": {
"scripts": ["background.js"],
//this script is the main one which your extension communicates with
"persistent": false
},
"browser_action": {
"default_title": "BET",
"default_popup": "popup.html"
//this html file is the one that will be shown when clicked on your extension icon
},
"content_scripts": [{
//this file will get injected into the tabs
"matches": ["file:///*"],
"js": ["content.js"]
}],
"permissions": [
"tabs",
"<all_urls>"
]
}
So inside your content.js your should have
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
And inside background.js you receive the message
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request.greeting);
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
Doing it this way, you will be able to log what you sent from your injected script to your extension...just open the background console from the extensions page.
Hope this will help if you change the structure around a little. Let me know if it helps

Getting DOM in Chrome extension popup?

I'm trying to create a Chrome extension that displays the current page's DOM in a popup.
As a warmup, I tried putting a string in getBackgroundPage().dummy, and this is visible to the popup.js script. But, when I try saving the DOM in getBackgroundPage().domContent, popup.js just sees this as undefined.
Any idea what might be going wrong here?
I looked at this related post, but I couldn't quite figure out how to use the lessons from that post for my code.
Code:
background.js
chrome.extension.getBackgroundPage().dummy = "yo dummy";
function doStuffWithDOM(domContent) {
//console.log("I received the following DOM content:\n" + domContent);
alert("I received the following DOM content:\n" + domContent);
//theDomContent = domContent;
chrome.extension.getBackgroundPage().domContent = domContent;
}
chrome.tabs.onUpdated.addListener(function (tab) {
//communicate with content.js, get the DOM back...
chrome.tabs.sendMessage(tab.id, { text: "report_back" }, doStuffWithDOM); //FIXME (doesnt seem to get into doStuffWithDOM)
});
content.js
/* Listen for messages */
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
/* If the received message has the expected format... */
if (msg.text && (msg.text == "report_back")) {
/* Call the specified callback, passing
the web-pages DOM content as argument */
//alert("hi from content script"); //DOESN'T WORK ... do we ever get in here?
sendResponse(document.all[0].outerHTML);
}
});
popup.js
document.write(chrome.extension.getBackgroundPage().dummy); //WORKS.
document.write(chrome.extension.getBackgroundPage().domContent); //FIXME (shows "undefined")
popup.html
<!doctype html>
<html>
<head>
<title>My popup that should display the DOM</title>
<script src="popup.js"></script>
</head>
</html>
manifest.json
{
"manifest_version": 2,
"name": "Get HTML example w/ popup",
"version": "0.0",
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"]
}],
"browser_action": {
"default_title": "Get HTML example",
"default_popup": "popup.html"
},
"permissions": ["tabs"]
}
You got the syntax of chrome.tabs.onUpdated wrong.
In background.js
chrome.tabs.onUpdated.addListener(function(id,changeInfo,tab){
if(changeInfo.status=='complete'){ //To send message after the webpage has loaded
chrome.tabs.sendMessage(tab.id, { text: "report_back" },function(response){
doStuffWithDOM(response);
});
}
})

Content-Security-Policy error in google chrome extension making

I am making a chrome extension that will open all links on a page in new tabs.
Here are my code files:
manifest.json
{
"name": "A browser action which changes its icon when clicked.",
"version": "1.1",
"permissions": [
"tabs", "<all_urls>"
],
"browser_action": {
"default_title": "links", // optional; shown in tooltip
"default_popup": "popup.html" // optional
},
"content_scripts": [
{
"matches": [ "<all_urls>" ],
"js": ["background.js"]
}
],
"manifest_version": 2
}
popup.html
<!doctype html>
<html>
<head>
<title>My Awesome Popup!</title>
<script>
function getPageandSelectedTextIndex()
{
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function (response)
{
console.log(response.farewell);
});
});
}
chrome.browserAction.onClicked.addListener(function(tab) {
getPageandSelectedTextIndex();
});
</script>
</head>
<body>
<button onclick="getPageandSelectedTextIndex()">
</button>
</body>
</html>
background.js
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
updateIcon();
});
function updateIcon() {
var allLinks = document.links;
for (var i=0; i<allLinks.length; i++) {
alllinks[i].style.backgroundColor='#ffff00';
}
}
Initially I wanted to highlight all the links on the page or mark them in some way; but I get the error "Refused to execute inline script because of Content-Security-Policy".
When I press the button inside the popup, I get this error: Refused to execute inline event handler because of Content-Security-Policy.
Please help me fix these errors, so I can open all links in new tabs using my chrome extension.
One of the consequences of "manifest_version": 2 is that Content Security Policy is enabled by default. And Chrome developers chose to be strict about it and always disallow inline JavaScript code - only code placed in an external JavaScript file is allowed to execute (to prevent Cross-Site Scripting vulnerabilities in extensions). So instead of defining getPageandSelectedTextIndex() function in popup.html you should put it into a popup.js file and include it in popup.html:
<script type="text/javascript" src="popup.js"></script>
And <button onclick="getPageandSelectedTextIndex()"> has to be changed as well, onclick attribute is also an inline script. You should assign an ID attribute instead: <button id="button">. Then in popup.js you can attach an event handler to that button:
window.addEventListener("load", function()
{
document.getElementById("button")
.addEventListener("click", getPageandSelectedTextIndex, false);
}, false);

Categories

Resources