@nasser-sw/fabric 7.0.1-beta12 → 7.0.1-beta13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -354,7 +354,7 @@ class Cache {
354
354
  }
355
355
  const cache = new Cache();
356
356
 
357
- var version = "7.0.1-beta11";
357
+ var version = "7.0.1-beta12";
358
358
 
359
359
  // use this syntax so babel plugin see this import here
360
360
  const VERSION = version;
@@ -20716,9 +20716,9 @@ function getBrowserLines(target) {
20716
20716
 
20717
20717
  let measuringContext;
20718
20718
 
20719
- /**
20720
- * Return a context for measurement of text string.
20721
- * if created it gets stored for reuse
20719
+ /**
20720
+ * Return a context for measurement of text string.
20721
+ * if created it gets stored for reuse
20722
20722
  */
20723
20723
  function getMeasuringContext() {
20724
20724
  if (!measuringContext) {
@@ -20731,17 +20731,17 @@ function getMeasuringContext() {
20731
20731
  return measuringContext;
20732
20732
  }
20733
20733
 
20734
- /**
20735
- * Measure and return the info of a single grapheme.
20736
- * needs the the info of previous graphemes already filled
20737
- * Override to customize measuring
20734
+ /**
20735
+ * Measure and return the info of a single grapheme.
20736
+ * needs the the info of previous graphemes already filled
20737
+ * Override to customize measuring
20738
20738
  */
20739
20739
 
20740
20740
  // @TODO this is not complete
20741
20741
 
20742
- /**
20743
- * Text class
20744
- * @see {@link http://fabricjs.com/fabric-intro-part-2#text}
20742
+ /**
20743
+ * Text class
20744
+ * @see {@link http://fabricjs.com/fabric-intro-part-2#text}
20745
20745
  */
20746
20746
  class FabricText extends StyledText {
20747
20747
  static getDefaults() {
@@ -20752,11 +20752,11 @@ class FabricText extends StyledText {
20752
20752
  }
20753
20753
  constructor(text, options) {
20754
20754
  super();
20755
- /**
20756
- * contains characters bounding boxes
20757
- * This variable is considered to be protected.
20758
- * But for how mixins are implemented right now, we can't leave it private
20759
- * @protected
20755
+ /**
20756
+ * contains characters bounding boxes
20757
+ * This variable is considered to be protected.
20758
+ * But for how mixins are implemented right now, we can't leave it private
20759
+ * @protected
20760
20760
  */
20761
20761
  _defineProperty(this, "__charBounds", []);
20762
20762
  Object.assign(this, FabricText.ownDefaults);
@@ -20773,9 +20773,9 @@ class FabricText extends StyledText {
20773
20773
  this.setCoords();
20774
20774
  }
20775
20775
 
20776
- /**
20777
- * If text has a path, it will add the extra information needed
20778
- * for path and text calculations
20776
+ /**
20777
+ * If text has a path, it will add the extra information needed
20778
+ * for path and text calculations
20779
20779
  */
20780
20780
  setPathInfo() {
20781
20781
  const path = this.path;
@@ -20784,10 +20784,10 @@ class FabricText extends StyledText {
20784
20784
  }
20785
20785
  }
20786
20786
 
20787
- /**
20788
- * @private
20789
- * Divides text into lines of text and lines of graphemes.
20790
- * Uses browser lines when available for pixel-perfect consistency.
20787
+ /**
20788
+ * @private
20789
+ * Divides text into lines of text and lines of graphemes.
20790
+ * Uses browser lines when available for pixel-perfect consistency.
20791
20791
  */
20792
20792
  _splitText() {
20793
20793
  // Check if we have valid browser lines and should use them
@@ -20803,9 +20803,9 @@ class FabricText extends StyledText {
20803
20803
  return newLines;
20804
20804
  }
20805
20805
 
20806
- /**
20807
- * Create TextLinesInfo from browser-extracted lines
20808
- * @private
20806
+ /**
20807
+ * Create TextLinesInfo from browser-extracted lines
20808
+ * @private
20809
20809
  */
20810
20810
  _splitTextFromBrowserLines(browserLines) {
20811
20811
  const lines = [];
@@ -20839,10 +20839,10 @@ class FabricText extends StyledText {
20839
20839
  return result;
20840
20840
  }
20841
20841
 
20842
- /**
20843
- * Initialize or update text dimensions.
20844
- * Updates this.width and this.height with the proper values.
20845
- * Does not return dimensions.
20842
+ /**
20843
+ * Initialize or update text dimensions.
20844
+ * Updates this.width and this.height with the proper values.
20845
+ * Does not return dimensions.
20846
20846
  */
20847
20847
  initDimensions() {
20848
20848
  // Check if font is ready for accurate measurements
@@ -20888,14 +20888,14 @@ class FabricText extends StyledText {
20888
20888
  }
20889
20889
  }
20890
20890
 
20891
- /**
20892
- * Enlarge space boxes and shift the others
20891
+ /**
20892
+ * Enlarge space boxes and shift the others
20893
20893
  */
20894
20894
  enlargeSpaces() {
20895
20895
  let diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;
20896
20896
  const isRtl = this.direction === 'rtl';
20897
20897
  for (let i = 0, len = this._textLines.length; i < len; i++) {
20898
- if (!this.textAlign.includes('justify') && (i === len - 1 || this.isEndOfWrapping(i))) {
20898
+ if (!this.textAlign.includes('justify') || i === len - 1 || this.isEndOfWrapping(i)) {
20899
20899
  continue;
20900
20900
  }
20901
20901
  accumulatedSpace = 0;
@@ -20951,18 +20951,18 @@ class FabricText extends StyledText {
20951
20951
  }
20952
20952
  }
20953
20953
 
20954
- /**
20955
- * Advanced layout using new text engine (Konva-compatible)
20956
- * @private
20954
+ /**
20955
+ * Advanced layout using new text engine (Konva-compatible)
20956
+ * @private
20957
20957
  */
20958
20958
  _layoutTextAdvanced() {
20959
20959
  const options = this._getAdvancedLayoutOptions();
20960
20960
  return layoutText(options);
20961
20961
  }
20962
20962
 
20963
- /**
20964
- * Get advanced layout options from current text properties
20965
- * @private
20963
+ /**
20964
+ * Get advanced layout options from current text properties
20965
+ * @private
20966
20966
  */
20967
20967
  _getAdvancedLayoutOptions() {
20968
20968
  return {
@@ -20984,9 +20984,9 @@ class FabricText extends StyledText {
20984
20984
  };
20985
20985
  }
20986
20986
 
20987
- /**
20988
- * Map Fabric textAlign to Konva align format
20989
- * @private
20987
+ /**
20988
+ * Map Fabric textAlign to Konva align format
20989
+ * @private
20990
20990
  */
20991
20991
  _mapTextAlignToAlign(textAlign) {
20992
20992
  switch (textAlign) {
@@ -21007,8 +21007,8 @@ class FabricText extends StyledText {
21007
21007
  }
21008
21008
  }
21009
21009
 
21010
- /**
21011
- * Enhanced initDimensions that uses advanced layout when enabled
21010
+ /**
21011
+ * Enhanced initDimensions that uses advanced layout when enabled
21012
21012
  */
21013
21013
  initDimensionsAdvanced() {
21014
21014
  if (!this.enableAdvancedLayout) {
@@ -21037,9 +21037,9 @@ class FabricText extends StyledText {
21037
21037
  this.dirty = true;
21038
21038
  }
21039
21039
 
21040
- /**
21041
- * Convert new layout format to legacy _textLines and __charBounds format
21042
- * @private
21040
+ /**
21041
+ * Convert new layout format to legacy _textLines and __charBounds format
21042
+ * @private
21043
21043
  */
21044
21044
  _convertLayoutToLegacyFormat(layout) {
21045
21045
  this._textLines = layout.lines.map(line => line.graphemes);
@@ -21061,30 +21061,30 @@ class FabricText extends StyledText {
21061
21061
  }
21062
21062
  }
21063
21063
 
21064
- /**
21065
- * Detect if the text line is ended with an hard break
21066
- * text and itext do not have wrapping, return false
21067
- * @return {Boolean}
21064
+ /**
21065
+ * Detect if the text line is ended with an hard break
21066
+ * text and itext do not have wrapping, return false
21067
+ * @return {Boolean}
21068
21068
  */
21069
21069
  isEndOfWrapping(lineIndex) {
21070
21070
  return lineIndex === this._textLines.length - 1;
21071
21071
  }
21072
21072
 
21073
- /**
21074
- * Detect if a line has a linebreak and so we need to account for it when moving
21075
- * and counting style.
21076
- * It return always 1 for text and Itext. Textbox has its own implementation
21077
- * @return Number
21073
+ /**
21074
+ * Detect if a line has a linebreak and so we need to account for it when moving
21075
+ * and counting style.
21076
+ * It return always 1 for text and Itext. Textbox has its own implementation
21077
+ * @return Number
21078
21078
  */
21079
21079
 
21080
21080
  missingNewlineOffset(_lineIndex) {
21081
21081
  return 1;
21082
21082
  }
21083
21083
 
21084
- /**
21085
- * Returns 2d representation (lineIndex and charIndex) of cursor
21086
- * @param {Number} selectionStart
21087
- * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.
21084
+ /**
21085
+ * Returns 2d representation (lineIndex and charIndex) of cursor
21086
+ * @param {Number} selectionStart
21087
+ * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.
21088
21088
  */
21089
21089
  get2DCursorLocation(selectionStart, skipWrapping) {
21090
21090
  const lines = skipWrapping ? this._unwrappedTextLines : this._textLines;
@@ -21104,24 +21104,24 @@ class FabricText extends StyledText {
21104
21104
  };
21105
21105
  }
21106
21106
 
21107
- /**
21108
- * Returns string representation of an instance
21109
- * @return {String} String representation of text object
21107
+ /**
21108
+ * Returns string representation of an instance
21109
+ * @return {String} String representation of text object
21110
21110
  */
21111
21111
  toString() {
21112
21112
  return `#<Text (${this.complexity()}): { "text": "${this.text}", "fontFamily": "${this.fontFamily}" }>`;
21113
21113
  }
21114
21114
 
21115
- /**
21116
- * Return the dimension and the zoom level needed to create a cache canvas
21117
- * big enough to host the object to be cached.
21118
- * @private
21119
- * @param {Object} dim.x width of object to be cached
21120
- * @param {Object} dim.y height of object to be cached
21121
- * @return {Object}.width width of canvas
21122
- * @return {Object}.height height of canvas
21123
- * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
21124
- * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
21115
+ /**
21116
+ * Return the dimension and the zoom level needed to create a cache canvas
21117
+ * big enough to host the object to be cached.
21118
+ * @private
21119
+ * @param {Object} dim.x width of object to be cached
21120
+ * @param {Object} dim.y height of object to be cached
21121
+ * @return {Object}.width width of canvas
21122
+ * @return {Object}.height height of canvas
21123
+ * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
21124
+ * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
21125
21125
  */
21126
21126
  _getCacheCanvasDimensions() {
21127
21127
  const dims = super._getCacheCanvasDimensions();
@@ -21131,9 +21131,9 @@ class FabricText extends StyledText {
21131
21131
  return dims;
21132
21132
  }
21133
21133
 
21134
- /**
21135
- * @private
21136
- * @param {CanvasRenderingContext2D} ctx Context to render on
21134
+ /**
21135
+ * @private
21136
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21137
21137
  */
21138
21138
  _render(ctx) {
21139
21139
  const path = this.path;
@@ -21146,9 +21146,9 @@ class FabricText extends StyledText {
21146
21146
  this._renderTextDecoration(ctx, 'linethrough');
21147
21147
  }
21148
21148
 
21149
- /**
21150
- * @private
21151
- * @param {CanvasRenderingContext2D} ctx Context to render on
21149
+ /**
21150
+ * @private
21151
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21152
21152
  */
21153
21153
  _renderText(ctx) {
21154
21154
  // Skip text rendering if in overlay editing mode
@@ -21164,15 +21164,15 @@ class FabricText extends StyledText {
21164
21164
  }
21165
21165
  }
21166
21166
 
21167
- /**
21168
- * Set the font parameter of the context with the object properties or with charStyle
21169
- * @private
21170
- * @param {CanvasRenderingContext2D} ctx Context to render on
21171
- * @param {Object} [charStyle] object with font style properties
21172
- * @param {String} [charStyle.fontFamily] Font Family
21173
- * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )
21174
- * @param {String} [charStyle.fontWeight] Font weight
21175
- * @param {String} [charStyle.fontStyle] Font style (italic|normal)
21167
+ /**
21168
+ * Set the font parameter of the context with the object properties or with charStyle
21169
+ * @private
21170
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21171
+ * @param {Object} [charStyle] object with font style properties
21172
+ * @param {String} [charStyle.fontFamily] Font Family
21173
+ * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )
21174
+ * @param {String} [charStyle.fontWeight] Font weight
21175
+ * @param {String} [charStyle.fontStyle] Font style (italic|normal)
21176
21176
  */
21177
21177
  _setTextStyles(ctx, charStyle, forMeasuring) {
21178
21178
  ctx.textBaseline = 'alphabetic';
@@ -21192,11 +21192,11 @@ class FabricText extends StyledText {
21192
21192
  ctx.font = this._getFontDeclaration(charStyle, forMeasuring);
21193
21193
  }
21194
21194
 
21195
- /**
21196
- * calculate and return the text Width measuring each line.
21197
- * @private
21198
- * @param {CanvasRenderingContext2D} ctx Context to render on
21199
- * @return {Number} Maximum width of Text object
21195
+ /**
21196
+ * calculate and return the text Width measuring each line.
21197
+ * @private
21198
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21199
+ * @return {Number} Maximum width of Text object
21200
21200
  */
21201
21201
  calcTextWidth() {
21202
21202
  let maxWidth = this.getLineWidth(0);
@@ -21209,23 +21209,23 @@ class FabricText extends StyledText {
21209
21209
  return maxWidth;
21210
21210
  }
21211
21211
 
21212
- /**
21213
- * @private
21214
- * @param {String} method Method name ("fillText" or "strokeText")
21215
- * @param {CanvasRenderingContext2D} ctx Context to render on
21216
- * @param {String} line Text to render
21217
- * @param {Number} left Left position of text
21218
- * @param {Number} top Top position of text
21219
- * @param {Number} lineIndex Index of a line in a text
21212
+ /**
21213
+ * @private
21214
+ * @param {String} method Method name ("fillText" or "strokeText")
21215
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21216
+ * @param {String} line Text to render
21217
+ * @param {Number} left Left position of text
21218
+ * @param {Number} top Top position of text
21219
+ * @param {Number} lineIndex Index of a line in a text
21220
21220
  */
21221
21221
  _renderTextLine(method, ctx, line, left, top, lineIndex) {
21222
21222
  this._renderChars(method, ctx, line, left, top, lineIndex);
21223
21223
  }
21224
21224
 
21225
- /**
21226
- * Renders the text background for lines, taking care of style
21227
- * @private
21228
- * @param {CanvasRenderingContext2D} ctx Context to render on
21225
+ /**
21226
+ * Renders the text background for lines, taking care of style
21227
+ * @private
21228
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21229
21229
  */
21230
21230
  _renderTextLinesBackground(ctx) {
21231
21231
  if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {
@@ -21288,15 +21288,15 @@ class FabricText extends StyledText {
21288
21288
  this._removeShadow(ctx);
21289
21289
  }
21290
21290
 
21291
- /**
21292
- * measure and return the width of a single character.
21293
- * possibly overridden to accommodate different measure logic or
21294
- * to hook some external lib for character measurement
21295
- * @private
21296
- * @param {String} _char, char to be measured
21297
- * @param {Object} charStyle style of char to be measured
21298
- * @param {String} [previousChar] previous char
21299
- * @param {Object} [prevCharStyle] style of previous char
21291
+ /**
21292
+ * measure and return the width of a single character.
21293
+ * possibly overridden to accommodate different measure logic or
21294
+ * to hook some external lib for character measurement
21295
+ * @private
21296
+ * @param {String} _char, char to be measured
21297
+ * @param {Object} charStyle style of char to be measured
21298
+ * @param {String} [previousChar] previous char
21299
+ * @param {Object} [prevCharStyle] style of previous char
21300
21300
  */
21301
21301
  _measureChar(_char, charStyle, previousChar, prevCharStyle) {
21302
21302
  const fontCache = cache.getFontCache(charStyle),
@@ -21341,19 +21341,19 @@ class FabricText extends StyledText {
21341
21341
  };
21342
21342
  }
21343
21343
 
21344
- /**
21345
- * Computes height of character at given position
21346
- * @param {Number} line the line index number
21347
- * @param {Number} _char the character index number
21348
- * @return {Number} fontSize of the character
21344
+ /**
21345
+ * Computes height of character at given position
21346
+ * @param {Number} line the line index number
21347
+ * @param {Number} _char the character index number
21348
+ * @return {Number} fontSize of the character
21349
21349
  */
21350
21350
  getHeightOfChar(line, _char) {
21351
21351
  return this.getValueOfPropertyAt(line, _char, 'fontSize');
21352
21352
  }
21353
21353
 
21354
- /**
21355
- * measure a text line measuring all characters.
21356
- * @param {Number} lineIndex line number
21354
+ /**
21355
+ * measure a text line measuring all characters.
21356
+ * @param {Number} lineIndex line number
21357
21357
  */
21358
21358
  measureLine(lineIndex) {
21359
21359
  const lineInfo = this._measureLine(lineIndex);
@@ -21366,11 +21366,11 @@ class FabricText extends StyledText {
21366
21366
  return lineInfo;
21367
21367
  }
21368
21368
 
21369
- /**
21370
- * measure every grapheme of a line, populating __charBounds
21371
- * @param {Number} lineIndex
21372
- * @return {Object} object.width total width of characters
21373
- * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs
21369
+ /**
21370
+ * measure every grapheme of a line, populating __charBounds
21371
+ * @param {Number} lineIndex
21372
+ * @return {Object} object.width total width of characters
21373
+ * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs
21374
21374
  */
21375
21375
  _measureLine(lineIndex) {
21376
21376
  let width = 0,
@@ -21433,13 +21433,13 @@ class FabricText extends StyledText {
21433
21433
  };
21434
21434
  }
21435
21435
 
21436
- /**
21437
- * Calculate the angle and the left,top position of the char that follow a path.
21438
- * It appends it to graphemeInfo to be reused later at rendering
21439
- * @private
21440
- * @param {Number} positionInPath to be measured
21441
- * @param {GraphemeBBox} graphemeInfo current grapheme box information
21442
- * @param {Object} startingPoint position of the point
21436
+ /**
21437
+ * Calculate the angle and the left,top position of the char that follow a path.
21438
+ * It appends it to graphemeInfo to be reused later at rendering
21439
+ * @private
21440
+ * @param {Number} positionInPath to be measured
21441
+ * @param {GraphemeBBox} graphemeInfo current grapheme box information
21442
+ * @param {Object} startingPoint position of the point
21443
21443
  */
21444
21444
  _setGraphemeOnPath(positionInPath, graphemeInfo) {
21445
21445
  const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2,
@@ -21452,13 +21452,13 @@ class FabricText extends StyledText {
21452
21452
  graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0);
21453
21453
  }
21454
21454
 
21455
- /**
21456
- *
21457
- * @param {String} grapheme to be measured
21458
- * @param {Number} lineIndex index of the line where the char is
21459
- * @param {Number} charIndex position in the line
21460
- * @param {String} [prevGrapheme] character preceding the one to be measured
21461
- * @returns {GraphemeBBox} grapheme bbox
21455
+ /**
21456
+ *
21457
+ * @param {String} grapheme to be measured
21458
+ * @param {Number} lineIndex index of the line where the char is
21459
+ * @param {Number} charIndex position in the line
21460
+ * @param {String} [prevGrapheme] character preceding the one to be measured
21461
+ * @returns {GraphemeBBox} grapheme bbox
21462
21462
  */
21463
21463
  _getGraphemeBox(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {
21464
21464
  const style = this.getCompleteStyleDeclaration(lineIndex, charIndex),
@@ -21486,10 +21486,10 @@ class FabricText extends StyledText {
21486
21486
  return box;
21487
21487
  }
21488
21488
 
21489
- /**
21490
- * Calculate height of line at 'lineIndex'
21491
- * @param {Number} lineIndex index of line to calculate
21492
- * @return {Number}
21489
+ /**
21490
+ * Calculate height of line at 'lineIndex'
21491
+ * @param {Number} lineIndex index of line to calculate
21492
+ * @return {Number}
21493
21493
  */
21494
21494
  getHeightOfLine(lineIndex) {
21495
21495
  if (this.__lineHeights[lineIndex]) {
@@ -21505,8 +21505,8 @@ class FabricText extends StyledText {
21505
21505
  return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;
21506
21506
  }
21507
21507
 
21508
- /**
21509
- * Calculate text box height
21508
+ /**
21509
+ * Calculate text box height
21510
21510
  */
21511
21511
  calcTextHeight() {
21512
21512
  let lineHeight,
@@ -21518,26 +21518,26 @@ class FabricText extends StyledText {
21518
21518
  return height;
21519
21519
  }
21520
21520
 
21521
- /**
21522
- * @private
21523
- * @return {Number} Left offset
21521
+ /**
21522
+ * @private
21523
+ * @return {Number} Left offset
21524
21524
  */
21525
21525
  _getLeftOffset() {
21526
21526
  return this.direction === 'ltr' ? -this.width / 2 : this.width / 2;
21527
21527
  }
21528
21528
 
21529
- /**
21530
- * @private
21531
- * @return {Number} Top offset
21529
+ /**
21530
+ * @private
21531
+ * @return {Number} Top offset
21532
21532
  */
21533
21533
  _getTopOffset() {
21534
21534
  return -this.height / 2;
21535
21535
  }
21536
21536
 
21537
- /**
21538
- * @private
21539
- * @param {CanvasRenderingContext2D} ctx Context to render on
21540
- * @param {String} method Method name ("fillText" or "strokeText")
21537
+ /**
21538
+ * @private
21539
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21540
+ * @param {String} method Method name ("fillText" or "strokeText")
21541
21541
  */
21542
21542
  _renderTextCommon(ctx, method) {
21543
21543
  ctx.save();
@@ -21554,9 +21554,9 @@ class FabricText extends StyledText {
21554
21554
  ctx.restore();
21555
21555
  }
21556
21556
 
21557
- /**
21558
- * @private
21559
- * @param {CanvasRenderingContext2D} ctx Context to render on
21557
+ /**
21558
+ * @private
21559
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21560
21560
  */
21561
21561
  _renderTextFill(ctx) {
21562
21562
  if (!this.fill && !this.styleHas(FILL)) {
@@ -21565,9 +21565,9 @@ class FabricText extends StyledText {
21565
21565
  this._renderTextCommon(ctx, 'fillText');
21566
21566
  }
21567
21567
 
21568
- /**
21569
- * @private
21570
- * @param {CanvasRenderingContext2D} ctx Context to render on
21568
+ /**
21569
+ * @private
21570
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21571
21571
  */
21572
21572
  _renderTextStroke(ctx) {
21573
21573
  if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {
@@ -21584,14 +21584,14 @@ class FabricText extends StyledText {
21584
21584
  ctx.restore();
21585
21585
  }
21586
21586
 
21587
- /**
21588
- * @private
21589
- * @param {String} method fillText or strokeText.
21590
- * @param {CanvasRenderingContext2D} ctx Context to render on
21591
- * @param {Array} line Content of the line, splitted in an array by grapheme
21592
- * @param {Number} left
21593
- * @param {Number} top
21594
- * @param {Number} lineIndex
21587
+ /**
21588
+ * @private
21589
+ * @param {String} method fillText or strokeText.
21590
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21591
+ * @param {Array} line Content of the line, splitted in an array by grapheme
21592
+ * @param {Number} left
21593
+ * @param {Number} top
21594
+ * @param {Number} lineIndex
21595
21595
  */
21596
21596
  _renderChars(method, ctx, line, left, top, lineIndex) {
21597
21597
  const lineHeight = this.getHeightOfLine(lineIndex),
@@ -21673,16 +21673,16 @@ class FabricText extends StyledText {
21673
21673
  ctx.restore();
21674
21674
  }
21675
21675
 
21676
- /**
21677
- * This function try to patch the missing gradientTransform on canvas gradients.
21678
- * transforming a context to transform the gradient, is going to transform the stroke too.
21679
- * we want to transform the gradient but not the stroke operation, so we create
21680
- * a transformed gradient on a pattern and then we use the pattern instead of the gradient.
21681
- * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size
21682
- * is limited.
21683
- * @private
21684
- * @param {TFiller} filler a fabric gradient instance
21685
- * @return {CanvasPattern} a pattern to use as fill/stroke style
21676
+ /**
21677
+ * This function try to patch the missing gradientTransform on canvas gradients.
21678
+ * transforming a context to transform the gradient, is going to transform the stroke too.
21679
+ * we want to transform the gradient but not the stroke operation, so we create
21680
+ * a transformed gradient on a pattern and then we use the pattern instead of the gradient.
21681
+ * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size
21682
+ * is limited.
21683
+ * @private
21684
+ * @param {TFiller} filler a fabric gradient instance
21685
+ * @return {CanvasPattern} a pattern to use as fill/stroke style
21686
21686
  */
21687
21687
  _applyPatternGradientTransformText(filler) {
21688
21688
  // TODO: verify compatibility with strokeUniform
@@ -21738,12 +21738,12 @@ class FabricText extends StyledText {
21738
21738
  };
21739
21739
  }
21740
21740
 
21741
- /**
21742
- * This function prepare the canvas for a stroke style, and stroke and strokeWidth
21743
- * need to be sent in as defined
21744
- * @param {CanvasRenderingContext2D} ctx
21745
- * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined
21746
- * @returns
21741
+ /**
21742
+ * This function prepare the canvas for a stroke style, and stroke and strokeWidth
21743
+ * need to be sent in as defined
21744
+ * @param {CanvasRenderingContext2D} ctx
21745
+ * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined
21746
+ * @returns
21747
21747
  */
21748
21748
  _setStrokeStyles(ctx, _ref) {
21749
21749
  let {
@@ -21758,12 +21758,12 @@ class FabricText extends StyledText {
21758
21758
  return this.handleFiller(ctx, 'strokeStyle', stroke);
21759
21759
  }
21760
21760
 
21761
- /**
21762
- * This function prepare the canvas for a ill style, and fill
21763
- * need to be sent in as defined
21764
- * @param {CanvasRenderingContext2D} ctx
21765
- * @param {CompleteTextStyleDeclaration} style with ill defined
21766
- * @returns
21761
+ /**
21762
+ * This function prepare the canvas for a ill style, and fill
21763
+ * need to be sent in as defined
21764
+ * @param {CanvasRenderingContext2D} ctx
21765
+ * @param {CompleteTextStyleDeclaration} style with ill defined
21766
+ * @returns
21767
21767
  */
21768
21768
  _setFillStyles(ctx, _ref2) {
21769
21769
  let {
@@ -21772,16 +21772,16 @@ class FabricText extends StyledText {
21772
21772
  return this.handleFiller(ctx, 'fillStyle', fill);
21773
21773
  }
21774
21774
 
21775
- /**
21776
- * @private
21777
- * @param {String} method
21778
- * @param {CanvasRenderingContext2D} ctx Context to render on
21779
- * @param {Number} lineIndex
21780
- * @param {Number} charIndex
21781
- * @param {String} _char
21782
- * @param {Number} left Left coordinate
21783
- * @param {Number} top Top coordinate
21784
- * @param {Number} lineHeight Height of the line
21775
+ /**
21776
+ * @private
21777
+ * @param {String} method
21778
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21779
+ * @param {Number} lineIndex
21780
+ * @param {Number} charIndex
21781
+ * @param {String} _char
21782
+ * @param {Number} left Left coordinate
21783
+ * @param {Number} top Top coordinate
21784
+ * @param {Number} lineHeight Height of the line
21785
21785
  */
21786
21786
  _renderChar(method, ctx, lineIndex, charIndex, _char, left, top) {
21787
21787
  const decl = this._getStyleDeclaration(lineIndex, charIndex),
@@ -21810,30 +21810,30 @@ class FabricText extends StyledText {
21810
21810
  ctx.restore();
21811
21811
  }
21812
21812
 
21813
- /**
21814
- * Turns the character into a 'superior figure' (i.e. 'superscript')
21815
- * @param {Number} start selection start
21816
- * @param {Number} end selection end
21813
+ /**
21814
+ * Turns the character into a 'superior figure' (i.e. 'superscript')
21815
+ * @param {Number} start selection start
21816
+ * @param {Number} end selection end
21817
21817
  */
21818
21818
  setSuperscript(start, end) {
21819
21819
  this._setScript(start, end, this.superscript);
21820
21820
  }
21821
21821
 
21822
- /**
21823
- * Turns the character into an 'inferior figure' (i.e. 'subscript')
21824
- * @param {Number} start selection start
21825
- * @param {Number} end selection end
21822
+ /**
21823
+ * Turns the character into an 'inferior figure' (i.e. 'subscript')
21824
+ * @param {Number} start selection start
21825
+ * @param {Number} end selection end
21826
21826
  */
21827
21827
  setSubscript(start, end) {
21828
21828
  this._setScript(start, end, this.subscript);
21829
21829
  }
21830
21830
 
21831
- /**
21832
- * Applies 'schema' at given position
21833
- * @private
21834
- * @param {Number} start selection start
21835
- * @param {Number} end selection end
21836
- * @param {Number} schema
21831
+ /**
21832
+ * Applies 'schema' at given position
21833
+ * @private
21834
+ * @param {Number} start selection start
21835
+ * @param {Number} end selection end
21836
+ * @param {Number} schema
21837
21837
  */
21838
21838
  _setScript(start, end, schema) {
21839
21839
  const loc = this.get2DCursorLocation(start, true),
@@ -21846,10 +21846,10 @@ class FabricText extends StyledText {
21846
21846
  this.setSelectionStyles(style, start, end);
21847
21847
  }
21848
21848
 
21849
- /**
21850
- * @private
21851
- * @param {Number} lineIndex index text line
21852
- * @return {Number} Line left offset
21849
+ /**
21850
+ * @private
21851
+ * @param {Number} lineIndex index text line
21852
+ * @return {Number} Line left offset
21853
21853
  */
21854
21854
  _getLineLeftOffset(lineIndex) {
21855
21855
  const lineWidth = this.getLineWidth(lineIndex),
@@ -21899,8 +21899,8 @@ class FabricText extends StyledText {
21899
21899
  return leftOffset;
21900
21900
  }
21901
21901
 
21902
- /**
21903
- * @private
21902
+ /**
21903
+ * @private
21904
21904
  */
21905
21905
  _clearCache() {
21906
21906
  this._forceClearCache = false;
@@ -21909,12 +21909,12 @@ class FabricText extends StyledText {
21909
21909
  this.__charBounds = [];
21910
21910
  }
21911
21911
 
21912
- /**
21913
- * Measure a single line given its index. Used to calculate the initial
21914
- * text bounding box. The values are calculated and stored in __lineWidths cache.
21915
- * @private
21916
- * @param {Number} lineIndex line number
21917
- * @return {Number} Line width
21912
+ /**
21913
+ * Measure a single line given its index. Used to calculate the initial
21914
+ * text bounding box. The values are calculated and stored in __lineWidths cache.
21915
+ * @private
21916
+ * @param {Number} lineIndex line number
21917
+ * @return {Number} Line width
21918
21918
  */
21919
21919
  getLineWidth(lineIndex) {
21920
21920
  if (this.__lineWidths[lineIndex] !== undefined) {
@@ -21933,12 +21933,12 @@ class FabricText extends StyledText {
21933
21933
  return 0;
21934
21934
  }
21935
21935
 
21936
- /**
21937
- * Retrieves the value of property at given character position
21938
- * @param {Number} lineIndex the line number
21939
- * @param {Number} charIndex the character number
21940
- * @param {String} property the property name
21941
- * @returns the value of 'property'
21936
+ /**
21937
+ * Retrieves the value of property at given character position
21938
+ * @param {Number} lineIndex the line number
21939
+ * @param {Number} charIndex the character number
21940
+ * @param {String} property the property name
21941
+ * @returns the value of 'property'
21942
21942
  */
21943
21943
  getValueOfPropertyAt(lineIndex, charIndex, property) {
21944
21944
  var _charStyle$property;
@@ -21946,9 +21946,9 @@ class FabricText extends StyledText {
21946
21946
  return (_charStyle$property = charStyle[property]) !== null && _charStyle$property !== void 0 ? _charStyle$property : this[property];
21947
21947
  }
21948
21948
 
21949
- /**
21950
- * @private
21951
- * @param {CanvasRenderingContext2D} ctx Context to render on
21949
+ /**
21950
+ * @private
21951
+ * @param {CanvasRenderingContext2D} ctx Context to render on
21952
21952
  */
21953
21953
  _renderTextDecoration(ctx, type) {
21954
21954
  if (!this[type] && !this.styleHas(type)) {
@@ -22032,10 +22032,10 @@ class FabricText extends StyledText {
22032
22032
  this._removeShadow(ctx);
22033
22033
  }
22034
22034
 
22035
- /**
22036
- * return font declaration string for canvas context
22037
- * @param {Object} [styleObject] object
22038
- * @returns {String} font declaration formatted for canvas context.
22035
+ /**
22036
+ * return font declaration string for canvas context
22037
+ * @param {Object} [styleObject] object
22038
+ * @returns {String} font declaration formatted for canvas context.
22039
22039
  */
22040
22040
  _getFontDeclaration() {
22041
22041
  let {
@@ -22061,9 +22061,9 @@ class FabricText extends StyledText {
22061
22061
  return [fontStyle, fontWeight, `${forMeasuring ? this.CACHE_FONT_SIZE : fontSize}px`, parsedFontFamily].join(' ');
22062
22062
  }
22063
22063
 
22064
- /**
22065
- * Renders text instance on a specified context
22066
- * @param {CanvasRenderingContext2D} ctx Context to render on
22064
+ /**
22065
+ * Renders text instance on a specified context
22066
+ * @param {CanvasRenderingContext2D} ctx Context to render on
22067
22067
  */
22068
22068
  render(ctx) {
22069
22069
  if (!this.visible) {
@@ -22078,22 +22078,22 @@ class FabricText extends StyledText {
22078
22078
  super.render(ctx);
22079
22079
  }
22080
22080
 
22081
- /**
22082
- * Override this method to customize grapheme splitting
22083
- * @todo the util `graphemeSplit` needs to be injectable in some way.
22084
- * is more comfortable to inject the correct util rather than having to override text
22085
- * in the middle of the prototype chain
22086
- * @param {string} value
22087
- * @returns {string[]} array of graphemes
22081
+ /**
22082
+ * Override this method to customize grapheme splitting
22083
+ * @todo the util `graphemeSplit` needs to be injectable in some way.
22084
+ * is more comfortable to inject the correct util rather than having to override text
22085
+ * in the middle of the prototype chain
22086
+ * @param {string} value
22087
+ * @returns {string[]} array of graphemes
22088
22088
  */
22089
22089
  graphemeSplit(value) {
22090
22090
  return graphemeSplit(value);
22091
22091
  }
22092
22092
 
22093
- /**
22094
- * Returns the text as an array of lines.
22095
- * @param {String} text text to split
22096
- * @returns Lines in the text
22093
+ /**
22094
+ * Returns the text as an array of lines.
22095
+ * @param {String} text text to split
22096
+ * @returns Lines in the text
22097
22097
  */
22098
22098
  _splitTextIntoLines(text) {
22099
22099
  const lines = text.split(this._reNewline),
@@ -22119,18 +22119,18 @@ class FabricText extends StyledText {
22119
22119
  };
22120
22120
  }
22121
22121
 
22122
- /**
22123
- * Check if text contains Arabic characters
22124
- * @private
22122
+ /**
22123
+ * Check if text contains Arabic characters
22124
+ * @private
22125
22125
  */
22126
22126
  _containsArabicText(text) {
22127
22127
  return /[\u0600-\u06FF\u0750-\u077F\uFB50-\uFDFF\uFE70-\uFEFF]/.test(text);
22128
22128
  }
22129
22129
 
22130
- /**
22131
- * Returns object representation of an instance
22132
- * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
22133
- * @return {Object} Object representation of an instance
22130
+ /**
22131
+ * Returns object representation of an instance
22132
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
22133
+ * @return {Object} Object representation of an instance
22134
22134
  */
22135
22135
  toObject() {
22136
22136
  let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
@@ -22173,23 +22173,23 @@ class FabricText extends StyledText {
22173
22173
  return this;
22174
22174
  }
22175
22175
 
22176
- /**
22177
- * Returns complexity of an instance
22178
- * @return {Number} complexity
22176
+ /**
22177
+ * Returns complexity of an instance
22178
+ * @return {Number} complexity
22179
22179
  */
22180
22180
  complexity() {
22181
22181
  return 1;
22182
22182
  }
22183
22183
 
22184
- /**
22185
- * List of generic font families
22186
- * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#generic-name
22184
+ /**
22185
+ * List of generic font families
22186
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#generic-name
22187
22187
  */
22188
22188
 
22189
- /**
22190
- * Returns FabricText instance from an SVG element (<b>not yet implemented</b>)
22191
- * @param {HTMLElement} element Element to parse
22192
- * @param {Object} [options] Options object
22189
+ /**
22190
+ * Returns FabricText instance from an SVG element (<b>not yet implemented</b>)
22191
+ * @param {HTMLElement} element Element to parse
22192
+ * @param {Object} [options] Options object
22193
22193
  */
22194
22194
  static async fromElement(element, options, cssRules) {
22195
22195
  const parsedAttributes = parseAttributes(element, FabricText.ATTRIBUTE_NAMES, cssRules);
@@ -22228,10 +22228,10 @@ class FabricText extends StyledText {
22228
22228
  scaledDiff = lineHeightDiff * textHeightScaleFactor,
22229
22229
  textHeight = text.getScaledHeight() + scaledDiff;
22230
22230
  let offX = 0;
22231
- /*
22232
- Adjust positioning:
22233
- x/y attributes in SVG correspond to the bottom-left corner of text bounding box
22234
- fabric output by default at top, left.
22231
+ /*
22232
+ Adjust positioning:
22233
+ x/y attributes in SVG correspond to the bottom-left corner of text bounding box
22234
+ fabric output by default at top, left.
22235
22235
  */
22236
22236
  if (textAnchor === CENTER) {
22237
22237
  offX = text.getScaledWidth() / 2;
@@ -22249,9 +22249,9 @@ class FabricText extends StyledText {
22249
22249
 
22250
22250
  /* _FROM_SVG_END_ */
22251
22251
 
22252
- /**
22253
- * Check if the font is ready for accurate measurements
22254
- * @private
22252
+ /**
22253
+ * Check if the font is ready for accurate measurements
22254
+ * @private
22255
22255
  */
22256
22256
  _isFontReady() {
22257
22257
  if (typeof document === 'undefined' || !('fonts' in document)) {
@@ -22264,9 +22264,9 @@ class FabricText extends StyledText {
22264
22264
  }
22265
22265
  }
22266
22266
 
22267
- /**
22268
- * Schedule re-initialization after font loads
22269
- * @private
22267
+ /**
22268
+ * Schedule re-initialization after font loads
22269
+ * @private
22270
22270
  */
22271
22271
  _scheduleInitAfterFontLoad() {
22272
22272
  if (typeof document === 'undefined' || !('fonts' in document)) {
@@ -22302,8 +22302,8 @@ class FabricText extends StyledText {
22302
22302
  });
22303
22303
  }
22304
22304
 
22305
- /**
22306
- * Force complete text re-initialization (useful after JSON loading)
22305
+ /**
22306
+ * Force complete text re-initialization (useful after JSON loading)
22307
22307
  */
22308
22308
  forceTextReinitialization() {
22309
22309
  console.log('🔄 Force reinitializing text object');
@@ -22331,10 +22331,10 @@ class FabricText extends StyledText {
22331
22331
  }
22332
22332
  }
22333
22333
 
22334
- /**
22335
- * Returns FabricText instance from an object representation
22336
- * @param {Object} object plain js Object to create an instance from
22337
- * @returns {Promise<FabricText>}
22334
+ /**
22335
+ * Returns FabricText instance from an object representation
22336
+ * @param {Object} object plain js Object to create an instance from
22337
+ * @returns {Promise<FabricText>}
22338
22338
  */
22339
22339
  static fromObject(object) {
22340
22340
  return this._fromObject({
@@ -22436,10 +22436,10 @@ class FabricText extends StyledText {
22436
22436
  });
22437
22437
  }
22438
22438
  }
22439
- /**
22440
- * Properties that requires a text layout recalculation when changed
22441
- * @type string[]
22442
- * @protected
22439
+ /**
22440
+ * Properties that requires a text layout recalculation when changed
22441
+ * @type string[]
22442
+ * @protected
22443
22443
  */
22444
22444
  _defineProperty(FabricText, "textLayoutProperties", textLayoutProperties);
22445
22445
  _defineProperty(FabricText, "cacheProperties", [...cacheProperties, ...additionalProps]);
@@ -22447,9 +22447,9 @@ _defineProperty(FabricText, "ownDefaults", textDefaultValues);
22447
22447
  _defineProperty(FabricText, "type", 'Text');
22448
22448
  _defineProperty(FabricText, "genericFonts", ['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy', 'system-ui', 'ui-serif', 'ui-sans-serif', 'ui-monospace', 'ui-rounded', 'math', 'emoji', 'fangsong']);
22449
22449
  /* _FROM_SVG_START_ */
22450
- /**
22451
- * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement})
22452
- * @see: http://www.w3.org/TR/SVG/text.html#TextElement
22450
+ /**
22451
+ * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement})
22452
+ * @see: http://www.w3.org/TR/SVG/text.html#TextElement
22453
22453
  */
22454
22454
  _defineProperty(FabricText, "ATTRIBUTE_NAMES", SHARED_ATTRIBUTES.concat('x', 'y', 'dx', 'dy', 'font-family', 'font-style', 'font-weight', 'font-size', 'letter-spacing', 'text-decoration', 'text-anchor'));
22455
22455
  applyMixins(FabricText, [TextSVGExportMixin]);
@@ -26588,11 +26588,11 @@ const textboxDefaultValues = {
26588
26588
 
26589
26589
  // @TODO this is not complete
26590
26590
 
26591
- /**
26592
- * Textbox class, based on IText, allows the user to resize the text rectangle
26593
- * and wraps lines automatically. Textboxes have their Y scaling locked, the
26594
- * user can only change width. Height is adjusted automatically based on the
26595
- * wrapping of lines.
26591
+ /**
26592
+ * Textbox class, based on IText, allows the user to resize the text rectangle
26593
+ * and wraps lines automatically. Textboxes have their Y scaling locked, the
26594
+ * user can only change width. Height is adjusted automatically based on the
26595
+ * wrapping of lines.
26596
26596
  */
26597
26597
  class Textbox extends IText {
26598
26598
  static getDefaults() {
@@ -26602,10 +26602,10 @@ class Textbox extends IText {
26602
26602
  };
26603
26603
  }
26604
26604
 
26605
- /**
26606
- * Constructor
26607
- * @param {String} text Text string
26608
- * @param {Object} [options] Options object
26605
+ /**
26606
+ * Constructor
26607
+ * @param {String} text Text string
26608
+ * @param {Object} [options] Options object
26609
26609
  */
26610
26610
  constructor(text, options) {
26611
26611
  super(text, {
@@ -26615,10 +26615,10 @@ class Textbox extends IText {
26615
26615
  this.initializeEventListeners();
26616
26616
  }
26617
26617
 
26618
- /**
26619
- * Creates the default control object.
26620
- * If you prefer to have on instance of controls shared among all objects
26621
- * make this function return an empty object and add controls to the ownDefaults object
26618
+ /**
26619
+ * Creates the default control object.
26620
+ * If you prefer to have on instance of controls shared among all objects
26621
+ * make this function return an empty object and add controls to the ownDefaults object
26622
26622
  */
26623
26623
  static createControls() {
26624
26624
  return {
@@ -26626,11 +26626,11 @@ class Textbox extends IText {
26626
26626
  };
26627
26627
  }
26628
26628
 
26629
- /**
26630
- * Unlike superclass's version of this function, Textbox does not update
26631
- * its width.
26632
- * @private
26633
- * @override
26629
+ /**
26630
+ * Unlike superclass's version of this function, Textbox does not update
26631
+ * its width.
26632
+ * @private
26633
+ * @override
26634
26634
  */
26635
26635
  initDimensions() {
26636
26636
  if (!this.initialized) {
@@ -26698,6 +26698,7 @@ class Textbox extends IText {
26698
26698
  if (this._usingBrowserWrapping) {
26699
26699
  this._browserWrapInitialized = true;
26700
26700
  }
26701
+ this.calcTextWidth();
26701
26702
  if (this.textAlign.includes(JUSTIFY)) {
26702
26703
  // For browser wrapping fonts, apply browser-calculated justify spaces
26703
26704
  if (this._usingBrowserWrapping) {
@@ -26772,11 +26773,38 @@ class Textbox extends IText {
26772
26773
  } else {
26773
26774
  this.height = this.calcTextHeight();
26774
26775
  }
26776
+
26777
+ // Double-check that justify was applied by checking space widths
26778
+ if (this.textAlign.includes('justify') && this.__charBounds) {
26779
+ setTimeout(() => {
26780
+ // Verify justify was applied by checking if space widths vary
26781
+ let hasVariableSpaces = false;
26782
+ this.__charBounds.forEach((lineBounds, i) => {
26783
+ if (lineBounds && this._textLines && this._textLines[i]) {
26784
+ const spaces = lineBounds.filter((bound, j) => /\s/.test(this._textLines[i][j]));
26785
+ if (spaces.length > 1) {
26786
+ const firstSpaceWidth = spaces[0].width;
26787
+ hasVariableSpaces = spaces.some(space => Math.abs(space.width - firstSpaceWidth) > 0.1);
26788
+ }
26789
+ }
26790
+ });
26791
+ if (!hasVariableSpaces && this.__charBounds.length > 0) {
26792
+ console.warn(' ⚠️ Justify spaces still uniform - forcing enlargeSpaces again');
26793
+ if (this.enlargeSpaces) {
26794
+ var _this$canvas3;
26795
+ this.enlargeSpaces();
26796
+ (_this$canvas3 = this.canvas) === null || _this$canvas3 === void 0 || _this$canvas3.requestRenderAll();
26797
+ }
26798
+ } else {
26799
+ console.log(' ✅ Justify spaces properly expanded');
26800
+ }
26801
+ }, 10);
26802
+ }
26775
26803
  }
26776
26804
 
26777
- /**
26778
- * Schedule justify calculation after font loads (Textbox-specific)
26779
- * @private
26805
+ /**
26806
+ * Schedule justify calculation after font loads (Textbox-specific)
26807
+ * @private
26780
26808
  */
26781
26809
  _scheduleJustifyAfterFontLoad() {
26782
26810
  if (typeof document === 'undefined' || !('fonts' in document)) {
@@ -26790,22 +26818,22 @@ class Textbox extends IText {
26790
26818
  this._fontJustifyScheduled = true;
26791
26819
  const fontSpec = `${this.fontSize}px ${this.fontFamily}`;
26792
26820
  document.fonts.load(fontSpec).then(() => {
26793
- var _this$canvas3;
26821
+ var _this$canvas4;
26794
26822
  this._fontJustifyScheduled = false;
26795
26823
  console.log('🔧 Textbox: Font loaded, applying justify alignment');
26796
26824
 
26797
26825
  // Re-run initDimensions to ensure proper justify calculation
26798
26826
  this.initDimensions();
26799
- (_this$canvas3 = this.canvas) === null || _this$canvas3 === void 0 || _this$canvas3.requestRenderAll();
26827
+ (_this$canvas4 = this.canvas) === null || _this$canvas4 === void 0 || _this$canvas4.requestRenderAll();
26800
26828
  }).catch(() => {
26801
26829
  this._fontJustifyScheduled = false;
26802
26830
  console.warn('⚠️ Textbox: Font loading failed, justify may be incorrect');
26803
26831
  });
26804
26832
  }
26805
26833
 
26806
- /**
26807
- * Advanced dimensions calculation using new layout engine
26808
- * @private
26834
+ /**
26835
+ * Advanced dimensions calculation using new layout engine
26836
+ * @private
26809
26837
  */
26810
26838
  initDimensionsAdvanced() {
26811
26839
  if (!this.initialized) {
@@ -26860,9 +26888,9 @@ class Textbox extends IText {
26860
26888
  this.dirty = true;
26861
26889
  }
26862
26890
 
26863
- /**
26864
- * Generate style map from new layout format
26865
- * @private
26891
+ /**
26892
+ * Generate style map from new layout format
26893
+ * @private
26866
26894
  */
26867
26895
  _generateStyleMapFromLayout(layout) {
26868
26896
  const map = {};
@@ -26884,12 +26912,12 @@ class Textbox extends IText {
26884
26912
  return map;
26885
26913
  }
26886
26914
 
26887
- /**
26888
- * Generate an object that translates the style object so that it is
26889
- * broken up by visual lines (new lines and automatic wrapping).
26890
- * The original text styles object is broken up by actual lines (new lines only),
26891
- * which is only sufficient for Text / IText
26892
- * @private
26915
+ /**
26916
+ * Generate an object that translates the style object so that it is
26917
+ * broken up by visual lines (new lines and automatic wrapping).
26918
+ * The original text styles object is broken up by actual lines (new lines only),
26919
+ * which is only sufficient for Text / IText
26920
+ * @private
26893
26921
  */
26894
26922
  _generateStyleMap(textInfo) {
26895
26923
  let realLineCount = 0,
@@ -26916,10 +26944,10 @@ class Textbox extends IText {
26916
26944
  return map;
26917
26945
  }
26918
26946
 
26919
- /**
26920
- * Returns true if object has a style property or has it on a specified line
26921
- * @param {Number} lineIndex
26922
- * @return {Boolean}
26947
+ /**
26948
+ * Returns true if object has a style property or has it on a specified line
26949
+ * @param {Number} lineIndex
26950
+ * @return {Boolean}
26923
26951
  */
26924
26952
  styleHas(property, lineIndex) {
26925
26953
  if (this._styleMap && !this.isWrapping) {
@@ -26931,10 +26959,10 @@ class Textbox extends IText {
26931
26959
  return super.styleHas(property, lineIndex);
26932
26960
  }
26933
26961
 
26934
- /**
26935
- * Returns true if object has no styling or no styling in a line
26936
- * @param {Number} lineIndex , lineIndex is on wrapped lines.
26937
- * @return {Boolean}
26962
+ /**
26963
+ * Returns true if object has no styling or no styling in a line
26964
+ * @param {Number} lineIndex , lineIndex is on wrapped lines.
26965
+ * @return {Boolean}
26938
26966
  */
26939
26967
  isEmptyStyles(lineIndex) {
26940
26968
  if (!this.styles) {
@@ -26971,11 +26999,11 @@ class Textbox extends IText {
26971
26999
  return true;
26972
27000
  }
26973
27001
 
26974
- /**
26975
- * @protected
26976
- * @param {Number} lineIndex
26977
- * @param {Number} charIndex
26978
- * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined
27002
+ /**
27003
+ * @protected
27004
+ * @param {Number} lineIndex
27005
+ * @param {Number} charIndex
27006
+ * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined
26979
27007
  */
26980
27008
  _getStyleDeclaration(lineIndex, charIndex) {
26981
27009
  if (this._styleMap && !this.isWrapping) {
@@ -26989,59 +27017,59 @@ class Textbox extends IText {
26989
27017
  return super._getStyleDeclaration(lineIndex, charIndex);
26990
27018
  }
26991
27019
 
26992
- /**
26993
- * @param {Number} lineIndex
26994
- * @param {Number} charIndex
26995
- * @param {Object} style
26996
- * @private
27020
+ /**
27021
+ * @param {Number} lineIndex
27022
+ * @param {Number} charIndex
27023
+ * @param {Object} style
27024
+ * @private
26997
27025
  */
26998
27026
  _setStyleDeclaration(lineIndex, charIndex, style) {
26999
27027
  const map = this._styleMap[lineIndex];
27000
27028
  super._setStyleDeclaration(map.line, map.offset + charIndex, style);
27001
27029
  }
27002
27030
 
27003
- /**
27004
- * @param {Number} lineIndex
27005
- * @param {Number} charIndex
27006
- * @private
27031
+ /**
27032
+ * @param {Number} lineIndex
27033
+ * @param {Number} charIndex
27034
+ * @private
27007
27035
  */
27008
27036
  _deleteStyleDeclaration(lineIndex, charIndex) {
27009
27037
  const map = this._styleMap[lineIndex];
27010
27038
  super._deleteStyleDeclaration(map.line, map.offset + charIndex);
27011
27039
  }
27012
27040
 
27013
- /**
27014
- * probably broken need a fix
27015
- * Returns the real style line that correspond to the wrapped lineIndex line
27016
- * Used just to verify if the line does exist or not.
27017
- * @param {Number} lineIndex
27018
- * @returns {Boolean} if the line exists or not
27019
- * @private
27041
+ /**
27042
+ * probably broken need a fix
27043
+ * Returns the real style line that correspond to the wrapped lineIndex line
27044
+ * Used just to verify if the line does exist or not.
27045
+ * @param {Number} lineIndex
27046
+ * @returns {Boolean} if the line exists or not
27047
+ * @private
27020
27048
  */
27021
27049
  _getLineStyle(lineIndex) {
27022
27050
  const map = this._styleMap[lineIndex];
27023
27051
  return !!this.styles[map.line];
27024
27052
  }
27025
27053
 
27026
- /**
27027
- * Set the line style to an empty object so that is initialized
27028
- * @param {Number} lineIndex
27029
- * @param {Object} style
27030
- * @private
27054
+ /**
27055
+ * Set the line style to an empty object so that is initialized
27056
+ * @param {Number} lineIndex
27057
+ * @param {Object} style
27058
+ * @private
27031
27059
  */
27032
27060
  _setLineStyle(lineIndex) {
27033
27061
  const map = this._styleMap[lineIndex];
27034
27062
  super._setLineStyle(map.line);
27035
27063
  }
27036
27064
 
27037
- /**
27038
- * Wraps text using the 'width' property of Textbox. First this function
27039
- * splits text on newlines, so we preserve newlines entered by the user.
27040
- * Then it wraps each line using the width of the Textbox by calling
27041
- * _wrapLine().
27042
- * @param {Array} lines The string array of text that is split into lines
27043
- * @param {Number} desiredWidth width you want to wrap to
27044
- * @returns {Array} Array of lines
27065
+ /**
27066
+ * Wraps text using the 'width' property of Textbox. First this function
27067
+ * splits text on newlines, so we preserve newlines entered by the user.
27068
+ * Then it wraps each line using the width of the Textbox by calling
27069
+ * _wrapLine().
27070
+ * @param {Array} lines The string array of text that is split into lines
27071
+ * @param {Number} desiredWidth width you want to wrap to
27072
+ * @returns {Array} Array of lines
27045
27073
  */
27046
27074
  _wrapText(lines, desiredWidth) {
27047
27075
  this.isWrapping = true;
@@ -27055,12 +27083,12 @@ class Textbox extends IText {
27055
27083
  return wrapped;
27056
27084
  }
27057
27085
 
27058
- /**
27059
- * For each line of text terminated by an hard line stop,
27060
- * measure each word width and extract the largest word from all.
27061
- * The returned words here are the one that at the end will be rendered.
27062
- * @param {string[]} lines the lines we need to measure
27063
- *
27086
+ /**
27087
+ * For each line of text terminated by an hard line stop,
27088
+ * measure each word width and extract the largest word from all.
27089
+ * The returned words here are the one that at the end will be rendered.
27090
+ * @param {string[]} lines the lines we need to measure
27091
+ *
27064
27092
  */
27065
27093
  getGraphemeDataForRender(lines) {
27066
27094
  const splitByGrapheme = this.splitByGrapheme,
@@ -27093,17 +27121,17 @@ class Textbox extends IText {
27093
27121
  };
27094
27122
  }
27095
27123
 
27096
- /**
27097
- * Helper function to measure a string of text, given its lineIndex and charIndex offset
27098
- * It gets called when charBounds are not available yet.
27099
- * Override if necessary
27100
- * Use with {@link Textbox#wordSplit}
27101
- *
27102
- * @param {CanvasRenderingContext2D} ctx
27103
- * @param {String} text
27104
- * @param {number} lineIndex
27105
- * @param {number} charOffset
27106
- * @returns {number}
27124
+ /**
27125
+ * Helper function to measure a string of text, given its lineIndex and charIndex offset
27126
+ * It gets called when charBounds are not available yet.
27127
+ * Override if necessary
27128
+ * Use with {@link Textbox#wordSplit}
27129
+ *
27130
+ * @param {CanvasRenderingContext2D} ctx
27131
+ * @param {String} text
27132
+ * @param {number} lineIndex
27133
+ * @param {number} charOffset
27134
+ * @returns {number}
27107
27135
  */
27108
27136
  _measureWord(word, lineIndex) {
27109
27137
  let charOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
@@ -27118,26 +27146,26 @@ class Textbox extends IText {
27118
27146
  return width;
27119
27147
  }
27120
27148
 
27121
- /**
27122
- * Override this method to customize word splitting
27123
- * Use with {@link Textbox#_measureWord}
27124
- * @param {string} value
27125
- * @returns {string[]} array of words
27149
+ /**
27150
+ * Override this method to customize word splitting
27151
+ * Use with {@link Textbox#_measureWord}
27152
+ * @param {string} value
27153
+ * @returns {string[]} array of words
27126
27154
  */
27127
27155
  wordSplit(value) {
27128
27156
  return value.split(this._wordJoiners);
27129
27157
  }
27130
27158
 
27131
- /**
27132
- * Wraps a line of text using the width of the Textbox as desiredWidth
27133
- * and leveraging the known width o words from GraphemeData
27134
- * @private
27135
- * @param {Number} lineIndex
27136
- * @param {Number} desiredWidth width you want to wrap the line to
27137
- * @param {GraphemeData} graphemeData an object containing all the lines' words width.
27138
- * @param {Number} reservedSpace space to remove from wrapping for custom functionalities
27139
- * @returns {Array} Array of line(s) into which the given text is wrapped
27140
- * to.
27159
+ /**
27160
+ * Wraps a line of text using the width of the Textbox as desiredWidth
27161
+ * and leveraging the known width o words from GraphemeData
27162
+ * @private
27163
+ * @param {Number} lineIndex
27164
+ * @param {Number} desiredWidth width you want to wrap the line to
27165
+ * @param {GraphemeData} graphemeData an object containing all the lines' words width.
27166
+ * @param {Number} reservedSpace space to remove from wrapping for custom functionalities
27167
+ * @returns {Array} Array of line(s) into which the given text is wrapped
27168
+ * to.
27141
27169
  */
27142
27170
  _wrapLine(lineIndex, desiredWidth, _ref) {
27143
27171
  let {
@@ -27219,11 +27247,11 @@ class Textbox extends IText {
27219
27247
  return graphemeLines;
27220
27248
  }
27221
27249
 
27222
- /**
27223
- * Detect if the text line is ended with an hard break
27224
- * text and itext do not have wrapping, return false
27225
- * @param {Number} lineIndex text to split
27226
- * @return {Boolean}
27250
+ /**
27251
+ * Detect if the text line is ended with an hard break
27252
+ * text and itext do not have wrapping, return false
27253
+ * @param {Number} lineIndex text to split
27254
+ * @return {Boolean}
27227
27255
  */
27228
27256
  isEndOfWrapping(lineIndex) {
27229
27257
  if (!this._styleMap[lineIndex + 1]) {
@@ -27237,12 +27265,12 @@ class Textbox extends IText {
27237
27265
  return false;
27238
27266
  }
27239
27267
 
27240
- /**
27241
- * Detect if a line has a linebreak and so we need to account for it when moving
27242
- * and counting style.
27243
- * This is important only for splitByGrapheme at the end of wrapping.
27244
- * If we are not wrapping the offset is always 1
27245
- * @return Number
27268
+ /**
27269
+ * Detect if a line has a linebreak and so we need to account for it when moving
27270
+ * and counting style.
27271
+ * This is important only for splitByGrapheme at the end of wrapping.
27272
+ * If we are not wrapping the offset is always 1
27273
+ * @return Number
27246
27274
  */
27247
27275
  missingNewlineOffset(lineIndex, skipWrapping) {
27248
27276
  if (this.splitByGrapheme && !skipWrapping) {
@@ -27251,12 +27279,12 @@ class Textbox extends IText {
27251
27279
  return 1;
27252
27280
  }
27253
27281
 
27254
- /**
27255
- * Gets lines of text to render in the Textbox. This function calculates
27256
- * text wrapping on the fly every time it is called.
27257
- * @param {String} text text to split
27258
- * @returns {Array} Array of lines in the Textbox.
27259
- * @override
27282
+ /**
27283
+ * Gets lines of text to render in the Textbox. This function calculates
27284
+ * text wrapping on the fly every time it is called.
27285
+ * @param {String} text text to split
27286
+ * @returns {Array} Array of lines in the Textbox.
27287
+ * @override
27260
27288
  */
27261
27289
  _splitTextIntoLines(text) {
27262
27290
  // Check if we need browser wrapping using smart font detection
@@ -27303,9 +27331,9 @@ class Textbox extends IText {
27303
27331
  return newText;
27304
27332
  }
27305
27333
 
27306
- /**
27307
- * Use browser's native text wrapping for accurate handling of fonts without English glyphs
27308
- * @private
27334
+ /**
27335
+ * Use browser's native text wrapping for accurate handling of fonts without English glyphs
27336
+ * @private
27309
27337
  */
27310
27338
  _splitTextIntoLinesWithBrowser(text) {
27311
27339
  if (typeof document === 'undefined') {
@@ -27431,9 +27459,9 @@ class Textbox extends IText {
27431
27459
  };
27432
27460
  }
27433
27461
 
27434
- /**
27435
- * Extract justify space measurements from browser
27436
- * @private
27462
+ /**
27463
+ * Extract justify space measurements from browser
27464
+ * @private
27437
27465
  */
27438
27466
  _extractJustifySpaceMeasurements(element, lines) {
27439
27467
  console.log(`🔤 Extracting browser justify space measurements for ${lines.length} lines`);
@@ -27469,9 +27497,9 @@ class Textbox extends IText {
27469
27497
  return spaceWidths;
27470
27498
  }
27471
27499
 
27472
- /**
27473
- * Apply browser-calculated justify space measurements
27474
- * @private
27500
+ /**
27501
+ * Apply browser-calculated justify space measurements
27502
+ * @private
27475
27503
  */
27476
27504
  _applyBrowserJustifySpaces() {
27477
27505
  if (!this._textLines || !this.__charBounds) {
@@ -27494,23 +27522,59 @@ class Textbox extends IText {
27494
27522
  const lineBounds = this.__charBounds[lineIndex];
27495
27523
  const lineSpaceWidths = spaceWidths[lineIndex];
27496
27524
  let spaceIndex = 0;
27525
+ let accumulatedSpace = 0;
27526
+ const isRtl = this.direction === 'rtl';
27527
+ const spaceDiffs = [];
27528
+
27529
+ // First, calculate the difference for each space
27497
27530
  for (let charIndex = 0; charIndex < line.length; charIndex++) {
27498
27531
  if (/\s/.test(line[charIndex]) && spaceIndex < lineSpaceWidths.length) {
27499
- const expandedWidth = lineSpaceWidths[spaceIndex];
27500
- if (lineBounds[charIndex]) {
27501
- const oldWidth = lineBounds[charIndex].width;
27502
- lineBounds[charIndex].width = expandedWidth;
27503
- console.log(`🔤 Line ${lineIndex} space ${spaceIndex}: ${oldWidth.toFixed(1)}px -> ${expandedWidth.toFixed(1)}px`);
27532
+ const charBound = lineBounds[charIndex];
27533
+ if (charBound) {
27534
+ spaceDiffs.push(lineSpaceWidths[spaceIndex] - charBound.width);
27504
27535
  }
27505
27536
  spaceIndex++;
27506
27537
  }
27507
27538
  }
27539
+ spaceIndex = 0;
27540
+ let remainingDiff = spaceDiffs.reduce((a, b) => a + b, 0);
27541
+ for (let charIndex = 0; charIndex < line.length; charIndex++) {
27542
+ const charBound = lineBounds[charIndex];
27543
+ if (!charBound) continue;
27544
+ if (isRtl) {
27545
+ charBound.left += remainingDiff;
27546
+ } else {
27547
+ charBound.left += accumulatedSpace;
27548
+ }
27549
+ if (/\s/.test(line[charIndex]) && spaceIndex < spaceDiffs.length) {
27550
+ const diff = spaceDiffs[spaceIndex];
27551
+ const oldWidth = charBound.width;
27552
+ charBound.width += diff;
27553
+ charBound.kernedWidth += diff;
27554
+ console.log(`🔤 Line ${lineIndex} space ${spaceIndex}: ${oldWidth.toFixed(1)}px -> ${charBound.width.toFixed(1)}px`);
27555
+ if (isRtl) {
27556
+ remainingDiff -= diff;
27557
+ } else {
27558
+ accumulatedSpace += diff;
27559
+ }
27560
+ spaceIndex++;
27561
+ }
27562
+ }
27563
+ // also need to update the last charBound
27564
+ const lastBound = lineBounds[line.length];
27565
+ if (lastBound) {
27566
+ if (isRtl) {
27567
+ lastBound.left += remainingDiff;
27568
+ } else {
27569
+ lastBound.left += accumulatedSpace;
27570
+ }
27571
+ }
27508
27572
  });
27509
27573
  }
27510
27574
 
27511
- /**
27512
- * Fallback to default Fabric wrapping
27513
- * @private
27575
+ /**
27576
+ * Fallback to default Fabric wrapping
27577
+ * @private
27514
27578
  */
27515
27579
  _splitTextIntoLinesDefault(text) {
27516
27580
  const newText = super._splitTextIntoLines(text),
@@ -27542,12 +27606,12 @@ class Textbox extends IText {
27542
27606
  }
27543
27607
  }
27544
27608
 
27545
- /**
27546
- * Initialize event listeners for safety snap functionality
27547
- * @private
27609
+ /**
27610
+ * Initialize event listeners for safety snap functionality
27611
+ * @private
27548
27612
  */
27549
27613
  initializeEventListeners() {
27550
- var _this$canvas4;
27614
+ var _this$canvas5;
27551
27615
  // Track which side is being used for resize to handle position compensation
27552
27616
  let resizeOrigin = null;
27553
27617
 
@@ -27578,7 +27642,7 @@ class Textbox extends IText {
27578
27642
  });
27579
27643
 
27580
27644
  // Also listen to canvas-level modified event as backup
27581
- (_this$canvas4 = this.canvas) === null || _this$canvas4 === void 0 || _this$canvas4.on('object:modified', e => {
27645
+ (_this$canvas5 = this.canvas) === null || _this$canvas5 === void 0 || _this$canvas5.on('object:modified', e => {
27582
27646
  if (e.target === this) {
27583
27647
  const currentResizeOrigin = resizeOrigin; // Capture the value before reset
27584
27648
  setTimeout(() => this.safetySnapWidth(currentResizeOrigin), 10);
@@ -27587,12 +27651,12 @@ class Textbox extends IText {
27587
27651
  });
27588
27652
  }
27589
27653
 
27590
- /**
27591
- * Safety snap to prevent glyph clipping after manual resize.
27592
- * Similar to Polotno - checks if any glyphs are too close to edges
27593
- * and automatically expands width if needed.
27594
- * @private
27595
- * @param resizeOrigin - Which side was used for resizing ('left' or 'right')
27654
+ /**
27655
+ * Safety snap to prevent glyph clipping after manual resize.
27656
+ * Similar to Polotno - checks if any glyphs are too close to edges
27657
+ * and automatically expands width if needed.
27658
+ * @private
27659
+ * @param resizeOrigin - Which side was used for resizing ('left' or 'right')
27596
27660
  */
27597
27661
  safetySnapWidth(resizeOrigin) {
27598
27662
  // For Textbox objects, we always want to check for clipping regardless of isWrapping flag
@@ -27622,7 +27686,7 @@ class Textbox extends IText {
27622
27686
  const safetyThreshold = 2; // px - very subtle trigger
27623
27687
 
27624
27688
  if (maxRequiredWidth > this.width - safetyThreshold) {
27625
- var _this$canvas5;
27689
+ var _this$canvas6;
27626
27690
  // Set width to exactly what's needed + minimal safety margin
27627
27691
  const newWidth = maxRequiredWidth + 1; // Add just 1px safety margin
27628
27692
 
@@ -27655,13 +27719,13 @@ class Textbox extends IText {
27655
27719
  this.__overlayEditor.refresh();
27656
27720
  }, 0);
27657
27721
  }
27658
- (_this$canvas5 = this.canvas) === null || _this$canvas5 === void 0 || _this$canvas5.requestRenderAll();
27722
+ (_this$canvas6 = this.canvas) === null || _this$canvas6 === void 0 || _this$canvas6.requestRenderAll();
27659
27723
  }
27660
27724
  }
27661
27725
 
27662
- /**
27663
- * Fix character selection mismatch after JSON loading for browser-wrapped fonts
27664
- * @private
27726
+ /**
27727
+ * Fix character selection mismatch after JSON loading for browser-wrapped fonts
27728
+ * @private
27665
27729
  */
27666
27730
  _fixCharacterMappingAfterJsonLoad() {
27667
27731
  if (this._usingBrowserWrapping) {
@@ -27681,9 +27745,9 @@ class Textbox extends IText {
27681
27745
  }
27682
27746
  }
27683
27747
 
27684
- /**
27685
- * Force complete textbox re-initialization (useful after JSON loading)
27686
- * Overrides Text version with Textbox-specific logic
27748
+ /**
27749
+ * Force complete textbox re-initialization (useful after JSON loading)
27750
+ * Overrides Text version with Textbox-specific logic
27687
27751
  */
27688
27752
  forceTextReinitialization() {
27689
27753
  console.log('🔄 Force reinitializing Textbox object');
@@ -27706,7 +27770,7 @@ class Textbox extends IText {
27706
27770
  // Double-check that justify was applied by checking space widths
27707
27771
  if (this.textAlign.includes('justify') && this.__charBounds) {
27708
27772
  setTimeout(() => {
27709
- var _this$canvas6;
27773
+ var _this$canvas7;
27710
27774
  // Verify justify was applied by checking if space widths vary
27711
27775
  let hasVariableSpaces = false;
27712
27776
  this.__charBounds.forEach((lineBounds, i) => {
@@ -27735,36 +27799,36 @@ class Textbox extends IText {
27735
27799
  this.height = this.calcTextHeight();
27736
27800
  console.log(`🔧 JUSTIFY: Used calcTextHeight: ${this.height}px`);
27737
27801
  }
27738
- (_this$canvas6 = this.canvas) === null || _this$canvas6 === void 0 || _this$canvas6.requestRenderAll();
27802
+ (_this$canvas7 = this.canvas) === null || _this$canvas7 === void 0 || _this$canvas7.requestRenderAll();
27739
27803
  }, 10);
27740
27804
  }
27741
27805
  }
27742
27806
 
27743
- /**
27744
- * Returns object representation of an instance
27745
- * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
27746
- * @return {Object} object representation of an instance
27807
+ /**
27808
+ * Returns object representation of an instance
27809
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
27810
+ * @return {Object} object representation of an instance
27747
27811
  */
27748
27812
  toObject() {
27749
27813
  let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
27750
27814
  return super.toObject(['minWidth', 'splitByGrapheme', ...propertiesToInclude]);
27751
27815
  }
27752
27816
  }
27753
- /**
27754
- * Minimum width of textbox, in pixels.
27755
- * @type Number
27817
+ /**
27818
+ * Minimum width of textbox, in pixels.
27819
+ * @type Number
27756
27820
  */
27757
- /**
27758
- * Minimum calculated width of a textbox, in pixels.
27759
- * fixed to 2 so that an empty textbox cannot go to 0
27760
- * and is still selectable without text.
27761
- * @type Number
27821
+ /**
27822
+ * Minimum calculated width of a textbox, in pixels.
27823
+ * fixed to 2 so that an empty textbox cannot go to 0
27824
+ * and is still selectable without text.
27825
+ * @type Number
27762
27826
  */
27763
- /**
27764
- * Use this boolean property in order to split strings that have no white space concept.
27765
- * this is a cheap way to help with chinese/japanese
27766
- * @type Boolean
27767
- * @since 2.6.0
27827
+ /**
27828
+ * Use this boolean property in order to split strings that have no white space concept.
27829
+ * this is a cheap way to help with chinese/japanese
27830
+ * @type Boolean
27831
+ * @since 2.6.0
27768
27832
  */
27769
27833
  _defineProperty(Textbox, "type", 'Textbox');
27770
27834
  _defineProperty(Textbox, "textLayoutProperties", [...IText.textLayoutProperties, 'width']);