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);
Related
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
}
});
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);
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);
});
}
})
I need to get the source code of the Active Tab when the extension icon is clicked; it needs to be visible in a new tab (because a pop up is limited to 800px, among other reasons).
I had no issue with this when I was using a popup, however, I now want to get the data into a new tab.
What is happening is the targetTab variable used in the onClicked callback contains the correct tab information. However, once the new tab (popup.html) is opened, nothing occurs; the document.body.innerHTML does not get changed.
Any ideas?
manifest.json
{
"name": "Stock Alert",
"description": "Create an alert and display streaming stock quotes.",
"version": "1.1",
"permissions": [
"https://www.gwm.ml.wallst.com/",
"https://*/*",
"http://*/*",
"tabs",
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_icon": "logo.png"
},
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(targetTab) {
chrome.tabs.create({'url': chrome.extension.getURL('popup.html')}, function(tab)
{
chrome.tabs.executeScript(
targetTab.id,
{
code: "document.getElementsByTagName('html')[0].innerHTML;"
},
function (sourceCode)
{
document.getElementById('dump').innerHTML = sourceCode;
});
});
});
popup.html (misnomer; this is the url of the new tab created onClicked)
<html>
<head>
<title>Stock Tracker</title>
<!--<script src="background.js"></script>-->
<link href="Streamer.css.package.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="out"></div>
<div id="dump"></div>
</body>
</html>
The issue is that the callback function is executed within the background page context. It will therefore try to find <div id="dump"></div> inside that page, rather than inside the popup page.
I've fiddled around, and I've came up with the following solution.
On click, get the content of the current page
Store that content in the background page
Load the popup.html
On load, get the code content from the background page
background.js
var myCode;
chrome.browserAction.onClicked.addListener(function(targetTab) {
chrome.tabs.executeScript(
targetTab.id,
{
code: "document.getElementsByTagName('html')[0].innerHTML;"
},
function (sourceCode)
{
myCode = sourceCode;
chrome.tabs.create({'url': chrome.extension.getURL('popup.html')});
});
});
popup.html
Add <script src="popup.js"></script>
popup.js
chrome.runtime.getBackgroundPage(function(bg)
{
document.getElementById('dump').innerHTML = bg.myCode;
});
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.