On 4/21/2014 10:52 PM, Boris Zbarsky wrote:
On 4/21/14, 11:35 PM, Joshua Cranmer 🐧 wrote:
I'm referring to using a Promise, essentially, in backend code of
Thunderbird. There is no "window"

I mean Window in the "DOM Window" sense.

Promises can be created using some other global (which one is up to the person creating it), but typically they're associated with a Window.

I managed to, in one of my playground techniques, create a global using a backstage pass and some xpconnect APIs, so it's not impossible but it is damn annoying.

Of course if you're doing something that doesn't look like anything in the web platform then using web platform APIs may give you a bad time, though... :(

I consider Promise more like a generic platform feature (considering that the specification is moving to ES6 instead of DOM): they are useful well outside the scope of Windows/Workers, and their specification isn't intrinsically tied to such objects (except maybe insofar as things like realms/compartments/etc. are concerned). I think there are proposals to add it to XPCOM JS component/module scopes, which to me is the definition of "should be usable outside of web platform APIs."

Can you back up a second?

What do you mean by "react to a promise"? Do you mean the equivalent of invoking its then() method (so being notified when it's resolved or rejected)?

Yes.
If so, if your promise is an actual Promise then you implement a subclass of PromiseNativeHandler and call Promise::AppendNativeHandler() with an instance of that subclass. No JS callables involved, though of course you will get resolved/rejected with a JS::Value and then have to deal with it.

But that's only true if it's an actual Promise.

I consider manual JSAPI calls pretty hairy already

I think we can all agree that minimizing the amount of manual JSAPI that needs to be done is a goal here.

I'm not following the reasoning, but chances are it's wrong. Unless
you need your thing to be gettable from C++ via
createInstace/getService, you shouldn't need XPIDL.

That is exactly what my need.

OK.

Note that this still does not require XPIDL; it just makes object creation a bit more annoying if the object is using WebIDL bindings instead [1]. Whether that annoyance is a bigger problem than the other issues you get when using XPIDL here is hard for me to tell given the lack of context.

For more specific explanation then:
I have a (non-negotiably) JS-implemented XPCOM service called the Folder Lookup Service. I want to add an API to it called getOrCreateFolder that returns a Promise<nsIMsgFolder>. I have non-negotiable C++ code that wants to call this method, and do something when the promise is resolved or rejected.

I don't have any other choice.

Sure you do. You can use raw JSAPI (yes, you don't want to and I don't want you to) or WebIDL. Again, it's a matter of tradeoffs...

I think I would consider adding helpers to xpconnect before doing raw JSAPI: considering how often JS people change their APIs, and the fact that comm-central is a separate repository, manual JSAPI calls are even more painful from comm-central. All the more so because the JSAPI documentation is now so woefully out-of-date I couldn't figure out how to pass undefined to a JS::Handle<JS::Value>. o_O

I don't think WebIDL is applicable in this circumstance if the JS promises are coming from Promises.jsm... I'd generally love to use WebIDL a lot more (it has sane semantics for things like arrays), but the problem is I have a lot of JS-implemented services that need to be called from C++ which is where WebIDL is almost completely useless the last time I checked.

Hopefully the fact that I need to go through XPIDL is sufficient
explanation.

See above. It would really help if you'd just explain what you're trying to do instead of talking about the solutions to a problem that's not actually stated...

It might help if you ping me on IRC instead of trying to go back and forth on the newsgroup...

-Boris

[1] You can have an object that has a WebIDL binding and implements a contract that QIs only to nsISupports, then createInstance it, QI to nsIXPConnectWrappedJS, extract the chrome-side JS::Value and then construct the webidl binding object. In fact, this is exactly how JS-implemented WebIDL bindings work.

But not if the object isn't a WebIDL binding in the first place (e.g., coming from Promises.jsm), as I understand it, but I don't really know WebIDL bindings all that well.

--
Joshua Cranmer
Thunderbird and DXR developer
Source code archæologist

_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to