host_permissions for 1 user specified domain - google-chrome-extension

We have an extension that currently has host_permission access to 3 different domains. We want to add a 4th. The issue is that this 4th domain will be set by the user in the extension's options page, and could be anything.
I have read about using all_urls as the host_permission and believe it can be done that way. My questions are:
Is there no other way to give permission to the specific domain the user sets up in options? (Something like the background script would see a new domain there and prompt the user for permission to access that 1 domain)
Is there potentially any issues with getting pass Google's approval process when using all_urls? We would be using all_urls to access just 1 domain, which I read was an issue at least in the past, but in our case that 1 domain is unknown at install time.

This sample adds host to origins on request button click.
Also, click the getAll button to display origins and permissions on the console.
Adding to origins without user gesture will result in the following error:
"Unchecked runtime.lastError: This function must be called during a user gesture"
manifest.json
{
"name": "optional_host_permissions",
"version": "1.0",
"manifest_version": 3,
"host_permissions": [
"*://*.google.com/"
],
"optional_host_permissions": [
"<all_urls>"
],
"action": {
"default_popup": "popup.html"
}
}
myscript.js
const elmRequest = document.getElementById("request");
const elmGetAll = document.getElementById("getAll");
elmRequest.onclick = () => {
request();
}
elmGetAll.onclick = () => {
getAll();
}
function request() {
chrome.permissions.request({
origins: ["https://hoge.com/"]
}, (granted) => {
console.log(granted);
});
}
function getAll() {
chrome.permissions.getAll((permissions) => {
console.log(permissions);
});
}
popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body style="min-width:250px">
<input type="button" id="request" value="request"><br>
<input type="button" id="getAll" value="getAll">
<script src="myscript.js"></script>
</body>
</html>

Related

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.

Chrome Extensions Optional Permissions wont evaluate callback function

I've encountered a problem using the Optional Permissions API for Chrome Extensions. In the following minimal example of an extension, I expect the script to first check whether a permission exists, and if not, request permissions and modify a token to say the permission exists. I implemented this via the options page for an extension, and success is indicated by a square turning from red to blue. Failure is indicated by the square remaining red.
Here's the funny thing, the script only works if I set a breakpoint in Chrome's Inspector and proceed step by step through it. It fails to work (wont even prompt for permissions) when the extension is run without breakpoints. I submitted this as a bug for Chrome, but I really wonder if I'm doing something wrong.
manifest.json
{
"description": "Permissions Tester",
"name": "Permissions Tester",
"options_page": "options.html",
"optional_permissions": [ "http://api.labs.crossref.org/" ],
"version": "1.0.0"
}
options.html
<script>
function setCrossrefPermission() {
var perm;
chrome.permissions.contains({
origins: ['http://api.labs.crossref.org/']
}, function(result) {
if(!result) {
chrome.permissions.request({
origins: ['http://api.labs.crossref.org/']
}, function(granted) {
perm = granted;
});
} else {
perm = true;
}
});
return perm;
}
function hitIt() {
if( setCrossrefPermission() ) document.getElementById("notify").style.backgroundColor = "blue";
}
</script>
<html>
<body>
<div style="width: 100px; height:100px; background-color:red;" id="notify"></div>
<input type="submit" id="button" onclick="hitIt(); return false;" value="Accept Permission" />
</body>
</html>
I uploaded this as a CRX here for ease of installing and trying. Or you can simply load the unpacked extension above.
Unfortunately you can't call chrome.permissions.request in the chrome.permissions.contains callback function because it isn't in the correct context. Also, you don't actually need to check for the permission beforehand either.
function setCrossrefPermission() {
chrome.permissions.request({
origins: ['http://api.labs.crossref.org/']
}, function(granted) {
return granted;
});
}
For an already accepted permission prompt the warning message isn't displayed.

Trivial Chrome pageAction extension not working

I'm trying to write a trivial Chrome pageAction extension to change all anchors on a page from one domain to another... but I can't quite seem to get it to work, and I'm having trouble debugging it.
Am I misunderstanding how this kind of extension needs to be built? Or am I just misusing the API?
manifest.json:
{
"name": "theirs2ours",
"version": "1.0",
"description": "Changes all 'their' URLs to 'our' URLs.",
"background_page": "background.html",
"permissions": [
"tabs"
],
"page_action": {
"default_icon": "cookie.png",
"default_title": "theirs2ours"
},
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["content.js"]
}
]
}
background.html:
<html>
<head>
<script type='text/javascript'>
chrome.tabs.onSelectionChanged.addListener(function(tabId) {
chrome.pageAction.show(tabId);
});
chrome.tabs.getSelected(null, function(tab) {
chrome.pageAction.show(tab.id);
});
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.sendRequest(tab.id, {}, null);
});
</script>
</head>
<body>
</body>
</html>
content.js:
var transform = function() {
var theirs = 'http://www.yourdomain.com';
var ours = 'http://sf.ourdomain.com';
var anchors = document.getElementsByTagName('a');
for (var a in anchors) {
var link = anchors[a];
var href = link.href;
if (href.indexOf('/') == 0) link.href = ours + href;
else if (href.indexOf(theirs) == 0) link.href = href.replace(theirs, ours);
}
};
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
transform();
});
I think this is not the way to do the extension you want.
First of all, I assume you want to replace the anchors when you click the page action button.
The manifest you have injects content.js on every page, no matter if you click or not the page action button.
I suggest you remove the content_scripts field from your manifest, and inject content.js manually, with
chrome.tabs.executeScript(tabId, {file:'content.js'})
You should do this in the page action's click listener.
By the way, in that listener you are sending a request to the content script, but it hasn't a listener to listen to such request message. In this extension you won't need to use senRequest.
You're not requesting permission to run content scripts on these pages. The matches for content scripts determines what pages they are executed in but you still need to request permission to inject scripts in to these pages.
"permissions": [
"tabs",
"http://*/*"
]

Chrome extension and history.onVisited event

I'm new to the Chrome extensions development, and i have the following questions:
My extension should work in background, with no UI, and show an alert dialog every time the user visits a specific web page. So it should work always, in backround, when the browser is executed.
I was trying with the following code without results:
manifest.json
{
"name": "My First Extension",
"version": "1.0",
"description": "The first extension that I made.",
"background_page": "background.html",
"permissions": [
"history"
]
}
background.html
<html>
<head>
<script>
chrome.history.onVisited.addListener(function(HistoryItem result) {
if (result.url == "http://my.url.com") {
alert("My message");
}
});
</script>
</head>
</html>
What's wrong with this code?
Thanks
Take HistoryItem out of the function and you are fine:
<html>
<head>
<script>
chrome.history.onVisited.addListener(function(result) {
if (result.url == "http://my.url.com/") {
alert("My message");
}
});
</script>
</head>
</html>
Also note that I added the slash at the end of "http://my.url.com/" since that is what will be returned in result.url.
Test this:
<script>
chrome.history.onVisited.addListener(function(e) { console.log(e)})
</script>
it's clearly

Resources