Skip to content

Commit

Permalink
provide window.LiveDashboard.registerCustomHooks function
Browse files Browse the repository at this point in the history
  • Loading branch information
SteffenDE committed Nov 10, 2024
1 parent c44ed4d commit e7728dd
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 29 deletions.
4 changes: 1 addition & 3 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ let Hooks = {
PhxRememberRefresh: PhxRememberRefresh
}

window.customHooks = window.customHooks || {}

let socketPath = document.querySelector("html").getAttribute("phx-socket") || "/live"
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveView.LiveSocket(socketPath, Phoenix.Socket, {
hooks: { ...Hooks, ...window.customHooks },
hooks: { ...Hooks, ...window.LiveDashboard.customHooks },
params: (liveViewName) => {
return {
_csrf_token: csrfToken,
Expand Down
8 changes: 4 additions & 4 deletions dist/js/app.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/js/app.js.map

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions lib/phoenix/live_dashboard/layouts/dash.html.heex
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
<!DOCTYPE html>
<html lang="en" phx-socket={live_socket_path(@conn)}>
<head>
<script nonce={csp_nonce(@conn, :script)}>
window.LiveDashboard = {
customHooks: {},
registerCustomHooks(hooks) {
this.customHooks = {...this.customHooks, ...hooks}
}
}
</script>
<%= custom_head_tags(assigns, :after_opening_head_tag) %>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
Expand Down
46 changes: 28 additions & 18 deletions lib/phoenix/live_dashboard/page_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,14 @@ defmodule Phoenix.LiveDashboard.PageBuilder do
defp after_opening_head_tag(assigns) do
~H\"\"\"
<script>
window.customHooks = {
...(window.customHooks || {}),
<script nonce={@csp_nonces[:script]}>
window.LiveDashboard.registerCustomHooks({
MyHook: {
mounted() {
// do something
}
}
}
})
</script>
\"\"\"
end
Expand All @@ -156,23 +155,34 @@ defmodule Phoenix.LiveDashboard.PageBuilder do
]
```
The LiveDashboard will merge the `window.customHooks` object into the hooks that are
configured on the LiveSocket.
> #### Warning {: .warning}
>
> If you are building a library that will be used by others, ensure that you are
> not overwriting the `window.customHooks` object instead of extending it.
>
> Instead of `window.customHooks = {...}`,
> use `window.customHooks = {...(window.customHooks || {}), ...}`.
The LiveDashboard provides a function `window.LiveDashboard.registerCustomHooks({ ... })` that you can call
with an object of hook declarations.
Note that in order to use external libraries, you will either need to include them from
a CDN, or bundle them yourself and include them from your apps static paths.
a CDN, or bundle them yourself and include them from your app's static paths.
Also, you are responsible for ensuring that your Content Security Policy (CSP) allows
the hooks to be executed. If you are building a library that will be used by others,
consider including a valid nonce on your script tags.
> #### A note on CSPs and libraries {: .info}
>
> Phoenix LiveDashboard supports CSP nonces for its own assets, configurable using the
> `Phoenix.LiveDashboard.Router.live_dashboard/2` macro by setting the `:csp_nonce_assign_key`
> option. If you are building a library, ensure that you render those CSP nonces on any scripts,
> styles or images of your page. The nonces are passed to your custom page under the `:csp_nonces` assign
> and also available in the `after_opening_head_tag` component.
>
> You should use those when including scripts or styles like this:
>
> ```heex
> <script nonce={@csp_nonces[:script]}>...</script>
> <script nonce={@csp_nonces[:script]} src="..."></script>
> <style nonce={@csp_nonces[:style]}>...</style>
> <link rel="stylesheet" href="..." nonce={@csp_nonces[:style]}>
> ```
>
> This ensures that your custom page can be used when a CSP is in place using the mechanism
> supported by Phoenix LiveDashboard.
>
> If your custom page needs a different CSP policy, for example due to inline styles set by scripts,
> please consider documenting these requirements.
"""

use Phoenix.Component
Expand Down
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ defmodule Phoenix.LiveDashboard.MixProject do
{:stream_data, "~> 0.1", only: :test},
{:ecto_sqlite3, "~> 0.9.1", only: [:dev, :test]},
{:ex_doc, "~> 0.21", only: :docs},
{:makeup_eex, ">= 0.1.1", only: :docs},
{:esbuild, "~> 0.5", only: :dev},
{:dart_sass, "~> 0.7", only: :dev}
]
Expand Down
6 changes: 4 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
"makeup_eex": {:hex, :makeup_eex, "1.0.0", "436d4c00204c250b17a775d64e197798aaf374627e6a4f2d3fd3074a8db61db4", [:mix], [{:makeup, "~> 1.2.1 or ~> 1.3", [hex: :makeup, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_html, "~> 0.1.0 or ~> 1.0", [hex: :makeup_html, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "3bb699bc519e4f509f1bf8a2e0ba0e08429edf3580053cd31a4f9c1bc5da86c8"},
"makeup_elixir": {:hex, :makeup_elixir, "1.0.0", "74bb8348c9b3a51d5c589bf5aebb0466a84b33274150e3b6ece1da45584afc82", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49159b7d7d999e836bedaf09dcf35ca18b312230cf901b725a64f3f42e407983"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"},
"makeup_html": {:hex, :makeup_html, "0.1.2", "19d4050c0978a4f1618ffe43054c0049f91fe5feeb9ae8d845b5dc79c6008ae5", [:mix], [{:makeup, "~> 1.2", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b7fb9afedd617d167e6644a0430e49c1279764bfd3153da716d4d2459b0998c5"},
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
"myxql": {:hex, :myxql, "0.6.3", "3d77683a09f1227abb8b73d66b275262235c5cae68182f0cfa5897d72a03700e", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:geo, "~> 3.4", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "af9eb517ddaced5c5c28e8749015493757fd4413f2cfccea449c466d405d9f51"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
Expand Down

0 comments on commit e7728dd

Please sign in to comment.