cm-chessboard 8.12.4 → 8.12.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cm-chessboard",
3
- "version": "8.12.4",
3
+ "version": "8.12.6",
4
4
  "description": "A JavaScript chessboard which is lightweight, ES6 module based, responsive, SVG rendered and without dependencies.",
5
5
  "keywords": [
6
6
  "chess",
@@ -28,6 +28,33 @@ Removes markers from the board.
28
28
  Only set `type` to remove all markers of `type` from the board. Set `type` to `undefined`, to remove all types
29
29
  of markers from a square. Call without parameters to remove all markers from the board.
30
30
 
31
+ ## Marker type identity
32
+
33
+ Marker types are matched by **object reference**, not by structural
34
+ equality. Two type objects that only *look* the same are intentionally
35
+ treated as different types — this lets you have several visually
36
+ identical marker types that can be managed independently.
37
+
38
+ Always keep your marker types as module-level constants and pass the
39
+ **same reference** to `addMarker` and `removeMarkers`:
40
+
41
+ ```js
42
+ // ✅ works — same reference
43
+ const myType = {class: "marker-frame", slice: "markerFrame"}
44
+ board.addMarker(myType, "e4")
45
+ board.removeMarkers(myType) // removed
46
+
47
+ // ❌ silently does nothing — different reference, even though the
48
+ // object looks identical
49
+ board.addMarker({class: "marker-frame", slice: "markerFrame"}, "e4")
50
+ board.removeMarkers({class: "marker-frame", slice: "markerFrame"})
51
+ ```
52
+
53
+ The same applies to the exported `MARKER_TYPE.*` constants: import them
54
+ once and reuse that reference — don't clone them (e.g. via
55
+ `JSON.parse(JSON.stringify(...))` or a framework store that
56
+ deep-copies), or `removeMarkers` won't find a match.
57
+
31
58
  ## Create your own custom markers
32
59
 
33
60
  Just create an object like `const myMarker = {class: "markerCssClass", slice: "markerSliceId"}`, where `class` is the
@@ -246,7 +246,10 @@ export class PositionAnimationsQueue extends PromiseQueue {
246
246
 
247
247
  async enqueuePositionChange(positionFrom, positionTo, animated) {
248
248
  if(positionFrom.getFen() === positionTo.getFen()) {
249
- return Promise.resolve()
249
+ // No diff to animate. Still go through the queue so the promise
250
+ // resolves after any animations already in flight (e.g. an
251
+ // earlier movePiece from a drag). See issue #154.
252
+ return super.enqueue(() => Promise.resolve())
250
253
  } else {
251
254
  return super.enqueue(() => new Promise((resolve) => {
252
255
  let duration = animated ? this.chessboard.props.style.animationDuration : 0
@@ -69,6 +69,36 @@ describe("TestChessboard", () => {
69
69
  chessboard.destroy()
70
70
  })
71
71
 
72
+ // Regression for https://github.com/shaack/cm-chessboard/issues/154
73
+ //
74
+ // A setPosition() call with a null diff (positionFrom === positionTo)
75
+ // used to bypass the animation queue entirely and resolve on the next
76
+ // microtask. That's wrong when an earlier animation — here the animated
77
+ // movePiece — is still in the queue: the setPosition promise must wait
78
+ // for that to drain before resolving, otherwise callers following the
79
+ // "await setPosition(...); then continue" pattern run their
80
+ // continuation before the board is visually settled.
81
+ it("setPosition should wait for pending animations even on a null diff (#154)", async () => {
82
+ const chessboard = new Chessboard(document.getElementById("TestPosition"), {
83
+ assetsUrl: "../assets/",
84
+ position: FEN.start,
85
+ style: {animationDuration: 100}
86
+ })
87
+ let movePieceResolved = false
88
+ const movePromise = chessboard.movePiece("e2", "e4", true).then(() => {
89
+ movePieceResolved = true
90
+ })
91
+ // Same FEN as the position after movePiece → null diff inside
92
+ // setPosition. The animated movePiece above is still queued.
93
+ const targetFen = "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR"
94
+ const setPromise = chessboard.setPosition(targetFen, true).then(() => {
95
+ assert.equal(movePieceResolved, true,
96
+ "setPosition resolved before the pending movePiece animation finished")
97
+ })
98
+ await Promise.all([movePromise, setPromise])
99
+ chessboard.destroy()
100
+ })
101
+
72
102
  // Regression for a production crash: the ResizeObserver callback defers
73
103
  // handleResize() via setTimeout to avoid "ResizeObserver loop completed"
74
104
  // warnings. If destroy() is called between the observer firing and the