`, only the interpolation part is marked as dynamic
- If the attribute can be empty, such as "class" and "style", keep the attribute name as static
- Add a function component for rendering `Phoenix.LiveComponent`. Instead of `<%= live_component FormComponent, id: "form" %>`, you must now do: `<.live_component module={FormComponent} id="form" />`
### Bug fixes
- Fix LiveViews with form recovery failing to properly mount following a reconnect when preceded by a live redirect
- Fix stale session causing full redirect fallback when issuing a `push_redirect` from mount
- Add workaround for Safari bug causing `
` tags with srcset and video with autoplay to fail to render
- Support EEx interpolation inside HTML comments in HEEx templates
- Support HTML tags inside script tags (as in regular HTML)
- Raise if using quotes in attribute names
- Include the filename in error messages when it is not possible to parse interpolated attributes
- Make sure the test client always sends the full URL on `live_patch`/`live_redirect`. This mirrors the behaviour of the JavaScript client
- Do not reload flash from session on `live_redirect`s
- Fix select drop-down flashes in Chrome when the DOM is patched during focus
### Deprecations
- `<%= live_component MyModule, id: @user.id, user: @user %>` is deprecated in favor of `<.live_component module={MyModule} id={@user.id} user={@user} />`. Notice the new API requires using HEEx templates. This change allows us to further improve LiveComponent and bring new features such as slots to them.
- `render_block/2` in deprecated in favor of `render_slot/2`
## 0.16.4 (2021-09-22)
### Enhancements
- Improve HEEx error messages
- Relax HTML tag validation to support mixed case tags
- Support self closing HTML tags
- Remove requirement for `handle_params` to be defined for lifecycle hooks
### Bug fixes
- Fix pushes failing to include channel `join_ref` on messages
## 0.16.3 (2021-09-03)
### Bug fixes
- Fix `on_mount` hooks calling view mount before redirecting when the hook issues a halt redirect.
## 0.16.2 (2021-09-03)
### Enhancements
- Improve error messages on tokenization
- Improve error message if `@inner_block` is missing
### Bug fixes
- Fix `phx-change` form recovery event being sent to wrong component on reconnect when component order changes
## 0.16.1 (2021-08-26)
### Enhancements
- Relax `phoenix_html` dependency requirement
- Allow testing functional components by passing a function reference
to `Phoenix.LiveViewTest.render_component/3`
### Bug fixes
- Do not generate CSRF tokens for non-POST forms
- Do not add compile-time dependencies on `on_mount` declarations
## 0.16.0 (2021-08-10)
### Security Considerations Upgrading from 0.15
LiveView v0.16 optimizes live redirects by supporting navigation purely
over the existing WebSocket connection. This is accomplished by the new
`live_session/3` feature of `Phoenix.LiveView.Router`. The
[security guide](/guides/server/security-model.md) has always stressed
the following:
> ... As we have seen, LiveView begins its life-cycle as a regular HTTP
> request. Then a stateful connection is established. Both the HTTP
> request and the stateful connection receives the client data via
> parameters and session. This means that any session validation must
> happen both in the HTTP request (plug pipeline) and the stateful
> connection (LiveView mount) ...
These guidelines continue to be valid, but it is now essential that the
stateful connection enforces authentication and session validation within
the LiveView mount lifecycle because **a `live_redirect` from the client
will not go through the plug pipeline** as a hard-refresh or initial HTTP
render would. This means authentication, authorization, etc that may be
done in the `Plug.Conn` pipeline must also be performed within the
LiveView mount lifecycle.
Live sessions allow you to support a shared security model by allowing
`live_redirect`s to only be issued between routes defined under the same
live session name. If a client attempts to live redirect to a different
live session, it will be refused and a graceful client-side redirect will
trigger a regular HTTP request to the attempted URL.
See the `Phoenix.LiveView.Router.live_session/3` docs for more information
and example usage.
### New HTML Engine
LiveView v0.16 introduces HEEx (HTML + EEx) templates and the concept of function
components via `Phoenix.Component`. The new HEEx templates validate the markup in
the template while also providing smarter change tracking as well as syntax
conveniences to make it easier to build composable components.
A function component is any function that receives a map of assigns and returns
a `~H` template:
```elixir
defmodule MyComponent do
use Phoenix.Component
def btn(assigns) do
~H"""
<%= @text %>
"""
end
end
```
This component can now be used as in your HEEx templates as:
The introduction of HEEx and function components brings a series of deprecation
warnings, some introduced in this release and others which will be added in the
future. Note HEEx templates require Elixir v1.12+.
### Upgrading and deprecations
The main deprecation in this release is that the `~L` sigil and the `.leex` extension
are now soft-deprecated. The docs have been updated to discourage them and using them
will emit warnings in future releases. We recommend using the `~H` sigil and the `.heex`
extension for all future templates in your application. You should also plan to migrate
the old templates accordingly using the recommendations below.
Migrating from `LEEx` to `HEEx` is relatively straightforward. There are two main differences.
First of all, HEEx does not allow interpolation inside tags. So instead of:
```elixir
...
```
One should use the HEEx syntax:
```elixir
...
```
The other difference is in regards to `form_for`. Some templates may do the following:
```elixir
~L"""
<%= f = form_for @changeset, "#" %>
<%= input f, :foo %>
"""
```
However, when converted to `~H`, it is not valid HTML: there is a `` tag but
its opening is hidden inside the Elixir code. On LiveView v0.16, there is a function
component named `form`:
```elixir
~H"""
<.form :let={f} for={@changeset}>
<%= input f, :foo %>
"""
```
We understand migrating all templates from `~L` to `~H` can be a daunting task.
Therefore we plan to support `~L` in LiveViews for a long time. However, we can't
do the same for stateful LiveComponents, as some important client-side features and
optimizations will depend on the `~H` sigil. Therefore **our recommendation is to
replace `~L` by `~H` first in live components**, particularly stateful live components.
Furthermore, stateless `live_component` (i.e. live components without an `:id`)
will be deprecated in favor of the new function components. Our plan is to support
them for a reasonable period of time, but you should avoid creating new ones in
your application.
### Breaking Changes
LiveView 0.16 removes the `:layout` and `:container` options from
`Phoenix.LiveView.Routing.live/4` in favor of the `:root_layout`
and `:container` options on `Phoenix.Router.live_session/3`.
For instance, if you have the following in LiveView 0.15 and prior:
```elixir
live "/path", MyAppWeb.PageLive, layout: {MyAppWeb.LayoutView, "custom_layout.html"}
```
Change it to:
```elixir
live_session :session_name, root_layout: {MyAppWeb.LayoutView, "custom_layout.html"} do
live "/path", MyAppWeb.PageLive
end
```
On the client, the `phoenix_live_view` package no longer provides a default export for `LiveSocket`.
If you have the following in your JavaScript entrypoint (typically located at `assets/js/app.js`):
```js
import LiveSocket from "phoenix_live_view"
```
Change it to:
```js
import { LiveSocket } from "phoenix_live_view"
```
Additionally on the client, the root LiveView element no longer exposes the
LiveView module name, therefore the `phx-view` attribute is never set.
Similarly, the `viewName` property of client hooks has been removed.
Codebases calling a custom function `component/3` should rename it or specify its module to avoid a conflict,
as LiveView introduces a macro with that name and it is special cased by the underlying engine.
### Enhancements
- Introduce HEEx templates
- Introduce `Phoenix.Component`
- Introduce `Phoenix.Router.live_session/3` for optimized live redirects
- Introduce `on_mount` and `attach_hook` hooks which provide a mechanism to tap into key stages of the LiveView lifecycle
- Add upload methods to client-side hooks
- [Helpers] Optimize `live_img_preview` rendering
- [Helpers] Introduce `form` function component which wraps `Phoenix.HTML.form_for`
- [LiveViewTest] Add `with_target` for scoping components directly
- [LiveViewTest] Add `refute_redirected`
- [LiveViewTest] Support multiple `phx-target` values to mirror JS client
- [LiveViewTest] Add `follow_trigger_action`
- [JavaScript Client] Add `sessionStorage` option `LiveSocket` constructor to support client storage overrides
- [JavaScript Client] Do not failsafe reload the page in the background when a tab is unable to connect if the page is not visible
### Bug fixes
- Make sure components are loaded on `render_component` to ensure all relevant callbacks are invoked
- Fix `Phoenix.LiveViewTest.page_title` returning `nil` in some cases
- Fix buttons being re-enabled when explicitly set to disabled on server
- Fix live patch failing to update URL when live patch link is patched again via `handle_params` within the same callback lifecycle
- Fix `phx-no-feedback` class not applied when page is live-patched
- Fix `DOMException, querySelector, not a valid selector` when performing DOM lookups on non-standard IDs
- Fix select dropdown flashing close/opened when assigns are updated on Chrome/macOS
- Fix error with multiple `live_file_input` in one form
- Fix race condition in `showError` causing null `querySelector`
- Fix statics not resolving correctly across recursive diffs
- Fix no function clause matching in `Phoenix.LiveView.Diff.many_to_iodata`
- Fix upload input not being cleared after files are uploaded via a component
- Fix channel crash when uploading during reconnect
- Fix duplicate progress events being sent for large uploads
### Deprecations
- Implicit assigns when passing a `do-end` block to `live_component` is deprecated
- The `~L` sigil and the `.leex` extension are now soft-deprecated in favor of `~H` and `.heex`
- Stateless live components (a `live_component` call without an `:id`) are deprecated in favor of the new function component feature
## 0.15.7 (2021-05-24)
### Bug fixes
- Fix broken webpack build throwing missing morphdom dependency
## 0.15.6 (2021-05-24)
### Bug fixes
- Fix live patch failing to update URL when live patch link is patched again from `handle_params`
- Fix regression in `LiveViewTest.render_upload/3` when using channel uploads and progress callback
- Fix component uploads not being cleaned up on remove
- Fix `KeyError` on LiveView reconnect when an active upload was previously in progress
### Enhancements
- Support function components via `component/3`
- Optimize progress events to send less messages for larger file sizes
- Allow session and local storage client overrides
### Deprecations
- Deprecate `@socket/socket` argument on `live_component/3` call
## 0.15.5 (2021-04-20)
### Enhancements
- Add `upload_errors/1` for returning top-level upload errors
### Bug fixes
- Fix `consume_uploaded_entry/3` with external uploads causing inconsistent entries state
- Fix `push_event` losing events when a single diff produces multiple events from different components
- Fix deep merging of component tree sharing
## 0.15.4 (2021-01-26)
### Bug fixes
- Fix nested `live_render`'s causing remound of child LiveView even when ID does not change
- Do not attempt push hook events unless connected
- Fix preflighted refs causing `auto_upload: true` to fail to submit form
- Replace single upload entry when `max_entries` is 1 instead of accumulating multiple file selections
- Fix `static_path` in `open_browser` failing to load stylesheets
## 0.15.3 (2021-01-02)
### Bug fixes
- Fix `push_redirect` back causing timeout on the client
## 0.15.2 (2021-01-01)
### Backwards incompatible changes
- Remove `beforeDestroy` from `phx-hook` callbacks
### Bug fixes
- Fix form recovery failing to send input on first connection failure
- Fix hooks not getting remounted after LiveView reconnect
- Fix hooks `reconnected` callback being fired with no prior disconnect
## 0.15.1 (2020-12-20)
### Enhancements
- Ensure all click events bubble for mobile Safari
- Run `consume_uploaded_entries` in LiveView caller process
### Bug fixes
- Fix hooks not getting remounted after LiveView recovery
- Fix bug causing reload with jitter on timeout from previously closed channel
- Fix component child nodes being lost when component patch goes from single root node to multiple child siblings
- Fix `phx-capture-click` triggering on mouseup during text selection
- Fix LiveView `push_event`'s not clearing up in components
- Fix `