-
-
Notifications
You must be signed in to change notification settings - Fork 276
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
Click handler refactoring proposal #274
Click handler refactoring proposal #274
Conversation
This is a big one, so I'll try to take a look at it over the weekend. Thanks for the heads-up about the whitespace changes. |
No rush 😉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I got a chance to review this. I really like the changes overall! It's exciting to see my proposal in #86 taking shape.
I added a handful of small comments about variable names and function signatures, but this looks good otherwise 👍
PS: It turns out that using ?w=1
to ignore whitespace changes makes it impossible to add inline comments (isaacs/github#394). That didn't cause much trouble though, as I had already read the code without the whitespace changes, before I tried to start adding comments.
lib/click-handler.js
Outdated
}; | ||
}); | ||
} | ||
const pluginName = dataAttr._pluginName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should rename _pluginName
to simply pluginName
, since there's no previously existing pluginName
variable that it would be shadowing.
lib/insert-link.js
Outdated
const dataAttr = {}; | ||
function buildDataAttr(_pluginName, data, match) { | ||
const dataAttr = { | ||
_pluginName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EDIT: See this comment first: https://github.com/OctoLinker/browser-extension/pull/274/files#r99663118
If you agree with my comment at https://github.com/OctoLinker/browser-extension/pull/274/files#r99657441, we should also change _pluginName
to pluginName
on this line (and in the function definition).
lib/click-handler.js
Outdated
}); | ||
} | ||
const pluginName = dataAttr._pluginName; | ||
const resolver = pluginManager.getClickHandler(pluginName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should rename getClickHandler
to getResolver
, since that more accurately describes what the return value does (and matches the variable name used here).
lib/plugin-manager.js
Outdated
this._plugins = buildPluginCache(plugins); | ||
} | ||
|
||
getClickHandler(pluginName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you agree with my comment at https://github.com/OctoLinker/browser-extension/pull/274/files#r99658228, we should also change getClickHandler
to getResolver
here.
lib/plugin-manager.js
Outdated
return; | ||
} | ||
|
||
return plugin.clickHandler; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the spirit of https://github.com/OctoLinker/browser-extension/pull/274/files#r99658228, I think clickHandler
should instead be resolve
on this line and in the previous conditional.
lib/plugins/docker/index.js
Outdated
@@ -4,13 +4,25 @@ import preset from '../../pattern-preset'; | |||
|
|||
export default class Docker { | |||
|
|||
static clickHandler({ image }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you agree with my comment at https://github.com/OctoLinker/browser-extension/pull/274/files#r99658736, we should also change clickHandler
to resolve
here.
lib/plugins/python/index.js
Outdated
|
||
export default class Python { | ||
|
||
static clickHandler({ path, target }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you agree with my comment at https://github.com/OctoLinker/browser-extension/pull/274/files#r99658736, we should also change clickHandler
to resolve
here.
lib/plugins/docker/index.js
Outdated
getPattern() { | ||
return preset('Docker'); | ||
} | ||
|
||
parseBlob(blob) { | ||
insertLink(blob.el, DOCKER_FROM, { | ||
resolver: 'dockerImage', | ||
insertLink(this, blob.el, DOCKER_FROM, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing the plugin as the first argument to insertLink
, what if we just put it into the object literal, alongside image
:
insertLink(blob.el, DOCKER_FROM, {
pluginName: this.constructor.name,
image: '$1',
});
This way, insertLink
won't have to pass an extra argument to replace
and buildDataAttr
at all. Note that doing this would invalidate my comment at https://github.com/OctoLinker/browser-extension/pull/274/files#r99657840, since the extra argument will no longer be present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of passing the plugin to insertLink
was to avoid duplication of pluginName: this.constructor.name
across all plugins. To avoid conflicts with other prop key names passed to insertLink
the name is prefixed with an underscore.
Maybe it's not the best idea, since it hides the actual behaviour and makes it just more complicated. Thanks for pointing me in the right direction.
That's why I believe and love code reviews 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking about the duplication as well, when I was writing the comment. It's not ideal, but I think it's worth the gains in clarity that putting it in the map gives.
If you'd like, you could instead pass plugin: this
to insertLink
, and insertLink
could delete the plugin
key and add a pluginName
key, to avoid duplicating .constructor.name
, but I'm not sure if that's better...
I definitely agree on loving code reviews 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with the map solution for simplicity.
lib/plugins/python/index.js
Outdated
getPattern() { | ||
return preset('Python'); | ||
} | ||
|
||
parseBlob(blob) { | ||
insertLink(blob.el, PYTHON_IMPORT, { | ||
resolver: 'pythonUniversal', | ||
insertLink(this, blob.el, PYTHON_IMPORT, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same comment as https://github.com/OctoLinker/browser-extension/pull/274/files#r99663118)
Thanks for the great feedback. I'll follow up on your naming suggestions. Regarding the refactoring. Do you think it makes sense to open a refactor PR for every single plugin? If we do that, we have to make it backwards compatible in order to keep the other plugins working. If you agree, I would like to open one big PR where every plugin refactoring is a commit. This should make it easier to review. |
I think it'd be much better to have a single PR with one plugin per commit, as you've described. Making separate PRs doesn't seem like it's worth the effort of maintaining backwards-compatibility. I look forward to seeing the updates! |
141eee7
to
04b9ae2
Compare
@@ -1,38 +1,38 @@ | |||
import assert from 'assert'; | |||
import dockerImage from '../../lib/resolver/docker-image.js'; | |||
import dockerImage from '../../lib/plugins/docker'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For simplicity and keeping the PR small as possible, I just fixed the broken tests. I'll polish all plugin tests in a separate PR.
04b9ae2
to
ee99bba
Compare
ea15c73
to
e24c1dd
Compare
gitUrl({ target }), | ||
githubShorthand({ target }), | ||
]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@josephfrazier what do you think about handling the different resolver types in one handler? It feels a bit inconvenient to me. In the old implementation this case was handled in a better way.
One possible option would be to split the plugin by features. In this case one for linking the dependencies and another which is responsible for linking the main
field. I'm not sure if this makes thing easier or more complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you talking about the calls to JavaScriptPlugin.resolve
, liveResolverQuery
, gitUrl
, and githubShorthand
being made explicitly, rather than implicitly like they are here and here? That doesn't really seem like a problem to me, but perhaps I'm misunderstanding the question. Splitting the Bower plugin into multiple other plugins sounds like it would just make things more complicated, especially if it's done as part of this refactor, rather than as a separate change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm talking about the if statements in the resolve function. In my current implementation, the type
attributes define which resolver is used. Without knowing how the click-handler works, I would assume that every insertLink
can have his own click handler. What do you think? Maybe I'm over-thinking it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's ignore this for now. It's not really important
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think we can worry about that later if needed :)
I'm almost complete with this one. There is one outstanding question regarding the resolve handler function. Besides that I'm almost through. I'll do some minor improvements + the remaining code review comments later this week. |
63a85f7
to
eb7b6c3
Compare
7d3ef18
to
eb7b6c3
Compare
@josephfrazier can you help with this? Disabling the cache didn't helped.
|
Hmm, that's a weird one. I just searched for the error and it looks like other people are seeing it too: https://chocolatey.org/packages/GoogleChrome#comment-3171878283 I don't really know why this would be happening, but it seems fine to add |
705e742
to
67a2726
Compare
@josephfrazier can I merge it by myself or is there anything left from your side? |
This looks good to me. Excellent work on this! I'll let you do the honors of merging 👍 |
😄 🎉 |
Once @josephfrazier suggested to combine the plugin click handler (aka resolver) with the actual plugin. At this time, I was assuming that we can benefit from reusing those resolver from one plugin in others. Now, after a couple of months of adding more and more languages, it shows up that only a small portion ( git-url, relative-file and live-resolver-query) of resolver are reused.
Exemplary I refactored the Docker and Python plugin to show you how it could work. I'll polish the PR if you agree with the solution. I'm looking forward to your feedback.
Please, review the PR with ?w=1 to ignore whitespace changes.
TODO