Repository: fabricjs/fabric.js
Pull request #10478 (2025-03-29 14:51:42)

refactor(): Remove custom triple click logic

## Description

While working on #10434 i hit some bug and issues with select all and other things, i found about event.details (!!!) and so figured out i can trash the custom triple click code.

Now tripleclick gets fired on every object, but after a doubleclick.
Before was an Itext/textbox internal gimmick.

Text beahiour should be unchanged.

SelectAll, SelectLine, SelectWord now they all behave consistently they just act on the selection data, while the user action behave consistently as well by updating the visual selection


## In Action

<!-- Add screenshots or recordings if necessary or requested -->
<!-- Are you proposing a performance change? show a some proof of performance -->


codesandbox[bot]: #### Review or Edit in CodeSandbox

Open the branch in <a href="https://codesandbox.io/p/github/fabricjs/fabric.js/remove-tripleclick-harness?mode=review&utm_source=gh_app">Web Editor</a> &bull; <a href="https://codesandbox.io/p/vscode?owner=fabricjs&repo=fabric.js&branch=remove-tripleclick-harness&utm_source=gh_app">VS Code</a> &bull; <a href="https://codesandbox.io/p/vscode?owner=fabricjs&repo=fabric.js&branch=remove-tripleclick-harness&insiders=true&utm_source=gh_app">Insiders</a><br>
<details>
<summary>Open Preview</summary>
<ul><li><a href="https://codesandbox.io/p/devtool/preview/fabricjs/fabric.js/remove-tripleclick-harness?task=next&port=3000&redirect=true&utm_source=gh_app">Run Next Template</a></li><li><a href="https://codesandbox.io/p/devtool/preview/fabricjs/fabric.js/remove-tripleclick-harness?task=node&port=8080&redirect=true&utm_source=gh_app">Run Node Template</a></li><li><a href="https://codesandbox.io/p/devtool/preview/fabricjs/fabric.js/remove-tripleclick-harness?task=vanilla&port=1234&redirect=true&utm_source=gh_app">Run Vanilla Template</a></li><li><a href="https://codesandbox.io/p/devtool/preview/fabricjs/fabric.js/remove-tripleclick-harness?task=vue&port=5173&redirect=true&utm_source=gh_app">Run Vue Template</a></li></ul>
</details>

<!-- open-in-codesandbox:complete -->

github-actions[bot]: <!-- BUILD STATS COMMENT -->
**Build Stats**

 | file / KB (diff) | bundled | minified | 
 | --- | --- | --- | 
 | fabric | 923.485 (**-0.756**) | 306.594 (**-0.490**) | 

asturur: Needs some test for the new logic, in jest.
github-actions[bot]: Coverage after merging <b>remove-tripleclick-harness</b> into <b>master</b> will be<table><tbody><tr><th>85.50%</th></tr></tbody></table>

<details><summary>Coverage Report</summary><table><tbody><tr><th>File</th><th>Stmts</th><th>Branches</th><th>Funcs</th><th>Lines</th><th>Uncovered Lines</th></tr><tr><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts'>fabric.ts</a></td><td><b>86.92%</b></td><td><b>20%</b></td><td><b>0%</b></td><td><b>95.79%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L10'>10</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L144'>144</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L144'>144</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L144'>144</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L144'>144</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L144'>144</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L190'>190</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L190'>190</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L190'>190</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L190'>190</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L190'>190</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L31'>31</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L33'>33</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L33'>33</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L33'>33</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L33'>33</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L33-L34'>33&ndash;34</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L34'>34</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L34'>34</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L34'>34</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L34'>34</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L39'>39</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/fabric.ts#L8'>8</a></td></tr><tr><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts'>index.node.ts</a></td><td><b>14.29%</b></td><td>100%</td><td><b>0%</b></td><td><b>25%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts#L23'>23</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts#L26'>26</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts#L29'>29</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts#L41'>41</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts#L44'>44</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/index.node.ts#L47'>47</a></td></tr><tr><td colspan='6'><b>extensions/aligning_guidelines/util</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/extensions/aligning_guidelines/util/basic.ts'>basic.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>extensions/data_updaters/origins</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/extensions/data_updaters/origins/index.ts'>index.ts</a></td><td><b>97.50%</b></td><td><b>75%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/extensions/data_updaters/origins/index.ts#L22-L23'>22&ndash;23</a></td></tr><tr><td colspan='6'><b>src</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/ClassRegistry.ts'>ClassRegistry.ts</a></td><td><b>92.54%</b></td><td><b>69.23%</b></td><td>100%</td><td><b>97.92%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/ClassRegistry.ts#L35'>35</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/ClassRegistry.ts#L56'>56</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts'>Collection.ts</a></td><td><b>75.29%</b></td><td><b>42.31%</b></td><td><b>51.61%</b></td><td><b>84.67%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L130'>130</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L153'>153</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L155-L157'>155&ndash;157</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L159'>159</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L167'>167</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L169-L170'>169&ndash;170</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L181'>181</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L197'>197</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L217'>217</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L228'>228</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L241'>241</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L243'>243</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L245'>245</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L252'>252</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L254'>254</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L263'>263</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L265'>265</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L270'>270</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L279'>279</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L281'>281</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L286-L287'>286&ndash;287</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L302'>302</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L304'>304</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L306'>306</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L309-L310'>309&ndash;310</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L327-L328'>327&ndash;328</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L328-L329'>328&ndash;329</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L333-L334'>333&ndash;334</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L337-L338'>337&ndash;338</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L338-L344'>338&ndash;344</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L346-L348'>346&ndash;348</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L350'>350</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L75'>75</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Collection.ts#L99'>99</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/CommonMethods.ts'>CommonMethods.ts</a></td><td><b>89.86%</b></td><td><b>69.23%</b></td><td><b>83.33%</b></td><td><b>96%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/CommonMethods.ts#L50'>50</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/CommonMethods.ts#L52'>52</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/CommonMethods.ts#L9'>9</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/EventTypeDefs.ts'>EventTypeDefs.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts'>Intersection.ts</a></td><td><b>82.32%</b></td><td><b>43.18%</b></td><td><b>73.33%</b></td><td><b>96.14%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L105'>105</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L132-L133'>132&ndash;133</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L166'>166</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L184-L190'>184&ndash;190</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L228'>228</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L228'>228</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L237'>237</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L239'>239</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L289-L291'>289&ndash;291</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L297'>297</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L297'>297</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L78'>78</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Intersection.ts#L80'>80</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts'>Observable.ts</a></td><td><b>74.59%</b></td><td><b>51.35%</b></td><td><b>31.25%</b></td><td><b>86.36%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L144'>144</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L153'>153</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L156'>156</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L168'>168</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L170'>170</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L172'>172</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L175'>175</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L41'>41</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L43'>43</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L68-L70'>68&ndash;70</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L72'>72</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L76'>76</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L78'>78</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L80'>80</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L82-L85'>82&ndash;85</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Observable.ts#L87-L91'>87&ndash;91</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts'>Point.ts</a></td><td><b>84.95%</b></td><td><b>62%</b></td><td><b>44.12%</b></td><td><b>92.68%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L104'>104</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L117'>117</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L148'>148</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L157'>157</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L179'>179</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L197'>197</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L206'>206</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L216'>216</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L225'>225</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L236-L239'>236&ndash;239</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L259'>259</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L284-L285'>284&ndash;285</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L294-L297'>294&ndash;297</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L328'>328</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L341'>341</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L349'>349</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L359'>359</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Point.ts#L95'>95</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts'>Shadow.ts</a></td><td><b>81.93%</b></td><td><b>15%</b></td><td><b>37.50%</b></td><td><b>90%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L139'>139</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L139-L140'>139&ndash;140</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L140-L141'>140&ndash;141</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L143'>143</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L145-L150'>145&ndash;150</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L159'>159</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L194'>194</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L196-L197'>196&ndash;197</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L199'>199</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L206'>206</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L206'>206</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L223-L230'>223&ndash;230</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L232'>232</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L232'>232</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Shadow.ts#L234-L235'>234&ndash;235</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/cache.ts'>cache.ts</a></td><td><b>86.75%</b></td><td><b>62.50%</b></td><td><b>75%</b></td><td><b>90.14%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/cache.ts#L57'>57</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/cache.ts#L59'>59</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/cache.ts#L71-L72'>71&ndash;72</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/cache.ts#L74-L77'>74&ndash;77</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts'>config.ts</a></td><td><b>82.63%</b></td><td><b>20%</b></td><td><b>44.44%</b></td><td><b>94.20%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L127'>127</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L135-L136'>135&ndash;136</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L138-L141'>138&ndash;141</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L143'>143</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L146-L147'>146&ndash;147</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L151'>151</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L156'>156</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L156'>156</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L156'>156</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L156'>156</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L156'>156</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/config.ts#L156'>156</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/constants.ts'>constants.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/typedefs.ts'>typedefs.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/LayoutManager</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/ActiveSelectionLayoutManager.ts'>ActiveSelectionLayoutManager.ts</a></td><td><b>85%</b></td><td><b>69.23%</b></td><td><b>28.57%</b></td><td>100%</td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/ActiveSelectionLayoutManager.ts#L43'>43</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutManager.ts'>LayoutManager.ts</a></td><td><b>90.38%</b></td><td><b>69.62%</b></td><td><b>53.85%</b></td><td><b>99.31%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutManager.ts#L279'>279</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutManager.ts#L344'>344</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutManager.ts#L355'>355</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/constants.ts'>constants.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts'>index.ts</a></td><td><b>48.57%</b></td><td><b>37.50%</b></td><td><b>80%</b></td><td><b>66.67%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L1'>1</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L1'>1</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L1-L2'>1&ndash;2</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L2'>2</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L2-L3'>2&ndash;3</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L3'>3</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L3-L4'>3&ndash;4</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L4'>4</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L4-L5'>4&ndash;5</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L5'>5</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L5'>5</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/index.ts#L5-L6'>5&ndash;6</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/types.ts'>types.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/LayoutManager/LayoutStrategies</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts'>ClipPathLayout.ts</a></td><td><b>72%</b></td><td><b>40%</b></td><td>100%</td><td><b>78.95%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts#L39'>39</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts#L41-L44'>41&ndash;44</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts#L46-L48'>46&ndash;48</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts#L54'>54</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts#L57-L58'>57&ndash;58</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts#L66-L69'>66&ndash;69</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/FitContentLayout.ts'>FitContentLayout.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/FixedLayout.ts'>FixedLayout.ts</a></td><td><b>85.71%</b></td><td><b>20%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/FixedLayout.ts#L23'>23</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/FixedLayout.ts#L23'>23</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts'>LayoutStrategy.ts</a></td><td><b>88.98%</b></td><td><b>64%</b></td><td><b>71.43%</b></td><td><b>97.67%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts#L54'>54</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts#L73'>73</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts#L75'>75</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts#L88'>88</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts'>utils.ts</a></td><td><b>62.90%</b></td><td><b>7.14%</b></td><td>100%</td><td><b>78.72%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L28-L32'>28&ndash;32</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L34-L35'>34&ndash;35</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L39'>39</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L39-L44'>39&ndash;44</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L47'>47</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L47'>47</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/LayoutManager/LayoutStrategies/utils.ts#L47'>47</a></td></tr><tr><td colspan='6'><b>src/Pattern</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts'>Pattern.ts</a></td><td><b>52.30%</b></td><td><b>2.94%</b></td><td><b>10%</b></td><td><b>63.08%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L105-L107'>105&ndash;107</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L113'>113</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L113-L114'>113&ndash;114</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L117'>117</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L117-L119'>117&ndash;119</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L119'>119</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L119-L122'>119&ndash;122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L130-L132'>130&ndash;132</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L132'>132</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L132'>132</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L132'>132</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L132'>132</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L132-L138'>132&ndash;138</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L140-L141'>140&ndash;141</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L143'>143</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L150'>150</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L150'>150</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L150'>150</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L150'>150</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L153-L160'>153&ndash;160</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L160'>160</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L160-L164'>160&ndash;164</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L174-L175'>174&ndash;175</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L175'>175</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L175'>175</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L175-L176'>175&ndash;176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L176-L182'>176&ndash;182</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L182'>182</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L182'>182</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L182-L183'>182&ndash;183</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L183'>183</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L183-L188'>183&ndash;188</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L190-L199'>190&ndash;199</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L203-L206'>203&ndash;206</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L209-L210'>209&ndash;210</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L212-L214'>212&ndash;214</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L216-L218'>216&ndash;218</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L218'>218</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L218-L221'>218&ndash;221</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L33'>33</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/Pattern.ts#L37'>37</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/index.ts'>index.ts</a></td><td><b>50%</b></td><td>100%</td><td>100%</td><td><b>50%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/index.ts#L2'>2</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/Pattern/types.ts'>types.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/brushes</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts'>BaseBrush.ts</a></td><td><b>79.19%</b></td><td><b>9.09%</b></td><td><b>14.29%</b></td><td><b>88.55%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L110'>110</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L114'>114</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L114-L115'>114&ndash;115</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L122'>122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L122'>122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L122'>122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L124-L125'>124&ndash;125</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L130'>130</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L135'>135</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L143'>143</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L146'>146</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L155'>155</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L155'>155</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L155'>155</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L155'>155</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L155-L160'>155&ndash;160</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/BaseBrush.ts#L99'>99</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts'>CircleBrush.ts</a></td><td><b>52.54%</b></td><td><b>14.29%</b></td><td><b>12.50%</b></td><td><b>58.25%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L100-L108'>100&ndash;108</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L108-L118'>108&ndash;118</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L122'>122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L130-L139'>130&ndash;139</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L55'>55</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L67'>67</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L69'>69</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L76'>76</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L76'>76</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L78-L79'>78&ndash;79</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L79'>79</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L83'>83</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L85-L86'>85&ndash;86</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/CircleBrush.ts#L92-L98'>92&ndash;98</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts'>PatternBrush.ts</a></td><td><b>44.12%</b></td><td><b>0%</b></td><td><b>0%</b></td><td><b>53.57%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L21'>21</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L25-L34'>25&ndash;34</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L36'>36</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L43'>43</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L43-L44'>43&ndash;44</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L51-L53'>51&ndash;53</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L53'>53</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L53-L54'>53&ndash;54</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L60-L64'>60&ndash;64</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L64'>64</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PatternBrush.ts#L64-L69'>64&ndash;69</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts'>PencilBrush.ts</a></td><td><b>42.18%</b></td><td><b>0%</b></td><td><b>0%</b></td><td><b>52.02%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L103'>103</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L116'>116</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L122'>122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L124'>124</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L129'>129</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L138-L139'>138&ndash;139</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L146'>146</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L146-L147'>146&ndash;147</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L147'>147</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L147-L152'>147&ndash;152</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L152'>152</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L152'>152</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L152'>152</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L155-L158'>155&ndash;158</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L167-L169'>167&ndash;169</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L176'>176</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L176-L177'>176&ndash;177</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L181-L185'>181&ndash;185</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L185'>185</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L185'>185</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L185'>185</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L188-L205'>188&ndash;205</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L215'>215</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L224-L232'>224&ndash;232</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L235-L238'>235&ndash;238</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L244'>244</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L244-L257'>244&ndash;257</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L257-L266'>257&ndash;266</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L274-L276'>274&ndash;276</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L276-L280'>276&ndash;280</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L280-L299'>280&ndash;299</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L54'>54</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L54'>54</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L68'>68</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L71'>71</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L71'>71</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L71-L72'>71&ndash;72</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L75'>75</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L84'>84</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L87'>87</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L87-L88'>87&ndash;88</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L88'>88</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L88'>88</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L91'>91</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L91'>91</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L91-L92'>91&ndash;92</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/PencilBrush.ts#L92'>92</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts'>SprayBrush.ts</a></td><td><b>52.25%</b></td><td><b>0%</b></td><td><b>0%</b></td><td><b>58.86%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L100'>100</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L107'>107</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L107'>107</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L107'>107</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L107-L112'>107&ndash;112</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L118-L120'>118&ndash;120</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L122'>122</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L128-L135'>128&ndash;135</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L137-L139'>137&ndash;139</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L141'>141</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L141'>141</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L141-L148'>141&ndash;148</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L148'>148</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L152'>152</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L157'>157</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L162'>162</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L164'>164</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L169-L170'>169&ndash;170</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L172'>172</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L180'>180</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L182'>182</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L185'>185</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L187'>187</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L195'>195</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L198-L200'>198&ndash;200</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L200'>200</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L200-L207'>200&ndash;207</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L207'>207</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L207-L210'>207&ndash;210</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L212'>212</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L22'>22</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L67'>67</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L85-L87'>85&ndash;87</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/SprayBrush.ts#L94-L99'>94&ndash;99</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/brushes/typedefs.ts'>typedefs.ts</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/canvas</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts'>Canvas.ts</a></td><td><b>76.19%</b></td><td><b>36.88%</b></td><td><b>87.50%</b></td><td><b>86.12%</b></td><td><a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1001-L1005'>1001&ndash;1005</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1029'>1029</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1031-L1034'>1031&ndash;1034</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1037'>1037</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1039'>1039</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1042'>1042</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1046'>1046</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1050-L1051'>1050&ndash;1051</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1056'>1056</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1095'>1095</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1095'>1095</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1100'>1100</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1102-L1107'>1102&ndash;1107</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1116'>1116</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1141-L1142'>1141&ndash;1142</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1160'>1160</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1163'>1163</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1165'>1165</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1167'>1167</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1172'>1172</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1174'>1174</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1177'>1177</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L124'>124</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1240-L1244'>1240&ndash;1244</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1278'>1278</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1286'>1286</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1323-L1327'>1323&ndash;1327</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1348'>1348</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1354'>1354</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1365'>1365</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1370-L1371'>1370&ndash;1371</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1371'>1371</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1375'>1375</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1375'>1375</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1381'>1381</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1417-L1434'>1417&ndash;1434</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1436-L1437'>1436&ndash;1437</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1437-L1453'>1437&ndash;1453</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1455'>1455</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1457-L1458'>1457&ndash;1458</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1460-L1462'>1460&ndash;1462</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1466'>1466</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1468'>1468</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1470-L1472'>1470&ndash;1472</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1475-L1480'>1475&ndash;1480</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1483-L1485'>1483&ndash;1485</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1488'>1488</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1490'>1490</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1504'>1504</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1511'>1511</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1513-L1524'>1513&ndash;1524</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1526'>1526</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1526-L1529'>1526&ndash;1529</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1529-L1530'>1529&ndash;1530</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1532-L1533'>1532&ndash;1533</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1537'>1537</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1537-L1538'>1537&ndash;1538</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1540-L1542'>1540&ndash;1542</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1545-L1547'>1545&ndash;1547</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L1550'>1550</a>, <a href='https://github.com/fabricjs/fabric.js/blob/c80c4d34c7caf533321e20b3b1ad27d84b6ef4dd/src/canvas/Canvas.ts#L193'>1

Patch:
diff --git a/.codesandbox/templates/vanilla/src/index.ts b/.codesandbox/templates/vanilla/src/index.ts
index 52d1f945f..390def753 100644
--- a/.codesandbox/templates/vanilla/src/index.ts
+++ b/.codesandbox/templates/vanilla/src/index.ts
@@ -1,6 +1,6 @@
 import * as fabric from 'fabric';
 import './styles.css';
-import { testCase } from './testcases/simpleTextbox';
+import { testCase } from './testcases/textbox-itext';
 
 const el = document.getElementById('canvas');
 const canvas = (window.canvas = new fabric.Canvas(el));
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76e2c1a8b..9681ca13a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## [next]
 
+- refactor(): Remove custom triple click logic [#10478](https://github.com/fabricjs/fabric.js/pull/10478)
 - chore(): Update qunit and nyc to latest [#10468](https://github.com/fabricjs/fabric.js/pull/10468)
 - fix(Fabtictext) Svg export for text on a path [#10284](https://github.com/fabricjs/fabric.js/pull/10284)
 - fix(FabricImage): add href parsing fixes for #10421 [#10465](https://github.com/fabricjs/fabric.js/pull/10465)
diff --git a/src/EventTypeDefs.ts b/src/EventTypeDefs.ts
index 155d989bc..758abd110 100644
--- a/src/EventTypeDefs.ts
+++ b/src/EventTypeDefs.ts
@@ -258,14 +258,33 @@ type TPointerEvents<Prefix extends string> = Record<
   `${Prefix}${
     | WithBeforeSuffix<'down'>
     | WithBeforeSuffix<'move'>
-    | 'dblclick'}`,
+    | 'dblclick'
+    | 'tripleclick'}`,
   TPointerEventInfo
 > &
+  Record<
+    `${Prefix}down`,
+    TPointerEventInfo & {
+      /**
+       * Indicates if the target or current target where already selected
+       * before the cycle of mouse down -> mouse up started
+       */
+      alreadySelected: boolean;
+    }
+  > &
   Record<
     `${Prefix}${WithBeforeSuffix<'up'>}`,
     TPointerEventInfo & {
       isClick: boolean;
+      /**
+       * The targets at the moment of mouseup that could be different from the
+       * target at the moment of mouse down in case of a drag action for example
+       */
       currentTarget?: FabricObject;
+      /**
+       * The subtargets at the moment of mouseup that could be different from the
+       * target at the moment of mouse down in case of a drag action for example
+       */
       currentSubTargets: FabricObject[];
     }
   > &
@@ -278,6 +297,7 @@ export type TPointerEventNames =
   | WithBeforeSuffix<'move'>
   | WithBeforeSuffix<'up'>
   | 'dblclick'
+  | 'tripleclick'
   | 'wheel';
 
 export type ObjectPointerEvents = TPointerEvents<'mouse'>;
@@ -351,3 +371,6 @@ export interface CanvasEvents
   'text:editing:entered': { target: IText } & Partial<TEvent>;
   'text:editing:exited': { target: IText };
 }
+
+export type TEventsExtraData = Record<PropertyKey, Record<PropertyKey, never>> &
+  Record<'down', { alreadySelected: boolean }>;
diff --git a/src/canvas/Canvas.ts b/src/canvas/Canvas.ts
index dc45759ab..496ce3baf 100644
--- a/src/canvas/Canvas.ts
+++ b/src/canvas/Canvas.ts
@@ -4,6 +4,7 @@ import type {
   CanvasEvents,
   DragEventData,
   ObjectEvents,
+  TEventsExtraData,
   TPointerEvent,
   TPointerEventNames,
   Transform,
@@ -110,6 +111,12 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
    */
   private declare _dropTarget: FabricObject<ObjectEvents> | undefined;
 
+  /**
+   * a boolean that keeps track of the click state during a cycle of mouse down/up.
+   * If a mouse move occurs it becomes false.
+   * Is true by default, turns false on mouse move.
+   * Used to determine if a mouseUp is a click
+   */
   private _isClick: boolean;
 
   textEditingManager = new TextEditingManager(this);
@@ -134,7 +141,7 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
         '_onMouseOut',
         '_onMouseEnter',
         '_onContextMenu',
-        '_onDoubleClick',
+        '_onClick',
         '_onDragStart',
         '_onDragEnd',
         '_onDragProgress',
@@ -174,7 +181,9 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
     functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);
     functor(canvasElement, 'wheel', this._onMouseWheel);
     functor(canvasElement, 'contextmenu', this._onContextMenu);
-    functor(canvasElement, 'dblclick', this._onDoubleClick);
+    functor(canvasElement, 'click', this._onClick);
+    // decide if to remove in fabric 7.0
+    functor(canvasElement, 'dblclick', this._onClick);
     functor(canvasElement, 'dragstart', this._onDragStart);
     functor(canvasElement, 'dragend', this._onDragEnd);
     functor(canvasElement, 'dragover', this._onDragOver);
@@ -544,9 +553,12 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
    * @private
    * @param {Event} e Event object fired on mousedown
    */
-  private _onDoubleClick(e: TPointerEvent) {
+  private _onClick(e: TPointerEvent) {
+    const clicks = e.detail;
+    if (clicks > 3 || clicks < 2) return;
     this._cacheTransformEventData(e);
-    this._handleEvent(e, 'dblclick');
+    clicks == 2 && e.type === 'dblclick' && this._handleEvent(e, 'dblclick');
+    clicks == 3 && this._handleEvent(e, 'tripleclick');
     this._resetTransformEventData();
   }
 
@@ -911,7 +923,11 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
    * @param {TPointerEvent} e event from mouse
    * @param {TPointerEventNames} eventType
    */
-  _handleEvent<T extends TPointerEventNames>(e: TPointerEvent, eventType: T) {
+  _handleEvent<T extends TPointerEventNames>(
+    e: TPointerEvent,
+    eventType: T,
+    extraData?: TEventsExtraData[T],
+  ) {
     const target = this._target,
       targets = this.targets || [],
       options: CanvasEvents[`mouse:${T}`] = {
@@ -928,6 +944,9 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
               currentSubTargets: this.targets,
             }
           : {}),
+        ...(eventType === 'down:before' || eventType === 'down'
+          ? extraData
+          : {}),
       } as CanvasEvents[`mouse:${T}`];
     this.fire(`mouse:${eventType}`, options);
     // this may be a little be more complicated of what we want to handle
@@ -951,7 +970,7 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
     const pointer = this.getScenePoint(e);
     this.freeDrawingBrush &&
       this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });
-    this._handleEvent(e, 'down');
+    this._handleEvent(e, 'down', { alreadySelected: false });
   }
 
   /**
@@ -1004,13 +1023,15 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
     this._handleEvent(e, 'down:before');
 
     let target: FabricObject | undefined = this._target;
-
+    let alreadySelected = !!target && target === this._activeObject;
     // if right/middle click just fire events
     const { button } = e as MouseEvent;
     if (button) {
       ((this.fireMiddleClick && button === 1) ||
         (this.fireRightClick && button === 2)) &&
-        this._handleEvent(e, 'down');
+        this._handleEvent(e, 'down', {
+          alreadySelected,
+        });
       this._resetTransformEventData();
       return;
     }
@@ -1061,8 +1082,9 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
       };
     }
 
+    // check again because things could have changed
+    alreadySelected = !!target && target === this._activeObject;
     if (target) {
-      const alreadySelected = target === this._activeObject;
       if (target.selectable && target.activeOn === 'down') {
         this.setActiveObject(target, e);
       }
@@ -1089,7 +1111,7 @@ export class Canvas extends SelectableCanvas implements CanvasOptions {
     //  we clear `_objectsToRender` in case of a change in order to repopulate it at rendering
     //  run before firing the `down` event to give the dev a chance to populate it themselves
     shouldRender && (this._objectsToRender = undefined);
-    this._handleEvent(e, 'down');
+    this._handleEvent(e, 'down', { alreadySelected: alreadySelected });
     // we must renderAll so that we update the visuals
     shouldRender && this.requestRenderAll();
   }
diff --git a/src/shapes/IText/ITextBehavior.ts b/src/shapes/IText/ITextBehavior.ts
index ad22afab3..8ff8c6c3c 100644
--- a/src/shapes/IText/ITextBehavior.ts
+++ b/src/shapes/IText/ITextBehavior.ts
@@ -1,8 +1,4 @@
-import type {
-  ObjectEvents,
-  TPointerEvent,
-  TPointerEventInfo,
-} from '../../EventTypeDefs';
+import type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';
 import { Point } from '../../Point';
 import type { FabricObject } from '../Object/FabricObject';
 import { FabricText } from '../Text/Text';
@@ -34,7 +30,6 @@ const reNonWord = /[ \n\.,;!\?\-]/;
 export type ITextEvents = ObjectEvents & {
   'selection:changed': never;
   changed: never | { index: number; action: string };
-  tripleclick: TPointerEventInfo;
   'editing:entered': never | { e: TPointerEvent };
   'editing:exited': never;
 };
@@ -70,6 +65,10 @@ export abstract class ITextBehavior<
   private declare _textBeforeEdit: string;
   protected declare __selectionStartOnMouseDown: number;
 
+  /**
+   * Keeps track if the IText object was selected before the actual click.
+   * This because we want to delay enter editing by a click.
+   */
   protected declare selected: boolean;
   protected declare cursorOffsetCache: { left?: number; top?: number };
   protected declare _savedProps?: {
@@ -224,6 +223,14 @@ export abstract class ITextBehavior<
     return this;
   }
 
+  /**
+   * Selects entire text and updates the visual state
+   */
+  cmdAll() {
+    this.selectAll();
+    this.renderCursorOrSelection();
+  }
+
   /**
    * Returns selected text
    * @return {String}
@@ -342,12 +349,11 @@ export abstract class ITextBehavior<
   }
 
   /**
-   * TODO fix: selectionStart set as 0 will be ignored?
-   * Selects a word based on the index
+   * Selects the word that contains the char at index selectionStart
    * @param {Number} selectionStart Index of a character
    */
   selectWord(selectionStart?: number) {
-    selectionStart = selectionStart || this.selectionStart;
+    selectionStart = selectionStart ?? this.selectionStart;
     // search backwards
     const newSelectionStart = this.searchWordBoundary(selectionStart, -1),
       // search forward
@@ -360,16 +366,16 @@ export abstract class ITextBehavior<
     this.selectionEnd = newSelectionEnd;
     this._fireSelectionChanged();
     this._updateTextarea();
+    // remove next major, for now it renders twice :(
     this.renderCursorOrSelection();
   }
 
   /**
-   * TODO fix: selectionStart set as 0 will be ignored?
-   * Selects a line based on the index
+   * Selects the line that contains selectionStart
    * @param {Number} selectionStart Index of a character
    */
   selectLine(selectionStart?: number) {
-    selectionStart = selectionStart || this.selectionStart;
+    selectionStart = selectionStart ?? this.selectionStart;
     const newSelectionStart = this.findLineBoundaryLeft(selectionStart),
       newSelectionEnd = this.findLineBoundaryRight(selectionStart);
 
@@ -377,7 +383,6 @@ export abstract class ITextBehavior<
     this.selectionEnd = newSelectionEnd;
     this._fireSelectionChanged();
     this._updateTextarea();
-    return this;
   }
 
   /**
diff --git a/src/shapes/IText/ITextClickBehavior.ts b/src/shapes/IText/ITextClickBehavior.ts
index 224e90c32..0b8fd2b69 100644
--- a/src/shapes/IText/ITextClickBehavior.ts
+++ b/src/shapes/IText/ITextClickBehavior.ts
@@ -1,7 +1,9 @@
-import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs';
-import type { XY } from '../../Point';
+import type {
+  ObjectPointerEvents,
+  TPointerEvent,
+  TPointerEventInfo,
+} from '../../EventTypeDefs';
 import { Point } from '../../Point';
-import { stopEvent } from '../../util/dom_event';
 import { invertTransform } from '../../util/misc/matrix';
 import { DraggableTextDelegate } from './DraggableTextDelegate';
 import type { ITextEvents } from './ITextBehavior';
@@ -19,28 +21,14 @@ export abstract class ITextClickBehavior<
   SProps extends SerializedTextProps = SerializedTextProps,
   EventSpec extends ITextEvents = ITextEvents,
 > extends ITextKeyBehavior<Props, SProps, EventSpec> {
-  private declare __lastSelected: boolean;
-  private declare __lastClickTime: number;
-  private declare __lastLastClickTime: number;
-  private declare __lastPointer: XY | Record<string, never>;
-  private declare __newClickTime: number;
-
   protected draggableTextDelegate: DraggableTextDelegate;
 
   initBehavior() {
     // Initializes event handlers related to cursor or selection
     this.on('mousedown', this._mouseDownHandler);
-    this.on('mousedown:before', this._mouseDownHandlerBefore);
     this.on('mouseup', this.mouseUpHandler);
     this.on('mousedblclick', this.doubleClickHandler);
-    this.on('tripleclick', this.tripleClickHandler);
-
-    // Initializes "dbclick" event handler
-    this.__lastClickTime = +new Date();
-    // for triple click
-    this.__lastLastClickTime = +new Date();
-    this.__lastPointer = {};
-    this.on('mousedown', this.onMouseDown);
+    this.on('mousetripleclick', this.tripleClickHandler);
 
     this.draggableTextDelegate = new DraggableTextDelegate(
       this as unknown as IText,
@@ -77,35 +65,6 @@ export abstract class ITextClickBehavior<
     return this.draggableTextDelegate.canDrop(e);
   }
 
-  /**
-   * Default event handler to simulate triple click
-   * @private
-   */
-  onMouseDown(options: TPointerEventInfo) {
-    if (!this.canvas) {
-      return;
-    }
-    this.__newClickTime = +new Date();
-    const newPointer = options.pointer;
-    if (this.isTripleClick(newPointer)) {
-      this.fire('tripleclick', options);
-      stopEvent(options.e);
-    }
-    this.__lastLastClickTime = this.__lastClickTime;
-    this.__lastClickTime = this.__newClickTime;
-    this.__lastPointer = newPointer;
-    this.__lastSelected = this.selected && !this.getActiveControl();
-  }
-
-  isTripleClick(newPointer: XY) {
-    return (
-      this.__newClickTime - this.__lastClickTime < 500 &&
-      this.__lastClickTime - this.__lastLastClickTime < 500 &&
-      this.__lastPointer.x === newPointer.x &&
-      this.__lastPointer.y === newPointer.y
-    );
-  }
-
   /**
    * Default handler for double click, select a word
    */
@@ -114,6 +73,7 @@ export abstract class ITextClickBehavior<
       return;
     }
     this.selectWord(this.getSelectionStartFromPointer(options.e));
+    this.renderCursorOrSelection();
   }
 
   /**
@@ -124,6 +84,7 @@ export abstract class ITextClickBehavior<
       return;
     }
     this.selectLine(this.getSelectionStartFromPointer(options.e));
+    this.renderCursorOrSelection();
   }
 
   /**
@@ -134,7 +95,7 @@ export abstract class ITextClickBehavior<
    * initializing a mousedDown on a text area will cancel fabricjs knowledge of
    * current compositionMode. It will be set to false.
    */
-  _mouseDownHandler({ e }: TPointerEventInfo) {
+  _mouseDownHandler({ e, alreadySelected }: ObjectPointerEvents['mousedown']) {
     if (
       !this.canvas ||
       !this.editable ||
@@ -150,7 +111,7 @@ export abstract class ITextClickBehavior<
 
     this.canvas.textEditingManager.register(this);
 
-    if (this.selected) {
+    if (alreadySelected) {
       this.inCompositionMode = false;
       this.setCursorByClick(e);
     }
@@ -162,28 +123,16 @@ export abstract class ITextClickBehavior<
       }
       this.renderCursorOrSelection();
     }
-  }
-
-  /**
-   * Default event handler for the basic functionalities needed on mousedown:before
-   * can be overridden to do something different.
-   * Scope of this implementation is: verify the object is already selected when mousing down
-   */
-  _mouseDownHandlerBefore({ e }: TPointerEventInfo) {
-    if (!this.canvas || !this.editable || notALeftClick(e)) {
-      return;
-    }
-    // we want to avoid that an object that was selected and then becomes unselectable,
-    // may trigger editing mode in some way.
-    this.selected = this === this.canvas._activeObject;
+    this.selected ||= alreadySelected || this.isEditing;
   }
 
   /**
    * standard handler for mouse up, overridable
    * @private
    */
-  mouseUpHandler({ e, transform }: TPointerEventInfo) {
+  mouseUpHandler({ e, transform }: ObjectPointerEvents['mouseup']) {
     const didDrag = this.draggableTextDelegate.end(e);
+
     if (this.canvas) {
       this.canvas.textEditingManager.unregister(this);
 
@@ -195,6 +144,7 @@ export abstract class ITextClickBehavior<
         return;
       }
     }
+
     if (
       !this.editable ||
       (this.group && !this.group.interactive) ||
@@ -205,17 +155,13 @@ export abstract class ITextClickBehavior<
       return;
     }
 
-    if (this.__lastSelected && !this.getActiveControl()) {
-      this.selected = false;
-      this.__lastSelected = false;
+    if (this.selected && !this.getActiveControl()) {
       this.enterEditing(e);
       if (this.selectionStart === this.selectionEnd) {
         this.initDelayedCursor(true);
       } else {
         this.renderCursorOrSelection();
       }
-    } else {
-      this.selected = true;
     }
   }
 
diff --git a/src/shapes/IText/ITextKeyBehavior.ts b/src/shapes/IText/ITextKeyBehavior.ts
index 054250d74..5a1b1b9b2 100644
--- a/src/shapes/IText/ITextKeyBehavior.ts
+++ b/src/shapes/IText/ITextKeyBehavior.ts
@@ -173,6 +173,7 @@ export abstract class ITextKeyBehavior<
    */
   onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {
     const fromPaste = this.fromPaste;
+    const { value, selectionStart, selectionEnd } = this.hiddenTextarea;
     this.fromPaste = false;
     e && e.stopPropagation();
     if (!this.isEditing) {
@@ -192,14 +193,12 @@ export abstract class ITextKeyBehavior<
       return;
     }
     // decisions about style changes.
-    const nextText = this._splitTextIntoLines(
-        this.hiddenTextarea.value,
-      ).graphemeText,
+    const nextText = this._splitTextIntoLines(value).graphemeText,
       charCount = this._text.length,
       nextCharCount = nextText.length,
-      selectionStart = this.selectionStart,
-      selectionEnd = this.selectionEnd,
-      selection = selectionStart !== selectionEnd;
+      _selectionStart = this.selectionStart,
+      _selectionEnd = this.selectionEnd,
+      selection = _selectionStart !== _selectionEnd;
     let copiedStyle: TextStyleDeclaration[] | undefined,
       removedText,
       charDiff = nextCharCount - charCount,
@@ -207,22 +206,22 @@ export abstract class ITextKeyBehavior<
       removeTo;
 
     const textareaSelection = this.fromStringToGraphemeSelection(
-      this.hiddenTextarea.selectionStart,
-      this.hiddenTextarea.selectionEnd,
-      this.hiddenTextarea.value,
+      selectionStart,
+      selectionEnd,
+      value,
     );
-    const backDelete = selectionStart > textareaSelection.selectionStart;
+    const backDelete = _selectionStart > textareaSelection.selectionStart;
 
     if (selection) {
-      removedText = this._text.slice(selectionStart, selectionEnd);
-      charDiff += selectionEnd - selectionStart;
+      removedText = this._text.slice(_selectionStart, _selectionEnd);
+      charDiff += _selectionEnd - _selectionStart;
     } else if (nextCharCount < charCount) {
       if (backDelete) {
-        removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);
+        removedText = this._text.slice(_selectionEnd + charDiff, _selectionEnd);
       } else {
         removedText = this._text.slice(
-          selectionStart,
-          selectionStart - charDiff,
+          _selectionStart,
+          _selectionStart - charDiff,
         );
       }
     }
@@ -236,8 +235,8 @@ export abstract class ITextKeyBehavior<
         // we want to copy the style before the cursor OR the style at the cursor if selection
         // is bigger than 0.
         copiedStyle = this.getSelectionStyles(
-          selectionStart,
-          selectionStart + 1,
+          _selectionStart,
+          _selectionStart + 1,
           false,
         );
         // now duplicate the style one for each inserted text.
@@ -249,15 +248,15 @@ export abstract class ITextKeyBehavior<
         );
       }
       if (selection) {
-        removeFrom = selectionStart;
-        removeTo = selectionEnd;
+        removeFrom = _selectionStart;
+        removeTo = _selectionEnd;
       } else if (backDelete) {
         // detect differences between forwardDelete and backDelete
-        removeFrom = selectionEnd - removedText.length;
-        removeTo = selectionEnd;
+        removeFrom = _selectionEnd - removedText.length;
+        removeTo = _selectionEnd;
       } else {
-        removeFrom = selectionEnd;
-        removeTo = selectionEnd + removedText.length;
+        removeFrom = _selectionEnd;
+        removeTo = _selectionEnd + removedText.length;
       }
       this.removeStyleFromTo(removeFrom, removeTo);
     }
@@ -270,7 +269,7 @@ export abstract class ITextKeyBehavior<
       ) {
         copiedStyle = copyPasteData.copiedTextStyle;
       }
-      this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);
+      this.insertNewStyleBlock(insertedText, _selectionStart, copiedStyle);
     }
     updateAndFire();
   }
diff --git a/src/shapes/IText/constants.ts b/src/shapes/IText/constants.ts
index c50bfc402..960453e06 100644
--- a/src/shapes/IText/constants.ts
+++ b/src/shapes/IText/constants.ts
@@ -11,7 +11,7 @@ export type CursorHandlingMethods =
   | 'exitEditing'
   | 'copy'
   | 'cut'
-  | 'selectAll';
+  | 'cmdAll';
 
 const MOVE_CURSOR_UP: CursorHandlingMethods = 'moveCursorUp';
 const MOVE_CURSOR_DOWN: CursorHandlingMethods = 'moveCursorDown';
@@ -61,5 +61,5 @@ export const ctrlKeysMapUp: TKeyMapIText = {
  * For functionalities on keyDown + ctrl || cmd
  */
 export const ctrlKeysMapDown: TKeyMapIText = {
-  65: 'selectAll',
+  65: 'cmdAll',
 };


Test patch:
diff --git a/.codesandbox/templates/vanilla/src/testcases/textbox-itext.ts b/.codesandbox/templates/vanilla/src/testcases/textbox-itext.ts
new file mode 100644
index 000000000..346b53493
--- /dev/null
+++ b/.codesandbox/templates/vanilla/src/testcases/textbox-itext.ts
@@ -0,0 +1,13 @@
+import * as fabric from 'fabric';
+
+export function testCase(canvas: fabric.Canvas) {
+  const textValue = 'Lorem ipsum dolor sit amet consecutrioeioreieo';
+  const text = new fabric.Textbox(textValue, {
+    width: 200,
+    top: 20,
+    fill: '',
+    stroke: 'red',
+  });
+  canvas.add(text);
+  canvas.centerObjectH(text);
+}
diff --git a/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap b/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap
index 696591c9e..d12aef3f1 100644
--- a/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap
+++ b/src/canvas/__tests__/__snapshots__/eventData.test.ts.snap
@@ -458,6 +458,7 @@ exports[`Canvas event data HTML event "mousedown" should fire a corresponding ca
         "x": -30,
         "y": -13,
       },
+      "alreadySelected": false,
       "e": MouseEvent {
         "isTrusted": false,
       },
diff --git a/src/canvas/__tests__/eventData.test.ts b/src/canvas/__tests__/eventData.test.ts
index f4f8347d2..d562a3150 100644
--- a/src/canvas/__tests__/eventData.test.ts
+++ b/src/canvas/__tests__/eventData.test.ts
@@ -54,9 +54,13 @@ describe('Canvas event data', () => {
     'HTML event "%s" should fire a corresponding canvas event',
     (type) => {
       canvas.setViewportTransform(genericVpt);
-      canvas
-        .getSelectionElement()
-        .dispatchEvent(new MouseEvent(type, { clientX: 50, clientY: 50 }));
+      canvas.getSelectionElement().dispatchEvent(
+        new MouseEvent(type, {
+          clientX: 50,
+          clientY: 50,
+          detail: type === 'dblclick' ? 2 : undefined,
+        }),
+      );
       expect(spy.mock.calls).toMatchSnapshot(snapshotOptions);
     },
   );
diff --git a/src/shapes/IText/IText.test.ts b/src/shapes/IText/IText.test.ts
index 14d132a5d..9f78ba2b4 100644
--- a/src/shapes/IText/IText.test.ts
+++ b/src/shapes/IText/IText.test.ts
@@ -1,4 +1,4 @@
-import type { Canvas } from '../../canvas/Canvas';
+import { Canvas } from '../../canvas/Canvas';
 import '../../../jest.extend';
 import { Group } from '../Group';
 import { IText } from './IText';
@@ -40,4 +40,15 @@ describe('IText', () => {
       },
     );
   });
+  describe('Interaction with mouse and editing', () => {
+    it('_mouseDownHandlerBefore set up selected property', () => {
+      const iText = new IText('test need some word\nsecond line');
+      iText.canvas = new Canvas();
+      expect(iText.selected).toBe(undefined);
+      iText._mouseDownHandler({ e: { button: 0 }, alreadySelected: false });
+      expect(iText.selected).toBe(false);
+      iText._mouseDownHandler({ e: {}, alreadySelected: true });
+      expect(iText.selected).toBe(true);
+    });
+  });
 });
diff --git a/src/shapes/IText/ITextBehavior.test.ts b/src/shapes/IText/ITextBehavior.test.ts
index b54514c95..780c5d01e 100644
--- a/src/shapes/IText/ITextBehavior.test.ts
+++ b/src/shapes/IText/ITextBehavior.test.ts
@@ -187,7 +187,7 @@ describe('IText _tick', () => {
     iText.enterEditing();
     expect(_tickMock).toHaveBeenCalledWith();
     _tickMock.mockClear();
-    iText.__lastSelected = true;
+    iText.selected = true;
     iText.mouseUpHandler({
       e: {
         button: 0,
diff --git a/test/unit/canvas_events.js b/test/unit/canvas_events.js
index c7b6d2608..83cfa272c 100644
--- a/test/unit/canvas_events.js
+++ b/test/unit/canvas_events.js
@@ -571,6 +571,9 @@
       event.initEvent(eventType, true, true);
       event.clientX = 5;
       event.clientY = 5;
+      if (eventType === 'dblclick') {
+        event.detail = 2;
+      }
       c.upperCanvasEl.dispatchEvent(event);
       assert.equal(counter, 1, eventname + ' fabric event fired');
       assert.equal(target, rect, eventname + ' on canvas has rect as a target');
diff --git a/test/unit/itext.js b/test/unit/itext.js
index 67708de91..4a5106835 100644
--- a/test/unit/itext.js
+++ b/test/unit/itext.js
@@ -445,7 +445,6 @@
       assert.equal(iText.selectionStart, 17); // |qux|
       assert.equal(iText.selectionEnd, 20);
 
-      assert.equal(iText.selectLine(0), iText, 'should be chainable');
     });
 
     QUnit.test('findWordBoundaryLeft', function(assert) {
diff --git a/test/unit/itext_click_behaviour.js b/test/unit/itext_click_behaviour.js
index 35c6dd362..18c82d91c 100644
--- a/test/unit/itext_click_behaviour.js
+++ b/test/unit/itext_click_behaviour.js
@@ -118,15 +118,6 @@
       assert.equal(iText.getSelectionStartFromPointer(eventData), 5, 'index');
       assert.equal(iText.getSelectionStartFromPointer({ ...eventData, clientY: 20 }), 5, 'index');
     });
-    QUnit.test('_mouseDownHandlerBefore set up selected property', function (assert) {
-      var iText = new fabric.IText('test need some word\nsecond line');
-      assert.equal(iText.selected, undefined, 'iText has no selected property');
-      canvas.setActiveObject(iText);
-      iText.canvas = canvas;
-      iText._mouseDownHandlerBefore({ e: {} });
-      assert.equal(iText.selected, true, 'iText has selected property');
-      assert.equal(iText.__lastSelected, undefined, 'iText has no __lastSelected property');
-    });
     QUnit.test('mouse down aborts cursor animation', function (assert) {
       var iText = new fabric.IText('test need some word\nsecond line', { canvas });
       assert.ok(typeof iText._animateCursor === 'function', 'method is defined');
@@ -139,17 +130,6 @@
       assert.equal(animate, 1, 'called from enterEditing');
       assert.equal(aborted, 1, 'called from render');
     });
-    QUnit.test('_mouseUpHandler set selected as true', function (assert) {
-      var iText = new fabric.IText('test');
-      iText.initDelayedCursor = function () { };
-      iText.renderCursorOrSelection = function () { };
-      assert.equal(iText.selected, undefined, 'iText has no selected property');
-      assert.equal(iText.__lastSelected, undefined, 'iText has no __lastSelected property');
-      canvas.setActiveObject(iText);
-      iText.canvas = canvas;
-      iText.mouseUpHandler({ e: {} });
-      assert.equal(iText.selected, true, 'iText has selected property');
-    });
     QUnit.test('_mouseUpHandler on a selected object enter edit', function (assert) {
       var iText = new fabric.IText('test');
       iText.initDelayedCursor = function () { };