This is really cool! I've worked with QML a lot in the past, so I've been interested in seeing ClojureScript run in QML!
On 4 July 2014 01:34, Aaron Craelius <[email protected]> wrote: > Hi all, > > I have been trying to get Clojurescript working with QML and want to > report how I have gotten a QML-based Clojurescript REPL working. > > Although some minimal working examples have been posted - > https://github.com/fehrenbach/qmcljs and > https://github.com/halgari/qt_with_cljs - it has become evident that > getting a working REPL is significantly more difficult. > > I initially got a somewhat functional REPL working by porting Weasel and > using Qt 5.3's Websockets: > https://github.com/aaronc/weasel/blob/master/src/cljs/weasel/repl.cljs. > Because of QML's unusual behavior with respect to scoping - the root cannot > be modified and the value of this for the file from which Clojurescript was > loaded cannot be modified after loading the file. As a result, QML usually > throws type errors when you try to def most things from the REPL. > > My solution to the scoping issue is somewhat of a hack and currently only > works with :whitespace optimizations. One nice thing about the hack, > however, is that it does allow Clojurescript to modify QML's global scope. > Therefore any namespaces defined by Clojurescript will be available to the > whole Qml environment. This may or may not be desirable, but it is the only > way I've been able to get a REPL working and I would like to ^:export at > least some Clojurescript var's globally to QML. > > Anyway, this is what I had to do: > > in C++: > QQmlApplicationEngine engine; > QObject* global = new QObject(); > // reset the root context to my context object > engine.rootContext()->setContextObject(global); > // and expose it globally as "global" > engine.rootContext()->setContextProperty("global", global); > > The following preamble is required to the generated javascript: > var goog = goog || {}; // make sure the goog object is created > // before base.js is loaded > goog.global = global; // set goog.global to point to my context property > // which is actually the QML root context! > global.goog = goog; // make sure goog is defined in my global context. > > > And line 47 in > https://github.com/google/closure-library/blob/master/closure/goog/base.js, > needs to be changed to: > goog.global = goog.global || this; // only redefine goog.global if it > doesn't exist > > I should mention that :simple optimizations almost work, but there are > issues if you want to modify an already defined namespace because the > Closure compiler converts a lot of google.provide("my_ns") into simply var > my_ns = {}. This turns out to be an issue if you want to modify that ns > from the REPL because of scoping issues. The good news is that, it looks > like :simple work if you don't need a full REPL and will only expose the > ^:export'ed vars. :advanced mode works partially is probably a matter of > declaring the correct externs. > > Would any of the Clojurescript maintainers want to comment on this > approach... and on the possibility of patching base.js and adding a :qml > compilation :target? > > -- > Note that posts from new members are moderated - please be patient with > your first post. > --- > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/clojurescript. > -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
