How do I add my own JavaScript libs to ClojureScript? - javascript

I want to write a Google Chrome extension, using ClojureScript. With ClojureScript I can use all the Google Closure libs, but afaik access to the Chrome browser is not included in those libs. So I want to wrap all the Chrome stuff in my own JavaScript lib.
So far I tried creating my own jar that has a single JavaScript file that just creates a Foo object and exports the constructor. I'v added this jar to the lib directory of the ClojureScript compiler (which also has for example goog.jar), but so far without luck:
Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :-compile of protocol: #'cljs.closure/Compilable found for class: nil
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:494)
at cljs.closure$eval1056$fn__1057$G__1047__1064.invoke(closure.clj:187)
at cljs.closure$get_compiled_cljs.invoke(closure.clj:422)
at cljs.closure$cljs_dependencies.invoke(closure.clj:440)
at cljs.closure$add_dependencies.doInvoke(closure.clj:462)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:602)
at cljs.closure$build.invoke(closure.clj:701)
at user$eval1246.invoke(cljsc.clj:21)
at clojure.lang.Compiler.eval(Compiler.java:6406)
at clojure.lang.Compiler.load(Compiler.java:6843)
at clojure.lang.Compiler.loadFile(Compiler.java:6804)
at clojure.main$load_script.invoke(main.clj:282)
at clojure.main$script_opt.invoke(main.clj:342)
at clojure.main$main.doInvoke(main.clj:426)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:405)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:518)
at clojure.main.main(main.java:37)
Has anyone tried this before?

Take a look at this post from Luke Vanderhart: "Using JavaScript libraries in ClojureScript"
http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html
Also, this video from Kevin Lynagh: "Extending JavaScript Libraries from ClojureScript"
http://www.youtube.com/watch?v=XfzXFWTT-z0

If I remember Rich Hickeys talk correctly the whole program optimization of the closure compiler needs any library code to adhere to certain coding conventions. I think he also said something of JQuery not doing this but Dojo doing this. I never did this but you might find some useful information here

Related

Is there a way to tell Google Closure Compiler to *NOT* inline my local functions?

Here's what I'm looking for:
I want to use the wonderful features of SIMPLE mode minification while disabling just one specific feature (disable local function inline).
UPDATE: The answer is NO, it's not possible given my setup. But for me there is a workaround given I am using Grails.
As #Chad has explained below, "This violates core assumptions of the compiler". See my UPDATE3 below for more info.
IN QUESTION FORM:
I'm using CompilationLevel.SIMPLE_OPTIMIZATIONS which does everything I want, except that it's inlining my local functions.
Is there any way around this? For example, is there a setting I can place in my JS files to tell Google Closure not to inline my local functions?
It would be cool to have some directives at the top of my javascript file such as:
// This is a JS comment...
// google.closure.compiler = [inlineLocalFunctions: false]
I'm developing a Grails app and using the Grails asset-pipeline plugin, which uses Google Closure Compiler (hereafter, Compiler). The plugin supports the different minification levels that Compiler supports via the Grails config grails.assets.minifyOptions. This allows for 'SIMPLE', 'ADVANCED', 'WHITESPACE_ONLY'.
AssetCompiler.groovy (asset-pipeline plugin) calls ClosureCompilerProcessor.process()
That eventually assigns SIMPLE_OPTIMIZATIONS on the CompilerOptions object. And by doing so, CompilerOptions.inlineLocalFunctions = true as a byproduct (this is hard coded behavior in Compiler). If I were to use WHITESPACE_ONLY the result would be inlineLocalFunctions=false.
So by using Asset Pipeline's 'SIMPLE' setting, local functions are being inlined and that is causing me trouble. Example: ExtJS ext-all-debug.js which uses lots of local functions.
SO post Is it possible to make Google Closure compiler *not* inline certain functions? provides some help. I can use its window['dontBlowMeAway'] = dontBlowMeAway trick to keep my functions from inlining. However I have LOTS of functions and I'm not about to manually do this for each one; nor would I want to write a script to do it for me. Creating a JS model and trying to identity local functions doesn't sound safe, fun nor fast.
The previous SO post directs the reader to https://developers.google.com/closure/compiler/docs/api-tutorial3#removal, where the window['bla'] trick is explained, and it works.
Wow thanks for reading this long.
Help? :-)
UPDATE1:
Okay. While spending all the effort in writing this question, I may have a trick that could work. Grails uses Groovy. Groovy makes method call interception easy using its MetaClass API.
I'm going to try intercepting the call to:
com.google.javascript.jscomp.Compiler.compile(
List<T1> externs, List<T2> inputs, CompilerOptions options)
My intercepting method will look like:
options.inlineLocalFunctions=false
// Then delegate call to the real compile() method
It's bed time so I'll have to try this later. Even so, it would be nice to solve this without a hack.
UPDATE2:
The response in a similar post (Is it possible to make Google Closure compiler *not* inline certain functions?) doesn't resolve my problem because of the large quantity of functions I need inlined. I've already explained this point.
Take the ExtJS file I cited above as an example of why the above similar SO post doesn't resolve my problem. Look at the raw code for ext-all-debug.js. Find the byAttribute() function. Then keep looking for the string "byAttribute" and you'll see that it is part of strings that are being defined. I am not familiar with this code, but I'm supposing that these string-based values of byAttribute are later being passed to JS's eval() function for execution. Compiler does not alter these values of byAttribute when it's part of a string. Once function byAttribute is inlined, attempts to call the function is no longer possible.
UPDATE3: I attempted two strategies to resolve this problem and both proved unsuccessful. However, I successfully implemented a workaround. My failed attempts:
Use Groovy method interception (Meta Object Protocol, aka MOP) to intercept com.google.javascript.jscomp.Compiler.compile().
Fork the closure-compiler.jar (make my own custom copy) and modify com.google.javascript.jscomp.applySafeCompilationOptions() by setting options.setInlineFunctions(Reach.NONE); instead of LOCAL.
Method interception doesn't work because Compiler.compile() is a Java class which is invoked by a Groovy class marked as #CompileStatic. That means Groovy's MOP is not used when process() calls Google's Compiler.compile(). Even ClosureCompilerProcessor.translateMinifyOptions() (Groovy code) can't be intercepted because the class is #CompileStatic. The only method that can be intercepted is ClosureCompilerProcessor.process().
Forking Google's closure-compiler.jar was my last ugly resort. But just like #Chad said below, simply inserting options.setInlineFunctions(Reach.NONE) in the right place didn't resurrect my inline JS functions names. I tried toggling other options such as setRemoveDeadCode=false to no avail. I realized what Chad said was right. I would end up flipping settings around and probably destroying how the minification works.
My solution: I pre-compressed ext-all-debug.js with UglifyJS and added them to my project. I could have named the files ext-all-debug.min.js to do it more cleanly but I didn't. Below are the settings I placed in my Grails Config.groovy:
grails.assets.minifyOptions = [
optimizationLevel: 'SIMPLE' // WHITESPACE_ONLY, SIMPLE or ADVANCED
]
grails.assets.minifyOptions.excludes = [
'**ext-all-debug.js',
'**ext-theme-neptune.js'
]
Done. Problem solved.
Keywords: minify, minification, uglify, UglifyJS, UglifyJS2
In this case, you would either need to make a custom build of the compiler or use the Java API.
However - disabling inlining is not enough to make this safe. Renaming and dead code elimination will also cause problems. This violates core assumptions of the compiler. This local function is ONLY referenced from within strings.
This code is only safe for the WHITESPACE_ONLY mode of the compiler.
Use the function constructor
var fnc = new Function("param1", "param2", "alert(param1+param2);");
Closure will leave the String literals alone.
See https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function

Visual representation of classes and/or objects

recently I started to work on some big project written in php/js.
It is really big and I have constant problem of backtracing what functions are called where.
Is there any tool, that would import all the code files and draw/write connections between classes, objects, functions and such?
Regards
BOUML can create UML diagrams out of your code
http://www.bouml.fr/
old 4.23 version is also free if that is needed
http://download.cnet.com/BOUML/3000-2094_4-10788888.html
I am using Intellij IDEA with the PHP Storm Plugin for my PHP/JS-Projects. There I'm able to right click a function and choose "Find Usage ALT+F7". Now I can see, where this function is getting called.
Intellij IDEA/PHP-Storm is also able to generate UML-Diagrams if needed.
I guess Netbeans, Eclipse+PHP-Plugin do have similar functions [maybe execpt of the uml-generator], if you need an IDE at no costs.

GWT 2.7: What is the difference between -XjsInteropMode JS and -XjsInteropMode CLOSURE?

I tried out GWT 2.7 and was woundering what is the difference between -XjsInteropMode JS and -XjsInteropMode CLOSURE compiler flag?
-XjsInteropMode JS will output standard deobfuscated javascript accessors (method names match up directly, bean getter/setters map to simple property access). I assumed that using CLOSURE option will add Closure type annotations to the output to ensure two-way type safety between Gwt and Closure... But Goktug has replied on G+, saying:
-XjsInteropMode CLOSURE was used to generate export code in a way
that was assuming closure goog.provide(...) statements exists in
the beginning of js (potentially produced and prepended by a linker).
It was not useful for general public.
I'm using past tense because the option is now removed from the trunk.
Anways, if you are interested in Closure with Gwt, the video is not up yet, but Ray Cromwell's talk about Google Inbox mentions how they support highly optimized, fast compilation of Gwt -> Closure Friendly JS -> Minified obfuscated JS.
When the video is up, check it out here:
http://gwtcreate.com/videos/index.html
Until then, here are the slides:
https://drive.google.com/a/wetheinter.net/file/d/0B3ktS-w9vr8IS2ZwQkw3WVRVeXc/view
Finally, Ray's talk specifically about Js Interop:
https://docs.google.com/a/wetheinter.net/file/d/0ByS1wxINeBWjeGYxbkJpamxFZ28/edit
Note that there is also a video for that talk pending. It's very good. You should watch them both when they are uploaded.

How to use C libraries to create GNOME app in JavaScript

I am a beginner in GNOME desktop application development so I am trying to learn about it as much as possible. I have read various tutorials present on developer.gnome.org written for JavaScript. I know that through GObject Introspection I can access C libraries in JavaScript.
As use of JavaScript for desktop applications is new so not many documentations are present. I was wondering if there is any way I can know which functions I can use with what parameters to access some libraries.
For example I can create a button using GTK in JavaScript by:
this.mybutton = new GTK.Button({some code here});
How can I come to know about the name of the functions I can use? Is there any way I can make out the name of the function for JavaScript seeing the documentation written for C?
For some of the libraries I have seen this documentation written for JavaScript. Any help will be appreciated to understand more about GNOME application development.
I agree with you: the documentation is pretty low on the subject.
Most of the time I try to find already written code from other developers and change it to have what I want.
The C documentation is pretty complete on http://developer.gnome.org and most of the time you can use nearly the same methods.
I suggest you to take a look at this web site: http://www.roojs.org/seed/gir-1.2-gtk-3.0/seed/
And also to this one: http://zetcode.com/gui/javascriptgtktutorial/
Good luck with your javascript development !!!
There is new host for Gnome GJS documentation:
https://gjs.guide/
https://gjs-docs.gnome.org/ for API's
You still can get Javascript function mapped to the that C library function by searching though GIR files. Each library should have an XML file containing introspection information.
Example from one question I asked before.
grep -rn gdk_keymap_get_default /usr/share/gir-1.0/
/usr/share/gir-1.0/Gdk-2.0.gir:16781: c:identifier="gdk_keymap_get_default"
/usr/share/gir-1.0/Gdk-3.0.gir:15776: <function name="get_default" c:identifier="gdk_keymap_get_default">
vim /usr/share/gir-1.0/Gdk-3.0.gir +15776
<class name="Keymap"
c:symbol-prefix="keymap"
c:type="GdkKeymap"
parent="GObject.Object"
glib:type-name="GdkKeymap"
glib:get-type="gdk_keymap_get_type">
<doc xml:space="preserve">A #GdkKeymap defines the translation from keyboard state
(including a hardware key, a modifier mask, and active keyboard group)
to a keyval. This translation has two phases. The first phase is
to determine the effective keyboard group and level for the keyboard
state; the second phase is to look up the keycode/group/level triplet
in the keymap and see what keyval it corresponds to.</doc>
<function name="get_default" c:identifier="gdk_keymap_get_default">
<doc xml:space="preserve">Returns the #GdkKeymap attached to the default display.</doc>
<return-value transfer-ownership="none">
<doc xml:space="preserve">the #GdkKeymap attached to the default display.</doc>
<type name="Keymap" c:type="GdkKeymap*"/>
</return-value>
</function>

JavaScript code completition done right?

I've tried some of the editors/IDEs regularly recommended for coding JavaScript (Aptana, WebStorm, ...) but none of them has a satisfying autocomplete functionality. I'm probably spoiled by Microsoft's IntelliSense for .NET. There is some JavaScript-IntelliSense in WebDeveloper, but that seems to be a stripped-down version. The best I've found so far is WebStorm, but its code completition is easily distracted by imported libraries (offering hundreds of suggestions) and identical function names.
Did I miss an editor/IDE that uses refactoring (or something else) to offer proper code completition, so that it really "knowns" what that variable-name stands for, I just put a dot behind? Or is something like this on its way?
I always recommend Komodo Edit from ActiveState (now up to version 6, with support for HTML 5 and CSS3 as well as recent versions of Javascript, PHP, etc.) Note that you may have to install addons for the languages you're working in, but you should find them through the Mozilla-like Addon manager.
Also supports jQuery and even lets you use jQuery (along with vanilla Javascript or Python) in its powerful macro IDE.
Code completion example:
<script type="application/x-javascript">
var obj = {};
obj.personnel = [{firstName:"John", lastName:"Brick", age:43},
{firstName:"Jane", lastName:"Motte", age:26}
];
// now type obj. and code completion immediately offers you "personnel"
// note: file must be saved for the app to find all members of declared
// variables, but I save about every 10 seconds so it's not a problem
</script>
The best I've found so far is
WebStorm, but its code completition is
easily distracted by imported
libraries (offering hundreds of
suggestions) and identical function
names.
This comment confuses me. If you import the libraries, and your code is using them, why is it bad to include the function names in the code completion suggestions? Wouldn't you want to have jQuery's functions included if you're using it?
If you're using Microsoft's IntelliSense with jQuery, does it stick to its guns and only show JavaScript core functions? Sounds limited to me, unable to be smart when I add libraries.
Or is something like this on it's [sic] way?
It sounds to me like you want a clairvoyant interface. I don't think it is on the way anytime soon.
By the way, "it's" == "it is"; "its" is the possessive.

Categories

Resources