Skip to content

Commit 1f8406d

Browse files
committed
Fix js_str interpolation broken by changing JSON.lower(::JSString) and cleanup some other ugliness.
1 parent de54b5a commit 1f8406d

File tree

3 files changed

+27
-33
lines changed

3 files changed

+27
-33
lines changed

src/node.jl

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,26 +93,21 @@ function JSON.lower(n::Node)
9393
"type" => "node",
9494
"nodeType" => nodetype(n),
9595
"instanceArgs" => JSON.lower(n.instanceof),
96-
"children" => map!(renderPreferScopeJSON,
96+
"children" => map!(render_internal,
9797
Vector{Any}(undef, length(children(n))),
9898
children(n)),
9999
"props" => props(n),
100100
)
101101
return result
102102
end
103103

104-
## TODO -- optimize
105-
function escapeHTML(i::String)
106-
# Refer to http://stackoverflow.com/a/7382028/3822752 for spec. links
107-
o = replace(i, "&" => "&")
108-
o = replace(o, "\"" => """)
109-
o = replace(o, "'" => "'")
110-
o = replace(o, "<" => "&lt;")
111-
o = replace(o, ">" => "&gt;")
112-
return o
113-
end
114-
115-
function escapeJSONForScriptTag(s::String)
104+
"""
105+
Escape characters for a "safe" representation of JSON.
106+
In particular, we escape '/' characters to avoid the presence of "</" (and
107+
especially "</script>") which cause the browser to break out of the current
108+
<script /> tag.
109+
"""
110+
function escape_json(s::String)
116111
# Replace all "/" with "\/"'s.
117112
# This prevents the browser from interpreting "</" as a close tag; since
118113
# everything within the string is JSON, any appearances of "/" should be
@@ -121,24 +116,17 @@ function escapeJSONForScriptTag(s::String)
121116
return replace(s, "/" => "\\/")
122117
end
123118

119+
escape_json(x::Any) = escape_json(JSON.json(x))
120+
124121
function Base.show(io::IO, m::MIME"text/html", x::Node)
125-
# write(io, "<div class='display:none'></div>" *
126-
# """<unsafe-script style='display:none'>
127-
# WebIO.mount(this.previousSibling,""")
128-
# # NOTE: do NOT add space between </div> and <unsafe-script>
129-
# write(io, sprint(s->jsexpr(s, x)))
130-
# write(io, ")</unsafe-script>")
131-
println("=== Base.show(::IO, text/html, ::Node)")
132-
println("=== Base.show: Node: $x")
133122
jsrepr = jsexpr(x)
134-
println("===jsexpr(Node): $jsrepr")
135123
write(
136124
io,
137125
"""
138126
<div class=\"webio-connected\"><script defer>
139127
WebIO.mount(
140128
document.currentScript.parentElement,
141-
$(escapeJSONForScriptTag(JSON.json(x))),
129+
$(escape_json(x)),
142130
)
143131
</script></div>
144132
"""

src/render.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,17 @@ end
7777
htmlstring(val::AbstractString) = val
7878

7979
# TODO: this is awkward
80-
function renderPreferScopeJSON(child)
81-
println("renderPreferScopeJSON(::Any/$(typeof(child)))")
80+
function render_internal(child)
8281
render(child)
8382
end
84-
function renderPreferScopeJSON(child::Observable)
85-
warn("renderPreferScopeJSON(::$(typeof(child)))")
83+
function render_internal(child::Observable)
8684
# show(STDOUT, "text/plain", stacktrace())
87-
renderPreferScopeJSON(observable_to_scope(child))
85+
render_internal(observable_to_scope(child))
8886
end
89-
function renderPreferScopeJSON(child::Node)
90-
println("renderPreferScopeJSON(::$(typeof(child)))")
87+
function render_internal(child::Node)
9188
return JSON.lower(child)
9289
end
93-
renderPreferScopeJSON(child::Scope) = renderPreferScopeJSON(node(child, child.dom))
90+
render_internal(child::Scope) = render_internal(node(child, child.dom))
9491

9592
function observable_to_scope(obs::Observable)
9693

src/syntax.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,18 @@ function str_interpolate(s, i0 = firstindex(s))
7575
strs
7676
end
7777

78+
"""
79+
Generate a js_str representation for an object.
80+
"""
81+
function js_str_repr end
82+
js_str_repr(io, x::Any) = jsexpr(io, x)
83+
js_str_repr(io, x::String) = print(io, x)
84+
js_str_repr(io, x::JSString) = print(io, x.s)
85+
7886
macro js_str(s)
79-
writes = [x isa String ? :(print(io, $(esc(x)))) : :(jsexpr(io, $(esc(x))))
80-
for x in str_interpolate(s)]
87+
writes = [:(js_str_repr(io, $(esc(x)))) for x in str_interpolate(s)]
88+
# writes = [x isa String ? :(print(io, $(esc(x)))) : :(jsexpr(io, $(esc(x))))
89+
# for x in str_interpolate(s)]
8190

8291
:(JSString(sprint() do io
8392
$(writes...)

0 commit comments

Comments
 (0)