fabric 6.7.1 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/index.js +120 -92
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.min.js +1 -1
  5. package/dist/index.min.js.map +1 -1
  6. package/dist/index.min.mjs +1 -1
  7. package/dist/index.min.mjs.map +1 -1
  8. package/dist/index.mjs +120 -92
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/index.node.cjs +120 -92
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.mjs +120 -92
  13. package/dist/index.node.mjs.map +1 -1
  14. package/dist/package.json.min.mjs +1 -1
  15. package/dist/package.json.mjs +1 -1
  16. package/dist/src/cache.d.ts +6 -4
  17. package/dist/src/cache.d.ts.map +1 -1
  18. package/dist/src/cache.min.mjs +1 -1
  19. package/dist/src/cache.min.mjs.map +1 -1
  20. package/dist/src/cache.mjs +16 -14
  21. package/dist/src/cache.mjs.map +1 -1
  22. package/dist/src/canvas/Canvas.d.ts.map +1 -1
  23. package/dist/src/canvas/Canvas.min.mjs +1 -1
  24. package/dist/src/canvas/Canvas.min.mjs.map +1 -1
  25. package/dist/src/canvas/Canvas.mjs +6 -1
  26. package/dist/src/canvas/Canvas.mjs.map +1 -1
  27. package/dist/src/canvas/SelectableCanvas.d.ts +1 -1
  28. package/dist/src/canvas/SelectableCanvas.d.ts.map +1 -1
  29. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  30. package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
  31. package/dist/src/canvas/SelectableCanvas.mjs +1 -7
  32. package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
  33. package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
  34. package/dist/src/canvas/StaticCanvas.min.mjs +1 -1
  35. package/dist/src/canvas/StaticCanvas.min.mjs.map +1 -1
  36. package/dist/src/canvas/StaticCanvas.mjs +10 -5
  37. package/dist/src/canvas/StaticCanvas.mjs.map +1 -1
  38. package/dist/src/color/Color.d.ts.map +1 -1
  39. package/dist/src/color/Color.min.mjs +1 -1
  40. package/dist/src/color/Color.min.mjs.map +1 -1
  41. package/dist/src/color/Color.mjs +3 -2
  42. package/dist/src/color/Color.mjs.map +1 -1
  43. package/dist/src/color/constants.d.ts +26 -20
  44. package/dist/src/color/constants.d.ts.map +1 -1
  45. package/dist/src/color/constants.min.mjs +1 -1
  46. package/dist/src/color/constants.min.mjs.map +1 -1
  47. package/dist/src/color/constants.mjs +28 -22
  48. package/dist/src/color/constants.mjs.map +1 -1
  49. package/dist/src/gradient/parser/parseCoords.d.ts.map +1 -1
  50. package/dist/src/gradient/parser/parseCoords.min.mjs +1 -1
  51. package/dist/src/gradient/parser/parseCoords.min.mjs.map +1 -1
  52. package/dist/src/gradient/parser/parseCoords.mjs +5 -4
  53. package/dist/src/gradient/parser/parseCoords.mjs.map +1 -1
  54. package/dist/src/parser/percent.d.ts +7 -2
  55. package/dist/src/parser/percent.d.ts.map +1 -1
  56. package/dist/src/parser/percent.min.mjs +1 -1
  57. package/dist/src/parser/percent.min.mjs.map +1 -1
  58. package/dist/src/parser/percent.mjs +9 -4
  59. package/dist/src/parser/percent.mjs.map +1 -1
  60. package/dist/src/shapes/IText/ITextKeyBehavior.d.ts.map +1 -1
  61. package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs +1 -1
  62. package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs.map +1 -1
  63. package/dist/src/shapes/IText/ITextKeyBehavior.mjs +2 -1
  64. package/dist/src/shapes/IText/ITextKeyBehavior.mjs.map +1 -1
  65. package/dist/src/shapes/Text/Text.d.ts +8 -0
  66. package/dist/src/shapes/Text/Text.d.ts.map +1 -1
  67. package/dist/src/shapes/Text/Text.min.mjs +1 -1
  68. package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
  69. package/dist/src/shapes/Text/Text.mjs +38 -30
  70. package/dist/src/shapes/Text/Text.mjs.map +1 -1
  71. package/dist/src/util/internals/cleanupSvgAttribute.d.ts.map +1 -1
  72. package/dist/src/util/internals/cleanupSvgAttribute.min.mjs +1 -1
  73. package/dist/src/util/internals/cleanupSvgAttribute.min.mjs.map +1 -1
  74. package/dist/src/util/internals/cleanupSvgAttribute.mjs +3 -2
  75. package/dist/src/util/internals/cleanupSvgAttribute.mjs.map +1 -1
  76. package/dist/src/util/internals/normalizeWhiteSpace.d.ts +2 -0
  77. package/dist/src/util/internals/normalizeWhiteSpace.d.ts.map +1 -0
  78. package/dist/src/util/internals/normalizeWhiteSpace.min.mjs +2 -0
  79. package/dist/src/util/internals/normalizeWhiteSpace.min.mjs.map +1 -0
  80. package/dist/src/util/internals/normalizeWhiteSpace.mjs +4 -0
  81. package/dist/src/util/internals/normalizeWhiteSpace.mjs.map +1 -0
  82. package/dist-extensions/src/cache.d.ts +6 -4
  83. package/dist-extensions/src/cache.d.ts.map +1 -1
  84. package/dist-extensions/src/canvas/Canvas.d.ts.map +1 -1
  85. package/dist-extensions/src/canvas/SelectableCanvas.d.ts +1 -1
  86. package/dist-extensions/src/canvas/SelectableCanvas.d.ts.map +1 -1
  87. package/dist-extensions/src/canvas/StaticCanvas.d.ts.map +1 -1
  88. package/dist-extensions/src/color/Color.d.ts.map +1 -1
  89. package/dist-extensions/src/color/constants.d.ts +26 -20
  90. package/dist-extensions/src/color/constants.d.ts.map +1 -1
  91. package/dist-extensions/src/gradient/parser/parseCoords.d.ts.map +1 -1
  92. package/dist-extensions/src/parser/percent.d.ts +7 -2
  93. package/dist-extensions/src/parser/percent.d.ts.map +1 -1
  94. package/dist-extensions/src/shapes/IText/ITextKeyBehavior.d.ts.map +1 -1
  95. package/dist-extensions/src/shapes/Text/Text.d.ts +8 -0
  96. package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
  97. package/dist-extensions/src/util/internals/cleanupSvgAttribute.d.ts.map +1 -1
  98. package/dist-extensions/src/util/internals/normalizeWhiteSpace.d.ts +2 -0
  99. package/dist-extensions/src/util/internals/normalizeWhiteSpace.d.ts.map +1 -0
  100. package/package.json +2 -2
  101. package/src/cache.spec.ts +74 -0
  102. package/src/cache.ts +20 -18
  103. package/src/canvas/Canvas-events.spec.ts +1667 -0
  104. package/src/canvas/Canvas.ts +7 -1
  105. package/src/canvas/SelectableCanvas.ts +2 -2
  106. package/src/canvas/StaticCanvas.ts +4 -9
  107. package/src/color/Color.ts +3 -2
  108. package/src/color/constants.ts +28 -22
  109. package/src/gradient/parser/parseCoords.ts +5 -6
  110. package/src/parser/percent.ts +10 -6
  111. package/src/shapes/IText/ITextKeyBehavior.ts +1 -0
  112. package/src/shapes/Text/Text.ts +41 -45
  113. package/src/util/internals/cleanupSvgAttribute.ts +7 -5
  114. package/src/util/internals/normalizeWhiteSpace.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [next]
4
+
5
+ ## [6.9.0]
6
+
7
+ - fix(): Prototype pollution risk on text char cache [#10782](https://github.com/fabricjs/fabric.js/pull/10782)
8
+
9
+ ## [6.8.0]
10
+
11
+ - fix(): CWE-1333 CWE-400 CWE-730 Simplify some regexes in order to avoid slowness with craft bad string #10746
12
+ - fix(): CWE-1333 CWE-400 CWE-730 in Text.ts regex #10745
13
+ - fix(StaticCanvas): After executing loadFromJSON, it unexpectedly adds an objects property to the canvas. #10741
14
+ - fix(textarea): A form field element has neither an id nor a name attribute. #10172
15
+ - fix(Canvas): The mouse enter and leave events of child elements will be executed twice. #10699
16
+ - chore(): Remove mouse wheel console warning by setting default explicitly. #10712
17
+ - fix(): fix rendering of text when line height is set to 0 #10785
18
+
3
19
  ## [6.7.1]
4
20
 
5
21
  - fix(SVGParser): Corrected CSS rule parsing for multiple style tags. [#10688](https://github.com/fabricjs/fabric.js/issues/10683)
package/dist/index.js CHANGED
@@ -337,11 +337,11 @@
337
337
  };
338
338
 
339
339
  class Cache {
340
+ /**
341
+ * Cache of widths of chars in text rendering.
342
+ */
343
+
340
344
  constructor() {
341
- /**
342
- * Cache of widths of chars in text rendering.
343
- */
344
- _defineProperty(this, "charWidthsCache", {});
345
345
  /**
346
346
  * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.
347
347
  * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing
@@ -351,7 +351,9 @@
351
351
  * It was an internal variable, is accessible since version 2.3.4
352
352
  */
353
353
  _defineProperty(this, "boundsOfCurveCache", {});
354
+ this.charWidthsCache = new Map();
354
355
  }
356
+
355
357
  /**
356
358
  * @return {Object} reference to cache
357
359
  */
@@ -362,15 +364,16 @@
362
364
  fontWeight
363
365
  } = _ref;
364
366
  fontFamily = fontFamily.toLowerCase();
365
- if (!this.charWidthsCache[fontFamily]) {
366
- this.charWidthsCache[fontFamily] = {};
367
+ const cache = this.charWidthsCache;
368
+ if (!cache.has(fontFamily)) {
369
+ cache.set(fontFamily, new Map());
367
370
  }
368
- const fontCache = this.charWidthsCache[fontFamily];
371
+ const fontCache = cache.get(fontFamily);
369
372
  const cacheKey = "".concat(fontStyle.toLowerCase(), "_").concat((fontWeight + '').toLowerCase());
370
- if (!fontCache[cacheKey]) {
371
- fontCache[cacheKey] = {};
373
+ if (!fontCache.has(cacheKey)) {
374
+ fontCache.set(cacheKey, new Map());
372
375
  }
373
- return fontCache[cacheKey];
376
+ return fontCache.get(cacheKey);
374
377
  }
375
378
 
376
379
  /**
@@ -385,11 +388,10 @@
385
388
  * @param {String} [fontFamily] font family to clear
386
389
  */
387
390
  clearFontCache(fontFamily) {
388
- fontFamily = (fontFamily || '').toLowerCase();
389
391
  if (!fontFamily) {
390
- this.charWidthsCache = {};
391
- } else if (this.charWidthsCache[fontFamily]) {
392
- delete this.charWidthsCache[fontFamily];
392
+ this.charWidthsCache = new Map();
393
+ } else {
394
+ this.charWidthsCache.delete((fontFamily || '').toLowerCase());
393
395
  }
394
396
  }
395
397
 
@@ -411,7 +413,7 @@
411
413
  }
412
414
  const cache = new Cache();
413
415
 
414
- var version = "6.7.1";
416
+ var version = "6.9.0";
415
417
 
416
418
  // use this syntax so babel plugin see this import here
417
419
  const VERSION = version;
@@ -2255,6 +2257,8 @@
2255
2257
  viewportTransform: [...iMatrix]
2256
2258
  };
2257
2259
 
2260
+ const _excluded$j = ["objects"];
2261
+
2258
2262
  /**
2259
2263
  * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset
2260
2264
  * Better try to restrict with types to avoid confusion.
@@ -3272,9 +3276,12 @@
3272
3276
  }
3273
3277
 
3274
3278
  // parse json if it wasn't already
3275
- const serialized = typeof json === 'string' ? JSON.parse(json) : json;
3279
+ const _ref2 = typeof json === 'string' ? JSON.parse(json) : json,
3280
+ {
3281
+ objects = []
3282
+ } = _ref2,
3283
+ serialized = _objectWithoutProperties(_ref2, _excluded$j);
3276
3284
  const {
3277
- objects = [],
3278
3285
  backgroundImage,
3279
3286
  background,
3280
3287
  overlayImage,
@@ -3294,8 +3301,8 @@
3294
3301
  clipPath
3295
3302
  }, {
3296
3303
  signal
3297
- })]).then(_ref2 => {
3298
- let [enlived, enlivedMap] = _ref2;
3304
+ })]).then(_ref3 => {
3305
+ let [enlived, enlivedMap] = _ref3;
3299
3306
  this.clear();
3300
3307
  this.add(...enlived);
3301
3308
  this.set(serialized);
@@ -3893,6 +3900,8 @@
3893
3900
  return moveX || moveY;
3894
3901
  };
3895
3902
 
3903
+ const normalizeWs = value => value.replace(/\s+/g, ' ');
3904
+
3896
3905
  /**
3897
3906
  * Map of the 148 color names with HEX code
3898
3907
  * @see: https://www.w3.org/TR/css3-color/#svg-color
@@ -4052,6 +4061,10 @@
4052
4061
  * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`)
4053
4062
  * Also matching rgba(r g b / a) as per new specs
4054
4063
  * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb
4064
+ *
4065
+ * In order to avoid performance issues, you have to clean the input string for this regex from multiple spaces before.
4066
+ * ex: colorString.replace(/\s+/g, ' ');
4067
+ *
4055
4068
  * Formal syntax at the time of writing:
4056
4069
  * <rgb()> =
4057
4070
  * rgb( [ <percentage> | none ]{3} [ / [ <alpha-value> | none ] ]? ) |
@@ -4063,35 +4076,35 @@
4063
4076
  *
4064
4077
  * /^ # Beginning of the string
4065
4078
  * rgba? # "rgb" or "rgba"
4066
- * \(\s* # Opening parenthesis and optional whitespace
4079
+ * \(\s? # Opening parenthesis and zero or one whitespace character
4067
4080
  * (\d{0,3} # 0 to three digits R channel
4068
4081
  * (?:\.\d+)? # Optional decimal with one or more digits
4069
4082
  * ) # End of capturing group for the first color component
4070
4083
  * %? # Optional percent sign after the first color component
4071
- * \s* # Optional whitespace
4084
+ * \s? # Zero or one whitespace character
4072
4085
  * [\s|,] # Separator between color components can be a space or comma
4073
- * \s* # Optional whitespace
4086
+ * \s? # Zero or one whitespace character
4074
4087
  * (\d{0,3} # 0 to three digits G channel
4075
4088
  * (?:\.\d+)? # Optional decimal with one or more digits
4076
4089
  * ) # End of capturing group for the second color component
4077
4090
  * %? # Optional percent sign after the second color component
4078
- * \s* # Optional whitespace
4091
+ * \s? # Zero or one whitespace character
4079
4092
  * [\s|,] # Separator between color components can be a space or comma
4080
- * \s* # Optional whitespace
4093
+ * \s? # Zero or one whitespace character
4081
4094
  * (\d{0,3} # 0 to three digits B channel
4082
4095
  * (?:\.\d+)? # Optional decimal with one or more digits
4083
4096
  * ) # End of capturing group for the third color component
4084
4097
  * %? # Optional percent sign after the third color component
4085
- * \s* # Optional whitespace
4098
+ * \s? # Zero or one whitespace character
4086
4099
  * (?: # Beginning of non-capturing group for alpha value
4087
- * \s* # Optional whitespace
4100
+ * \s? # Zero or one whitespace character
4088
4101
  * [,/] # Comma or slash separator for alpha value
4089
- * \s* # Optional whitespace
4102
+ * \s? # Zero or one whitespace character
4090
4103
  * (\d{0,3} # Zero to three digits
4091
4104
  * (?:\.\d+)? # Optional decimal with one or more digits
4092
4105
  * ) # End of capturing group for alpha value
4093
4106
  * %? # Optional percent sign after alpha value
4094
- * \s* # Optional whitespace
4107
+ * \s? # Zero or one whitespace character
4095
4108
  * )? # End of non-capturing group for alpha value (optional)
4096
4109
  * \) # Closing parenthesis
4097
4110
  * $ # End of the string
@@ -4101,12 +4114,14 @@
4101
4114
  * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color.
4102
4115
  * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us
4103
4116
  */
4104
- const reRGBa = () => /^rgba?\(\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d{0,3}(?:\.\d+)?%?)\s*)?\)$/i;
4117
+ const reRGBa = () => /^rgba?\(\s?(\d{0,3}(?:\.\d+)?%?)\s?[\s|,]\s?(\d{0,3}(?:\.\d+)?%?)\s?[\s|,]\s?(\d{0,3}(?:\.\d+)?%?)\s?(?:\s?[,/]\s?(\d{0,3}(?:\.\d+)?%?)\s?)?\)$/i;
4105
4118
 
4106
4119
  /**
4107
- * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))
4108
- * Also matching rgba(r g b / a) as per new specs
4120
+ * Regex matching color in HSL or HSLA formats (ex: hsl(0deg 0%, 0%), hsla(160, 100, 10, 0.5), hsla( 180 , 100 , 10 , 0.5 ), hsl(1,1,1))
4121
+ * Also matching hsla(h s l / a) as per new specs
4109
4122
  * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl
4123
+ * In order to avoid performance issues, you have to clean the input string for this regex from multiple spaces before.
4124
+ * ex: colorString.replace(/\s+/g, ' ');
4110
4125
  * Formal syntax at the time of writing:
4111
4126
  * <hsl()> =
4112
4127
  * hsl( [ <hue> | none ] [ <percentage> | none ] [ <percentage> | none ] [ / [ <alpha-value> | none ] ]? )
@@ -4123,30 +4138,30 @@
4123
4138
  * Regular expression for matching an hsla or hsl CSS color value
4124
4139
  *
4125
4140
  * /^hsla?\( // Matches the beginning of the string and the opening parenthesis of "hsl" or "hsla"
4126
- * \s* // Matches any whitespace characters (space, tab, etc.) zero or more times
4141
+ * \s? // Matches any whitespace character (space, tab, etc.) zero or one time
4127
4142
  * (\d{0,3} // Hue: 0 to three digits - start capture in a group
4128
4143
  * (?:\.\d+)? // Hue: Optional (non capture group) decimal with one or more digits.
4129
4144
  * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad
4130
4145
  * ) // Hue: End capture group
4131
- * \s* // Matches any whitespace characters zero or more times
4146
+ * \s? // Matches any whitespace character zero or one time
4132
4147
  * [\s|,] // Matches a space, tab or comma
4133
- * \s* // Matches any whitespace characters zero or more times
4148
+ * \s? // Matches any whitespace character zero or one time
4134
4149
  * (\d{0,3} // Saturation: 0 to three digits - start capture in a group
4135
4150
  * (?:\.\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group
4136
4151
  * %?) // Saturation: match optional % character and end capture group
4137
- * \s* // Matches any whitespace characters zero or more times
4152
+ * \s? // Matches any whitespace character zero or one time
4138
4153
  * [\s|,] // Matches a space, tab or comma
4139
- * \s* // Matches any whitespace characters zero or more times
4154
+ * \s? // Matches any whitespace character zero or one time
4140
4155
  * (\d{0,3} // Lightness: 0 to three digits - start capture in a group
4141
4156
  * (?:\.\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group
4142
4157
  * %?) // Lightness: match % character and end capture group
4143
- * \s* // Matches any whitespace characters zero or more times
4158
+ * \s? // Matches any whitespace character zero or one time
4144
4159
  * (?: // Alpha: Begins a non-capturing group for the alpha value
4145
- * \s* // Matches any whitespace characters zero or more times
4160
+ * \s? // Matches any whitespace character zero or one time
4146
4161
  * [,/] // Matches a comma or forward slash
4147
- * \s* // Matches any whitespace characters zero or more times
4162
+ * \s? // Matches any whitespace character zero or one time
4148
4163
  * (\d*(?:\.\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group
4149
- * \s* // Matches any whitespace characters zero or more times
4164
+ * \s? // Matches any whitespace character zero or one time
4150
4165
  * )? // Makes the alpha value group optional
4151
4166
  * \) // Matches the closing parenthesis
4152
4167
  * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode
@@ -4154,7 +4169,7 @@
4154
4169
  * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color.
4155
4170
  * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us.
4156
4171
  */
4157
- const reHSLa = () => /^hsla?\(\s*([+-]?\d{0,3}(?:\.\d+)?(?:deg|turn|rad)?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d*(?:\.\d+)?%?)\s*)?\)$/i;
4172
+ const reHSLa = () => /^hsla?\(\s?([+-]?\d{0,3}(?:\.\d+)?(?:deg|turn|rad)?)\s?[\s|,]\s?(\d{0,3}(?:\.\d+)?%?)\s?[\s|,]\s?(\d{0,3}(?:\.\d+)?%?)\s?(?:\s?[,/]\s?(\d*(?:\.\d+)?%?)\s?)?\)$/i;
4158
4173
 
4159
4174
  /**
4160
4175
  * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)
@@ -4436,7 +4451,7 @@
4436
4451
  * @return {TRGBAColorSource | undefined} source
4437
4452
  */
4438
4453
  static sourceFromRgb(color) {
4439
- const match = color.match(reRGBa());
4454
+ const match = normalizeWs(color).match(reRGBa());
4440
4455
  if (match) {
4441
4456
  const [r, g, b] = match.slice(1, 4).map(value => {
4442
4457
  const parsedValue = parseFloat(value);
@@ -4477,7 +4492,7 @@
4477
4492
  * @see http://http://www.w3.org/TR/css3-color/#hsl-color
4478
4493
  */
4479
4494
  static sourceFromHsl(color) {
4480
- const match = color.match(reHSLa());
4495
+ const match = normalizeWs(color).match(reHSLa());
4481
4496
  if (!match) {
4482
4497
  return;
4483
4498
  }
@@ -10600,9 +10615,9 @@
10600
10615
  };
10601
10616
 
10602
10617
  const regex$1 = new RegExp("(".concat(reNum, ")"), 'gi');
10603
- const cleanupSvgAttribute = attributeValue => attributeValue.replace(regex$1, ' $1 ')
10618
+ const cleanupSvgAttribute = attributeValue => normalizeWs(attributeValue.replace(regex$1, ' $1 ')
10604
10619
  // replace annoying commas and arbitrary whitespace with single spaces
10605
- .replace(/,/gi, ' ').replace(/\s+/gi, ' ');
10620
+ .replace(/,/gi, ' '));
10606
10621
 
10607
10622
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10608
10623
 
@@ -13429,17 +13444,11 @@
13429
13444
  */
13430
13445
  _defineProperty(this, "targets", []);
13431
13446
  /**
13432
- * hold the list of nested targets hovered
13447
+ * hold the list of nested targets hovered in the previous events
13433
13448
  * @type FabricObject[]
13434
13449
  * @private
13435
13450
  */
13436
13451
  _defineProperty(this, "_hoveredTargets", []);
13437
- /**
13438
- * hold the list of objects to render
13439
- * @type FabricObject[]
13440
- * @private
13441
- */
13442
- _defineProperty(this, "_objectsToRender", void 0);
13443
13452
  /**
13444
13453
  * hold a reference to a data structure that contains information
13445
13454
  * on the current on going transform
@@ -14591,7 +14600,9 @@
14591
14600
  functor(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions);
14592
14601
  functor(canvasElement, "".concat(eventTypePrefix, "out"), this._onMouseOut);
14593
14602
  functor(canvasElement, "".concat(eventTypePrefix, "enter"), this._onMouseEnter);
14594
- functor(canvasElement, 'wheel', this._onMouseWheel);
14603
+ functor(canvasElement, 'wheel', this._onMouseWheel, {
14604
+ passive: false
14605
+ });
14595
14606
  functor(canvasElement, 'contextmenu', this._onContextMenu);
14596
14607
  functor(canvasElement, 'click', this._onClick);
14597
14608
  // decide if to remove in fabric 7.0
@@ -15464,6 +15475,9 @@
15464
15475
  fireCanvas: true
15465
15476
  });
15466
15477
  for (let i = 0; i < length; i++) {
15478
+ if (targets[i] === target || _hoveredTargets[i] && _hoveredTargets[i] === _hoveredTarget) {
15479
+ continue;
15480
+ }
15467
15481
  this.fireSyntheticInOutEvents('mouse', {
15468
15482
  e,
15469
15483
  target: targets[i],
@@ -15811,15 +15825,20 @@
15811
15825
  return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value;
15812
15826
  };
15813
15827
 
15814
- const RE_PERCENT = /^(\d+\.\d+)%|(\d+)%$/;
15828
+ /**
15829
+ * Will loosely accept as percent numbers that are not like
15830
+ * 3.4a%. This function does not check for the correctness of a percentage
15831
+ * but it checks that values that are in theory correct are or arent percentages
15832
+ */
15815
15833
  function isPercent(value) {
15816
- return value && RE_PERCENT.test(value);
15834
+ // /%$/ Matches strings that end with a percent sign (%)
15835
+ return value && /%$/.test(value) && Number.isFinite(parseFloat(value));
15817
15836
  }
15818
15837
 
15819
15838
  /**
15820
- *
15839
+ * Parse a percentage value in an svg.
15821
15840
  * @param value
15822
- * @param valueIfNaN
15841
+ * @param fallback in case of not possible to parse the number
15823
15842
  * @returns ∈ [0, 1]
15824
15843
  */
15825
15844
  function parsePercent(value, valueIfNaN) {
@@ -15877,15 +15896,16 @@
15877
15896
  gradientUnits
15878
15897
  } = _ref;
15879
15898
  let finalValue;
15880
- return Object.keys(valuesToConvert).reduce((acc, prop) => {
15881
- const propValue = valuesToConvert[prop];
15899
+ return Object.entries(valuesToConvert).reduce((acc, _ref2) => {
15900
+ let [prop, propValue] = _ref2;
15882
15901
  if (propValue === 'Infinity') {
15883
15902
  finalValue = 1;
15884
15903
  } else if (propValue === '-Infinity') {
15885
15904
  finalValue = 0;
15886
15905
  } else {
15887
- finalValue = typeof propValue === 'string' ? parseFloat(propValue) : propValue;
15888
- if (typeof propValue === 'string' && isPercent(propValue)) {
15906
+ const isString = typeof propValue === 'string';
15907
+ finalValue = isString ? parseFloat(propValue) : propValue;
15908
+ if (isString && isPercent(propValue)) {
15889
15909
  finalValue *= 0.01;
15890
15910
  if (gradientUnits === 'pixels') {
15891
15911
  // then we need to fix those percentages here in svg parsing
@@ -19302,6 +19322,7 @@
19302
19322
  let drawStart;
19303
19323
  let currentColor;
19304
19324
  let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');
19325
+ const bgHeight = this.getHeightOfLineImpl(i);
19305
19326
  for (let j = 0; j < jlen; j++) {
19306
19327
  // at this point charbox are either standard or full with pathInfo if there is a path.
19307
19328
  const charBox = this.__charBounds[i][j];
@@ -19311,7 +19332,7 @@
19311
19332
  ctx.translate(charBox.renderLeft, charBox.renderTop);
19312
19333
  ctx.rotate(charBox.angle);
19313
19334
  ctx.fillStyle = currentColor;
19314
- currentColor && ctx.fillRect(-charBox.width / 2, -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction), charBox.width, heightOfLine / this.lineHeight);
19335
+ currentColor && ctx.fillRect(-charBox.width / 2, -bgHeight * (1 - this._fontSizeFraction), charBox.width, bgHeight);
19315
19336
  ctx.restore();
19316
19337
  } else if (currentColor !== lastColor) {
19317
19338
  drawStart = leftOffset + lineLeftOffset + boxStart;
@@ -19319,7 +19340,7 @@
19319
19340
  drawStart = this.width - drawStart - boxWidth;
19320
19341
  }
19321
19342
  ctx.fillStyle = lastColor;
19322
- lastColor && ctx.fillRect(drawStart, lineTopOffset, boxWidth, heightOfLine / this.lineHeight);
19343
+ lastColor && ctx.fillRect(drawStart, lineTopOffset, boxWidth, bgHeight);
19323
19344
  boxStart = charBox.left;
19324
19345
  boxWidth = charBox.width;
19325
19346
  lastColor = currentColor;
@@ -19333,7 +19354,7 @@
19333
19354
  drawStart = this.width - drawStart - boxWidth;
19334
19355
  }
19335
19356
  ctx.fillStyle = currentColor;
19336
- ctx.fillRect(drawStart, lineTopOffset, boxWidth, heightOfLine / this.lineHeight);
19357
+ ctx.fillRect(drawStart, lineTopOffset, boxWidth, bgHeight);
19337
19358
  }
19338
19359
  lineTopOffset += heightOfLine;
19339
19360
  }
@@ -19360,14 +19381,14 @@
19360
19381
  stylesAreEqual = previousChar && fontDeclaration === this._getFontDeclaration(prevCharStyle),
19361
19382
  fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE;
19362
19383
  let width, coupleWidth, previousWidth, kernedWidth;
19363
- if (previousChar && fontCache[previousChar] !== undefined) {
19364
- previousWidth = fontCache[previousChar];
19384
+ if (previousChar && fontCache.has(previousChar)) {
19385
+ previousWidth = fontCache.get(previousChar);
19365
19386
  }
19366
- if (fontCache[_char] !== undefined) {
19367
- kernedWidth = width = fontCache[_char];
19387
+ if (fontCache.has(_char)) {
19388
+ kernedWidth = width = fontCache.get(_char);
19368
19389
  }
19369
- if (stylesAreEqual && fontCache[couple] !== undefined) {
19370
- coupleWidth = fontCache[couple];
19390
+ if (stylesAreEqual && fontCache.has(couple)) {
19391
+ coupleWidth = fontCache.get(couple);
19371
19392
  kernedWidth = coupleWidth - previousWidth;
19372
19393
  }
19373
19394
  if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {
@@ -19376,16 +19397,16 @@
19376
19397
  this._setTextStyles(ctx, charStyle, true);
19377
19398
  if (width === undefined) {
19378
19399
  kernedWidth = width = ctx.measureText(_char).width;
19379
- fontCache[_char] = width;
19400
+ fontCache.set(_char, width);
19380
19401
  }
19381
19402
  if (previousWidth === undefined && stylesAreEqual && previousChar) {
19382
19403
  previousWidth = ctx.measureText(previousChar).width;
19383
- fontCache[previousChar] = previousWidth;
19404
+ fontCache.set(previousChar, previousWidth);
19384
19405
  }
19385
19406
  if (stylesAreEqual && coupleWidth === undefined) {
19386
19407
  // we can measure the kerning couple and subtract the width of the previous character
19387
19408
  coupleWidth = ctx.measureText(couple).width;
19388
- fontCache[couple] = coupleWidth;
19409
+ fontCache.set(couple, coupleWidth);
19389
19410
  // safe to use the non-null since if undefined we defined it before.
19390
19411
  kernedWidth = coupleWidth - previousWidth;
19391
19412
  }
@@ -19542,13 +19563,16 @@
19542
19563
  }
19543
19564
 
19544
19565
  /**
19545
- * Calculate height of line at 'lineIndex'
19566
+ * Calculate height of line at 'lineIndex',
19567
+ * without the lineHeigth multiplication factor
19568
+ * @private
19546
19569
  * @param {Number} lineIndex index of line to calculate
19547
19570
  * @return {Number}
19548
19571
  */
19549
- getHeightOfLine(lineIndex) {
19550
- if (this.__lineHeights[lineIndex]) {
19551
- return this.__lineHeights[lineIndex];
19572
+ getHeightOfLineImpl(lineIndex) {
19573
+ const lh = this.__lineHeights;
19574
+ if (lh[lineIndex]) {
19575
+ return lh[lineIndex];
19552
19576
  }
19553
19577
 
19554
19578
  // char 0 is measured before the line cycle because it needs to char
@@ -19557,18 +19581,25 @@
19557
19581
  for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) {
19558
19582
  maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);
19559
19583
  }
19560
- return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;
19584
+ return lh[lineIndex] = maxHeight * this._fontSizeMult;
19585
+ }
19586
+
19587
+ /**
19588
+ * Calculate height of line at 'lineIndex'
19589
+ * @param {Number} lineIndex index of line to calculate
19590
+ * @return {Number}
19591
+ */
19592
+ getHeightOfLine(lineIndex) {
19593
+ return this.getHeightOfLineImpl(lineIndex) * this.lineHeight;
19561
19594
  }
19562
19595
 
19563
19596
  /**
19564
19597
  * Calculate text box height
19565
19598
  */
19566
19599
  calcTextHeight() {
19567
- let lineHeight,
19568
- height = 0;
19600
+ let height = 0;
19569
19601
  for (let i = 0, len = this._textLines.length; i < len; i++) {
19570
- lineHeight = this.getHeightOfLine(i);
19571
- height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;
19602
+ height += i === len - 1 ? this.getHeightOfLineImpl(i) : this.getHeightOfLine(i);
19572
19603
  }
19573
19604
  return height;
19574
19605
  }
@@ -19600,11 +19631,8 @@
19600
19631
  const left = this._getLeftOffset(),
19601
19632
  top = this._getTopOffset();
19602
19633
  for (let i = 0, len = this._textLines.length; i < len; i++) {
19603
- const heightOfLine = this.getHeightOfLine(i),
19604
- maxHeight = heightOfLine / this.lineHeight,
19605
- leftOffset = this._getLineLeftOffset(i);
19606
- this._renderTextLine(method, ctx, this._textLines[i], left + leftOffset, top + lineHeights + maxHeight, i);
19607
- lineHeights += heightOfLine;
19634
+ this._renderTextLine(method, ctx, this._textLines[i], left + this._getLineLeftOffset(i), top + lineHeights + this.getHeightOfLineImpl(i), i);
19635
+ lineHeights += this.getHeightOfLine(i);
19608
19636
  }
19609
19637
  ctx.restore();
19610
19638
  }
@@ -19649,8 +19677,7 @@
19649
19677
  * @param {Number} lineIndex
19650
19678
  */
19651
19679
  _renderChars(method, ctx, line, left, top, lineIndex) {
19652
- const lineHeight = this.getHeightOfLine(lineIndex),
19653
- isJustify = this.textAlign.includes(JUSTIFY),
19680
+ const isJustify = this.textAlign.includes(JUSTIFY),
19654
19681
  path = this.path,
19655
19682
  shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path,
19656
19683
  isLtr = this.direction === 'ltr',
@@ -19671,7 +19698,7 @@
19671
19698
  ctx.direction = isLtr ? 'ltr' : 'rtl';
19672
19699
  ctx.textAlign = isLtr ? LEFT : RIGHT;
19673
19700
  }
19674
- top -= lineHeight * this._fontSizeFraction / this.lineHeight;
19701
+ top -= this.getHeightOfLineImpl(lineIndex) * this._fontSizeFraction;
19675
19702
  if (shortCut) {
19676
19703
  // render all the line in one pass without checking
19677
19704
  // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex);
@@ -20210,7 +20237,7 @@
20210
20237
  strokeWidth = 1
20211
20238
  } = _options$parsedAttrib,
20212
20239
  restOfOptions = _objectWithoutProperties(_options$parsedAttrib, _excluded$3);
20213
- const textContent = (element.textContent || '').replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' ');
20240
+ const textContent = normalizeWs(element.textContent || '').trim();
20214
20241
 
20215
20242
  // this code here is probably the usual issue for SVG center find
20216
20243
  // this can later looked at again and probably removed.
@@ -21581,7 +21608,8 @@
21581
21608
  autocomplete: 'off',
21582
21609
  spellcheck: 'false',
21583
21610
  'data-fabric': 'textarea',
21584
- wrap: 'off'
21611
+ wrap: 'off',
21612
+ name: 'fabricTextarea'
21585
21613
  }).map(_ref => {
21586
21614
  let [attribute, value] = _ref;
21587
21615
  return textarea.setAttribute(attribute, value);