# `Expresso.Element.Embed`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/embed.ex#L1)

An element that shows a web page in a slide

The `embed` entity takes the source of the page as its first argument:

  * An address that starts with `https://` or `http://`. The browser loads
    the page from the network.
  * The path of a local HTML file, relative to the working directory of the
    command or to the `root` option of the deck. `sources/1` reads the file, and the document holds its text.
    The deck then stays one file, and the page works with no network.

The `title` option names the page for a screen reader, and it is required.
The `fallback` option gives the path of an image, which shows on paper, in
the handout view, in the overview and while the page loads.

The document holds a copy of each slide for the present view and one for
each page of the handout view. A page in each copy would load the page many
times, so no copy holds the source. The `iframe` element holds only
`data-embed`, the number of the element in the deck, and the renderer
writes the sources one time into the element `expresso-embeds`. The
presenter loads a page when its slide shows in the present view, and the
page then stays loaded.

By default the page does not take a click or the focus, so the keys and the
clicks of the presenter still work on the slide. With `interactive true`,
the page takes the clicks, and a key goes to the page after a click on it.
`docs/reference/embed-element.md` gives the rules.

# `t`

```elixir
@type t() :: %Expresso.Element.Embed{
  __spark_metadata__: term(),
  aspect: term(),
  at: term(),
  class: term(),
  easing: term(),
  effect: term(),
  el: term(),
  fallback: term(),
  index: term(),
  interactive: term(),
  morph: term(),
  on: term(),
  signature: term(),
  speed: term(),
  src: term(),
  steps: term(),
  title: term(),
  width: term(),
  window: term(),
  window_title: term()
}
```

The struct of an embed element

# `address?`

```elixir
@spec address?(String.t()) :: boolean()
```

Tell whether a source is an address on the network

# `aspect`

```elixir
@spec aspect(term()) :: {:ok, String.t()} | {:error, String.t()}
```

Make sure that an `aspect` option is a ratio, such as `"16/9"`

The value is two positive numbers with a slash between them.

# `get_assigns`

```elixir
@spec get_assigns(t()) :: map()
```

Make the assigns of the render function from the struct

The key `overlay` holds the attributes of the overlay contract, and the
`style` attribute of the `width` and `aspect` options. The key `fallback`
holds the data URI of the fallback image, or `nil`. The key `sandbox`
holds the `sandbox` attribute of the frame.

# `json`

```elixir
@spec json(Expresso.Deck.t()) :: String.t() | nil
```

Write the sources of the embeds of a deck as JSON, or return `nil`

The value is a list with one object for each embed, in the order of their
numbers, such as `[{"kind":"src","value":"https://example.com/"}]`. The
renderer writes it into a `script` element, so the function escapes each
`<`. A deck with no embed gets `nil`, and the document then holds no such
element.

# `number`

```elixir
@spec number(Expresso.Deck.t()) :: Expresso.Deck.t()
```

Give each embed of a deck its number

The number is the position of the element in the deck, in document order,
from 0. `sources/1` writes the source of each embed at that position, and
the render function writes the number into `data-embed`.
`Expresso.Renderer` calls this function before the render.

# `render`

```elixir
@spec render(map()) :: Phoenix.HTML.safe()
```

Make the HTML of an embed

The root tag holds the fallback image or a placeholder with the title, and
the frame on it. The frame has no source, and the presenter gives it one.
A frame that is not interactive gets `tabindex="-1"`, so the key Tab does not
go into it.

# `source`

```elixir
@spec source(term()) :: {:ok, String.t()} | {:error, String.t()}
```

Make sure that the source of an embed is an address or the path of an HTML file

This function is the custom type of the first argument. An address starts
with `https://` or `http://`, and it has no space and no quotation mark. A
path ends with `.html` or `.htm`. The function does not read the file, so a
missing file gives an error at render time, as for an image.

    iex> Expresso.Element.Embed.source("https://example.com/page")
    {:ok, "https://example.com/page"}

    iex> Expresso.Element.Embed.source("pages/demo.html")
    {:ok, "pages/demo.html"}

    iex> {:error, _message} = Expresso.Element.Embed.source("javascript:alert(1)")

# `sources`

```elixir
@spec sources(Expresso.Deck.t()) :: [%{kind: String.t(), value: String.t()}]
```

Return the source of each embed of a deck, in the order of their numbers

An address gives `%{kind: "src", value: address}`. A local file gives
`%{kind: "srcdoc", value: text}`, and the function reads the file through
`Expresso.DeckFile`, so the watch mode renders the deck again after a
change to the file. The function raises for a file that it cannot read.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
