On Sunday, December 28, 2014 12:48:47 PM UTC-5, Pauli Jaakkola wrote: > Great to hear someone else is also working with ClojureScript on QML! > > Although a REPL is cool, what I would really like is getting the :advanced > mode working. I did get some trivial examples to work with your root context > manipulation trick. > > However, it falls apart with "global" scripts (.pragma library), since, > according to Qt docs: > > "Global code is run in a reduced scope. During startup, if a QML file > includes an external JavaScript file with "global" code, it is executed in a > scope that contains only the external file itself and the global object." > > After experimenting I conclude that even context properties set before > loading the .qml file(s) don't exist (I get a "global is not defined" error). > Using "this" doesn't work either and apparently its value is neither the root > context nor the root object of the script. > > I am at a loss here. Maybe the solution involves finding out what actually > exists when "global" code is loaded (is the "global object" the root context? > If not, what is it then?). If nothing else helps, maybe the script needs to > be loaded and evaluated from C++ with engine.evaluate? > > perjantai, 4. heinäkuuta 2014 3.34.44 UTC+3 Aaron Craelius kirjoitti: > > 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?
I haven't actually played with the QML Clojurescript REPL I got working for a while. In general, it required a lot of experimentation to get what I got working and as you can see, QML's restriction on global scope really makes it hard to integrate something like Clojurescript cleanly. I think advanced compilation might work if you define externs and only use those as your integration points but can't say for sure. -- 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.
