Check if a preference exist from Firefox extension - javascript

How to check if preference exist?
I need to create a new preference in the Firefox configuration, but I can't know whether it exists already.
var firstRun = prefs.getBoolPref('extensions.addon.firstRun');
Error: NS_ERROR_UNEXPECTED: Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIPrefBranch.getBoolPref]

As already stated by #try-catch-finally, MDN already has some code snippets.
I personally would however use #try-catch-finally's user name :p, e.g.
var somePref = false;
try {
firstRun = prefs.getBoolPref('extensions.addon.somePref');
}
catch (ex) {
prefs.setBoolPref('extensions.addon.somePref', somePref = true);
}
Well, even better would be if you added some default preferences (more) to your extension! Especially "first run" preferences are almost predestinated for this.
In defaults/preferences/somefilename.js add e.g.
pref("extensions.addon.firstRun", true);
Make sure to read through the Preferences article. In particular preference observers often are quite useful. ;)

Related

A way to reverse all prototype re-definitions?

Let's assume that I do not trust the browsers visiting my website. What if they for example override XMLHttpRequest.prototype and redirect or change the requests. Is there any way to prevent this? Perhaps by resetting all objects to "factory settings" at the end of loading?
If your script run at first, you can save references to whatever you need like below & freeze it.
(() => {
const XHR = XMLHttpRequest;
Object.freeze(XHR);
// use XHR here ...
)();
Otherwise, I think it is not possible to be sure other than check if function is native - casting to string (function + '') should show it is native function.
And running few simple unit tests against this function to be sure it is ok.
Running units test may be necessary to be sure if functions are not changed with each other (still remains native).
const alertRef = alert;
alert = console.log;
console.log = alertRef;
Another possible option that may be helpfull is checking functions length property which defines how many arguments it accepts.
Be careful with that becouse it may differ in different browsers.

Should I keep console statements in JavaScript application?

I am using console.log() and console.dir() statements in 3 places in my 780 lines of code JS script. But all of them are useful for debugging and discovering problems that might appear when using the application.
I have a function that prints internal application's state i.e current value of variables:
printData: function () {
var props = {
operation: this.operation,
operand: this.operand,
operandStr: this.operandStr,
memory: this.memory,
result: this.result,
digitsField: this.digitsField,
dgField: this.dgField,
operationField: this.operationField,
opField: this.opField
};
console.dir(props);
}
I also have a list of immutable "contants" which are hidden with closure but I can print them with accessor method called list(); in console.
Something like this:
list: function () {
var index = 0,
newStr = "",
constant = '';
for (constant in constants) {
if (constants.hasOwnProperty(constant)) {
index = constant.indexOf('_');
newStr = constant.substr(index + 1);
console.log(newStr + ": " + constants[constant]);
}
}
}
The third place where I use console in debugging purposes is in my init(); function, where I print exception error if it happens.
init: function (config) {
try {
this.memoryLabelField = global.getElementById(MEMORY_LABEL);
this.digitsField = global.getElementById(DIGITS_FIELD);
this.digitsField.value = '0';
this.operationField = global.getElementById(OPERATION_FIELD);
this.operationField.value = '';
return this;
} catch (error) {
console.log(error.message);
return error.message;
}
}
As my question states, should I keep these console statements in production code?
But they come very useful for later maintenance of the code.
Let me know your thoughts.
Since these are not persistent logs you won't get much benefit out of them. Also it runs on every individuals machine since everyone has their own copy of the program. If you really need it, it would be better to have a variable that can toggle this feature. Espcially if you are targetting to debug a whole lot of pre-determined stuffs.
Client Side issues needs to be debugged slightly different from Server Side. Everyone has their own copy of the program. Browser-JS is run on client side you open the browser and all code that you wrote is with you in a full blown repl and debugging is easy compared to Server side where most likely you wouldn't have access to that system. It is so flexible that you could just override it when you are checking something in production right from your own browser without affecting anyone. Just override it with those console statements and debug the issue.
Its a good idea to have logs in Server side programming. It gives a lot of useful information and is persistent.
As said above, debugging code should not be present on a production environment.
However, if you plan to keep it anyway, keep in mind that all browsers do not support it.
So you may check its availability and provide a fallback:
if (typeof window.console === 'undefined')
{
window.console = {};
}
if (typeof window.console.log === 'undefined')
{
window.console.log = function() { };
}
According to mozilla developer network
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
Leaving console.log() on production sites can cause issues since it is not supported by older browsers. It is most likely to throw exceptions in that case.
It's historically considered a bad-practice by Javascript programmers. At the start of the eons, some browsers didn't have support for it (IE8 or less for example). Other thing to take in mind is that you are making your code larger to download.

Firefox SDK : Listen for a change in non addon specific about:config entry

I am trying to listen for changes to settings in firefox's about:config that the user could have changed while my addon is running. The settings in question are part of the browser and not created by my addon.
I can read and set them manually when the user has used my addon with no problems using the "preferences/service" module, but I want to be able to make the appropriate changes in my addon if the user has changed a setting in about config independently of my addon.
The "simple-prefs" module provides a listener but that is only for settings specific to your application, like "extension.myaddon.mypreference" where as the settings I need to watch are like "network.someoptionhere"
If someone could point me in the right direction as to how I would go about this I would greatly appreciate it.
You'll need to use some XPCOM, namely nsIPrefService/nsIPrefBranch (e.g. via Services.jsm). This is the same stuff that preferences/service and simple-prefs wraps.
Here is a full example:
const {Ci, Cu} = require("chrome");
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
function observe(subject, topic, data) {
// instanceof actually also "casts" subject
if (!(subject instanceof Ci.nsIPrefBranch)) {
return;
}
console.error(subject.root, "has a value of", subject.getIntPref(""), "now");
}
var branch = Services.prefs.getBranch("network.http.max-connections")
branch.addObserver("", observe, false);
exports.onUnload = function() {
// Need to remove our observer again! This isn't automatic and will leak
// otherwise.
branch.removeObserver("", observe);
};

Enable/Disable debug code dynamically

I'm writing a decent sized JavaScript animation library, that I would like to include debugging code in. I could easily do a check :
if(myLib.debugger){
console.warn('warning message');
}
However if this runs a couple thousand times a second, it would eventually cause performance issues. Add in a few more checks throughout the code and the effect will be even more noticeable.
What I'm wondering is if it would be possible to check onload if the debugger should be enabled, and if so... turn something like this:
//debugger if(!this.name) console.warn('No name provided');
into:
if(!this.name) console.warn('No name provided');
Leaving the code commented if its not enabled, and uncommenting it if it is, thus removing any possible performance issues. Could this be done somehow with a regular expression on the entire script if loaded in through ajax? I'm trying to avoid the need for 2 versions of the same code, lib.dbug.js and a lib.js.
Cross browser compatibility is not of great importance for this (I'm really only worried about new browsers), I see it as nice to have item. If its possible however, it would be a great thing to have.
Any insight would be greatly appreciated.
The simplest way to do this would be to check if the debugger should be disabled and if so, replace it with a mock object that does nothing at the very start of your script:
if (!myLib.debugger) {
window.console = (function () {
var newConsole = {};
var key;
for (key in window.console) {
if (typeof window.console[key] === 'function') {
newConsole[key] = function () {};
}
}
return newConsole;
}());
}
The overhead of this approach should be negligible.
If this is a JavaScript library... then I'd expect as a 3rd party developer that I could download/use 2 versions. The production version (no debug, AND minimized). If I wanted to debug, I would point to the debug version of the library instead.
e.g.
<script src="foo-lib-min.js"></script>
<!-- swap to this for debugging <script src="foo-lib-full.js"></script>-->

programmatic way to check which version is installed?

Is there a way through javascript to see what version (or rollup) the crm organization/server is on? What I really want to know is if I am on UR11 or before.
I've tried:
Xrm.Page.context - but nothing about versions (did I miss something?)
Checking if (crmForm == null) (Since that was disabled as of UR12) The problem is that if the org enables HTC support then crmForm will not be null, and I need to know what version with or without HTC support enabled.
What I've done for now is put the onus on the solution installer to modify a javascript file that has the "isRollup12" variable to true or false, which is quite clunky.
There is a global JS variable you could check:
alert(APPLICATION_FULL_VERSION);
//on UR12 '5.0.9690.3236'
//on UR11 '5.0.9690.2839'
//and so on...
But this method isn't supported, so use at your own risk.
you can check if the getClientUrl function is defined, it's a new function included inside UR12.
var isRollup12 = false;
if (Xrm.Page.context.getClientUrl !== undefined) {
isRollup12 = true;
}

Categories

Resources