Fix remove fragment (#665)

* Replace delay function call

* Add test

* Improve tests

* Add release note
This commit is contained in:
Ben Croker 2025-02-13 09:38:29 -06:00 committed by GitHub
parent 2a16577829
commit 1e9c7a820b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 127 additions and 49 deletions

View File

@ -4,15 +4,8 @@ Each tagged version of Datastar is accompanied by a release note. Read the [rele
# WIP Release Notes
## v1.0.0-beta.6
### Changed
- The `data-on-load` callback is now delayed to the next microtask, making it possible to place the `data-indicator` attribute later on the same element.
## v1.0.0-beta.7
### Fixed
- Fixed a bug in which the `data-on-signals-change` attribute expression was not being executed when signal values changed ([#641](https://github.com/starfederation/datastar/issues/641)).
- Fixed a bug in which the signal created by `data-ref` was being removed during the cleanup process ([#642](https://github.com/starfederation/datastar/issues/642)).
- Fixed a bug in which errors were being caught in preact core, which was obfuscating the original error ([#643](https://github.com/starfederation/datastar/issues/643)).
- Fixed a bug in which morphed DOM elements could lose their focus, due to a change of behavior in Idiomorph ([#645](https://github.com/starfederation/datastar/issues/645)).
- Fixed a bug in which `datastar-remove-fragments` events were not having any effect ([#664](https://github.com/starfederation/datastar/issues/664)).

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,6 @@ import {
} from '../../../../engine/types'
import { elUniqId, walkDOM } from '../../../../utils/dom'
import { camel, isBoolString } from '../../../../utils/text'
import { delay } from '../../../../utils/timing'
import {
docWithViewTransitionAPI,
supportsViewTransitions,
@ -94,7 +93,6 @@ function applyToTargets(
walkDOM(fragmentWithIDs, (el) => {
if (!el.id?.length && Object.keys(el.dataset).length) {
el.id = elUniqId(el)
console.log(el.id)
}
})
@ -168,7 +166,7 @@ function applyToTargets(
const cl = modifiedTarget.classList
cl?.add(SWAPPING_CLASS)
delay(() => {
setTimeout(() => {
initialTarget.classList.remove(SWAPPING_CLASS)
cl?.remove(SWAPPING_CLASS)
}, settleDuration)
@ -177,7 +175,7 @@ function applyToTargets(
if (cl && originalHTML !== revisedHTML) {
cl.add(SETTLING_CLASS)
delay(() => {
setTimeout(() => {
cl.remove(SETTLING_CLASS)
}, settleDuration)
}

View File

@ -10,7 +10,6 @@ import {
import { initErr } from '../../../../engine/errors'
import { PluginType, type WatcherPlugin } from '../../../../engine/types'
import { isBoolString } from '../../../../utils/text'
import { delay } from '../../../../utils/timing'
import {
docWithViewTransitionAPI,
supportsViewTransitions,
@ -43,7 +42,7 @@ export const RemoveFragments: WatcherPlugin = {
target.classList.add(SWAPPING_CLASS)
}
delay(() => {
setTimeout(() => {
for (const target of removeTargets) {
target.remove()
}

View File

@ -80,7 +80,7 @@ export const On: AttributePlugin = {
if (key === 'load') {
// Delay the callback to the next microtask so that indicators can be set
delay(() => callback(), 0)()
setTimeout(() => callback(), 0)
return () => {}
}

4
sdk/go/consts.go generated
View File

@ -7,8 +7,8 @@ import "time"
const (
DatastarKey = "datastar"
Version = "1.0.0-beta.6"
VersionClientByteSize = 39873
VersionClientByteSizeGzip = 14814
VersionClientByteSize = 39885
VersionClientByteSizeGzip = 14805
//region Default durations

View File

@ -30,9 +30,11 @@ func setupTests(ctx context.Context, router chi.Router, signals sessions.Store)
Label: "tests",
Links: []*SidebarLink{
{ID: "key_casing"},
{ID: "merge_fragment"},
{ID: "merge_fragment_signal"},
{ID: "on_load"},
{ID: "ref"},
{ID: "remove_fragment"},
{ID: "signals_change"},
{ID: "signals_change_path"},
},
@ -87,8 +89,10 @@ func setupTests(ctx context.Context, router chi.Router, signals sessions.Store)
})
if err := errors.Join(
setupTestsMergeFragment(testsRouter),
setupTestsMergeFragmentSignal(testsRouter),
setupTestsOnLoad(testsRouter),
setupTestsRemoveFragment(testsRouter),
); err != nil {
panic(fmt.Sprintf("error setting up tests routes: %s", err))
}

View File

@ -0,0 +1,19 @@
package site
import (
"net/http"
"github.com/go-chi/chi/v5"
datastar "github.com/starfederation/datastar/sdk/go"
)
func setupTestsMergeFragment(testsRouter chi.Router) error {
testsRouter.Get("/merge_fragment/data", func(w http.ResponseWriter, r *http.Request) {
sse := datastar.NewSSE(w, r)
c := mergeFragmentTest()
sse.MergeFragmentTempl(c)
})
return nil
}

View File

@ -0,0 +1,5 @@
package site
templ mergeFragmentTest() {
<code id="result">1</code>
}

View File

@ -0,0 +1,18 @@
package site
import (
"net/http"
"github.com/go-chi/chi/v5"
datastar "github.com/starfederation/datastar/sdk/go"
)
func setupTestsRemoveFragment(testsRouter chi.Router) error {
testsRouter.Delete("/remove_fragment/data", func(w http.ResponseWriter, r *http.Request) {
sse := datastar.NewSSE(w, r)
sse.RemoveFragments("#remove")
})
return nil
}

View File

@ -5,5 +5,5 @@ import (
)
func TestKeyCasing(t *testing.T) {
setupLoadPageTest(t, "tests/key_casing")
setupPageTestOnLoad(t, "tests/key_casing")
}

View File

@ -0,0 +1,9 @@
package smoketests
import (
"testing"
)
func TestMergeFragment(t *testing.T) {
setupPageTestOnClick(t, "tests/merge_fragment")
}

View File

@ -4,6 +4,6 @@ import (
"testing"
)
func TestMergeFragment(t *testing.T) {
setupButtonPageTest(t, "tests/merge_fragment_signal")
func TestMergeFragmentSignal(t *testing.T) {
setupPageTestOnClick(t, "tests/merge_fragment_signal")
}

View File

@ -5,5 +5,5 @@ import (
)
func TestExampleOnLoad(t *testing.T) {
setupLoadPageTest(t, "tests/on_load")
setupPageTestOnLoad(t, "tests/on_load")
}

View File

@ -5,5 +5,5 @@ import (
)
func TestRef(t *testing.T) {
setupLoadPageTest(t, "tests/ref")
setupPageTestOnLoad(t, "tests/ref")
}

View File

@ -0,0 +1,9 @@
package smoketests
import (
"testing"
)
func TestRemoveFragment(t *testing.T) {
setupPageTestOnClick(t, "tests/remove_fragment")
}

View File

@ -65,7 +65,7 @@ func setupPageTest(t *testing.T, subURL string, gen func(runner runnerFn)) {
wg.Wait()
}
func setupButtonPageTest(t *testing.T, subURL string) {
func setupPageTestOnClick(t *testing.T, subURL string) {
setupPageTest(t, subURL, func(runner runnerFn) {
runner(subURL, func(t *testing.T, page *rod.Page) {
result := page.MustElement("#result")
@ -83,7 +83,7 @@ func setupButtonPageTest(t *testing.T, subURL string) {
})
}
func setupLoadPageTest(t *testing.T, subURL string) {
func setupPageTestOnLoad(t *testing.T, subURL string) {
setupPageTest(t, subURL, func(runner runnerFn) {
runner(subURL, func(t *testing.T, page *rod.Page) {
result := page.MustElement("#result")

View File

@ -5,5 +5,5 @@ import (
)
func TestExampleSignalsChangePath(t *testing.T) {
setupButtonPageTest(t, "tests/signals_change_path")
setupPageTestOnClick(t, "tests/signals_change_path")
}

View File

@ -5,5 +5,5 @@ import (
)
func TestExampleSignalsChange(t *testing.T) {
setupButtonPageTest(t, "tests/signals_change")
setupPageTestOnClick(t, "tests/signals_change")
}

View File

@ -0,0 +1,12 @@
# Merge Fregment
Tests that merging a fragment works.
<div>
<button data-on-click="@get('/tests/merge_fragment/data')" class="btn">Merge</button>
<hr />
Result:
<code id="result">0</code>
<hr />
Expected result on click: <code>1</code>
</div>

View File

@ -0,0 +1,12 @@
# Remove Fregment
Tests that removing a fragment works.
<div>
<button data-on-click="@delete('/tests/remove_fragment/data')" class="btn">Remove</button>
<hr />
Result:
<code id="result"><span id="remove">0</span>1</code>
<hr />
Expected result on click: <code>1</code>
</div>