chrome.extension.getBackgroundPage is undefined in an extension page in an iframe - javascript

I am trying to access my extension's background page using chrome.extension.getBackgroundPage function.
However, I get the following error:
Uncaught TypeError: chrome.extension.getBackgroundPage is not a function
I am calling the function from my bar.js file which is defined as a web_accessible_resource in my manifest.json
How do I make it work?
manifest.json
{
"manifest_version": 2,
"name": "XPath Helper",
"version": "1.0.13",
"description": "Extract, edit, and evaluate XPath queries with ease.",
"background": {
"page": "background.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["content.css"],
"js": ["content.js"]
}
],
"permissions": ["http://*/", "tabs", "identity", "identity.email"],
"icons": {
"32": "static/icon32.png",
"48": "static/icon48.png",
"128": "static/icon128.png"
},
"web_accessible_resources": [
"bar.css",
"bar.html",
"bar.js"
]
}
bar.js is a script inside bar.html (not a content script):
// ...
document.addEventListener('DOMContentLoaded',function(){
// previosuly chrome.extension.getBackgroundPage()
chrome.runtime.getBackgroundPage(function(page){
alert("hello");
})
})
content.js
// ...
this.barFrame_ = document.createElement('iframe');
this.barFrame_.src = chrome.extension.getURL('bar.html');
document.body.appendChild(this.barFrame_);
// ...

Most extension APIs can only be used if the page runs in the extension process, i.e. the top-level frame is a non-sandboxed chrome-extension: page.
chrome-extension:-frames in a non-extension process can only access the extension APIs available to content scripts and web pages. And unlike content scripts, they can also use web platform APIs at the extension's origin. For example, if you use localStorage in a content script, then the DOM storage of the page where the content script runs is accessed. If you use localStorage in a chrome-extension: page, then you'll get the extension's storage.
If you want to access functionality of the background page in your frame, use the extension messaging APIs to communicate between your frame and background page.

Related

Firefox Extension / Webextensions: Why doesn't the MDN example of Connection Based Messaging work?

This is the first time I read about writing Firefox extensions.
What I need is obviously only viable via WebExtensions and both a background and a contentscript. I actually only want to write all open tabs as links in a new tab and then File->Save it. Another alternative Idea was to put it into a JSON Object and save that through a dialog, then I probably could even spare the contentscript but I haven't found anything in the API to download a JSON Object via asking the user to download it via Download Dialog.
Whatever. I think I need to communicate with the content-script then.
I tried to run the following example, but it is not working. When I load the manifest file and open the debugger for extensions, it doesn't log anything and nothing has happened except that the variables myPort and portFromCS seem to be declared without any value.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#connection-based_messaging
// manifest.json
{
"manifest_version": 2,
"name": "Save Open Tabs",
"version": "1.0",
"description": "Save my tabs",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content.js"]
}
],
"permissions": [
"activeTab",
"tabs"
]
}
// content.js
let myPort=browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});
myPort.onMessage.addListener((m) => {
console.log("In content script, received message from background script: ");
console.log(m.greeting);
});
// background.js
let portFromCS;
function connected(p) {
portFromCS = p;
portFromCS.postMessage({greeting: "hi there content script!"});
portFromCS.onMessage.addListener((m) => {
portFromCS.postMessage({greeting: "In background script, received message from content script:" + m.greeting});
});
}
browser.runtime.onConnect.addListener(connected);
Why doesn't the example work? Maybe wrong URL matching in the manifest file?

chrome.idle is undefined in chrome extension

I'm trying to implement a simple idle detection in chrome.
I created an extension with this permission:
"permissions": [
"webNavigation",
"storage",
"tabs",
"*://*/*",
"idle"
],
"background": {
"scripts": ["js/background.js"]
},
"content_scripts": [
{
"run_at": "document_start",
"matches": [
"*://*/*"
],
"css": [
"css/content.css"
],
"js": [
"js/jquery.min.js",
"js/content.js"
]
}
]
and in content.js
$(function () {
console.log('init idle detection');
chrome.idle.queryState(5, function(newState){
//"active", "idle", or "locked"
if(newState === "idle"){ alert(newState); }
});
...init other things...
});
however, chrome.idle is always undefined.
According to documentation, content scripts cannot access idle API. Use it in background script (or popup script) and communicate with content script via messaging.
From the documentation:
Content scripts can access Chrome APIs used by their parent extension
by exchanging messages with the extension. They can also access the
URL of an extension's file with chrome.runtime.getURL() and use the
result the same as other URLs.
//Code for displaying <extensionDir>/images/myimage.png:
var imgURL = chrome.runtime.getURL("images/myimage.png");
document.getElementById("someImage").src = imgURL;
Additionally,
content script can access the following chrome APIs directly:
i18n
storage
runtime:
connect
getManifest
getURL
id
onConnect
onMessage
sendMessage
Content scripts are unable to access other APIs directly.
(Bold type on last line added)

Execute Script of Chrome extension only once

I've made a Chrome script that modifies a specific login Page. It works as expected, but I can see in the console that it is always active, although it should only be applied on the login site.
My manifest file:
{
"manifest_version": 2,
"name": "Login Enhancer",
"description": "Login without a hassle",
"version": "1.0",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"https://*.examplesite.io/subdomain/portal/#/login"
],
"background": {
"scripts": [
"background.js"
]
}
}
background.js:
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete' && tab.active) {
chrome.tabs.executeScript(null, {file: 'script.js'});
}
});
script.js
// delete useless Remember Me Function
document.querySelector('.remember-me').remove();
After I've logged in when I'm browsing on examplesite.io/subdomain the console says on every new page:
Uncaught TypeError: Cannot read property 'remove' of null
at script.js:2
Obviously there is no more remember-me button to remove. This has probably to do with the Listener in my background.js File. What is the correct listener so the script.js is only executed once on https://*.examplesite.io/subdomain/portal/#/login and not everywhere on https://*.examplesite.io?
For what you have shown in the question, the best way to do this is to use a content_scripts entry in your manifest.json to load your content script instead of using chrome.tabs.executeScript() to do so. Doing it as a content_scripts entry will inject the script once whenever the specified page is loaded. It is significantly less complicated than using chrome.tabs.executeScript() for the purpose of loading a script when a URL matches a certain page. In general, chrome.tabs.executeScript() should be used when the interaction with the user begins with the user clicking on a browserAction or pageAction button (which you are not using), or when you want more detailed control over when the script is injected other than always once for pages matching a specific URL, or URL pattern (which you don't need for what you are doing).
In your case, you are wanting to inject the script once, every time a specific URL is loaded. This is exactly the use case for which the content_scripts key in manifest.json exists.
Given that your background script was doing nothing other than loading your content script, using a content_scripts entry means you do not need a background script. In addition, you don't need to explicitly specify permissions for that particular URL. Your extension is implicitly given permissions for the URLs which match the content_scripts matches key.
You could do this by changing your manifest.json to:
{
"manifest_version": 2,
"name": "Login Enhancer",
"description": "Login without a hassle",
"version": "1.0",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"content_scripts": [
{
"matches": ["https://*.examplesite.io/subdomain/portal/#/login"],
"js": ["script.js"]
}
]
}

Chrome extension inject js

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"});
});

Can't xhr file inside of Chrome extension

I'm building out an extension and I'm trying to keep it well structured. Part of it will use a templating system of some type (Mustache, Handlebars, etc). Note that I'm already aware of having to use a specific non-eval version of what ever library I go with.
The problem is that from within the app.js script (the core logic) I cannot XHR to load the contents of the files in /templates (see below).
The load event never fires, and when I examine with onreadystatechange it immediate jumps to state 4 with a status code of 0. (state 4 and status 200 are what we want).
Getting the Chrome url for the file works, e.g.
chrome.extension.getURL('templates/view1.html')
//chrome-extension://hdhpjlpbepobcdgnkklnakdpoojaahjg/templates/view1.html
I suspect there's something in my manifest.json that isn't configured right. I've read through the CSP docs but nothing is jumping out at me why accessing files local to the extension should be denied. Note that the XHR requests don't throw errors, they just never return data.
The structure of the app is like this:
/manifest.json
/src
app.js
style.css
/libs
jquery.js
mustache.js
/templates
view1.html
view2.html
Manifest.json
{
"name": "Test Extension",
"version": "0.0.1",
"manifest_version": 2,
"icons": {
// "16": "",
// "48": ""
// "128": ""
},
// "default_locale": "en",
"permissions": [
"contentSettings",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"matches": [
"https://www.google.com/search*"
],
"css": [
"src/style.css"
],
"js": [
"src/app.js",
"libs/jquery.js",
"libs/mustache.js"
],
"run_at": "document_start"
}
]
}
You need to list the files you want to load in a web_accessible_resources section in your manifest.

Categories

Resources