Strict mode for JScript? - jscript

Is there something in JScript (used in Windows Script Host) that is similar to "use strict"; in JavaScript?
In particular, I want to prevent this:
var goodVar = 2;
misspelledVar = 3;
JScript will happily execute this without any warning or error.

Related

How to create a Thunderbird native extension?

I need to write an extension for Thunderbird. The extension will be used to do some text mining and relies on native C++ code. From my understanding, Thunderbird extensions are now mostly written in JavaScript and XPCOM is being slowly deprecated (https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM).
Besides, XPCOM seems a bit heavy and I would like an easier path to access my C++ code. Are there any alternatives besides XPCOM to access C++ code from a thunderbird extension?
Thanks!
Take a look at js-ctypes (https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes)
Little example:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/ctypes.jsm")
// path to C++ lib (/home/username/.thunderbird/PROFILE/extensions/EXTNAME/components/lib.so)
var libPath = FileUtils.getFile("ProfD", ["extensions", "EXTNAME", "components", "lib.so"]);
var lib = ctypes.open(libPath.path);
var libFunction = lib.declare("concatStrings", // function name in C++ code
ctypes.default_abi,
ctypes.char.ptr, // return value
ctypes.char.ptr, // param1
ctypes.char.ptr // param2
);
var ret = libFunction("abc", "efg");
lib.close()
Also be aware that C++ compiler does name mangling due to function overloading so your function name might be 'concatStrings' in C++ code, but then in assembly it might be something like '_123concatStrings'. To prevent this declare your function like:
extern "C" const char * concatStrings ( const char * str1, const char * str2 );

Purescript pulp build output generates requirejs error in browser

When I use pulp build -O -t html/main.js and then pulp build -O -I test -m Test.Main -t html/testmain.js (i.e. building main and test) I get two different js output. In the former case, the format is
// Generated by psc-bundle 0.8.2.0
var PS = { };
(function(exports) {
// Generated by psc version 0.8.2.0
"use strict";
var Prelude = require("../Prelude");
var Control_Monad_Eff = require("../Control.Monad.Eff");
exports["main"] = main;
})(PS["Main"] = PS["Main"] || {});
PS["Main"].main();
Please note the require. In the latter case, the require is not in place at all
// Generated by psc-bundle 0.8.2.0
var PS = { };
(function(exports) {
/* global exports */
"use strict";
exports.concatArray = function (xs) {
return function (ys) {
return xs.concat(ys);
};
};
exports.showNumberImpl = function (n) {
/* jshint bitwise: false */
return n === (n | 0) ? n + ".0" : n.toString();
};
})(PS["Prelude"] = PS["Prelude"] || {});
(function(exports) {
// Generated by psc version 0.8.2.0
"use strict";
var $foreign = PS["Prelude"];
var Semigroupoid = function (compose) {
this.compose = compose;
};
Both examples are shorten, but the point is that require is used in the first time, while not used in the second time.
The issue is that I am not able to run the version using require in the browser due to this error
ReferenceError: require is not defined
When I included require.js into page, I got this error
Error: Module name "../Prelude" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
Thus my question is, what can be done to run the first case in browser.
My guess would be that this comes from running builds with different --require-path options; once with the old default, which was an empty string, and once with ../. This would lead to psc-bundle not realising it needed to include Prelude and Control.Monad.Eff properly in the first case. psc-bundle should replace those require calls with references to the other modules, so that the code works in browsers.
There are a few different ways this can happen, and the compiler has been updated now in a way that should make the probability of this happening again much lower, so I wouldn't spend too much time worrying about exactly how this has occurred.
If none of the above makes any sense to you, don't worry; I think you just need to do the following to fix this:
Update to the latest version of psc (0.8.3 changed the --require-path default to ../, so any version after 0.8.3 should do, but you will want the latest version in most cases)
Delete your output directory
Compile everything again.
You probably need to use the --browserify option to build the first case for the browser.

How do I set default options for traceur.compile and traceur.require?

Using the official traceur module, is it possible to set the default options for compile and require?
For example, this code works:
var traceur = require('traceur');
console.log(
traceur.compile('{ let x = 1; }', { experimental:true }).js
);
Now if I remove traceur.compile's 2nd argument (the options object):
console.log(
traceur.compile('{ let x = 1; }').js
);
Traceur will throw an error as the blockBinding option is not enabled. Is there any way to change the default options, in order to compile files without always passing an options object?
My main concern, apart from applying the DRY principle, is getting the traceur.require function to compile files with customized options -- as far as I can see, traceur.require and traceur.require.makeDefault() do not even take an options argument.
For instance, considering this code sample:
require('traceur').require('./index');
And this piece of code:
require('traceur').require.makeDefault();
require('./index');
Is there any way to compile the required file with the experimental option enabled?
Preferably by altering the default options, as I cannot see any other viable way.
Using Node 0.10.29 and Traceur 0.0.49.
Here's a full example of what I'd like to achieve.
bootstrap.js (entry point):
var traceur = require('traceur');
traceur.options.experimental = true;
traceur.require.makeDefault();
require('./index');
index.js:
import {x} from './lib';
// using a block binding in order to check
// whether this file was compiled with experimental features enabled
{
let y = x;
console.log(y);
}
lib.js:
export var x = (() => {
if (true) {
// should be compiled with experimental features enabled too
let x = 1;
return x;
}
})();
Expected console output: 1
traceur.options.experimental=true serves as a setter which enables the experimental features in the traceur.options object, but unfortunately traceur.options does not seem to affect traceur.compile nor traceur.require as far as I can see.
The Using Traceur with Node.js Wiki page does not mention anything about compiling options. The Options for Compiling page does not mention the Traceur API in Node.js, in fact, I cannot find any documentation about the Traceur API in Node.js.
Fabrício Matté ;-) added support for giving the default options to makeDefault(), see
https://github.com/google/traceur-compiler/blob/master/src/node/require.js#L58
A separate bug with the option experimental was fixed today, 16JUL14.

Sharing constants between a web client and NodeJS server

I have a NodeJS application with common constants between the client and the server.
The constants are stored in variables rather than inline. Those variables could be defined in two separate files, one for client and one for server.
File 1:
// client_constants.js
MESSAGE_TYPE_A = "a";
MESSAGE_TYPE_B = "b";
File 2:
// server_constants.js
exports.MESSAGE_TYPE_A = "a";
exports.MESSAGE_TYPE_B = "b";
To avoid duplicate code I would like to store constants in a single location and a single format for both the client and the server. Wat do?
You can do something like this:
// constants.js
root = exports ? window
root.MESSAGE_TYPE_A = "a";
root.MESSAGE_TYPE_B = "b";
"exports" does not exist on the client side in which case it will use the default "window" object.
Sort of like Hector's answer, but works in my version of Node and in my browser because it uses comparisons to "undefined" and typeof.
var context = (typeof exports != "undefined") ? exports : window;
context.constant_name = "constant_name_string";

How can I create an object of a class which is defined in the remote page?

For example, in the remote webpage, there is a snippet of code like this:
<script>
function foo(){
this.bar = 0;
}
In my greasemonkey script, I want to create an object of this class:
var _foo= unsafeWindow['foo'];
new _foo();
Then I got an Illegal Value error.
Here's how to do it:
var _foo = eval('(' + unsafeWindow.foo.toSource() + ')');
var x = new _foo();
This workaround may be required due to the different security zones or sandboxing that Greasemonkey does, though I'm not entirely sure.

Resources