Refactor and expose `swap` in public API
Description
This PR includes swap method in htmx public API. This feature has been requested on multiple occasions, was proposed for 2.0 and finally delivered. To make it possible, I did a bit of a refactoring by gathering every swap-related piece of code in fullSwap method (name is up for discussion), which handles
- focus and selection preservation
- title updates
- head merging
- scroll
- OOB swapping
- normal swapping
- settling
This means that any extension and custom script can use full power of htmx's swapping features. I also anticipate that this change should significantly simplify maintenance of swapping in the future
This is a breaking change, as extensions no longer have access to selectAndSwap method. The new method fully covers the needs for swapping, while also removing responsibility of managing settling info.
The old method covered very specific part of swapping process and had a tricky signature which I struggle to keep untouched.
On the plus side, this is the entire code that's required to perform swapping from SSE extension
let target = api.getTarget(child);
let swapSpec = api.getSwapSpecification(child);
htmx.swap(target, event.data, {spec: swapSpec});
To be done/decided:
- [x] exposure of
SwapSpecificationtype to the public world (are we ok with it? need to document it) - added to htmx.d.ts and documented in JS API section - [x] documentation - documented
- [x] naming of the method - renamed to
swap - [ ] upgrading official extensions (ws, sse) - TBD
- [ ] handling view transitions from this method - TBD
Corresponding issue: 2.0
Testing
I ensured that this refactor did not affect existing tests at all. I also intend to write tests specifically for this method, if the team agrees that this approach works for us
Fwiw, I feel like "extension-breaking" and "user breaking" are two separate concepts. I wouldn't want to break out extensions randomly, but the bar for breaking user functionality is higher than breaking the internal API.
Why fullSwap and not just swap?
@alexpetros this was a placeholder name. I did it because we had swap method that implements specific swapping strategies and I wasn't sure how the refactor would turn out. I will rename it before merging
As discussed, I've renamed the method, and also cleaned up signature a bit to get rid of duplicated parameters from swapSpec and swapOptions. I decided to separate swapSpec and swapOptions as separate arguments, since the former will be used much more often compared to the latter.
Also, some basic tests for the method.