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
Use fixHtmlCmdFunc to ensure event-handlers are installed after the DOM is updated #1802
Conversation
Fixes #1801 |
So, I'm actually not sure if this will work… In the I wonder if the right way to fix this issue isn't to rewrite
I think this is incidentally also more in line with what would be the expected behavior of invoking this JS with an HTML block that contained a To be clear, I think the conversion of the things inside |
Actually I'm still not sure if that'll work either… Because these are designed to be chained with The solution in this PR is valid only as long as you do a single method call—e.g.
Once again, invalid JS... Oof, this is a tough one 😞 Could be that EDIT: The downside, of course, is that this makes all of these stateful, which feels dirty and unnecessary. Another way to do it is to maybe give |
Are there extra changes in this PR that don't deal with the core bug? I'm a bit confused at how all of this relates to the bug as described in the original issue. That said, revisiting the original issue:
Am I crazy or does this sound like more of an ordering issue than a JsExp or JsCmd issue? |
This is an ordering issue, but it's an ordering issue that gets at the fundamental underlying way that We can also manage this on the client via a Lastly, no matter what we do, we'll need unit tests for this so we're not tripped up by it in the future. |
@Shadowfiend Will those unit tests need to run JS in a browser environment? |
No, that would pretty much be an integration test by definition. We just need to basically confirm that the JS looks like what we expect it to. (EDIT: Once we decide what we expect it to look like, of course ;) ) |
Ok, understood. I asked because in my vdom branch, @blmeadows and I have used HtmlUnit to accomplish this. I agree that it's integration testing at that point, but I rarely take time to split those hairs. :) |
Ok, just looked at this again. I was wrong about this:
If we look at the invocations in the code base, we see patterns like this: case class JqAppend(content: NodeSeq) extends JsExp with JsMember {
override val toJsCmd =
"append("+fixHtmlFunc("inline", content){a => a}+")"
} Here, we apply However! This brings up a very interesting note: if there were ever a Net-net, my concern with the initial suggestion for fixing |
@andreak can you try the branch |
First; I think this is a serious issue that needs to be fixed before 3.0 goes final. Second; We need to make this work with potential I really don't like the approach with setTimeout, I'm sorry but it is a code-smell and it seems hacky. We should find a better way, although I'm not sure what that is. I'm sure we can figure this out though. I see that my proposed solution using I'm in Bulgaria with my 9-year old daughter this week (training camp) so I'm not able to be too creative here, but will try to give it some thoughts. |
Hmmm… When you get back from vacation, can you lay out why the JS needs to be executed pre-DOM-append? The problem for me is that having that JS evaluated before a chained call is an actively broken model, IMO. The simplest example of this is the following construction: Jq("#my-element") ~>
JqAppend(
Group(
<div id="new-element" style="display: none;">Show me!</div>
<script type="text/javascript">$('#new-element').show()</script>
)
) It is incorrect to execute that script until after the new element has been appended (and won't work otherwise anyway). Now, when it's laid out as above it's easy to fix. But imagine you had a snippet that included JS like the above that could be rendered in a regular snippet or could be rendered as a JQuery append expression. The execution of that script is no longer the same in the two cases. Btw, I do agree that using I think the correct solution to this is to have |
Another option is really to just provide a flag to disable event extraction, or disable event extraction automatically when inline scripts are allowed in the |
Note that I'm not advocating that the embeded JS needs to be executed pre-DOM-append, but before a potential chained call. Take this: JqId(JE.Str(uid)) ~> JqAppend(content) ~> JqSlideDown(600) What I mean is that if |
So, all JS (both the event-extraction code and in |
You're right… Unfortunately I think we have to choose either before inserting the content, or after any chained calls. Each case has its own problems, and neither is strictly correct. Only the latter works for extracted DOM event handlers. I don't think we can execute any JS after the current chained function actually executes, but before the next one does… Will keep thinking on it though. |
@andreak any updated thoughts on this? Thinking of opening a PR to allow for disabling event extraction and perhaps disable it by default in Lift 3… EDIT: Or disable it by default if your security rules allow inline JS. |
How should we proceed on this PR given that we've shipped @Shadowfiend's fix? |
I think we'll need to decide which path is the “correct” one—probably best done on the ML. The ultimate solution will have to be different than what's here, as it will be more core—would be down for closing this PR. While we wait on what @andreak thinks, I'll drop the milestone on the PR. |
@Shadowfiend @andreak Ping, this has been here for awhile now. |
Posted this ML thread to pick up the question of what to do. Closing this PR as the code here can produce invalid JS; we'll pick it back up in issue #1801 once we see what happens on the ML. |
Use fixHtmlCmdFunc to ensure event-handlers are installed after the DOM is updated