defmodule Vite.View do @moduledoc """ Help with View integration into Phoenix views """ alias Vite.{Config, ManifestReader} @doc """ The snippet for `@vite/client` during development. Does nothing in :prod env. """ @spec vite_client :: binary() | {:safe, binary()} def vite_client() do case Config.current_env() do :prod -> "" _ -> ~s() |> as_safe() end end @doc """ The complete snippet for a single entry-point during prod. Delegates to vite dev-server otherwise. See `:for_entry` for details. """ @spec vite_snippet(binary()) :: binary() | {:safe, binary()} def vite_snippet(entry_name) do case Config.current_env() do :prod -> Vite.Manifest.entry(entry_name) |> for_entry() |> as_safe() _ -> ~s() |> as_safe() end end @doc """ Generate all links for an entry struct in following order: 1. styles to prevent FOUC 2. main entry script 3. imports ` ` """ @spec for_entry(list(), binary()) :: binary() def for_entry(entry, prefix \\ "/") do entry |> Enum.map(fn file_tuple -> handle(file_tuple, prefix) end) |> Enum.join("\n") end defp handle({:css, file}, prefix) do css_link(file, prefix) end defp handle({:import_css, file}, prefix) do css_link(file, prefix) end defp handle({:module, file}, prefix) do module_script(file, prefix) end defp handle({:import_module, file}, prefix) do module_preload(file, prefix) end defp handle(_, _prefix) do nil end @doc """ Helper to get HTML for all entry points at once """ @spec for_entries(list(list)) :: binary() def for_entries(entries, prefix \\ "/") do entries |> Enum.map(&for_entry(&1, prefix)) |> Enum.join("\n") end @doc """ Helper to generate HTML for module preloading, eg: ` ` """ @spec module_preload(binary(), binary()) :: binary() def module_preload(href, prefix) do ~s() end @doc """ Helper to generate HTML for a CSS link with static tracking: ` ` """ @spec css_link(binary(), binary()) :: binary() def css_link(href, prefix) do ~s{} end @doc """ Helper to generate HTML for JS modules Has automatic inclusion of `defer`, `crossorigin` and `phx-track-static` attributes. ` ` """ @spec module_script(binary(), binary()) :: binary() def module_script(src, prefix) do ~s{} end @doc """ Helper to generate inlined Phoenix cache manifest to simplify integration with Javascript code. The manifest generated by `mix phx.digest` is stored in a global variable `window.PhxManifest`. Only works in :prod environment. """ @spec inlined_phx_manifest() :: {atom(), binary()} | binary() def inlined_phx_manifest do case Config.current_env() do :prod -> manifest = ManifestReader.read_phx() |> Map.get("latest") |> Config.json_library().encode!(pretty: true) as_safe([""]]]) _ -> "" end end defp as_safe(s), do: {:safe, s} end