Adding background scripts to a firefox add-on - firefox

I want to add a file(background.js) which is a background script for my firefox extension.
I added content scripts to my main.js using the following code.
var panel = panels.Panel({
contentURL: self.data.url("panel.html"),
onHide: handleHide,
contentScriptFile: [self.data.url("js/jquery.js"),
self.data.url("tipsy/jquery.tipsy.js"),,
self.data.url("js/settings.js")]
});
How do I add background scripts to the main.js file.

Simply place the file in the lib folder.
Except for scripts that interact directly with web content, all the JavaScript code you'll write or use when developing add-ons using the SDK is part of a CommonJS module.
Essentially, backend script don't share variables like content scripts/normal JS. You export and require variables between modules.
See adding local modules

Related

Is it possible to open a local native Application like Terminal.app from a button in Chrome browser

I know this sounds crazy... but I really hope to have something like this...
Click on a button in a page, like:
localhost:8080/index
And there is a button in it. When I click that button, it runs a local application. In this case I hope it can get some extra information from the button, like:
<button id="script1.sh">Run</button>
<script>
$("button").click(function(){
var scriptName = $(this).attr("id");
OpenTermninalWithScript(scriptName);
});
</script>
I am using Macintosh / Google Chrome.
as you are on localhost:8080/index I assure you can open it from the backend part (frontend API is not yet evolved to have security permission which allow that in a safe manner)
To do so, your frontend script would create an ajax call to the backend at a specific url you choose asking the backend to proceed. You could start a child process in a terminal (you could do anything you want that is already possible via command line interface (CLI) or just use the default open to simplify
here is a nodejs / express example but it's possible with java, php python and manymore
var spawn = require('child_process').spawn;
var app = require('express')();
app.get('/path/to/trigger/comand', function(req, res){
spawn('open', ['http://google.com']);
res.end('ok');
});
// [...]
open take a ressource to open, you may put here any kind of ressource your OS will open with it's default behaviour

Firefox SDK require regular JS files

Is there a way to include regular javascript files in the Firefox SDK background script?
If I just have a script file that defines some variables, include it and access those in the background script.
Its my understanding so far that they MUST be CommonJS modules. I am porting a Chrome Ext that also uses alot of common code with a mobile app, etc which I'd rather not try converting to CommonJS modules.
Is this possible?
Its my understanding so far that they MUST be CommonJS modules.
That's correct.
If you want to include standard JS files that are already structured in some way, you'd either have to inject them into a page worker, which will
Create a permanent, invisible page and access its DOM,
then send in and out the few variables needed and resulting, respectively, using port, as I explained in your last question.
Or you could use some sort of file concatenation (if you minify your files, this should already happen), then save this new JS file in the lib folder, and require/export those same variables.
These approaches only require you to input/output the variables that are needed externally from the system of files you already have in place, so it's less of a pain than converting each file to commonJS.
NB: I use Angular for my webapp, and have used some modules for both like so
var syncHelper = function() {
this.filter = function(objects, prop) {
// do stuff
}
this.consolidate = function(local, server, id) {
//more stuff
}
}
// app is my angular webapp var
if (typeof app==='undefined') syncHelper.call(exports);
else app.service('syncHelper', syncHelper);

How can I authenticate with google inside of a firefox plugin

I'd like to add a calendar entry from my Firefox plugin to the user's Google calendar (with their authorization, of course). Unfortunately, I can't seem to figure out how to authenticate with Gapi within the context of the Firefox SDK.
I tried including the client.js from gapi directly as a module in my source, but this isn't effective, since it can't access the window object. My next attempt was something akin to what I do with jQuery - load it in a content script:
googleClient.js
var tabs = require("sdk/tabs");
var self = require('sdk/self');
function initAuth() {
var worker = tabs.activeTab.attach({
url: 'about:blank',
contentScriptFile: [self.data.url('gapi.js'), self.data.url('authContentScript.js')]
});
}
exports.initAuth = initAuth;
main.js:
var googleClient = require('./googleClient');
I get the following problem:
console.error: foxplugin:
Error opening input stream (invalid filename?)
In the ideal situation, it would open a new window in the browser that allows the user to login to Google (similar to what happens when one requests access to the oauth2 endpoint from within a "real" content script).
I had the same problem so I've made an npm plugin for that. It's called addon-google-oauth2 and works for Google OAuth2 tested with AdSense API. It's really simple, it just calls REST APIs for OAuth2. Steps:
Create an OAuth2 client for native application. No web or Android, just native.
If your addon is using jpm ok, if it uses cfx, please migrate to jpm
Download and save the dependency with npm
npm install addon-google-oauth2 --save
Follow the tutorial on the README.md file. It's easy, just two API calls
refreshToken(options,callback);
getToken();
Insert the HTML and JS file on your data/ directory

communication between web page script and content script and main.js(Add-on code) script [duplicate]

This question already has an answer here:
How can my Add-on SDK content script interact with a website page script?
(1 answer)
Closed 8 years ago.
UPDATE: Sorry, this example works, I found a minor bug and fixed in my full source code.
But I still want somebody who know better then me to give a good answer to this question about how to achieve communication between web page script and content script and main.js(Add-on code) script, also please answer how we can access localStorage from web page script and send to add-on script.
I cannot find how to build correctly a basic communication between:
page script -> content script -> add-on script
and vice versa
add-on script -> content script -> page script
please notice that I understand page script as the original webpage script, it is not in a sandbox. The page script is from webpage header:
<head>
<script type="text/javascript" src="http://www.domain.com/script.js"></script>
</head>
Add-on script is main.js and content script is attached contentScriptFile from PageMod
This is what i know .
I have tried this and it is not working:
main.js add-on script:
pageMod.PageMod({
include: "*",
contentScriptFile: self.data.url("content.js"),
contentScriptWhen: 'ready',
onAttach: function(worker) {
worker.port.on("message_from_content_script", function(data) {
worker.port.emit("message_to_page_script",mainStorage);
});
},
attachTo: ["existing","top", "frame"]
});
content script:
document.addEventListener('DOMContentLoaded', function () {
self.port.emit("message_from_content_script", "some text");
});
as you see I have tried so far only to make a communication between content script and add-on script, but it is not working. Please somebody show me an example of how to achieve:
page script -> content script -> add-on script
and vice versa
add-on script -> content script -> page script
There is extensive documentation, including examples, on how to communicate between page scripts and content scripts using custom DOM events.
Alternatively, you can use unsafeWindow, but there are potential security issues, and your extension will probably get rejected from addons.mozilla.org (AMO)

How to implement message passing in Firefox extension?

I have a file which overwrites overlay.xul that overwrites browser.xul. I want to implement message passing in a similar way as implemented in chrome extensions.
chrome.manifest-
content helloworld content/
overlay chrome://browser/content/browser.xul chrome://helloworld/content/overlay.xul
overlay chrome://navigator/content/navigator.xul chrome://helloworld/content/overlay.xul
skin helloworld classic/1.0 skin/
style chrome://global/content/customizeToolbar.xul chrome://helloworld/content/overlay.css
How to I register content_script.js which in my case is overlay.js?
Overlay.xul -
<script type="application/x-javascript" src="chrome://helloworld/content/jquery.js" />
<script type="application/x-javascript" src="chrome://helloworld/content/overlay.js" />
<script type="application/x-javascript" src="chrome://helloworld/content/background.js" />
Now inside my overlay.js I'm using -
document.documentElement.addEventListener('click', function(e) {
messageManager.sendAsyncMessage('MyMessenger.MyMessage', {});
}, true);
And the background.js is-
addMessageListener("MyMessenger.MyMessage", function(obj) {
Firebug.Console.log(obj.name);
}, true);
What is the correct syntax for message passing?
How do I configure the connection between content script and browser script?
If all you are interested in is really injecting a content script and communicating with it then it should be easier to use the Add-on SDK, particularly the page-mod package. It allows injecting content scripts easily and provides a way to communicate (see "Communicating With Content Scripts" section in the docs I mentioned).
As to messageManager, it is meant for a multi-process environment but it will work in the current single-process Firefox as well. The main problem with your code above is: addMessageListener isn't a global function, you should call messageManager.addMessageListener(). But using messageManager to pass messages between scripts that are loaded into the same namespace and could call each other directly is an overkill anyway.
To communicate with a content script in the current tab the script in the overlay would do:
gBrowser.selectedBrowser.messageManager.sendAsyncMessage('MyMessenger.MyMessage', {});
And the content script would indeed have addMessageListener as a global function so this should work:
addMessageListener("MyMessenger.MyMessage", function(obj) {
console.log(obj.name);
});

Resources