Skip to content

bigskysoftware/paxi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

♻️ paxi.js - a clever little diff...

paxi.js is an experimental, minimalist companion to fixi.js that swaps HTML into the DOM by morphing instead of replacing: preserving existing nodes, focus, scroll position, and form state wherever the old and new trees align.

Part of the fixi project.

When paired with fixi, paxi registers itself as the morph swap strategy, so you can write fx-swap="morph" and get id-keyed reconciliation out of the box. It also works stand-alone via the window.morph(target, html) global.

Here is an example:

<script src="fixi.js"></script>
<script src="paxi.js"></script>

<button fx-action="/profile"
        fx-target="#profile"
        fx-swap="morph">
    Reload Profile
</button>
<div id="profile">
    <input id="nickname" placeholder="typing here survives the swap">
    <p id="bio">...</p>
</div>

The response HTML replaces the contents of #profile, but the <input> keeps its focus, caret, and any in-progress value because its id matches a node in the incoming markup.

Minimalism

paxi is to idiomorph what fixi is to htmx: a smaller, less ambitious take on the same idea. No configuration, no callbacks, no head-merging, no id-set inference - just a single recursive diff that keeps id-keyed nodes stable as the tree around them changes.

As such, it does not include many features found in idiomorph or morphdom:

  • head merging / stylesheet reconciliation
  • beforeNodeMorphed / afterNodeMorphed callbacks
  • outerHTML vs innerHTML modes
  • id-set propagation across ancestors
  • pluggable node matchers

A hard constraint on the project is that the unminified, uncompressed size stays under 2KB.

Installing

Drop paxi.js in a script tag after (or before) fixi.js:

<script src="fixi.js"></script>
<script src="paxi.js"></script>

Or install via npm:

npm install paxi-js

API

window.morph(target, html)

Morph target (an Element) toward the first element parsed from html (a string). The target is updated in place when the root node names match; otherwise it is replaced.

morph(document.getElementById("panel"), "<div id='panel'>new contents</div>")

fx-swap="morph"

When loaded alongside fixi, paxi registers a config hook that intercepts fx-swap="morph" and wires it to morph(cfg.target, cfg.text).

Modus Operandi

paxi walks the old and new trees in lockstep:

  1. If node type or name differ, the old node is replaced - but any id-keyed descendant of the incoming node whose id matches a node in the old tree is first rescued into place.
  2. For text and comment nodes, the value is updated when it differs.
  3. For elements, attributes are synced (extras removed, missing added, values updated).
  4. Children are reconciled positionally, except that id-keyed children in the incoming tree pull their original counterparts forward when they exist.

LICENCE

Zero-Clause BSD
=============

Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

About

paxi.js - a companion to fixi.js

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors