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

Third batch of commits for a review #79

Merged
merged 7 commits into from
Oct 2, 2019
Merged

Third batch of commits for a review #79

merged 7 commits into from
Oct 2, 2019

Conversation

hmdne
Copy link
Member

@hmdne hmdne commented Sep 26, 2019

No description provided.

This may not be an obvious improvement and it certainly looks destructive.
I checked the whole library and tried to test it where possible. It seems
like it works well and doesn't break any assumptions when applied carefully.

When implementing Iframe#content_window I had a realization that every next
call to this function created a new Ruby object. I wondered if that's the
best idea. I think it's also how jQuery encapsulates things. But we are not
jQuery.

I noticed that DOM::Node includes a #== override. That's nice, but Window
is not a subclass of DOM::Node. There should have been some better way
than adding a #== method in Native::Wrapper.

I got inspired by the way we do .new dispatching in DOM::Node. Why not return
there an existing object if it was already created. This way our Ruby DOM
should kind of reflect the native DOM better.

I thought about storing a map of references in some global variable, but
I realized it would cause issues with a GC. Storing a reference to a Ruby
object inside a JS object seems like a good compromise.

The name Singleton usually means a class with a single instance. That may
not be the best name here, but I couldn't find a better one.

This change should offer some memory improvements under certain circumstances
and under certain it won't.
This reverts commit 4f5d772.

This commit isn't needed anymore since Native::Wrapper::Singleton.
Copy link
Member

@elia elia left a comment

Choose a reason for hiding this comment

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

Looks good thanks! 👍
Just a couple of notes about the name and some implementation details of Wrapper::Singleton

# doesn't mind arbitrary properties.
#
# The rule of thumb is: if it does overload `#initialize`'s signature
# and not `.new`'s - it won't work. Use Native::Wrapper in this case.
Copy link
Member

Choose a reason for hiding this comment

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

It all makes sense, but it needs a couple of adjustments.

  1. It's better to stay within the Browser namespace and have a local, specific wrapper (that also helps in not polluting the constants space of every class that already includes Native::Wrapper)
  2. As of the name I think something like Browser::CachedNativeWrapper, but possibly something even better (please look for variations), as you said Singleton is generally interpreted with another meaning, although it makes sense once you reason about it.
  3. I would use something like $$opal_browser_native or $$native instead of __opal_singleton__ because that wouldn't show up in instance variables, and it's the common practice in opal.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this module isn't necessarily opal-browser only and maybe someday it would be wise to move it to some more general repo, like opal. After all, it's not tied to DOM, but for now it's most needed by DOM. I want to keep its name as similar to Native::Wrapper as possible (because some classes include one, others include the other), so maybe Native::CachedWrapper and $$opal_native_cached? If staying inside the namespace is more important, then Browser::NativeCachedWrapper will be the choice I will take for this pull request.

Copy link
Member Author

Choose a reason for hiding this comment

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

By the way, the module has another ClassMethods module inside. I think it's the Ruby convention to do extends this way, but it will pollute the namespace anyway.

Copy link
Member

Choose a reason for hiding this comment

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

So, the thing is, this looks like something that should end up in opal's stdlib. If by any chance the final version has a different api that opal-browser's version it will give us some trouble in reconciling the two, that's why I'd like to keep it in a namespace. The name you proposed and the desire to keep the names similar are 👍 so, what about Browser::Native::CachedWrapper?

WRT ClassMethods I'm not sure where it's coming from, but the stdlib module seems clean: https://github.com/opal/opal/blob/3eae98d70045b3daa56ca6656e3331c92ed18e57/stdlib/native.rb#L189-L212

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea about the naming, I'm preparing the patch right now.

I override new which is a class method, so I need to extend it but simultaneously I want to include Native::Wrapper. The established way to do is to create a submodule and extend the class with this submodule inside self.included. Now I see that the submodule gets added as a constant as well. I moved it a level up and renamed it to CachedWrapperClassMethods. In a moment I will produce the commit.

Copy link
Member Author

@hmdne hmdne Sep 28, 2019

Choose a reason for hiding this comment

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

Oh wait, that's not really a good idea. This caused a lot of tests to fail with

undefined method `convert' for Browser::Native

And a few related errors like Browser::Native::Array etc. I will use the Browser::NativeCachedWrapper name.

Copy link
Member

Choose a reason for hiding this comment

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

constant lookup is always fun 😄

This commit basically refactors the DOM::Element::Scroll module.
This module was broken before, because there were multiple conflicting
definitions of a #to function. I retained the classic one adding
some syntactic sugar like $window.scroll.to :bottom. The other one
got renamed to #into_view.

My refactor integrated this code with Window::Scroll and removed
this module afterwards.

Inside this commit there are also minor caching changes for Window.

After having implemented all that I noticed, that actually there are
two DOM interfaces for Element.scroll* and Window.scroll* with a
differing browser support. The thing we do is extracting a root
Element from a Window so we don't need to use the Window interface
at all (and it should be supported well cross-browser - and it's
actually what we did partially with the Window::Scroll implementation
before this commit).
As per @elia's suggestion, because, in his own words:

"So, the thing is, this looks like something that should end up in
opal's stdlib. If by any chance the final version has a different
api that opal-browser's version it will give us some trouble in
reconciling the two, that's why I'd like to keep it in a namespace"

This commit also isolates ClassMethods to be located a level higher
as Browser::NativeCachedWrapperClassMethods so as not to pollute the
namespace of the including modules.

This commit also renames the JS property name to "$$opal_native_cached"
as per Opal current guidelines.
@meh
Copy link
Member

meh commented Sep 28, 2019

Just dropping by to say I'm happy someone is working on opal-browser 🐼

@hmdne
Copy link
Member Author

hmdne commented Sep 28, 2019

Just dropping by to say I'm happy someone is working on opal-browser panda_face

It's one of the most enjoyable projects I worked on :)

Copy link
Member

@elia elia left a comment

Choose a reason for hiding this comment

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

@elia elia merged commit eccf077 into opal:master Oct 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants