weavejester / hiccup

Fast library for rendering HTML in Clojure
http://weavejester.github.io/hiccup
Eclipse Public License 1.0
2.68k stars 174 forks source link

raw-string is not respected inside of maps #154

Closed mgerlach-klick closed 2 years ago

mgerlach-klick commented 5 years ago

The RawString type is not respected inside of maps.

Compare:

 (str (h2/html [:a (hiccup.util/raw-string "<'foo>")]))
;=> <a><'foo></a>

to

(str (h2/html [:a {:onclick (hiccup.util/raw-string "<'foo>")}]))
;=> <a onclick="&lt;&apos;foo&gt;"></a>

This makes it hard to embed javascript snippets into element onclick handlers. That may or may not be a good idea, but ignoring the raw-string in certain places goes against my expectations.

mgerlach-klick commented 5 years ago

Notably I cannot even work around this by setting util/*escape-strings?* to false, because hiccup.compiler/xml-attribute directly calls hiccup.utils/escape-html(https://github.com/weavejester/hiccup/blob/master/src/hiccup/compiler.clj#L41), instead of using hiccup.compiler/escape-html (https://github.com/weavejester/hiccup/blob/master/src/hiccup/compiler.clj#L14)

Is there a reason for this or is this a legitimate bug?

weavejester commented 5 years ago

This makes it hard to embed javascript snippets into element onclick handlers.

Why's that? HTML entities are resolved before the Javascript snippet is parsed.

Is there a reason for this or is this a legitimate bug?

In theory it shouldn't matter if attributes are escaped or not. Allowing raw-string to override the default sounds reasonable for performance purposes, so I'd be happy to accept a patch, though I'd consider this a new feature rather than a bug fix.

mgerlach-klick commented 5 years ago

This makes it hard to embed javascript snippets into element onclick handlers.

Why's that? HTML entities are resolved before the Javascript snippet is parsed.

Maybe I'm misunderstanding you, but:

(str (hiccup2.core/html [:a {:onclick "alert('Hi James!!')"}])))
;=>  "<a onclick=\"alert(&apos;Hi James!!&apos;)\"></a>"

;; and also
 (str (hiccup2.core/html [:a {:onclick (hiccup2.core/raw "alert('Hi James!!')")}]))
;=>  "<a onclick=\"alert(&apos;Hi James!!&apos;)\"></a>"

So I obviously cannot use any Javascript that includes any HTML elements in it?

mgerlach-klick commented 5 years ago

Is there a reason for this or is this a legitimate bug?

In theory it shouldn't matter if attributes are escaped or not. Allowing raw-string to override the default sounds reasonable for performance purposes, so I'd be happy to accept a patch, though I'd consider this a new feature rather than a bug fix.

What about the part where hiccup.compiler/xml-attribute doesn't respect util/*escape-strings?*. That's the part that seemed like a bug to me.

weavejester commented 5 years ago

So I obviously cannot use any Javascript that includes any HTML elements in it?

Have you actually tried running those examples you provided? The HTML is parsed before the Javascript snippet, so the HTML entities are resolved before the Javascript is parsed. I've just tested your code on Firefox and Chrome, and it works fine in both.

What about the part where hiccup.compiler/xml-attribute doesn't respect util/*escape-strings?*. That's the part that seemed like a bug to me.

The purpose of turning *escape-strings?* off is so that you can embed a string of HTML inside a Hiccup element. Attributes can't be nested, so there's no benefit to turning it off except as an optimisation.

mgerlach-klick commented 5 years ago

Have you actually tried running those examples you provided? The HTML is parsed before the Javascript snippet, so the HTML entities are resolved before the Javascript is parsed. I've just tested your code on Firefox and Chrome, and it works fine in both.

You're completely right. I hadn't run it and I just assumed it wouldn't work like that. Thanks & sorry!