I'm currently trying to make sense of Google Chrome Extension development, but I'm having issues understanding it correctly.
I'm developing an extension that hosts a list of URLs and opens them on click. This sounds like a trivial task, but it doesn't work. Probably I'm doing something blatantly wrong.
Screenshot
It's not styled, but that's step 2. Basically, I want to open a shortcut on click:
manifest.json
{
"manifest_version": 2,
"name": "Chrome Shortcuts",
"description": "This extension provides shortcuts to locations in Google Chrome",
"version": "1.0.0",
"browser_action":
{
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts":
[
{
"js": [ "popup.js" ],
"matches": [ "http://*/*", "https://*/*" ]
}
],
"permissions":
[
"tabs",
"http://*/*"
]
}
popup.html
<!doctype html>
<html>
<head>
<title>Chrome Shortcuts</title>
<script src="popup.js"></script>
</head>
<body>
<ul>
<li>Settings - Passwords</li>
</ul>
</body>
</html>
popup.js
function OpenShortcut(location)
{
chrome.tabs.create({ url: location });
}
You cannot open chrome:// URLs using standard methods. This is a privileged page and the navigation will fail.
Instead, you need to use tabs API. Specifically,
chrome.tabs.create({url: "chrome://settings/passwords"});
Add active: false if you need it to open in background without closing the popup.
I completely missed the fact you're doing it already, sorry! The issue is with trying to activate your code with href="javascript:[some code]".
This, as well as onclick="[some code]", will fail in a Chrome extension due to the Content Security Policy. Specifically, inline code is not allowed (and you cannot modify the CSP in a way that allows it).
The docs give a solution to this - assign the handler from your code, i.e.
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('link1').addEventListener('click', function() {
OpenShortcut('chrome://settings/passwords');
});
});
For this to work, add an id attribute to your links. DOMContentLoaded wrapper is required, since your popup.js is executed before your node exists in the DOM.
Related
Preface: I'm a beginner to this stuff.
I'm trying to make an extension that replaces the current tab url with a predefined url. So far I have the following:
chrome.tabs.getSelected(null, function(tab){
chrome.tabs.update(tabs.id, {url: "https://www.wikipedia.org/"});
});
The chrome app developer tool tells me that "tabs is not defined" but I have "tabs" in my manifest permissions. Manifest:
"permissions": [
"tabs",
"declarativeContent",
"https://www.wikipedia.org/"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_icon": "icon-19.png",
"default_title": "Simple-Switch"
}
Permissions don’t declare variables that you can use (as if there were a "var tabs"); they define what functions you are allowed to use (in this case, that you can call functions in chrome.tabs).
Your problem is that your callback takes an argument of tab, but you use the variable tabs. Hence "tabs is not defined". So the simplest fix would be function(tabs). But you should also use tabs.query instead of the deprecated tabs.getSelected:
chrome.tabs.query({active:true,currentWindow:true}, function(tabs){
chrome.tabs.update(tabs[0].id, {url: "https://www.wikipedia.org/"});
});
You can also change the tabs permission to activeTab.
How can I create an extension for Chrome that adds an icon to the toolbar, and when you click it, it opens a new tab with some local web page (for example: f.html)?
I saw this question, but it doesn't really explains what should I add in the manifest file...
This is not true for newer chrome apps.
Newer chrome apps having manifest_version: 2
requires the tabs be opened as:
chrome.browserAction.onClicked.addListener(function(activeTab)
{
var newURL = "http://www.youtube.com/watch?v=oHg5SJYRHA0";
chrome.tabs.create({ url: newURL });
});
Well, in the extensions docs, it states in manifest, you would need to include "tabs" as its permission. Same way they explain the hello world application:
Manifest File:
{
"name": "My Extension",
"version": "1.0",
"description": "Opens up a local webpage",
"icons": { "128": "icon_128.png" },
"background_page": "bg.html",
"browser_action": {
"default_title": "",
"default_icon": "icon_19.png"
},
"permissions": [
"tabs"
],
}
Within the background page, you listen to the mouse click event on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('f.html')}, function(tab) {
// Tab opened.
});
});
As you noticed above, you will see that I used the question you saw in the other post. Note, this isn't tested, but I believe it should work.
chrome.tabs.create need the permission of "tabs".
Simply using window.open in extension without need of any permission. and the code is shorter. I suggest this solution.
window.open(url,'_blank');
I have tried many ways( all documented procedures)to inject script into a specific page upon checking URL at onUpdated.addListener. Finally the below code with 'executescript' seems to work, but not perfectly. I could able to get alerts but can not able to find document elements of the page through getElementById/getElementsByName.
When I inspected the page, script is injected. But in error console I get:
Denying load of chrome-extension://jfeiadiicafjpmaefageabnpamkapdhe/js/Leoscript.js. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
Manifest.json:
{
"name": "Leo Extension for Job Boards",
"version": "1.6",
"manifest_version": 2,
"content_security_policy": "script-src 'self'; object-src 'self'",
"description": "Leo Extension",
"background": {
"scripts": ["js/Leojshelper.js"],
"persistent": true
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/eventPage.js"],
"run_at" : "document_start"
}
],
"icons":{"48":"images/bob48.png", "128":"images/bob128.png"}, //Define any icon sizes and the files that you want to use with them. 48/128 etc.
"browser_action": {
"default_icon": "images/bob.png", // What icon do you want to display on the chrome toolbar
"default_popup": "LeoExtwatch.html" // The page to popup when button clicked.
},
"permissions": [
"tabs", "<all_urls>" // "http://*/*","https://*/*" // Cross Site Access Requests
],
"web_accessible_resources": ["js/LeoScript.js"]
}
I have also given 'web_accessible_resources' permission to the script, but still no success. Code in background script:
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
if (tab.url.indexOf("in.yahoo") !== -1) {
chrome.tabs.update(tabId, { url: "https://login.yahoo.com/config/mail?.intl=us" });
chrome.tabs.executeScript(tabId, {
code: "document.body.appendChild(document.createElement('script')).src='" +
chrome.extension.getURL("js/LeoScript.js") + "';"
}, null);
Code in LeoScript.js, which will be injected into specific page.
$(document).ready(function () {
alert('injected');
document.getElementById('username').value='aaaaaaa';
});
Content Script :eventPage.js which I used to inject script.
var script = document.createElement('script');
script.src = chrome.extension.getURL("js/Leoscript.js");
(document.body || document.head || document.documentElement).appendChild(script);
Please point me at any changes in the above code that will solve the permission issues. Thanks in advance.
UPDATE: Finally figured out your problem. In eventPage.js, you tried to inject js/Leoscript.js, which is NOT whitelisted, instead of js/LeoScript.js (with a capital 'S'), which is whitelisted. Note that URLs are case-sensitive!
chrome.tabs.executeScript(tabId, {file: 'js/LeoScript.js'});
LeoScript.js:
alert('injected');
document.getElementById('username').value='aaaaaaa';
EDIT:
This is working version where combination of web_accessible_resources and Injection is used
manifest.json
{
"name":"Off Screen Tabs Demo",
"description":"This demonstrates Off Screen Tabs API",
"manifest_version":2,
"version":"1",
"permissions":["tabs","<all_urls>"],
"browser_action":{
"default_icon":"screen.png",
"default_popup":"popup.html"
},
"web_accessible_resources": ["js/LeoScript.js"] ,
"permissions":["tabs","<all_urls>"]
}
LeoScript.js
alert("Injected..");
popup.html
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js*
document.addEventListener("DOMContentLoaded",function (){
chrome.tabs.executeScript( {"file": "js/LeoScript.js"});
});
Let me know if you still have problem in getting it running
Many will land up on this page for this error because they have not included their images/web resources in the manifest.json file. The link to the api documentation is helpful, so sharing it: web resource in manifest
For some reason I cannot see the HTTP calls made from within a swf file (video) using the Google Chrome webRequest API. I have two files: background.html + manifest.json. I do capture normal requests to example.com (images, AJAX, js), but do not capture AJAX requests made within a swf file on the same page. Is this possible?
background.html
<!DOCTYPE html>
<html>
<head>
<script>
function interceptRequest(request) {
alert(request.url);
}
chrome.webRequest.onSendHeaders.addListener(
interceptRequest,
{ urls: [ '*://*.example.com/*', ] }
);
</script>
</head><body></body>
</html>
manifest.json
{
"name": "My Extension",
"version": "0.1",
"background_page": "background.html",
"permissions" : [
"webRequest",
"*://*/*"
]
}
I was able to fix this by selecting "Log XMLHttpRequests" under Developer Tools Settings. Hope this helps someone else.
I have created a chrome extension and managed to open the popup.html file using window.open. however I want to open it in a new tab, I've tried lots of different ways including:
<script type="text/javascript" language="JavaScript">
chrome.tabs.create('url': 'popup.html');
Am I just placing the code in the wrong place or is it the wrong code altogether?
why would you want to open the popup.html in a new tab? You should create a different page for that. Anyways, if you want to open up the popup.html, in a new tab, you would need to pass in the extension url.
http://code.google.com/chrome/extensions/extension.html#method-getURL
chrome.tabs.create({'url': chrome.extension.getURL('popup.html')}, function(tab) {
// Tab opened.
});
Now you can use Event Pages to open popup.html in new tab when extension icon is clicked without creating a default_popup page.
manifest:
"background": {
"scripts": ["background.js"],
"persistent": false
}
js:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('popup.html'), 'selected': true});
});
Use chrome.tabs.create(Object properties, function callback) as described on http://code.google.com/chrome/extensions/tabs.html
The object properties could contain fields for windowId, index, url and selected. The optional callback function receives a Tab object of the newly created tab.
So the simplest example to create a new tab in the current window and get it selected would look like this:
chrome.tabs.create({'url': chrome.extension.getURL('popup.html')});
Not sure why you would like to show the popup.html in a new tab, but I find it very useful while developing/debugging my extension ... it is quite a pain that on the extension page there is "usually" only a link to the background page.
Would love to know how to open it in a new window and maybe in a kiosk mode ;-)
One complete, worked example:
Manifest.json
{
"manifest_version": 2,
"name": "HelloWorld",
"version": "0.0.1",
"description": "This is HelloWorld",
"author": "BaiJiFeiLong#gmail.com",
"browser_action": {
},
"background": {
"scripts": [
"background.js"
]
}
}
background.js
// Created by BaiJiFeiLong#gmail.com at 2022/4/13
chrome.browserAction.onClicked.addListener(async () => {
await chrome.tabs.create({url: chrome.extension.getURL("popup.html")});
})
popup.html
<!--Created by BaiJiFeiLong#gmail.com at 2022/4/13-->
<body style="min-width: 500px">
<h1>Hello World</h1>
</body>