diff --git a/CHANGELOG.md b/CHANGELOG.md index c0d05115..695abcf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## 9.3.21 (not released) +## 9.3.22 (2025-07-08) + +- Fixed possible crash on `node.to()` method + +## 9.3.21 (2025-07-07) - Fixed memory leaks on Tween destroy - Fixed incorrect export of stage/layer when internal nodes used buffer canvas for rendering - Fixed incorrect render of cached node when buffer canvas is used - Fixed incorrect path lenth calculations +- Fixed `pointerleave` bubbling +- Added `pointerleave` event in `Stage` ## 9.3.20 (2025-03-20) diff --git a/package.json b/package.json index 77ad4079..d34289cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "konva", - "version": "9.3.20", + "version": "9.3.22", "description": "HTML5 2d canvas library.", "author": "Anton Lavrenov", "files": [ diff --git a/src/Stage.ts b/src/Stage.ts index 71ce4910..7c03a85b 100644 --- a/src/Stage.ts +++ b/src/Stage.ts @@ -58,6 +58,7 @@ const STAGE = 'Stage', [POINTERMOVE, '_pointermove'], [POINTERUP, '_pointerup'], [POINTERCANCEL, '_pointercancel'], + [POINTERLEAVE, '_pointerleave'], [LOSTPOINTERCAPTURE, '_lostpointercapture'], ]; diff --git a/src/Tween.ts b/src/Tween.ts index c1d61b78..b744e914 100644 --- a/src/Tween.ts +++ b/src/Tween.ts @@ -530,11 +530,13 @@ export class Tween { delete Tween.attrs[nodeId][thisId]; // Clean up parent objects if empty - if (Object.keys(Tween.tweens[nodeId]).length === 0) { - delete Tween.tweens[nodeId]; - } - if (Object.keys(Tween.attrs[nodeId]).length === 0) { - delete Tween.attrs[nodeId]; + if (Tween.tweens[nodeId]) { + if (Object.keys(Tween.tweens[nodeId]).length === 0) { + delete Tween.tweens[nodeId]; + } + if (Object.keys(Tween.attrs[nodeId]).length === 0) { + delete Tween.attrs[nodeId]; + } } } } diff --git a/test/unit/Stage-test.ts b/test/unit/Stage-test.ts index c3d48f73..1a309a48 100644 --- a/test/unit/Stage-test.ts +++ b/test/unit/Stage-test.ts @@ -1223,6 +1223,19 @@ describe('Stage', function () { assert.equal(count, 2); }); + it('stage pointerleave should fire when leaving stage', function () { + var stage = addStage(); + + var stageLeave = 0; + stage.on('pointerleave', function () { + stageLeave += 1; + }); + + stage.fire('pointerleave', undefined, false); + + assert.equal(stageLeave, 1, 'stage pointerleave should fire'); + }); + it('stage pointerleave should not fire when leaving a child', function () { var stage = addStage(); var layer = new Konva.Layer(); diff --git a/test/unit/Tween-test.ts b/test/unit/Tween-test.ts index 0b0321fc..dc076029 100644 --- a/test/unit/Tween-test.ts +++ b/test/unit/Tween-test.ts @@ -257,6 +257,34 @@ describe('Tween', function () { }); }); + it('to method double simple usage', function (done) { + var stage = addStage(); + + let finishCount = 0; + const onFinish = () => { + if (finishCount === 2) { + done(); + } + }; + stage.to({ + x: 10, + duration: 0.001, + onFinish: () => { + assert(stage.x() === 10); + finishCount += 1; + onFinish(); + }, + }); + stage.to({ + y: 10, + duration: 0.001, + onFinish: () => { + finishCount += 1; + onFinish(); + }, + }); + }); + it('tween to call update callback', function (done) { var stage = addStage(); var updateCount = 0; @@ -303,6 +331,8 @@ describe('Tween', function () { line.to({ points: [100, 100, 200, 100, 200, 200, 100, 200], + // add another attribute for better test of cleanup + x: 10, duration: 0.1, onFinish: function () { assert.deepEqual(