has anyone experienced hoplon's prerendering turning <
in inline scripts into <
?
i'm running into trouble with my app's content security policy because the prerender step is changing the content of an inline script that contains <
so that it contains <
instead
it looks like it's probably happening here: https://github.com/hoplon/boot-hoplon/blob/3e0fdb799c505dc54a2e5953798262538fef2ec4/src/hoplon/boot_hoplon/tagsoup.clj#L86-L87 via https://github.com/hoplon/boot-hoplon/blob/3e0fdb799c505dc54a2e5953798262538fef2ec4/src/hoplon/boot_hoplon/impl.clj#L40
which seems like a bug. the content of script tags should not be html-escaped
@dave look here though: https://github.com/hoplon/boot-hoplon/blob/3e0fdb799c505dc54a2e5953798262538fef2ec4/src/hoplon/boot_hoplon/impl.clj#L33
the prerenderer specifically skips scripts
in both the head and the body
in this case, the scripts have :prerender-keep
yeah but that code doesn't look like it knows about :prerender-keep
it's suspicious that it broke all of a sudden
in the middle of changing all the tooling
i think it's been broken the whole time, we just didn't notice in this particular project because the existing scripts we had with :prerender-keep
happened not to contain &, <, or >
the new one we're adding wants to do a less-than comparison
can you make a minimal repro case?
to be clear, i've put the debooted branch aside
this is all using the existing boot pipeline for geir
like a helloworld that exhibits the problem
i'll see if i can take a stab at that when i have time
for now, i think i might need to add a postprocessing step that re-encodes <
as <
i don't see how it can possibly be including those scripts
i guess inside of script tags only
there are better ways, you can use the baackslash hex encoding if you need to
in the js
ah! i was wondering if there were another way to encode it in the JS
like \x12
or whatever
but link me to the script tag in the cljs code
the problematic one
and also have you tried with prerendering off?
sending it to you on adzerk slack
i've actually been wondering if we really need prerendering
since we're getting caching via cloudfront, i'm not sure if prerendering is helping much beyond that
prerendering helps with the flash of unstyled content
have you built it with prerendering off though?
to eliminate other issues unrelated to prerendering that may be causing it
yeah, without prerendering the problem goes away
my first thought was that it might be an advanced optimizations issue, but that wasn't it
hmm, it looks like \x3C
is the escape sequence for <
, but it doesn't seem to work outside of javascript string literals
i've only experimented in the JS console, though. not sure if it behaves differently in an inline script tag
in the JS console you can do escape("<")
, which returns "%3C"
then you can do "\x3C"
, and that returns "<"
you should be able to put that in the js source, no?
i'll give it a try
you need to escape the backslash because clojure strings interpret it
like (script "foo \\3C ...")
makes sense
that doesn't appear to work
what does it look like when you do "show source" (not the elements pane of the devtools)
i changed the offending part of the code to for(w=0,x=v.length;w\\x3Cx;++w)
whereas the \\x3C
used to be <
i haven't tried prerendering yet, so show source doesn't include the script tag
i suspect the result would be the same
what does the script tag look like in the elements pane
the easiest thing to do really is to make your own html file and then mount the app in a div inside there
then you don't need prerendering because you can pull out the things you want to have prerendered into the html file
looks like what i expected: w\x3Cx
intsead of w<x
making our own html file is a good suggestion. i've been thinking about that in the back of my mind
i would just need to do some post-processing to insert the right cache keys for cache busting
could another solution be to put the inline JS into a file instead? or would that potentially screw up the load order?
putting the JS into a file got me un-stuck
just catching up,was the problem literla JS inside a script tag in a cljs file?
yes
with :prerender-keep
although i guess i'm not 100% sure if :prerender-keep
was related
i think i've run into that before,with google analytics or something
i wonder about using js* to inline JS strategically
that would roll it into the cljs source
i guess sometimes you need JS to run before the cljs kicks in tho
does it need to be inline for that to be the case?
like is the load order for this:
<script>alert("lol");</script>
<script src="index.cachekeygoeshere.html.js"></script>
any different than the load order for this?
<script src="alert_lol.js"></script>
<script src="index.cachekeygoeshere.html.js"></script>
should be no different
i was suggesting using js* to put alert("lol") in index.cachekeygoeshere.html.js
ah, i see
we're actually doing that for google analytics in geir
it's just that it only works because the inline JS doesn't include &, <, or > which hoplon's prerenderer would escape
seems to me like the prerender shouldn't escape script tag innards
from a pure xml sense it make sense, and is a good default. maybe a bug in prerender?
i'm thinking it's a bug, too
like if the type of the DOM node is "script," then the escaping shouldn't happen
absolut nyet
anothre option is golf that code to not use any escaped chars like goog did
partially as entertainment 😆
haha, nothing like a rousing game of code golf 😄
i'm sure there is some too-clever way to get "less-than" semantics without using <
function lt(x, y) { var z = (y - x); return z != "0" && z.toString()[0] !== "-"; }
crap,ampersand
lol
function lt(x, y) { return (x - y).toString()[0] == "-"; }
would this work?that would be <= because if x == y, [0] !== "-"
close but no banana
hmm, i tried that in my browser and lt(2, 2)
is false like i expected
oh i see, yes, it should work
my thing was lte, yours is lt
x is < y iff (y - x) < 0, e.g. its string rep. has a leading dash
i bet google did that intentionally man
i wonder if a tool of theirs does this kind of rewriting even
lt=(x,y)=>(x-y).toString()[0]=="-"
golfed a bit further 😄aha that =>
tho
gotta keep it es3
i keep forgetting that JS has had that for like 5-10 years lol
ha yeah
a few years ago at my new job i spent a few weeks relearning JS starting from 2012 or something
it has all the things now pretty much
in addition to all the crazy things it always had
you know, i guess you can't make a real short-circuting &&
as a function, because the real one delays evaluation
the best you could do is wrap every argument in a function at the call site
for the purposes of <= and >=, you could just implement < and > and then call it with !
lol this is unfolding into a great big tech company interview question
haha
"please sort this linked list in JS, and you can't use &, <, or >"
oh sweet, yes good point
you could even say it's not a contrived question, it actually came up in the course of work haha
hahah