-
-
Notifications
You must be signed in to change notification settings - Fork 69
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 an invoke_method
operation
#198
Add an invoke_method
operation
#198
Conversation
I love this! ❤️ I'm wondering if we additionally should support a way of invoking a function on the |
100% but what's the least janky API? If there was only one, we could structure it as a boolean that falls through to the selector as default. We could accept a string option called |
... or a string option called |
I worry that would expose limitations of the API on a regular basis…like what if you had a global object so somebody would expect to be able to call |
That is a good point, but technically isn't this already an issue with selector-based objects as well? A Web Component could expose an Object that has several methods, no? Part of the reason I suggested As it happens, I have a theoretical solution / syntax to propose. Note that I'm not lobbying for this approach, just stating my first instinct of how I might tackle it. Once your
I think this is pretty reasonable, and no more exploitable than a script tag already is. |
@leastbad dayyuum, that's tempting. 😄 |
I wonder if that last example would feel more appropriate as: cable_ready operation: "call_method", receiver: "window.Foo.Bar", method: "baz" |
I am just chewing over all of this. We have three potential options in play, because we shant forget Actually, let me back up... In CR, most operations operate on a This is what lead to me proposing a My goals here are to expose functionality in a maximally useful way that is consistent with the call signatures of the other operations. I believe we also share a powerful motivation to eliminate confusion without restricting creativity. I bring this up because there's a sharp edge that I am actively trying to round off: # bad, in my opinion
cable_ready operation: "call_method", selector: "#test", receiver: "Foo.Bar", method: "baz"
cable_ready operation: "call_method", receiver: "window.Foo.Bar", method: "baz"
# good, in my opinion
cable_ready operation: "call_method", selector: "#test", method: "Foo.Bar.baz"
cable_ready operation: "call_method", receiver: "window", method: "Foo.Bar.baz" Do you see what I see? I am trying to avoid a "if you're doing a DOM element, no receiver is required but if you're working with window or document, you include the name of the object as a string inside of the receiver" scenario. That, to me, does not pass the sniff test. |
Maybe even better: cable_ready operation: "invoke", method: "Foo.Bar.baz" @hopsoft and some others suggested and we don't need |
I'm also realizing this re-raises the specter of "is it a method or a function?" …because if you declare a global function (setting ESM/imports stuff aside): function printStr(str) {
console.log(str)
} it becomes a method on the window.printStr("Hello world") which you could then invoke… 🧐 |
This operation will be called
Oh, man... you had me super excited for about two minutes. The problem is that the way CR works - and it's been this way for a long time - is that an undeclared Still, I love where you were headed with this. Not having to specify a If you have any other ideas that would get us there, keep 'em coming. |
Ah, that document fallback totally escaped me. Well…I think I'm on board with your syntax then! |
Do you want to take a crack at the implementation? Happy to help but don't want to step on toes. |
Maybe I'm not following 100%, but if you have this call... cable_ready.invoke_method(receiver: "window", method: "Foo.Bar.baz") ... you are assuming that But what if those are not actual properties, but functions? Functions which might even take arguments? Should we support something like this as well? In JavaScript this could look like: Foo.getBar().getBaz(0).doSomethingOnBaz("with arguments", 2) I feel like method chaining would be the "most natural" in that case. Maybe, something like: cable_ready
.invoke_method(receiver: "window", method: "Foo.getBar")
.invoke_method(chain: true, method: "getBaz", args: [0])
.invoke_method(chain: true, method: "doSomethingOnBaz", args: ["with arguments", 2]) Is this too far? |
Strong first reaction: that's a lot. I think that at some point, you need a sane cut-off before it makes more sense to write a custom operation or just call something that calls something else. Is this partially motivated by having no idea how this would actually be implemented? Sure. But mostly it just seems complicated AF for a vanishingly small surface area of opportunity. |
Well, speaking only for myself, the number of times I expect to call methods off of global JS objects is roughly, er, never. 😄 My original use case was wanting to trigger a custom element to do something via a method call, so that doesn't even need any method chaining. I do like the idea of method chaining, but only in the simple property-based form until you get to the final method signature. I think beyond that it becomes too fiddly. |
call_method
operationinvoke_method
operation
I wonder if we should also update |
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.
We're close! Great work on this one so far.
Sounds good, I'll try to get to these changes soon. Been outta commission for a few days now, not sure exactly when I'll be back to full speed ahead… |
This one is close, too. 😉 |
@leastbad Updated to support |
This adds an operation which allows you to call a JavaScript method for an element, whether that's a builtin HTML element or a custom element. Or you can use
window
as the receiver instead of an element. Example: