Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move all methods on Window back to methods #847

Merged
merged 10 commits into from
Sep 18, 2018

Conversation

alexcrichton
Copy link
Contributor

As brought up in #834 these are both fallible (in the worker context Window isn't defined) and you can also have multiple Window objects!

Closes #834

@@ -17,4 +17,15 @@ extern crate wasm_bindgen;
extern crate js_sys;
use js_sys::Object;

#[cfg(feature = "Window")]
pub fn window() -> Option<Window> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should automatically generate this function for every [Global] interface, so that one can get self in workers too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was originally wondering that as well, but I'm somewhat wary to do that because we get things like:

crates/web-sys/webidls/enabled/ServiceWorkerGlobalScope.webidl:[Global=(Worker,ServiceWorker),
crates/web-sys/webidls/enabled/ServiceWorkerGlobalScope.webidl- Exposed=ServiceWorker]
crates/web-sys/webidls/enabled/ServiceWorkerGlobalScope.webidl-interface ServiceWorkerGlobalScope : WorkerGlobalScope {
--
crates/web-sys/webidls/enabled/AudioWorkletGlobalScope.webidl:[Global=(Worklet,AudioWorklet),Exposed=AudioWorklet]
crates/web-sys/webidls/enabled/AudioWorkletGlobalScope.webidl-interface AudioWorkletGlobalScope : WorkletGlobalScope {
crates/web-sys/webidls/enabled/AudioWorkletGlobalScope.webidl-    void registerProcessor (DOMString name, VoidFunction processorCtor);
--
crates/web-sys/webidls/enabled/PaintWorkletGlobalScope.webidl:[Global=(Worklet,PaintWorklet),Exposed=PaintWorklet]
crates/web-sys/webidls/enabled/PaintWorkletGlobalScope.webidl-interface PaintWorkletGlobalScope : WorkletGlobalScope {
crates/web-sys/webidls/enabled/PaintWorkletGlobalScope.webidl-    void registerPaint(DOMString name, VoidFunction paintCtor);
--
crates/web-sys/webidls/enabled/Window.webidl:[Global=Window,
crates/web-sys/webidls/enabled/Window.webidl- Exposed=Window,
crates/web-sys/webidls/enabled/Window.webidl- LegacyUnenumerableNamedProperties]
--
crates/web-sys/webidls/enabled/DedicatedWorkerGlobalScope.webidl:[Global=(Worker,DedicatedWorker),
crates/web-sys/webidls/enabled/DedicatedWorkerGlobalScope.webidl- Exposed=DedicatedWorker]
crates/web-sys/webidls/enabled/DedicatedWorkerGlobalScope.webidl-interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
--
crates/web-sys/webidls/enabled/WorkerDebuggerGlobalScope.webidl:[Global=(WorkerDebugger), Exposed=WorkerDebugger]
crates/web-sys/webidls/enabled/WorkerDebuggerGlobalScope.webidl-interface WorkerDebuggerGlobalScope : EventTarget {
crates/web-sys/webidls/enabled/WorkerDebuggerGlobalScope.webidl-  [Throws]
--
crates/web-sys/webidls/enabled/SharedWorkerGlobalScope.webidl:[Global=(Worker,SharedWorker),
crates/web-sys/webidls/enabled/SharedWorkerGlobalScope.webidl- Exposed=SharedWorker]
crates/web-sys/webidls/enabled/SharedWorkerGlobalScope.webidl-interface SharedWorkerGlobalScope : WorkerGlobalScope {

It looks like there's a lot of semi-weird *GlobalScope objects perhaps?

One option we could do though is to perhaps define a self_ method which returns self, and then have other handwritten methods that cast this to the various scopes? I also figured that a top-level window accessor should at least be forwards compatible with an automatic solution!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I suppose it is fine to special case and hand-code globals right now.

If you are writing an audio worklet, you will want to get the audio worklet global scope... but almost no one is doing that (relative to people using window)

WorkerDebuggerGlobalScope can probably be removed -- I think that is only for the debugger.

I think a fn self_() -> js_sys::Object function would be useful regardless. 👍


js_sys::Function::new_no_args("return this")
.call0(&JsValue::undefined())
.ok()?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be unwrapped because we know that the function we are constructing is not going to throw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True! LLVM doesn't know this though and I figured it may be good to avoid all the panic code unwrap() brings in for something as small as window. (not that the current code is that small code-footprint-wise)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good point. Sounds good to me!

pub fn window() -> Option<Window> {
use wasm_bindgen::{JsValue, JsCast};

js_sys::Function::new_no_args("return this")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructing a new function on every invocation is super heavy. Can we stuff this inside a Once and cache the results?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was just kinda shooting in the dark here adding "simply anything that worked". Do you have an idea of how we could make this "better"? (apart from caching in a static, which would of course be better than this!)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking a static mut, yeah. Do you have concerns with that approach?

This is intended to address rustwasm#834 where we don't actually want methods scoped
like this! Instead we'll provide one unique accessor for the `window` object
itself.
All APIs on `Windows` are tagged where `Window` has `[Global]`, and they all
need to be structurally accessed rather than through a prototype.
This is roughly defined by
https://html.spec.whatwg.org/multipage/window-object.html#windowproxy and
otherwise fits the bill how otherwise only `interface WindowProxy;` exists in
the WebIDL.
Returns `Option<Window>` and can be used as a convenience to get a handle to the
global `window` object.
@alexcrichton
Copy link
Contributor Author

@fitzgen do you think we should go ahead and add fn self_? Or go with just window() for now?

@fitzgen
Copy link
Member

fitzgen commented Sep 18, 2018

I think it is fine to go with just window right now.

The more I think about it, the more I think that the generic give-me-the-global-object function (what we've been calling self_) should probably be in js_sys, since you might want to get the global object in non-Web environments as well.

@alexcrichton
Copy link
Contributor Author

True yeah! I'm not sure what a good name for that would be though? fn global_scope() -> Object perhaps?

@fitzgen
Copy link
Member

fitzgen commented Sep 18, 2018

or just global?

@alexcrichton
Copy link
Contributor Author

Ok, done!

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 👍

@alexcrichton alexcrichton merged commit 5832ff3 into rustwasm:master Sep 18, 2018
@alexcrichton alexcrichton deleted the fix-window branch September 18, 2018 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants