Unpoly 3.12.0 released #778
triskweline
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This release adds asynchronous compilers and many other features requested by the community.
We also fixed a number of performance regressions introduced by Unpoly 3.11.
Breaking changes are marked with a⚠️ emoji and polyfilled by
unpoly-migrate.js.Note
Our sponsor makandra funded this release ❤️
Please consider hiring makandra for Unpoly support.
Asynchronous compilers
Compiler functions can now be
async. This is useful when a compiler needs to fetch network resources, or when calling a library with an asynchronous API:You can also use this to split up expensive tasks, giving the browser a chance to render and process user input:
Cleaning up async work
Like synchronous compilers, async compiler functions can return a destructor function:
Unpoly guarantees that the destructor is called, even if the element gets destroyed before the compiler function terminates.
Timing render-blocking mutations
Unpoly will run the first task of every compiler function before allowing the browser to render DOM changes. If an async compiler function runs for multiple tasks, the browser will render between tasks. If you have render-blocking mutations that should be hidden from the user, these must happen in the first task.
Async compilers will not delay the promise returned by rendering functions
up.render()orup.layer.open().Async compilers will delay the promise returned by
up.render().finishedandup.hello().up.hello()is now asyncup.hello()function now returns a promise that fulfills when all synchronous and asynchronous compilers have terminated:The fulfillment value is the same element that was passed as an argument:
Performance fixes
Unpoly 3.11 introduced a number of performance regressions that would be very noticable on pages with many elements, or many forms. To address this, this release includes a number of performance fixes:
[up-validate]fields for every form. Now fields are only tracked for forms that use[up-validate].HTML content-type required
text/htmlorapplication/xhtml+xml. Trying to render responses with a different type will throw an error, even if the response body contains HTML markup.Restricting content types is a security precaution. It protects in a hypothetical scenario where an attacker can both upload a file and can use an existing XSS vulnerability to cause Unpoly to render that file. It doesn't affect applications that reliably escape user input.
You can configure which responses Unpoly will process by configuring a function in
up.fragment.config.renderableResponse. To render any response regardless of content-type, configure a function that always returns true`:New guides
The documentation has been extended with new guides:
Submit buttons can override form attributes
Submit buttons can now supplement or override most Unpoly attributes from the form:
Individual submit buttons can now opt for a full page load, by setting an
[up-submit="false"]attribute:See
[up-submit]for a list of overridable attributesSticky layout elements
When scrolling to reveal a target element, Unpoly will ensure that layout elements with
[up-fixed=top]are not covering the revealed content.You can now use
[up-fixed]on elements withposition: sticky. Unpoly will measure sticky element like permanently fixed elements. The current scroll position is not taken into account.Support partial tables responses
In the past Unpoly didn't allow a server to optimize its response when the result was a single table row (or cell) without an enclosing
<table>:Unpoly can now parse responses that only contain a
<tr>,<td>or<th>element, without an enclosing<table>(issue #91).Expanding click areas
Unpoly lets you enlarge a link's click area using the
[up-expand]attribute. This version addresses inconsistent (or impractical) assignment of the.up-activefeedback class when an expanded link is clicked.When either the
[up-expand]container or the first link is clicked, the.up-activeclassis now assigned to both elements:
When a non-expanded link is clicked, now only that link becomes
.up-active:Preserving fragments
Two changes were made to preserving elements using the
[up-keep]attribute:up:fragment:kept. This event is emitted after all keep conditions are evaluated and preservation can no longer be prevented. A listener can be sure that the element is going to be kept.[up-poll]and[up-keep]now continue polling when the element is kept (fixesup-pollandup-keepdon't work well together #763)Closing overlays
up.Layer#isOpen()has been deprecated. Useup.Layer#isAlive() instead.up.Layer#isClosed()has been deprecated. Use!up.Layer#isAlive() instead.AbortErrorinstead of doing nothing.[up-switch]input without a containing form is placed in an overlay, and that overlay is closed.Manual booting
[up-boot=manual]must now be set on the<html>element instead of on the<script>loading Unpoly.<script type="module">.Fragment API
up.fragment.get()function now has a{ destroying: true }option. This allows to find destroyed elements that are still playing out their exit animation. Note that allup.fragmentfunctions normally ignore elements in an exit animation.up.fragment.isAlive(). It returns whether an element is both attached to the DOM and also not in an exit animation.Smaller fixes and changes
up.util.task()to again queue macrotasks usingsetTimeout()instead ofpostMessage(). Unpoly 3.11 only recently switched topostMessage()because of its tighter scheduling. Unfortunately message order is erratic withpostMessage()in Safari, making it hard to reason about the sequence of asynchronous callbacks.up.Response#isHTML(). It returns whether the response has a content-type oftext/htmlorapplication/xml+html. It doesn't test if the response body actual contains a valid HTML document.up.render({ response })is called while another request is in flight.{ failTarget }was made while waiting for the network, and the first request responded with an error status and updates , the second request is now aborted.Beta Was this translation helpful? Give feedback.
All reactions