# `MishkaCmsMigration.Targets.Helpers.Frames`
[🔗](https://github.com/mishka-group/mishka_cms_migration/blob/v0.0.1/lib/mishka_cms_migration/targets/__helpers/frames.ex#L5)

The video players a post's or a page's content frames, allowed on the run's site, for the
targets that write the content (`MishkaCmsMigration.Targets.BlogPost`,
`MishkaCmsMigration.Targets.CmsPage`). The CMS's Content-Security-Policy lets a page frame only
the origins of the site's `security.frame_origins` setting (Sites pages may embed), so an
imported YouTube or Vimeo player would show nothing without its origin there.

Only the players' own origins are added: `https://www.youtube.com`, `https://youtube.com`,
`https://www.youtube-nocookie.com`, `https://youtube-nocookie.com` and
`https://player.vimeo.com`, each when an `<iframe>` of the content plays from it. An `<iframe>`
from any other origin is kept in the content, and is shown only once an admin allows its origin.

`call/2` adds the origins the site does not allow yet to the site's own setting, after the ones it
allows (its own, or the installation's global ones it takes), through
`MishkaCmsCore.Settings.put_as/4` as the admin, and the settings cache knows them once it answers:
a later item of the same run, which reads the cache, adds nothing, so a run adds each origin once.
Whether the admin may write the setting (`MishkaCmsCore.Settings.write_permission/1`,
`admin:dashboard:setting`) is read from the permissions the job's admin carries, so it costs no
query.

## An admin who may not allow them

An item whose players the site does not allow, imported by an admin who may not change the
setting, is never written with a player that shows nothing: it waits for a decision as
`"player_not_allowed"` (`MishkaCmsMigration.MigrationItem`'s Decide…), in a dry run through the
target's `waiting/2` (`waiting/2`) and in an import through its `prepare/3` (`call/2`), for an
item an earlier import wrote as for a new one. Wait for an admin skips it as `"waits_for_admin"`
until a run by an admin who may
allow the players writes it with them; Import without the player writes it with those
`<iframe>`s left out of its content (`playable/2`), and the report says so (`"player_left_out"`).
`note/2` says which for the report, `"frames_allowed: <origins>"` naming the origins when the
admin allows them, in a dry run too.

# `call`

```elixir
@spec call(MishkaCmsMigration.Source.Item.t(), MishkaCmsMigration.Target.context()) ::
  :ok | {:error, term()} | {:skipped, String.t()} | {:undecided, String.t()}
```

Allows on the run's site the players `item`'s content frames that it does not allow yet, when the
admin may: `:ok`, or the core's refusal of the write. For an admin who may not, `:ok` once an
admin decided to import the item without them, else what `waiting/2` says.

# `note`

```elixir
@spec note(MishkaCmsMigration.Source.Item.t(), MishkaCmsMigration.Target.context()) ::
  String.t() | nil
```

What the report says of `item`'s players: `"frames_allowed: <origins>"` when its content frames
players the run's site does not allow yet and the admin may allow them, the origins joined by
`", "`; `"player_left_out"` when they may not and an admin decided to import it without the
player, `"player_not_allowed"` or `"waits_for_admin"` while it waits, else `nil`.

# `playable`

```elixir
@spec playable(String.t(), MishkaCmsMigration.Target.context()) :: String.t()
```

`html` without the `<iframe>`s of a player the run's site does not allow, for an item an admin
decided to import without them; every other `<iframe>` is kept. After `call/2` allowed the
players of an admin who may, it leaves out none.

# `waiting`

```elixir
@spec waiting(MishkaCmsMigration.Source.Item.t(), MishkaCmsMigration.Target.context()) ::
  {:undecided | :skipped, String.t()} | nil
```

What a dry run plans for `item` (the target's `waiting/2`) whose content frames a player the site
does not allow, for an admin who may not allow it: `{:undecided, "player_not_allowed"}` until an
admin decides,
`{:skipped, "waits_for_admin"}` once one decided to wait for an admin who may, and `nil`, to be
written, once one decided to import it without the player, for an admin who may allow it, and
for an item that frames no such player.

---

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