Unpoly Show archive.org snapshot 3.5 brings major quality-of-life improvements and addresses numerous edge cases in existing functionality.
You can now use an
[up-flashes]
Show archive.org snapshot
element to render confirmations, alerts or warnings.
To render a flash message, include an
[up-flashes]
Show archive.org snapshot
element in your response.
The element's content should be the messages you want to render:
<div up-flashes>
<strong>User was updated!</strong>
</div>
<main>
Main response content ...
</main>
An
[up-flashes]
Show archive.org snapshot
element comes with useful default behavior for rendering notifications:
[up-hungry]
Show archive.org snapshot
).[up-flashes]
Show archive.org snapshot
container.See notification flashes Show archive.org snapshot for more details and examples.
Unpoly now detects changes in your JavaScripts and stylesheets after deploying a new version of your application.
While rendering new content, Unpoly compares script and style elements in the <head>
and emits an
up:assets:changed
Show archive.org snapshot
event if anything changed.
It is up to you to handle new frontend code revisions, e.g. by loading new assets Show archive.org snapshot or notifying the user Show archive.org snapshot .
See handling asset changes Show archive.org snapshot for more details and examples.
Render passes that update history
now synchronize meta tags
Show archive.org snapshot
in the <head>
, such as meta[name=description]
or link[rel=canonical]
.
In the document below, the highlighted elements will be updated when history is changed, in additional to the location URL:
<head>
<title>AcmeCorp</title> <!-- will update -->
<link rel="canonical" href="https://example.com/dresses/green-dresses"> <!-- will update -->
<meta name="description" content="About the AcmeCorp team"> <!-- will update -->
<meta prop="og:image" content="https://app.com/og.jpg"> <!-- will update -->
<script src="/assets/app.js"></script>
<link rel="stylesheet" href="/assets/app.css">
</head>
The linked JavaScript and stylesheet are not part of history state and will not be updated.
Overlays with history Show archive.org snapshot now update meta tags when opening. When the overlay closes the parent layer's meta tags are restored.
[up-hungry]
Show archive.org snapshot
in the <head>
Existing solutions using
[up-hungry]
Show archive.org snapshot
to update meta tags can be removed from your application code.
Other than
[up-hungry]
Show archive.org snapshot
the new implementation can deal with meta tags that only exist on some pages.
See
[up-meta]
Show archive.org snapshot
for ways to include or exclude head elements from synchronization.
You can disable the synchronization of meta tags globally Show archive.org snapshot or per render pass Show archive.org snapshot :
up.render('.element', { url: '/path', history: true, metaTags: false })
In earlier versions, errors in user code would often crash Unpoly. This would sometimes leave the page in a corrupted state. For example,
a render pass would only update some fragments, fail to scroll, or fail to run destuctors.
This version changes how Unpoly handles exceptions thrown from user code, like compilers, transition functions or callbacks like { onAccepted }
.
Starting with this version, Unpoly functions generally succeed despite exceptions from user code.
The code below will successfully compile Show archive.org snapshot an element despite a broken compiler Show archive.org snapshot :
up.compiler('.element', () => { throw new Error('broken compiler') })
let element = up.element.affix(document.body, '.element')
up.hello(element) // no error is thrown
Instead an
error
event on window
Show archive.org snapshot
is emitted:
window.addEventListener('error', function(event) {
alert("Got an error " + event.error.name)
})
This behavior is consistent with how the web platform handles errors in event listeners
and custom elements.
Exceptions in user code are also logged to the browser's
error console
Show archive.org snapshot
.
This way you can still access the stack trace or detect JavaScript errors in E2E tests.
Some test runners like
Jasmine
Show archive.org snapshot
already listen to the error
event and fail your test if any uncaught exception is observed.
In Jasmine you may use jasmine.spyOnGlobalErrorsAsync()
to make assertions on the unhandled error.
Element with an [up-hungry]
attribute are updated whenever the server
sends a matching element, even if the element isn't
targeted
Show archive.org snapshot
.
This release addresses many issues and requests concerning hungry elements:
There is now defined behavior when multiple targets want to render the same new fragments from a server response:
Many edge cases have been addressed for render passes that affect multiple layers:
[up-if-layer]
Show archive.org snapshot
.[up-if-layer="current child"]
would only piggy-back on render passes for the current layer or its direct overlay.You can now freely control when an hungry element is updated:
Before a hungry element is added to a render pass, a new event up:fragment:hungry
is now emitted on the element.
The event has properties for the old and new element, and information about the current render pass.
You may prevent this event to exclude the hungry element from the render pass. Use this to define arbitrary conditions
for when an hungry element should be updated:
element.addEventListener('up:fragment:hungry', function(event) {
if (event.newFragment.classList.contains('is-empty')) {
console.log('Ignoring a fragment with an .is-empty class')
event.preventDefault()
}
})
Hungry elements can now set an [up-on-hungry]
attribute. It contains a code snippet that receives an
up:fragment:hungry
Show archive.org snapshot
event.
Calling event.preventDefault()
will prevent the hungry fragment from being updated.
Deprecated the [up-if-history]
modifier for hungry elements.
This functionality is now covered by the more generic [up-on-hungry]
attribute. Also its main use case was synchronizing meta tags,
and that is now
supported out of the box
Show archive.org snapshot
.
Some improvements have been to hungry elements with animated transitions Show archive.org snapshot :
[up-duration]
and [up-easing]
attributes.up.render().finished
Show archive.org snapshot
promise.This release ships many improvements for the [up-poll]
attribute.
Unpoly has always paused
polling
Show archive.org snapshot
when the user minimizes the window or switches to another tab.
This behavior has been improved by the following:
When at least one poll interval was spent paused in the background and the user then returns to the tab, Unpoly will now immediately reload the fragment.
You can use this to load recent data when the user returns to your app after working on something else for a while. For example, the following
would reload your
main
Show archive.org snapshot
element after an absence of 5 minutes or more:
<main up-poll up-interval="300_000">
...
</main>
Polling now unschedules all JavaScript timers while polling is paused. This allows browser to keep the inactive window suspended, saving battery life.
Unpoly also pauses polling Show archive.org snapshot for fragments that are covered by an overlay. This behavior has been improved by the following:
[up-if-layer="any"]
attribute on an
[up-poll]
Show archive.org snapshot
fragment.[up-poll=false]
. The previous method of omitting the
[up-poll]
Show archive.org snapshot
attribute remains supported.up.radio.config.pollEnabled
Show archive.org snapshot
. To disable polling, prevent the
up:fragment:poll
Show archive.org snapshot
event instead.Unpoly's rendering engine has been reworked to address many edge cases found in production use.
.up-current
classes are updated before compilers are called.{ onAccepted }
and { onDismissed }
callbacks
Show archive.org snapshot
fire.This release addresses many many errors when matching fragments in closed layers, detached elements or destroyed elements in their exit animation:
{ failTarget }
or { failLayer }
cannot be resolved.up.fragment.toTarget()
no longer crashes when deriving targets for destroyed elements that are still in their exit animation.{ layer }
does not exist or has been closed.{ failLayer }
is no longer open.[up-validate]
in forms that are not
submitted through Unpoly
Show archive.org snapshot
.[up-keep]
no longer need to also be [up-keep]
. You can prevent keeping by setting [up-keep=false]
. This allows you to set [up-keep]
via a
macro
Show archive.org snapshot
."/true"
(sic)."revalidating undefined"
Previous versions of Unpoly adapted the behavior some features when it detected high latency or low network throughput.
Due to cross-browser support for the
Network Information API
Show archive.org snapshot
,
measuring of network quality was removed:
Unpoly no longer doubles
poll
Show archive.org snapshot
intervals on slow connections. The configuration up.radio.config.stretchPollInterval
was removed.
Unpoly no longer prevents
preloading
Show archive.org snapshot
on slow connections. The configuration up.link.config.preloadEnabled = 'auto'
was removed.
To disable preloading based on your own metrics, you can still prevent the up:link:preload
event.
The configuration up.network.config.badDownlink
was removed.
The configuration up.network.config.badRTT
was removed.
The function up.network.shouldReduceRequests()
was removed.
Unpoly retains all other functionality for dealing with network issues Show archive.org snapshot .
When
targeting fragments
Show archive.org snapshot
, Unpoly will prefer to
match fragments in the region of the user interaction
Show archive.org snapshot
. For example, when
a link's [up-target]
could match multiple fragments, the fragment closest to the link is updated.
In cases where you don't want this behavior, you now have more options:
{ match: 'first' }
option to any function that matches or renders a fragment.[up-match=first]
option on a link or form that matches or renders a fragment.up.fragment.config.matchAroundOrigin
has been replaced by up.fragment.config.match
. Its values are 'region'
(default) and 'first'
.New experimental function up.fragment.contains()
. It returns whether the given root
matches or contains the given selector or element.
Other than Element#contains()
it only matches fragments on the same layer. It also ignores destroyed fragments in an exit animation.
The event up:fragment:keep
received a new property { renderOptions }
. It contains the render options for the current render pass.
The event up:fragment:aborted
received new experimental property { newLayer }
. It returns whether the fragment was aborted by a
new overlay opening
Show archive.org snapshot
.
Many functions in the fragment API now also support a Document
as the search root:
up.fragment.get()
up.fragment.all()
up.fragment.contains()
Passing an element to up.fragment.get()
now returns that element unchanged.
Destructors are now called with the element being destroyed.
This allows you to reuse the same destructor function Show archive.org snapshot for multiple elements:
let fn = (element) => console.log('Element %o was destroyed', element)
for (let element of document.querySelector('div')) {
up.destructor(element, fn)
}
Unpoly 3.0.0 introduced a
third meta
argument for compilers
Show archive.org snapshot
containing information about the current render pass:
up.compiler('.user', function(element, data, meta) {
console.log(meta.response.text.length) // => 160232
console.log(meta.response.header('X-Course')) // => "advanced-ruby"
console.log(meta.layer.mode) // => "root"
console.log(meta.revalidating) // => boolean
})
Unfortunately we realized that access to the response this would to bad patterns where fragments would compile
differently for the initial page load vs. subsequent fragment updates.
In Unpoly 3.5 compilers can no longer access the current response via the { response }
of that meta
argument.
The { layer }
and { revalidating }
property remains available.
The up.syntax
package has been renamed to
up.script
Show archive.org snapshot
.
subtree
in your { layer }
options or [up-layer]
attributes.up.Layer
Show archive.org snapshot
objects now support a new method
#subtree()
Show archive.org snapshot
. It returns an array of up.Layer
containing this layer and its descendant overlays.up:link:preload
event received a new property { renderOptions }
. It contains the render options for the current render pass.[up-on-offline]
Show archive.org snapshot
attribute now supports a
CSP nonce
Show archive.org snapshot
.up.link.followOptions()
now takes an Object
as a second argument. It will override any options parsed from the link attributes.up.link.config.preloadEnabled
was deprecated. To disable preloading, prevent up:link:preload
.up.element.isEmpty()
was added. It returns whether an element has neither child elements nor non-whitespace text.up.viewport.config.anchoredRight
to up.viewport.config.anchoredRightSelectors
up.viewport.config.fixedTop
to up.viewport.config.fixedTopSelectors
up.viewport.config.fixedBottom
to up.viewport.config.fixedBottomSelectors
unpoly-migrate.js
up.element.isAttached()
and up.element.isDetached()
functions were changed so they behavewindow.document
, but not to other Document
instances.unpoly.js
is now compiled using ES2021 (up from ES2020). The
ES6 build
Show archive.org snapshot
for legacy browsers remains available.
Improve compression of minified builds. In particular private object properties are now prefixed with an underscore (_
) so they can be mangled safely.
If you are re-bundling the unminified build of Unpoly you can configure your minifier
to do the same.