Unable to use var tabs = require("sdk/tabs"); in WebExtension add-on - javascript

"sdk/tabs" seems impossible to use in my Firefox add-on. I wonder what's wrong. My background.js stops processing any code after this part:
var tabs = require("sdk/tabs");
E.g. if I run this code, the console will output "error1?" -- including everything above, but nothing from underneath that snippet.
console.log('error1?');
var tabs = require("sdk/tabs");
console.log('error2?');
// Listen for tab content loads.
tabs.on('ready', function(tab) {
console.log('error3?');
console.log('tab is loaded', tab.title, tab.url);
console.log('error4?');
});
console.log('error5?');
I have included "tabs" as permission in my manifest.json file. Do I need to include anything else to use "sdk/tabs"?

You mention a manifest.json file and having the tabs permission in it. manifest.json files are only used in WebExtension based add-ons. You desire to use require("sdk/tabs") which is only available in Add-on SDK extensions.
You appear to mixing APIs between WebExtensions and the Firefox Add-on SDK. These are two of the four different types of extensions for Firefox. None of the Add-on SDK APIs (neither High-Level, or Low-Level) are available from a WebExtension. Similarly, the WebExtension JavaScript APIs are not available from an Add-on SDK based extension.
Specifically, you appear to be developing a WebExtension. The sdk/tabs API is for the Add-on SDK. It will definitely not work in a WebExtension based add-on. In general, if you see require() you are almost certainly dealing with the Add-on SDK which will not work in your WebExtension add-on. Thus, you will not be able to use require("sdk/tabs") in your WebExtension based add-on.
Firefox/Mozilla has four different types of extensions:
Add-on SDK: These add-ons are described by a package.json file which is initially generated by executing jpm init. These extensions will often use require() to load either High-Level, or Low-Level APIs to interface with Firefox. Currently, these add-ons are wrapped into a bootstrapped extension when they are loaded for testing by jpm run or consolidated into an .xpi file by jpm xpi for distribution (i.e. upload to AMO/Mozilla). In other words, they are bootstrapped extensions with an SDK wrapper.
Mozilla appears to be committed to continuing to support Add-on SDK based extensions as long as the extension does not use require("chrome"), or otherwise depend on XUL, XPCOM, or XBL.
Most of the things that can be done in a bootstrapped extension can be done in an Add-on SDK based one. However, many such things bypass the SDK which forfeits a significant portion of the benefits of using the Add-on SDK.
WebExtensions: These add-ons are described by a manifest.json file. This API is similar to what is used for Google Chrome extensions. While Mozilla is claiming that this API is the future of Firefox extensions, this API is still in development. For now, you are probably best off developing and testing your WebExtension add-on with Firefox Developer Edition, or Firefox Nightly. You should also make careful note of what version of Firefox is required for the functionality you desire to use. This information is contained in the "Browser compatibility" section of the MDN documentation pages.
WebExtensions use a significantly different API. There is, intentionally, no ability to use the interfaces provided by any of the other add-on types.
Bootstrapped: These extensions are also commonly called "restartless" because they were the first type of Mozilla extension which did not require the application to be restarted in order to load/unload the add-on. However, restartless is a descriptor of how they function. Using "restartless" as the name for this type of add-on is confusing because both Add-on SDK and WebExtension add-ons also do not require the application to be restarted upon load or unload of the add-on. For that reason, there is a tendency to no longer use "restartless" as the name for this type of add-on.
These add-ons have a JavaScript file called bootstrap.js which must contain entry points (functions) which are called for add-on startup(), shutdown(), install() and uninstall().
These add-ons contain a install.rdf that describes the add-on.
They usually, but not always, also contain a chrome.manifest file that describes how the files and directories in the extension relate to the Mozilla application (e.g. Firefox).
Most, but not all, of the things that can be done in overlay/XUL/Legacy extensions can be accomplished in bootstrapped add-ons. Anything that can be done in the Add-on SDK can be done in a bootstrapped extension (Add-on SDK extensions are bootstrapped add-ons with some JavaScript based API layers).
Mozilla has stated that they plan to deprecate "add-ons that depend on XUL, XPCOM, and XBL." While not all bootstrapped add-ons depend on these technologies, there is a tendency for for bootstrapped add-ons to operate at a lower level than Add-on SDK and WebExtension add-ons. Thus, they are more likely to use these technologies. While there are some that are saying that all bootstrapped add-ons are planned to be deprecated, it is not clear that is the case. After all, Add-on SDK extensions are not being deprecated (unless they use require("chrome"), or otherwise depend on XUL, XPCOM, or XBL) and all Add-on SDK extensions are bootstrapped extensions, just with an SDK wrapper.
Overlay/XUL/Legacy: These add-ons contain a install.rdf that describes the add-on and a chrome.manifest file to describe how the add-on's files relate to (e.g. overlay) the application's files. How the add-on functions with the application is completely dependent on the relationships described in the chrome.manifest file. The only exceptions to this are a few things like icons for the extension and the file describing the extension's options which are indicated in the install.rdf file. These extensions interact with the application (e.g. Firefox) at a very low level. This tends to make them more likely to break when changes are made to the application.
All Overlay/XUL/Legacy extensions are planned to be deprecated.

Related

Check if chrome extension inline installation is supported

I am building a chrome extension and a JS library to allow installing this extension.
There are a couple of ways to ask a user to install the extension:
Inline installation if the site is verified and added to the extension webstore settings.
Redirect to chrome webstore otherwise.
Is there a way to check if the inline installation is supported on the site using javascript beforehand?
The only way I found so far is to trigger inline installation and then fallback to redirecting to webstore:
chrome.webstore.install(extensionUrl, successCallback, function() {
redirectToChromeWebstoreExtensionUrl();
});
This is not ideal because the redirect will be blocked by chrome since it was not triggered by a user.
What I would like to do is to first check if the site supports inline installation and then choose an appropriate method of installation.

How to test firefox plugin locally

I have a basic Google Chrome extension which needs to be ported to Firefox. I uploaded the .crx file to the Firefox marketplace and it got accepted but is under review rightnow. I downloaded the the generated xpi file and tried to install it locally but without any success. It tell that the plugin is invalid or corrupted.
Another method that I tried is I ported the extension using chrome-tailor and generated the xpi. I am able to install the extension in this but the content scripts are not injected and the extension doesn't work as expected.
I want to install it in Firefox and test it. I have also set xpinstall.signatures.required to false.
WebExtensions
To test WebExtension based add-ons, they are usually loaded as a "Temporary Installation in Firefox"
That MDN page describes how to temporarily install a WebExtensions (i.e. similar code to Chrome) in Firefox. The gist of it is:
Navigate to about:debugging
Click the button "Load Temporary Add-on"
Use the file selection dialog to select the manifest.json file, or packaged .xpi file for the extension.
Note on testing WebExtensions:
The WebExtensions API is still in development. For now, you are probably best off developing and testing your WebExtension add-on with Firefox Developer Edition, or Firefox Nightly. You should also make careful note of what version of Firefox is required for the functionality you desire to use. This information is contained in the "Browser compatibility" section of the MDN documentation pages.
Firefox Add-on SDK
To test Firefox Add-on SDK based ad-ons, use jpm run. You might want to take a look at this answer to "jpm run does NOT work with Firefox 48, or later"

Enable a non-PlayStore UserScript with Chrome 35 and above

Since the version 35 of Google Chrome, the execution of any extension installed outside of the Google's PlayStore is blocked and cannot be enabled from the extensions menu.
The auto-installation of non-store scripts was removed two years ago but downloading the script and performing a drag & drop on the extensions menu still allowed the installation, so it was still possible to create and share scripts for Google's Chrome. But now everything is locked.
Is it possible to manually add permissions to your independant scripts ?
Is it possible to white-list a personnal website ?
Is there any other solution ?
I know that this restriction does not apply for dev and canary release channels but the scripts are purposed to be used by users with enough knowledge to know what they do, without forcing them to change their browser. The native support support is rather interresting on Chrome (even if completly locked now), so a solution without a third party plugin (ie : Tampermonkey) is better.
Thank you
The only way there seems to be left, short of installing an extension like Tampermonkey or getting a different browser, is starting the Chrome browser with the --enable-easy-off-store-extension-install flag.
Edit: Unfortunately, Google removed this flag from Chromium in April.
However, if the user (or any program) starts Chrome without this flag even once, the scripts will be disabled automatically. You can't re-enable them, even with the correct flag; your only option is to uninstall them and re-install then in the easy off-store extension install mode.
So, your options are:
Start Chrome with the --enable-easy-off-store-extension-install flag every time. If you have pinned Chrome to the task bar in Windows 7, the way to change the command line arguments for this shortcut is described here.If you have set Chrome as the default protocol handler for the HTTP and HTTPS protocols (which is the case if you made Chrome your default browser), you can modify the registry so this flag is set every time a program tries to open an HTTP or HTTPS URL with the default program.Also make sure you set this argument for file extensions Chrome is configured to open, such as .xht, .htm and .xhtml.
You can do this with the following .reg file:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\ChromeHTML\shell\open\command]
#="\"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe\" --allow-easy-off-store-extension-install -- \"%1\""
Make sure the path to Chrome is correct when you install this.
Install an extension such as Tampermonkey to manage your user scripts.
Install a different browser, either developer builds of Chrome or a completely different browser, such as Opera (which has native support for user scripts) or Firefox (with Scriptish).
Blocking Chrome updates before you receive version 35 and risk getting hacked.
Switching to a different operating system, as extensions are only blocked on Windows.
If your computer is part of a Windows domain, you can install extensions using Group Policy.
Turn your user scripts into bookmarklets.
I realize this is probably not what you want to hear, but as Google continues to restrict honest developers because of a few bad players there are no better options.
Edit: there is one more approach that I've found to be working, namely hijacking an installed extension with the correct permissions:
Find and install an extension that has permission to run a content script at the web page you want it to run at. For example, the Note Anywhere extension has permission to inject a user script when a document has loaded for any HTTP or HTTPS URI.
Go to the extensions page to find the ID of the extension.
Open the folder where Chrome stores the extensions. On Windows, this is %localappdata%\Google\Chrome\User Data\Default\Extensions.
In manifest.json, find the name and location of the injected script. Overwrite the contents of this file with your user script. (In the case of the extension chosen as an example, this is asset/stickies.js.
Remove any content of the extension not referenced in manifest.json. Replace any referenced scripts and HTML pages that you aren't using with emtpy files.For the extension mentioned above, I'd remove anything except for the icons, the content script, asset/stickies.css and background.html and replace the latter two with an empty file.
Go to the Chrome extensions page and disable and then re-enable the extension.
Make a back-up of your work in case the extension is updated.
Make a note somewhere that the extension in the extensions list has its contents replaced with your user script.
EDIT : I validate this solution because it's what helped me particularly on this problem. A much richer answer is the list of workarounds submited by user2428118. Even if they did not solved my specific problem, they should be considered.
I finally could find an answer to my question thanks to the link posted by yoz, and the fact is that you can still enable a script unrelated to the PlayStore, without any third party plug-in, but as you'll see : it might be better to use TamperMonkey (even if it might imply little adaptations, it's 200% easier).
The solution is to import the unpacked user-script in developer mode.
Step By Step Explanation
Create your user script myscript.user.js as usually
Include it in a directory and create a file named manifest.json. You'll get this structure (can be zipped for distribution) :
myscript/
manifest.json
myscript.user.js
The manifest.json is a file required to import your script as a Chrome extension in developer. It describes your user script. Here is the related documentation, but the minimal code for our purpose is :
{
"manifest_version":2,
"version":"1.0",
"name": "MyScript",
"content_scripts": [
{
"js": ["myscript.user.js"],
"matches": ["http://domain.com/"]
}
]
}
Now that you have your directory with your user script and manifest.json, you can import it as an unpacked extension (a packed one will be disabled after Chrome's restart). To achieve this, simply check the "developer mode" and choose "Load Unpacked Extension...". Navigate to the directory created at step 2 and select it : that's "all".
Pros
Native solution
Natural for you if your developing your script on Chrome (obviously this wasn't my case :P)
Your script is now treated like a "real" extension.
Cons
Oh, god... I'm missing the one-click install : even if the user only has to achieve the step 4 it's still a pain.
Looks less "professional" because the user has to enable the developer mode
No longer "cross-browser" distribution since the Google Chrome's script has to be packed in a special way
The original directory cannot be (re)moved without breaking the script
A warning will be triggered every single time Chrome is opened to ask if you are sure that you want to use developer mode
Conclusion
I liked the way user-scripts had native support on Chrome : every third party plugin has some small variations (ie : datas or xhr handling). But the cons are to numerous and to important (especially the two last ones)... Even if enabling a non-PlayStore script is possible in a native way, it became such a pain that I recommend to adapt the script for a plugin such as TamperMonkey. After all, Chrome was an exception since every other browser require a plugin, now these plugins are the only way.
I still feel a bit disappointed, so if anyone happens to find a better solution (still hoping for some white-lists) I would enjoy to offer some bounty.
EDIT : Please note that user2428118 provided a list of other interesting workarounds. Even if they did not solved my specifif problem, they should be considered.
EDIT : manifest fixed
The continuation of solution number 1 from #user2428118 answer.
To ensure that you ALWAYS starts Chrome with --enable-easy-off-store-extension-install flag you, can use (additional to editing all shortcuts in menu start etc.) this registry file:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\http\shell\open\command]
#="\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" --enable-easy-off-store-extension-install -- \"%1\""
[HKEY_CLASSES_ROOT\https\shell\open\command]
#="\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" --enable-easy-off-store-extension-install -- \"%1\""
Replace C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe with actual path to chrome.exe in your system.
Unfortunately, aside from extensions like Tampermonkey, there don't seem to be good workarounds, given the way your script is generated differently for each user.
This is the best explanation I've found:
http://www.chromium.org/developers/extensions-deployment-faq

Communicating between a Chrome packaged app and a Chrome extension?

I need to combine functionality available only in a Chrome packaged app (access to syncFileSystem) and functionality available only in a Chrome extension (injecting a script into a 3rd party website).
It seems that neither a packaged app nor an extension can achieve both these things, so I'm now considering trying to achieve what I'm after with a separate packaged app and extension communicating.
I see that Chrome's documentation explains how two extensions can communicate via chrome.runtime.onMessageExternal.addListener and chrome.runtime.sendMessage, but nothing about packaged apps and extensions communicating.
Does anyone know if this is allowed? Is there any documentation, or a working example out there?
Yes, that is possible. The code sample in the documentation you linked works for any combination of app and extension.
The extension documentation for chrome.runtime.sendMessage says:
Sends a single message to onMessage event listeners within the extension (or another extension/app).
Messaging works the same in both extensions and apps, and they seem to be fully compatible; simply use the ID for the destination extension or app. If you look at the docs for the app version of chrome.runtime.sendMessage, you'll see that it is identical to the extension version.

How to work with locale-file for language settings and simple-prefs for options window with add-on builder

I am developing an add-on with the Mozilla Add-on Builder.
There are 3 problems that I cannot find a solution for:
To be able to provide a user dependent language I have to add properties-files to the locale-file - i.e. en-US.properties. But how do I implement this using the Add-on Builder?
I can use the ln10-module but I have no clue how to create the property files since the only visible (to me) folders are lib, data and libraries - and not locale.
Other extensions that I have installed open a small preferences-window when I click on "Options" in the Add-on Manager. But when I use the module simple-prefs the prefs are displayed on the same site as all other informations displayed when clicking on "more". How do I achieve a small seperate "window" for my prefs? And are there othere options for me to style it besides the spartanic "type"-"value"-thingy?
I know how to use Erik Vold's toolbarbutton module but how can I achieve such nice options windows that open when I click i.e. on the toolbar icon or on "options" in the menu like other extensions?
I want to get rid of the basic misconception first. There are two very different types of Firefox extensions: the classic XUL-based extensions and the extensions based on the Add-on SDK. The Add-on Builder works with the latter, pretty much all of the extensions documentation on MDN applies to the former.
I can use the ln10-module but I have no clue how to create the property files since the only visible (to me) folders are lib, data and libraries - and not locale.
It seems that the Add-on Builder doesn't support localized add-ons yet. You can download the Add-on SDK and build your extension from the command line - this will give you more options.
Other extensions that I have installed open a small preferences-window when I click on "Options" in the Add-on Manager.
These are XUL-based extensions. The Add-on SDK doesn't support opening new windows, merely panels. However, even opening a panel for the add-on options would require some very creative hacking.
how can I achieve such nice options windows that open when I click i.e. on the toolbar icon or on "options" in the menu like other extensions?
Same here - the Add-on SDK supports HTML-based panels, no real (XUL-based) application windows.

Categories

Resources