I'm trying to write a chrome extension that closes tabs when they're loaded if their links contain specific words / strings. My intention was to solve that using the matches statement in the manifest.json. Unfortuantely this doesn't work. My manifest.json looks like this:
{
"manifest_version": 2,
"name": "Chrome Extension",
"version": "0.1",
"permissions": [
"tabs"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["content.js"]
}
],
"background": {
"matches": [
"https://www.google.de/",
"https://sghm.eu/iserv/login"
],
"scripts": ["background.js"],
"persistent": true
}
}
And my background.js like this:
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
console.log('background running');
chrome.tabs.remove(tabId, function() { });
}
})
In my opinion I've expressed clearly that the script only runs on google and sghm.eu, so why does it run on every loaded page?
Problems:
The "background" section can't have "matches" as you can see in the documentation. The background script runs in a separate hidden background page that's not related to tabs.
The content script declared in your manifest.json runs on all URLs. For the task you want to achieve you don't need a content script at all.
Solution consists of several steps:
Remove "content_scripts" section
Remove "matches" from "background" section
Switch to an event page script by specifying "persistent": false
Add "webNavigation" permission in manifest.json and use it to detect URL navigation.
background.js:
chrome.webNavigation.onCompleted.addListener(closeTab, {
url: [
{urlPrefix: 'https://www.google.de/'},
{urlPrefix: 'https://sghm.eu/iserv/login'},
]
});
function closeTab(e) {
if (!e.frameId) {
chrome.tabs.remove(e.tabId);
}
}
Related
I'm making a simple chrome extension for a project. I am making an extension that blocks certain URL's(social media etc) to make studying more efficient. I'm not very good in JS but I want to learn. I had some ideas that maybe it could either block the website or just draw something in a div blocking its content. Also, maybe I could input an URL into popup.html to specify the blocked website. Saving data in firebase. Also, I read that maybe its easier to use declarativeWebRequest but not quite sure how to use it.
Manifest.js
"name": "StudyBuddy",
"description": "Helps you study by blocking distracting websites",
"version": "2.0",
"permissions": [
"webRequestBlocking",
"webRequest",
"activeTab",
"tabs",
"http://*/*",
"https://*/*"
],
"content_scripts" : [{
"matches": ["<all_urls>"],
"js" : ["background.js"],
"css" : ["styles.css"]
}],
"browser_action": {
"default_title": "Blocks websites",
"default_popup": "popup.html"
},
"manifest_version": 2
background.js
console.log("Loaded extension");
function blockRequest(details) {
return {cancel: true};
}
function updateFilters(urls) {
if(chrome.webRequest.onBeforeRequest.hasListener(blockRequest))
chrome.webRequest.onBeforeRequest.removeListener(blockRequest);
chrome.webRequest.onBeforeRequest.addListener(blockRequest, {urls: ["*://*.facebook.com/*", "*://*.facebook.net/*"]}, ['blocking']);
}
At the moment my extension doesnt block anything.
Ok, your code has two issues :
Your manifest.json didn't specify background.js, so that code wasn't running.
You didn't actually call the updateFilters function from anywhere.
I corrected both those issues and this extension works fine for me, it blocks Facebook as expected.
In general I suggest you do some more reading of the documentation for extensions as you try to get started, especially the parts on background pages and event pages.
manifest.json: (note that I don't have access to your popup html/css so I had to remove that section from the manifest).
{
"name": "StudyBuddy",
"description": "Helps you study by blocking distracting websites",
"version": "2.0",
"permissions": [
"webRequestBlocking",
"webRequest",
"activeTab",
"tabs",
"http://*/*",
"https://*/*"
],
"background" : {
"scripts": [
"background.js"
]
},
"manifest_version": 2
}
background.js
console.log("Loaded extension");
function blockRequest(details) {
return {cancel: true};
}
function updateFilters(urls) {
if(chrome.webRequest.onBeforeRequest.hasListener(blockRequest))
chrome.webRequest.onBeforeRequest.removeListener(blockRequest);
chrome.webRequest.onBeforeRequest.addListener(blockRequest, {urls: ["*://*.facebook.com/*", "*://*.facebook.net/*"]}, ['blocking']);
}
updateFilters();
I am trying to define a new hotkey in Google documents. I am trying to use a Chrome extension, the problem is when the document area is active, the browser can't listen to the event fired. Here's the extension code.
Edit: Here's the manifest file
{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "0.1",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-3.2.1.js", "content.js"]
}
],
"permissions": [
"tabs"
]
}
Here's the content.js file
var map = {17: false};
$('body').keydown(function(e) {
if (e.keyCode in map) {
map[e.keyCode] = true;
if (map[17]) {
console.log("Hi");
}
}
}).keyup(function(e) {
if (e.keyCode in map) {
map[e.keyCode] = false;
}
});
The above extension works fine on any website. When you press ctrl, it will log "Hi". The extension works fine on any website and in Google Docs itself if the upper bar that contains the menus is active. It logs Hi when the ctrl key is pressed. But when the document area is active, the code doesn't fire.
Background: I am thinking of having the ability to use Chrome extensions with Google Apps Script to define custom hotkeys, just faced the problem of not firing events in the active document area.
While it is not visible, Docs editing content is within an iframe. Your content_script is not loading on iframes.
You can enable this by adding to new rules to your content_scripts in manifest.json:
"all_frames": true,
"match_about_blank": true
The first allows your code to load on frames. The second one allows to load on empty pages (and frames). Together with your current manifest.json:
{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "0.1",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery.js", "content.js"],
"all_frames": true,
"match_about_blank": true
}
],
"permissions": [
"tabs"
]
}
Use the chrome.commands API instead of jQuery.
I want to change the url of current tab in chrome and reload the page.
I tried this code but not work, any help here will be greatly appreciated.
background.js:
function updateUrl(){
chrome.tabs.getCurrent(function (tab) {
var tabUrl = encodeURIComponent(tab.url);
var myNewUrl = tabUrl + "some text";
chrome.tabs.update(tab.id, {url: myNewUrl});
})
}
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
updateUrl();
}
})
manifest.json:
{
"name": "test",
"version": "0.1",
"manifest_version": 2,
"permissions": [
"tabs",
"webNavigation",
"http://www.example.com/*"
],
"background": { "scripts": ["background.js"] },
"content_scripts":
[
{
"matches": ["http://www.example.com/*"],
"js": ["background.js", "jquery.js"]
}
]
}
From your manifest it looks like you're trying to include background.js as a content script and a background script. chrome.tabs isn't available in content scripts so this won't work.
Depending on your specific use case, if you want to append a specific URL you could use the chrome.webRequest API to achieve this.
background.js:
chrome.webRequest.onBeforeRequest.addListener(function (details) {
return {
redirectUrl: details.url + "some text"
}
}, {
urls: ["http://www.example.com/*"]
}, ["blocking"]);
manifest.js:
{
"name": "test",
"version": "0.1",
"manifest_version": 2,
"permissions": [
"webRequest",
"webRequestBlocking",
"http://www.example.com/*"
],
"background": {
"scripts": [
"background.js"
]
}
}
This will add "some text" to the end of every request the browser makes to "http://www.example.com/*"
If you do want to use a content script to do this, then you'll need to take a look at message passing. This will allow you to make a call to the background script (which can use chrome.tabs) from your content script. Once the message has been sent the background page could then update the tab.
chrome.tabs.getCurrent is used to get the tab that this script is being made from. It will return undefined if called from a non-tab context (for example: a background page or popup view).
Since you have got the tab inside chrome.tabs.onUpdated handler, you could directly use it without the need to retrieve it again.
function updateUrl(tabId, tabUrl){
var myNewUrl = encodeURIComponent(tabUrl) + "some text";
chrome.tabs.update(tabId, {url: myNewUrl});
}
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
updateUrl(tab.id, tab.url);
}
});
From you manifest.json, background.js are used for both background page and content scripts, that's a bad design though not the root cause for this question.
It would be better if you could divide the logic into two parts, content script used for manipulating current web page DOM and background page used for extension related things.
I am working with a chrome extension . I want to inject js script in all tab. I am using this manifest.json :
{
"name": "ABC",
"version": "0.0.1",
"manifest_version": 2,
"background": {
"scripts": [
"src/background/background.min.js"
],
"persistent": true
},
"browser_action": {
"default_icon": "icons/128.png",
"default_title": "ABC",
"default_popup": "src/browser_action/index.html"
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*",
"<all_urls>"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["./src/inject/inject.min.js"],
"css": ["./css/inject.min.css"],
"all_frames": true
}]
}
And my inject.js is like this :
(function() {
console.log("Hello");
});
I am getting all log from all tab except the tab of the chrome setting (eg : chrome://extensions/:id , chrome://history etc).
Am I missing something in manifest.json or chrome disables the feature of injection in settings page ?
Thanks in advance.
Indeed, you can't inject code into chrome:// pages. They contain control elements / code that can modify the browser in ways that an extension is not allowed to.
Chrome resolves this by simply not allowing permissions to be set for chrome:// URLs, and <all_urls> does not include it.
However, you could use Override Pages to replace some of them (well, History page at least) completely.
I want to create a new chrome extension but it don't work.
I want to inject a js file into web page (all web page,not only one.If i push the chrome icon on google the script must execute,if i push the icon on facebook it must execute ect.)
this is background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
null,{file: "backgrounds.js"} });
});
this is backgrounds.js
document.body.innerHTML="display div elem with style and id";
this is manifest.json
{
"name": "MyExt",
"description": "an extension,what else?",
"version": "1.0",
"permissions": [
"activeTab"
],
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["background.js"]
}
],
"browser_action": {
"default_title": "myExt"
},
"manifest_version": 2
}
what i wrong?
I'm on windows 8.1 Update 1 with chrome last version
Your manifest is wrong: you should set background.js as your background script:
"background" : { "scripts" : [ "background.js" ] },
and remove the "content_scripts" section.
The "activeTab" permission means that you don't need to specify host permissions to inject in the current tab upon browser action click, so no other permissions are needed.
The tabId argument is optional, you can just drop it instead of passing null. And your invocation is wrong (you're wrapping two arguments in a single object). Here's the correct way:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({file: "backgrounds.js"});
});