jquery support works in html but not in .js? - komodo

Trying out komodo to build a jquery ui widget.. I enabled the jquery api reference and in a .html file it works great.. I then open my widget.js file and type in;
(function($) {
followed by
$.
I would expect to get intellisense here, but instead I get:
No completions found. (Error determining completions)
Is this a file extension thing? Are jquery ui widgets just unsupported?

From the guys at Komodo;
The problem is that Komodo doesn't know the context of the anonymous
function call - in other words Komodo is not smart enough to know that
"jQuery" == "$" in this case.
But all is not lost, you can help out Komodo by telling it what the
type is in such cases. Here is the example that uses jsDoc to help
define the type of "$":
(/** #param {jQuery} $ */function($) {
$. // will show jQuery completions now
})(jQuery)
;

The argument is the problem. Without it:
(function()
{
$. //works
jQuery. //works
...
}
);
Komodo knows both $ and jQuery as globals. Local scope takes precedence, so $ becomes undefined. Conversely, if you pass in jQuery instead, $ will work, but jQuery will not:
(function(jQuery)
{
$. //works
jQuery. //does not
...
}
);

Related

Passing variable from jade to ng-init not working

I'm trying to pass an object from jade to ng-init in angular
This: doesn't work:
ng-init='tables=!{JSON.stringify(tables)}'
This: expands but,
ng-init='tables=#{JSON.stringify(tables)}'
the output is unescaped and filled with "s
ng-init="tables={"12":{"id":....
and the view isn't updated in either of the cases. This article implies that first one should work, but like I said, it doesn't even expand,
ng-init='tables=!{JSON.stringify(tables)}'
in source code shows up exactly the same in the HTML source
ng-init='tables=!{JSON.stringify(tables)}'
Actually, the #{...} approach seems to work fine.
It is probably the way console.log prints attributes' values that confused you.
ng-init="tables=#{JSON.stringify(tables)}"
Take a look at this short demo.
In what use-case you want to pass data directly from Jade to angular? I think you could to this job in controller like this :
$scope.init = function () {
// init stuff
}
...and in your view :
ng-init = init()

Provide jquery explcitly with requirejs

I'm working on a page that is in progress of transitioning from script tags to require.js. This means that some dependencies are loaded via <script> and others via require.
For the most part, in my require modules I can still treat global scripts as modoules (and thereby help the transition) by doing something like this in my bootstrapping file
define('Globalize', Globalize);
define('knockout', ko);
However this won't work with jQuery since it is a function and require will try to invoke it as a callback. Is there a way to tell require "yes this is a function but return it directly, don't try to invoke it"?
And yeah, I can't just load jquery twice because I've got bootstrap modifying it, and things depending on bootstrap
Oh...
define('jquery', function() { return window.jQuery});
duh.

RequireJS Dynamic Paths Replacement

I have a requirejs module which is used as a wrapper to an API that comes from a different JS file:
apiWrapper.js
define([], function () {
return {
funcA: apiFuncA,
funcB: apiFuncB
};
});
It works fine but now I have some new use cases where I need to replace the implementation, e.g. instead of apiFuncA invoke my own function. But I don't want to touch other places in my code, where I call the functions, like apiWrapper.funcA(param).
I can do something like the following:
define([], function () {
return {
funcA: function(){
if(regularUseCase){
return apiFuncA(arguments);
} else {
return (function myFuncAImplementation(params){
//my code, instead of the external API
})(arguments);
}
},
funcB: apiFuncB
};
});
But I feel like it doesn't look nice. What's a more elegant alternative? Is there a way to replace the module (apiWrapper) dynamically? Currently it's defined in my require.config paths definition. Can this path definition be changed at runtime so that I'll use a different file as a wrapper?
Well, first of all, if you use Require.js, you probably want to build it before production. As so, it is important you don't update paths dynamically at runtime or depends on runtime variables to defines path as this will prevent you from running r.js successfully.
There's a lot of tools (requirejs plugins) out there that can help you dynamically change the path to a module or conditionnaly load a dependency.
First, you could use require.replace that allow you to change parts (or all) of a module URL depending on a check you made without breaking the build.
If you're looking for polyfilling, there's requirejs feature
And there's a lot more listed here: https://github.com/jrburke/requirejs/wiki/Plugins

Is there any fast tool which performs constant substitution without stripping out comments in JavaScript source code?

For example, setting MYCONST = true would lead to the transformation of
if (MYCONST) {
console.log('MYCONST IS TRUE!'); // print important message
}
to
if (true) {
console.log('MYCONST IS TRUE!'); // print important message
}
This tool ideally has a fast node.js accessible API.
A better way to achieve what you want -
Settings.js
settings = {
MYCONST = true
};
MainCode.js
if (settings.MYCONST) {
console.log('MYCONST IS TRUE!'); // print important message
}
This way, you make a change to one single file.
google's closure compiler does, among other things, inlining of constants when annotated as such, leaving string content untouched but I am not sure if it's a viable option for you.
Patch a beautifier, for example
Get the JS Beautifier https://raw.github.com/einars/js-beautify/master/beautify.js written in JS.
Replace the last line of function print_token() by something like
output.push(token_text=="MYCONST"?"true":token_text);
Call js_beautify(your_code) from within nodejs.
The Apache Ant build system supports a replace task that could be used to achieve this.
Edit: Whoops. Gotta read title first. Ignore me.
Google Closure Compiler has such a feature:
You can combine the #define tag in your code with the --define parameter to change variables at "compile" time.
The closure compiler will also remove your if-statement, which is probably what you want.
Simply write your code like this:
/** #define {boolean} */
var MYCONST = false; // default value is necessary here
if (MYCONST) {
console.log('MYCONST IS TRUE!'); // print important message
}
And call the compiler with the parameter:
java -jar closure-compiler.jar --define=MYCONST=true --js pathto/file.js
Regarding you API request: Closure Compiler has a JSON API.

How to make the Jade template compress inline javascript automatically?

when I check the html page source, the HTML tags and text content are compressed without blank and line, but inline javascript.
Just discovered something that works for me in Jade v0.30.0:
Rename your .js file with a .uglify extension
In your Jade template, use:
include name-of-javascript-file.uglify
Why it works: Digging into the Jade source code, I discovered a file called filters.js. In there, you'll see a dependency on transformers. In lib/transformers.js (of the transformers module), you will see the various transform utilities, including uglify. Apparently, Jade will call on any of those transformers if you match the right file extension in your include declaration.
I'm not sure about it and haven't tested it yet, but you can probalby add a filter and utilize UglifyJS. For example
var uglyParser = require("uglify-js").parser;
var uglyUgly = require("uglify-js").uglify;
var uglify = function(str) {
var ast = uglyParser.parse(str);
ast = uglyUgly.ast_mangle(ast);
ast = uglyUgly.ast_squeeze(ast);
return uglyUgly.gen_code(ast);
}
To be honest, I'm not sure where to put that in jade so it's treated as a filter. For now you should be able to just stick it at https://github.com/visionmedia/jade/blob/master/lib/filters.js.
The usage in jade would then be:
script(type="text/javascript")
:uglify
<Your JavaScript Code>
Again I haven't tested it. But I think it should work. I'll test it later today.
According to the docs, you can use any JSTransformer as a jade filter. So, where you would normally do this to inline JS:
script.
(function doSomething () { … })();
you should do it like this:
script
:uglify-js
(function doSomething () { … })();

Resources