Releases: grych/drab
Release list
No Limits
Potentially breaking release!
As a preparation to 0.8.0, this release contains fundamental change in Drab.Live behaviour. It
removes all the engine limitations, and makes a big change on how it treats @conn assign.
Please report any found issues with this release.
API Changes
The @conn case
Because sometimes it is huge, @conn is treated in the special way - it is trimmed to contain only
essential fields. By default it is :private => :phoenix_endpoint, but you may configure it.
config :drab, :live_conn_pass_through, %{
assigns: %{
users: true
},
private: %{
phoenix_endpoint: true
}
}
See Drab.Live documentation for more details on this case.
:templates_path config must be under priv/
If you are using :templates_path config, and your templates are not under the priv/ directory,
you'll have to move them. Solved #105.
Broadcast the assign
New Features
Living assigns per process cache
The performance of poke and peek operations increases significantly, as the event handler
does not have to get the assigns from the browser each time.
broadcast_poke
You now may broadcast the assign, in exactly the same way you're doing poke.
The Great Unification
This release finally contains all the features of Shared Commanders.
New Features
Living assigns inside the Shared Commander
If you are using drab-commander attribute, the requests coming from the shared commander updates stuff only under this tag.
<div drab-commander="DrabTestApp.Shared1Commander">
<div><%= @assign1 %></div>
<button drab-click="button_clicked">Shared 1</button>
</div>
<div drab-commander="DrabTestApp.Shared1Commander">
<div><%= @assign1 %></div>
<button drab-click="button_clicked">Shared 2</button>
</div>
defhandler button_clicked(socket, sender) do
poke socket, assign1: "changed"
end
This will update only the div with @assign1 in the same <div drab-commander> as the button. See new demo example.
The Great Unification
Callbacks now works in the Shared Commanders.
drab-id attribute now is generated with the counter, instead of UUID
This means you are now able to use this/1 and this_commander/1 with the broadcasting functions.
The browser will not reconnect when client library change
Forces user to reload the page in case the Drab JS library is changed.
Bugfix
This release fixes new, better bug introduced in 0.7.2
Fixed Bugs
#97 - 414: url too long when connect
This bug was introduced in 0.7.2, after moving update of assigns cache to the connect token.
#94 Jason not found in production
Updated the applications list in mix.exs
New Features
Pass options for Phoenix.Channel
Set the list of options to pass to use Phoenix.Channel. For example, to turn off logging of each handle_in:
config :drab, :phoenix_channel_options, [log_handle_in: false]
Fix connect issue found in 0.7.2
v0.7.3 fixed socket error
Reusable Components
This release introduces core API changes, and the important new feature: creating reusable components!
API changes
use Drab.Controller is now optional
When using default commander name, corresponding to the controller (like PageCommander -> PageController), there is no need to mark controller as Drab.Controller anymore.
Shared Commanders should be declared in the page controller
All shared commanders must be explicitly declared in the controller:
use Drab.Controller, commanders: [My.Shared.Commander]
In this version, system generates warning message if commanders are not declared. This warning will become error in v0.8.0
defhandler macro for creating event handlers in commanders
Since this version, all event handlers, whenever they are in shared or "normal" commander, must be declared with public or defhandler macro. Use defhandler instead of the standard def.
This:
public :button_clicked
def button_clicked(socket, sender), do: ...
is an equivalent of:
defhandler button_clicked(socket, sender), do: ...
In this version, system generates warning message if the function is not declared as handler. This warning will become error in v0.8.0
New Features
Create Reusable Drab Components with Shared Commanders
Accomplished this with the new Drab.Core.this_commander/1 function, returning the unique selector of the sourrounding commander tag, so you may easly reduce the region where your update works.
Having the page as below, we want the button to update .spaceholder1 only within the range of drab-commander.
<div drab-commander="DrabTestApp.Shared1Commander">
<div class="spaceholder1">Nothing</div>
<button drab-click="button_clicked">Shared 1</button>
</div>
<div drab-commander="DrabTestApp.Shared1Commander">
<div class="spaceholder1">Nothing</div>
<button drab-click="button_clicked">Shared 2</button>
</div>
Just like we can use Drab.Core.this/1 to select the exact sender of the event, we may have Drab.Core.this_commander/1, to build a selector which chooses the desired object:
defhandler button_clicked(socket, sender) do
set_prop socket, this_commander(sender) <> " .spaceholder1", innerText: "changed"
end
Notice the space before “.spaceholder1”. this_commander/1 returns the string like [drab-id="f59d54e6-a924-4e72-90d1-5177efecac9b"], so you may build any selector based on it.
Shared commanders and additional arguments
This version is a step forward for creating component-like pieces of code with Drab, with enhanced Shared Commanders and possibility to pass additional argument to the handler function.
Finally, most functions got their own @spec and Drab is now dialyzable.
Warning!
Drab.Live cache DETS has changed, please ensure your "*.drab templates are recompiled after the upgrade.
New Features
Define Shared Commander with drab-commander on all children nodes
If you add drab-commander attribute to any tag, all children of this tag will use Shared Commander defined in this tag. Notice it will not redefine nodes, which already has Shared Commander defined.
Thus this:
<div drab-commander="DrabExample.SharedCommander">
<button drab-click="button1_clicked">1</button>
<button drab-click="button2_clicked">1</button>
<button drab-click="DrabExample.AnotherCommander.button3_clicked">1</button>
</div>
is equivalent of:
<div>
<button drab-click="DrabExample.SharedCommander.button1_clicked">1</button>
<button drab-click="DrabExample.SharedCommander.button2_clicked">1</button>
<button drab-click="DrabExample.AnotherCommander.button3_clicked">1</button>
</div>
Additional argument for handlers
Since this version you may create handler with arity of 3, and pass the additional parameter using parenthesis after the handler name in drab attribute:
<button drab-click='button_clicked(42)'>
This will run button_clicked/3 instead of button_clicked/2 in your Commander:
def button_clicked(socket, sender, the_answer_for_the_ultimate_question)
The attribute is evaluated on the client side, so it could be any valid JS expression:
<button drab-click='button_clicked({the_answer: 42})'>
<button drab-click='button_clicked(window.location)'>
drab-argument
Analogically to drab-commander attribute, there is a drab-argument to set this argument for more nodes. Notice that the existing arguments are not overwritten, so this:
<div drab-argument='42'>
<button drab-click='button_clicked'>
<button drab-click='button_clicked(43)'>
</div>
is the equivalent to:
<button drab-click='button_clicked(42)'>
<button drab-click='button_clicked(43)'>
Client-side errors now appears in the application log
For developer happines, all client-side errors are now displayed both on JS console and on the Phoenix side.
Example:
<button drab=":wrong">
generates:
[error] Browser reports: Drab attribute value ':wrong' is incorrect.
Bugfixes
Core redesigned
Updated the Drab core to introduce few important features. Fixed to Elixir version >= 1.5.2. Tested with Elixir 1.6.0.
Possibility to provide own connect/2 callback for socket authentication, etc
Previously, Drab intercepted the connect/2 callback in your UserSocket. Now, there is a possibility to use your own callback:
defmodule MyApp.UserSocket do
use Phoenix.Socket
channel "__drab:*", Drab.Channel
def connect(params, socket) do
Drab.Socket.verify(socket, params)
end
end
Use of the custom marker "/" in Drab templates
This version allow you to use of <%/ %> marker to avoid using Drab.Live for a given expression. The expression would be treaten as a normal Phoenix one, so will be displayed in rendered html, but Drab will have no access to it.
<div>
<%/ @this_assigns_will_be_displayed_but_not_drabbed %>
</div>Changed event definition core
The existing syntax drab-event and drab-handler attributes does not allow having multiple events on the one DOM object (#73). This form is now depreciated and replaces with the brand new, better syntax of:
<tag drab="event:handler">
Now may set more event on the single object:
<input drab="focus:input_focus blur:input_blur"
or:
<input drab-focus="input_focus" drab-blur="input_blur">
Event shorthands list is now configurable
By default, you can use only few arbitrary-chosen shorthands for the event name / handler name (drab-click="clicked") attribute. Now you may configure the list with :events_shorthands config.
See #73.
Style changes:
- source code formatted with 1.6.0
- use
@impl truein behaviour callbacks - started annotating all functions with
@spec(so far only few) - small style improvements suggested by Credo
Depreciations:
Drab.Client.js/2becomesDrab.Client.run/2drab-eventanddrab-handlerattributes combination replaced bydrab