Chrome Extensions Optional Permissions wont evaluate callback function - google-chrome-extension

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.

Related

host_permissions for 1 user specified domain

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>

window.open _self not working in background.js - chrome extension

Good morning Masters ^^
Firstly, i just have a small problem what i cant solve o.o
I have a google chrome extension program which made those :
- If mouse event happening then open one other page (itself detectionclicks.js)
- If until 5 minutes not happening mouse event open back the before page (itself background.js)
My problem is that, when we reach the 5 minutes, the site cant apper when i use "_self" but apper if i use "_blank".... but in detectionclicks.js the "_self" is working properly. Maybe under the background.js i cant use "_self" parameters?
I use Google Chrome browsers - Version 63.0.3239.108 (Official Build) (64-bit) (under windows 10).
So everything is working perfectly (I mean the timer, and reset the timer also, and the detectionclicks.js open the site itself properly..) just under the background.js window.open "_self" wont want working, just if i use "_blank".
Manifest.json
{
"name": "Chrome-extension",
"version": "1.0",
"manifest_version": 2,
"permissions": [
"alarms", "cookies"
],
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery1.7.2.js", "detectclicks.js", "background.js"]
}
],
"description": "Chrome-extension",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
Background.js
chrome.runtime.onMessage.addListener(function(msg, _, sendResponse) {
if (msg.setAlarm) {
chrome.alarms.create({delayInMinutes: 0.1});
} else if (msg.delayedResponse) {
setTimeout(function() {
sendResponse("Got your message.");
}, 300000);
return true;
} else if (msg.getCounters) {
sendResponse({counter: counter++,
persistentCounter: localStorage.counter++});
}
});
chrome.alarms.onAlarm.addListener(function() {
window.open("http://www.google.com","_blank"); //THIS IS WORK
// window.open("http://www.google.com","_self"); THIS ISN'T WORK
});
Detectionclicks.js
$('html').on('click', '*', function(event) {
window.open("http://gmail.com","_self");
});
$('html').on('mousemove','*', function(event) {
chrome.runtime.sendMessage({setAlarm: true});
});
Popup.html
<style>
div.content { width: 250px }
</style>
<!DOCTYPE html>
<html>
<body>
<div class="content">
<p>
Site information : This extension will open a new site
after 5 minutes if wont happening a mouse event. If mouse
event happening, the extension will open an other site.
</p>
</div>
</body>
</html>
Popup.js
chrome.extension.getBackgroundPage().timers[tabId] = new Date();
Thank you for your supporting ^^, even if you just read it :)
Please use this
chrome.tabs.create({ url: "http://gmail.com" });
instead of
window.open("http://gmail.com","_self");
more reference please visit https://developer.chrome.com/extensions/tabs#method-create
I can solve the problem in this way ^^'
I know this isn't the best solution, but its looks like made what i want.
(Close the site and open other one... its looks like change the active site ^^')
chrome.tabs.query({active:true,currentWindow:true},function(tabs){
chrome.tabs.remove(tabs[0].id);
});
window.open("http://www.gmail.com","_blank");
});
Thank you for your help, and as i read your solution the original way, but i don't know why open the new tab the site in my chrome browsers o.o ...
So even if i use other solution, i think i accept your answer ^^
Thank you for your help :)

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>

How to make a extension/script/program that will refresh a browser until a certain phrase/keyword is found or is not found?

Is there any program/extension that I can use with browser that will refresh a webpage and search for a certain phrase or text and then stop once the phrase is found or is not found.
For example say I made a site that cycles using a randomizer through the words "One," "Two," and "Three."
This program would refresh the page until the word "Three" is found, If I set it to find that word, and then stop once it is found.
OR
This program would refresh the page until the word "Three" is not found, If I set it to find that word, and then stop once it is not found.
I know that we can use curl and grep to do that, but the page is not loaded on webbrowser. This is not what I want. see if there is solution that we can load on browser as well
If there no such things exists, any idea on how to write this kind of program? use what tool to do that?
You could very easily write an extension to do this. I would suggest instead of refreshing the page every time, you poll the data until you get the desired result then refresh the page once you find it. A short example using jQuery because I am familiar with it:
Manifest.json
{
"name": "Find Text",
"version": "0.1",
"description": "Find Text",
"manifest_version": 2,
"browser_action": {
"default_icon": "on.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs","http://*/*","https://*/*"
],
"background": {
"scripts": ["bgp.js","jquery-1.8.3.min.js"],
"persistent": true
}
}
Popup.html
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 300px; }
</style>
<script src="jquery-1.8.3.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<div>Desired Search Url</div>
<input type="text" id="searchUrl">
<div>Desired Search Text</div>
<input type="text" id="searchText">
<button id="searchButton">Search</button>
</body>
</html>
Popup.js
$(function(){
var tabId;
chrome.tabs.query({active:true,currentWindow:true}, function(tab) {
$('#searchUrl').val(tab[0].url);
tabId = tab[0].id;
});
$('#searchButton').click(function(){
chrome.extension.sendMessage({
url:$('#searchUrl').val(),
text:$('#searchText').val(),
tab:tabId
});
});
});
bgp.js
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
checkUrlForText(message.url,message.text,message.tab);
});
function checkUrlForText(url,text,tab){
var contains;
$.ajax({
url:url,
async:false,
success: function(data){
contains = $(':contains('+text+')',data);
while(contains.length == 0){
$.ajax({
url:url,
async:false,
success: function(dat){
contains = $(':contains('+text+')',dat);
}
});
}
}
});
chrome.tabs.reload(tab);
}
If having it refresh the tab every time is a requirement (the content would change between the time it found what you were looking for and when it refreshes the page) then you should use content scripts to test for the desired value and send a message to the background page if the desired text is not there to refresh the page and start again. Like this:
bgp.js
var contains;
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
checkTabForText(message.text,message.tab);
contains = false;
});
function checkTabForText(text,tab){
chrome.tabs.executeScript(tab,{file:"jquery-1.8.3.min.js"});
chrome.tabs.executeScript(tab,{file:"checkText.js"},function(){
chrome.tabs.sendMessage(tab, {text:text}, function(response){
contains = response.contains;
if(!contains){
chrome.tabs.reload(tab,function(){
checkTabForText(text,tab);
});
}
});
});
}
checkText.js
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
var contains = $(':contains('+message.text+')');
if(contains.length > 0)
sendResponse({contains:true});
else
sendResponse({contains:false});
});

Timer for chrome extension [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Chrome extension delay condition
Im very beginner at extensions and by collecting codes from here and there I created a simple one which collects the tab's url (works for specific website) and using ajax Im sending it to my server in order to store it in my database.
What Im trying to do is to add a timer so the browser button will be disabled (or do nothing) if the previous click occured in less than 5 seconds.
Below is the structure of the extension:
Manifest:
{
"name": "The name",
"icons": { "16": "Big.png",
"48": "Big.png",
"128": "Big.png" },
"version": "1.0",
"manifest_version": 2,
"description": "and the description",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "<all_urls>"]
}
popup.js:
chrome.tabs.getSelected(null,function(tab) {
var Mp=tab.url
if(Mp=='http://www.examplesite.com')
{
var xhr=new XMLHttpRequest();
var Params;
xhr.open("POST", "http://myserver.com/post_from_extension.asp", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
Params='Url=' + tab.url;
xhr.onreadystatechange=function()
{
if(xhr.readyState==4)
{
message.innerHTML=xhr.responseText;
}
}
xhr.send(Params);
}
else
{
message.innerHTML='<span style="font-family: Segoe UI, Tahoma;color: #f00">This is not a valid url</span>';
}
});
popup.html
<!DOCTYPE html>
<html style=''>
<head>
<script src='popup.js'></script>
</head>
<body style="width:400px;">
<div id='message'><span style="font-family: Segoe UI, Tahoma;color: #00f">Sending request</span></div>
</body>
</html>
As a side question, is there any other method to post the url in my database, if not with Ajax?
Thank you for reading me.
I think you should add a background page (script) to your extension - this is a kind of application state. Add this in the manifest:
"background": {
"scripts": ["background.js"]
},
Then in the page you can define an array storing last times when browser action was performed for each tab.
var timers = [];
You can update this array's elements from your popup.js, something like that (in getSelected callback):
chrome.extension.getBackgroundPage().timers[tabId] = new Date();
chrome.browserAction.disable(tabId);
chrome.browserAction.setIcon({path: "icon-disabled.png", tabId: tabId});
Note how you can disable browser action and change its appearence to a disable/grayed one.
When a period passed since the registered time exceeds 5 seconds you should re-enable the button from the background page.
var currentTime = new Date();
if(currentTime - chrome.extension.getBackgroundPage().timers[tabId] > 5000)
{
chrome.browserAction.enable(tabId);
chrome.browserAction.setIcon({path: "icon-enabled.png", tabId: tabId});
}
You can execute this code from setInterval callback and within a cycle through all elements in the timers array.

Resources