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

Add DOM shims #24

Open
kittens opened this Issue May 25, 2016 · 16 comments

Comments

Projects
None yet
@kittens
Member

kittens commented May 25, 2016

No description provided.

@anilanar

This comment has been minimized.

anilanar commented May 4, 2017

The community is eager to have shims for DOM, if prepack team invests in documenting what needs to be done, how to do them, and split this into smaller tasks.

@mohsen1

This comment has been minimized.

mohsen1 commented May 4, 2017

Will something like this work?

https://github.com/mohsen1/prepack-assume-browser-globals/blob/master/index.js

Obviously not every global is a function and I need to fix that.

@deltaidea

This comment has been minimized.

deltaidea commented May 4, 2017

That's a good start, but it probably won't be so easy. For example, this would still fail for nested methods window.history.back() and window.document.createElement().
And then we also need to define types of return values. For example, document.querySelector() returns a DOM Element or undefined. If it's an Element, it also has its own methods and properties, which can also return another Element (e.g. el.parentElement), and so on.

This is going to be a lot of work. I'm tempted to look for workarounds and hacks.

@aiboy

This comment has been minimized.

aiboy commented May 4, 2017

@deltaidea Can https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts help us in some way? Typescript have quite good type definitions.

@cblappert

This comment has been minimized.

Contributor

cblappert commented May 4, 2017

The Flow typing of the DOM (https://github.com/facebook/flow/blob/v0.44.1/lib/dom.js) is also of interest for this, as we may want to be able to generate models from Flow typed APIs for React Native. The Flow typing does seem to be a lot shorter and may be less complete.

I think @sebmarkbage has though the most about the web use case, maybe he had some ideas.

@sebmarkbage

This comment has been minimized.

Member

sebmarkbage commented May 4, 2017

I think it is interesting to narrow down which cases cause side-effects and which might read from a JS provided object that needs to preserve ordering.

For many other things we might get away with making it fully abstract for most use cases.

@sebmarkbage

This comment has been minimized.

Member

sebmarkbage commented May 4, 2017

This is an example of where it is important to know something about the DOM implementation itself rather than just the structure of it:

let obj = {x: false};
document.body.addEventListener('foo', function (e) {
  if (obj.x) {
    console.log('foo');
  } else {
    console.log('bar');
  }
}, false);
document.body.dispatchEvent(new Event('foo'));
obj.x = true;
document.body.dispatchEvent(new Event('foo'));

Prepack will have to know that there is an intermediate state of obj.x that needs to be represented here.

I don't know how common it is to have any such scenarios of synchronous events but there might be other similar cases that are synchronous that we'll have to know about.

Using the JSDOM library can tell us a lot more about these implementations than Flow/TypeScript types can.

@Janpot

This comment has been minimized.

Janpot commented May 8, 2017

here's how those typescript definitions are generated: https://github.com/Microsoft/TSJS-lib-generator

@sebmarkbage

This comment has been minimized.

Member

sebmarkbage commented May 8, 2017

Here are some more examples of patterns that Prepack has trouble encoding right now.

let options = {};
options.passive = false;
document.body.addEventListener('click', function() {}, options); 
options.passive = true;
window.addEventListener('click', function() {}, options);

options = {};
options.prototype = Object.create(HTMLElement.prototype);
document.registerElement('x-foo', options);
options.prototype = Object.create(HTMLElement.prototype);
document.registerElement('x-bar', options);

Note how the options object is read by native code and at different times during initialization.

@bertho-zero

This comment has been minimized.

bertho-zero commented Mar 30, 2018

Hi team, is there anything new on this side?

@skyne98

This comment has been minimized.

skyne98 commented Jul 27, 2018

It would be nice to have a place to track progress, or some kind of a workaround for now @hermanventer

@hermanventer

This comment has been minimized.

Contributor

hermanventer commented Jul 27, 2018

We are swamped with non DOM related work right now, so there is nothing specifically happening on this front. If there are specific issues that are blocking you from doing something in this area, please add new issues.

I hope to write some documentation for Prepack a bit later on this year.

@skyne98

This comment has been minimized.

skyne98 commented Jul 28, 2018

@hermanventer, the main problem is that it seems like it's impossible to compile any existing or new web application using prepack right now. Each time there would be some DOM operation, or browser API call that makes the process fail. That is very unfortunate, considering the fact that prepack might be the future of JS optimization. People should be able to test and evaluate it already, I think.

The second point is -- why not just make every unsupported API call an abstract unknown value right now? Yeah, it will disallow lots of optimizations, but it won't crush the process. Also, as far as I understand --abstractEffectsInAdditionalFunctions can be used to optimize the bodies of functions, right?

Anyways, thanks for your time! I see the barrage of issues you have, but I think that prepack is worth some attention, therefore people have to be able to play with it, without it crashing on them. May be I am just missing some stupid option that makes it happen, in that case I am sorry!

@hermanventer

This comment has been minimized.

Contributor

hermanventer commented Jul 29, 2018

I'm afraid that we are all going to have to be very patient with Prepack. Getting to the point where it can usefully run on real browser based applications is going to take a lot of very hard work and a long time. Taking short cuts will result in something that works only for some ill defined subset of JavaScript and only up to a point.

Right now, Prepack can deal with initialization code (global code) in environments that we can easily model and about which we can make restrictive assumptions. We are hard at work to go beyond that, but the war will be won in a long series of small, hard won victories.

Some previous work on analyzing JavaScript has already highlighted just how difficult things become once you try to support all of JavaScript and you have to deal with untyped call backs. The conclusion reached in those efforts was that, in the end, the analyzer knows nothing much. Since this is a good description of a typical browser based web app, it makes sense for us to set our sights on gains that are more attainable in the short term.

That said, if Prepack actually crashes for some input (i.e. a false invariant or a runtime exception, we'll be glad to hear about it particularly if you have a way to reproduce it). The expected behavior of Prepack is that it should give you a nice error message telling you that your program is not suitable for the current state of Prepack. We have quite a bit of work to do on that front as well.

@skyne98

This comment has been minimized.

skyne98 commented Jul 30, 2018

@hermanventer, thanks for your descriptive answer! It's nice to hear that people are hard at work writing this wonderful project.

@skyne98

This comment has been minimized.

skyne98 commented Jul 31, 2018

By the way, I think we should add a place where all the implemented APIs are tracked, shouldn't we?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment