Skip to content
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 the IO context passed to Base.show to render DOM #198

Closed
wants to merge 2 commits into from

Conversation

fonsp
Copy link
Contributor

@fonsp fonsp commented Nov 22, 2023

Hello!! 👋

This PR makes sure that the IOContext used to render the App (i.e. the io passed to Base.show), is also used to render the app's DOM (using the context kwarg of repr). I decided to store the IO in the Session, but feel free to change that.

In Pluto, the IOContext is used to make special API available to display code like Hyperscript.jl. We use IOContext instead of a global variable because we found that this lets us make the API available only if we know it will work. It also allows us to differentiate between cells in a thread-safe way. In particular, the IOContext is used to support fonsp/Pluto.jl#2726

This PR is similar to JuliaPluto/HypertextLiteral.jl#27 and JuliaWeb/Hyperscript.jl#29 and MichaelHatherly/CommonMark.jl#58

This is only effective if JuliaWeb/Hyperscript.jl#43 is released, you currently need Hyperscript#master to use this.

Example

To run this notebook, you need to have in your global environment:

  • JSServe with this PR
  • Hyperscript#master
  • AbstractPlutoDingetjes
  • HypertextLiteral
### A Pluto.jl notebook ###
# v0.19.32

using Markdown
using InteractiveUtils

# ╔═╡ b608aa3b-cf74-4691-868a-4acef20e5e39
import Pkg

# ╔═╡ 8dd1c508-c7f5-48ae-b499-e828adffe311
Pkg.activate()

# ╔═╡ 9101edb2-d622-4070-89f4-ff8e50cde50e
using Revise

# ╔═╡ c2032a57-281b-4cd0-8e93-579fcbe2c6d4
using JSServe

# ╔═╡ 9977756c-f96a-4a36-a3e7-8020439bbbcf
using AbstractPlutoDingetjes

# ╔═╡ 50b8d6bc-8431-4c49-ac03-a51a37ecfca7
using HypertextLiteral

# ╔═╡ 5a27a6bc-5ccd-42d9-8d9a-0e89f2f7d15b
import Hyperscript

# ╔═╡ d0d41337-89da-4c18-88d3-8c4ef94c3f0b
md"""
Example of using the `io` to access information provided by the display:
"""

# ╔═╡ 3e54528c-6949-4ec1-bbb5-44e75c9d8ab1
begin
	struct GiveMeCellID
	end

	function Base.show(io::IO, m::MIME"text/javascript", x::GiveMeCellID)
		write(io, "'", string(get(io, :pluto_cell_id, "unknown")), "'")
	end
end

# ╔═╡ 7eca8539-8ed3-4865-88d2-c7dc3544b30d
md"""
`AbstractPlutoDingetjes.Display.published_to_js` also uses this `get(io, :key, default)` internally to access the API.
"""

# ╔═╡ 7af2205a-cb70-42a2-b044-ab9c6afa8262
md"""
This snippet uses HypertextLiteral.jl to create a `<script>` node with interpolated objects. HypertextLiteral is lazy-rendering: it only generates the HTML string when rendered to an `io`, not when the macro is called.
"""

# ╔═╡ e862e31c-5215-43fb-975d-5553ade84bb2
htl_snippet = @htl("""
<script>
	let x = $(AbstractPlutoDingetjes.Display.published_to_js([1,2,3]))
	let cellid = $(GiveMeCellID())
	alert("data: " + x + ", cell id: " + cellid)
</script>
""");

# ╔═╡ b3e9e682-de08-4969-a60a-8534d7c60f4a
app = App() do
    return DOM.div(
		DOM.h1("hello world"), 
		htl_snippet
	)
end

# ╔═╡ f05eee23-376d-451b-9846-d94fe8463b67
app

# ╔═╡ Cell order:
# ╠═b608aa3b-cf74-4691-868a-4acef20e5e39
# ╠═8dd1c508-c7f5-48ae-b499-e828adffe311
# ╠═9101edb2-d622-4070-89f4-ff8e50cde50e
# ╠═5a27a6bc-5ccd-42d9-8d9a-0e89f2f7d15b
# ╠═c2032a57-281b-4cd0-8e93-579fcbe2c6d4
# ╠═9977756c-f96a-4a36-a3e7-8020439bbbcf
# ╠═50b8d6bc-8431-4c49-ac03-a51a37ecfca7
# ╟─d0d41337-89da-4c18-88d3-8c4ef94c3f0b
# ╠═3e54528c-6949-4ec1-bbb5-44e75c9d8ab1
# ╟─7eca8539-8ed3-4865-88d2-c7dc3544b30d
# ╟─7af2205a-cb70-42a2-b044-ab9c6afa8262
# ╠═e862e31c-5215-43fb-975d-5553ade84bb2
# ╠═b3e9e682-de08-4969-a60a-8534d7c60f4a
# ╠═f05eee23-376d-451b-9846-d94fe8463b67

@fonsp
Copy link
Contributor Author

fonsp commented May 7, 2024

Simon and I talked today, Simon liked the intent of the PR but the implementation with currently_rendering_io is not so charming, so he will see if something nicer is possible.

@SimonDanisch SimonDanisch mentioned this pull request Jul 8, 2024
@SimonDanisch
Copy link
Owner

Thank you :) merged in #238

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants