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

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 (47) hide show
  1. package/dist/index.js +177 -117
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.min.js +1 -1
  4. package/dist/index.min.js.map +1 -1
  5. package/dist/index.min.mjs +1 -1
  6. package/dist/index.min.mjs.map +1 -1
  7. package/dist/index.mjs +177 -117
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/index.node.cjs +177 -117
  10. package/dist/index.node.cjs.map +1 -1
  11. package/dist/index.node.mjs +177 -117
  12. package/dist/index.node.mjs.map +1 -1
  13. package/dist/package.json.min.mjs +1 -1
  14. package/dist/package.json.mjs +1 -1
  15. package/dist/src/shapes/IText/ITextBehavior.d.ts.map +1 -1
  16. package/dist/src/shapes/IText/ITextBehavior.min.mjs +1 -1
  17. package/dist/src/shapes/IText/ITextBehavior.min.mjs.map +1 -1
  18. package/dist/src/shapes/IText/ITextBehavior.mjs +10 -0
  19. package/dist/src/shapes/IText/ITextBehavior.mjs.map +1 -1
  20. package/dist/src/shapes/IText/ITextKeyBehavior.d.ts.map +1 -1
  21. package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs +1 -1
  22. package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs.map +1 -1
  23. package/dist/src/shapes/IText/ITextKeyBehavior.mjs +162 -116
  24. package/dist/src/shapes/IText/ITextKeyBehavior.mjs.map +1 -1
  25. package/dist/src/shapes/Text/Text.d.ts.map +1 -1
  26. package/dist/src/shapes/Text/Text.min.mjs +1 -1
  27. package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
  28. package/dist/src/shapes/Text/Text.mjs +4 -0
  29. package/dist/src/shapes/Text/Text.mjs.map +1 -1
  30. package/dist/src/shapes/Text/constants.d.ts +1 -1
  31. package/dist/src/shapes/Text/constants.d.ts.map +1 -1
  32. package/dist/src/shapes/Text/constants.min.mjs +1 -1
  33. package/dist/src/shapes/Text/constants.min.mjs.map +1 -1
  34. package/dist/src/shapes/Text/constants.mjs +1 -1
  35. package/dist/src/shapes/Text/constants.mjs.map +1 -1
  36. package/dist-extensions/src/shapes/IText/ITextBehavior.d.ts.map +1 -1
  37. package/dist-extensions/src/shapes/IText/ITextKeyBehavior.d.ts.map +1 -1
  38. package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
  39. package/dist-extensions/src/shapes/Text/constants.d.ts +1 -1
  40. package/dist-extensions/src/shapes/Text/constants.d.ts.map +1 -1
  41. package/fabric-test-editor.html +1 -1
  42. package/package.json +1 -1
  43. package/rtl-debug.html +745 -0
  44. package/src/shapes/IText/ITextBehavior.ts +11 -0
  45. package/src/shapes/IText/ITextKeyBehavior.ts +732 -691
  46. package/src/shapes/Text/Text.ts +4 -0
  47. package/src/shapes/Text/constants.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ITextBehavior.mjs","sources":["../../../../src/shapes/IText/ITextBehavior.ts"],"sourcesContent":["import type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';\r\nimport { Point } from '../../Point';\r\nimport type { FabricObject } from '../Object/FabricObject';\r\nimport { FabricText } from '../Text/Text';\r\nimport { animate } from '../../util/animation/animate';\r\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\r\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\r\nimport type { TextStyleDeclaration } from '../Text/StyledText';\r\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\r\nimport type { TOptions } from '../../typedefs';\r\nimport { getDocumentFromElement } from '../../util/dom_misc';\r\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\r\nimport type { IText } from './IText';\r\nimport { enterTextOverlayEdit } from '../../text/overlayEditor';\r\nimport { extractLinesFromDOM, storeBrowserLines } from '../../text/browserLines';\r\n\r\n/**\r\n * extend this regex to support non english languages\r\n *\r\n * - ` ` Matches a SPACE character (char code 32).\r\n * - `\\n` Matches a LINE FEED character (char code 10).\r\n * - `.` Matches a \".\" character (char code 46).\r\n * - `,` Matches a \",\" character (char code 44).\r\n * - `;` Matches a \";\" character (char code 59).\r\n * - `!` Matches a \"!\" character (char code 33).\r\n * - `\\?` Matches a \"?\" character (char code 63).\r\n * - `\\-` Matches a \"-\" character (char code 45).\r\n */\r\n// eslint-disable-next-line no-useless-escape\r\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\r\n\r\nexport type ITextEvents = ObjectEvents & {\r\n 'selection:changed': never;\r\n changed: never | { index: number; action: string };\r\n 'editing:entered': never | { e: TPointerEvent };\r\n 'editing:exited': never;\r\n};\r\n\r\nexport abstract class ITextBehavior<\r\n Props extends TOptions<TextProps> = Partial<TextProps>,\r\n SProps extends SerializedTextProps = SerializedTextProps,\r\n EventSpec extends ITextEvents = ITextEvents,\r\n> extends FabricText<Props, SProps, EventSpec> {\r\n declare abstract isEditing: boolean;\r\n declare abstract cursorDelay: number;\r\n declare abstract selectionStart: number;\r\n declare abstract selectionEnd: number;\r\n declare abstract cursorDuration: number;\r\n declare abstract editable: boolean;\r\n declare abstract editingBorderColor: string;\r\n\r\n declare abstract compositionStart: number;\r\n declare abstract compositionEnd: number;\r\n\r\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\r\n\r\n /**\r\n * Helps determining when the text is in composition, so that the cursor\r\n * rendering is altered.\r\n */\r\n declare protected inCompositionMode: boolean;\r\n\r\n declare protected _reSpace: RegExp;\r\n declare private _currentTickState?: ValueAnimation;\r\n declare private _currentTickCompleteState?: ValueAnimation;\r\n protected _currentCursorOpacity = 1;\r\n declare private _textBeforeEdit: string;\r\n declare protected __selectionStartOnMouseDown: number;\r\n\r\n /**\r\n * Keeps track if the IText object was selected before the actual click.\r\n * This because we want to delay enter editing by a click.\r\n */\r\n declare protected selected: boolean;\r\n declare protected cursorOffsetCache: { left?: number; top?: number };\r\n declare protected _savedProps?: {\r\n hasControls: boolean;\r\n borderColor: string;\r\n lockMovementX: boolean;\r\n lockMovementY: boolean;\r\n selectable: boolean;\r\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\r\n defaultCursor?: CSSStyleDeclaration['cursor'];\r\n moveCursor?: CSSStyleDeclaration['cursor'];\r\n };\r\n declare protected _selectionDirection: 'left' | 'right' | null;\r\n\r\n abstract initHiddenTextarea(): void;\r\n abstract _fireSelectionChanged(): void;\r\n abstract renderCursorOrSelection(): void;\r\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\r\n abstract _getCursorBoundaries(\r\n index: number,\r\n skipCaching?: boolean,\r\n ): {\r\n left: number;\r\n top: number;\r\n leftOffset: number;\r\n topOffset: number;\r\n };\r\n\r\n /**\r\n * Initializes all the interactive behavior of IText\r\n */\r\n initBehavior() {\r\n this._tick = this._tick.bind(this);\r\n this._onTickComplete = this._onTickComplete.bind(this);\r\n this.updateSelectionOnMouseMove =\r\n this.updateSelectionOnMouseMove.bind(this);\r\n }\r\n\r\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\r\n this.isEditing && this.exitEditing();\r\n this.selected = false;\r\n return super.onDeselect(options);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _animateCursor({\r\n toValue,\r\n duration,\r\n delay,\r\n onComplete,\r\n }: {\r\n toValue: number;\r\n duration: number;\r\n delay?: number;\r\n onComplete?: TOnAnimationChangeCallback<number>;\r\n }) {\r\n return animate({\r\n startValue: this._currentCursorOpacity,\r\n endValue: toValue,\r\n duration,\r\n delay,\r\n onComplete,\r\n abort: () =>\r\n !this.canvas ||\r\n // we do not want to animate a selection, only cursor\r\n this.selectionStart !== this.selectionEnd,\r\n onChange: (value) => {\r\n this._currentCursorOpacity = value;\r\n this.renderCursorOrSelection();\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * changes the cursor from visible to invisible\r\n */\r\n private _tick(delay?: number) {\r\n this._currentTickState = this._animateCursor({\r\n toValue: 0,\r\n duration: this.cursorDuration / 2,\r\n delay: Math.max(delay || 0, 100),\r\n onComplete: this._onTickComplete,\r\n });\r\n }\r\n\r\n /**\r\n * Changes the cursor from invisible to visible\r\n */\r\n private _onTickComplete() {\r\n this._currentTickCompleteState?.abort();\r\n this._currentTickCompleteState = this._animateCursor({\r\n toValue: 1,\r\n duration: this.cursorDuration,\r\n onComplete: this._tick,\r\n });\r\n }\r\n\r\n /**\r\n * Initializes delayed cursor\r\n */\r\n initDelayedCursor(restart?: boolean) {\r\n this.abortCursorAnimation();\r\n this._tick(restart ? 0 : this.cursorDelay);\r\n }\r\n\r\n /**\r\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\r\n */\r\n abortCursorAnimation() {\r\n let shouldClear = false;\r\n [this._currentTickState, this._currentTickCompleteState].forEach(\r\n (cursorAnimation) => {\r\n if (cursorAnimation && !cursorAnimation.isDone()) {\r\n shouldClear = true;\r\n cursorAnimation.abort();\r\n }\r\n },\r\n );\r\n\r\n this._currentCursorOpacity = 1;\r\n\r\n // make sure we clear context even if instance is not editing\r\n if (shouldClear) {\r\n this.clearContextTop();\r\n }\r\n }\r\n\r\n /**\r\n * Restart tue cursor animation if either is in complete state ( between animations )\r\n * or if it never started before\r\n */\r\n restartCursorIfNeeded() {\r\n if (\r\n [this._currentTickState, this._currentTickCompleteState].some(\r\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone(),\r\n )\r\n ) {\r\n this.initDelayedCursor();\r\n }\r\n }\r\n\r\n /**\r\n * Selects entire text\r\n */\r\n selectAll() {\r\n this.selectionStart = 0;\r\n this.selectionEnd = this._text.length;\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n return this;\r\n }\r\n\r\n /**\r\n * Selects entire text and updates the visual state\r\n */\r\n cmdAll() {\r\n this.selectAll();\r\n this.renderCursorOrSelection();\r\n }\r\n\r\n /**\r\n * Returns selected text\r\n * @return {String}\r\n */\r\n getSelectedText(): string {\r\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\r\n }\r\n\r\n /**\r\n * Find new selection index representing start of current word according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findWordBoundaryLeft(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom - 1;\r\n\r\n // remove space before cursor first\r\n if (this._reSpace.test(this._text[index])) {\r\n while (this._reSpace.test(this._text[index])) {\r\n offset++;\r\n index--;\r\n }\r\n }\r\n while (/S/.test(this._text[index]) && index > -1) {\r\n offset++;\r\n index--;\r\n }\r\n\r\n return startFrom - offset;\r\n }\r\n\r\n /**\r\n * Find new selection index representing end of current word according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findWordBoundaryRight(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom;\r\n\r\n // remove space after cursor first\r\n if (this._reSpace.test(this._text[index])) {\r\n while (this._reSpace.test(this._text[index])) {\r\n offset++;\r\n index++;\r\n }\r\n }\r\n while (/S/.test(this._text[index]) && index < this._text.length) {\r\n offset++;\r\n index++;\r\n }\r\n\r\n return startFrom + offset;\r\n }\r\n\r\n /**\r\n * Find new selection index representing start of current line according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findLineBoundaryLeft(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom - 1;\r\n\r\n while (!/\\n/.test(this._text[index]) && index > -1) {\r\n offset++;\r\n index--;\r\n }\r\n\r\n return startFrom - offset;\r\n }\r\n\r\n /**\r\n * Find new selection index representing end of current line according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findLineBoundaryRight(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom;\r\n\r\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\r\n offset++;\r\n index++;\r\n }\r\n\r\n return startFrom + offset;\r\n }\r\n\r\n /**\r\n * Finds index corresponding to beginning or end of a word\r\n * @param {Number} selectionStart Index of a character\r\n * @param {Number} direction 1 or -1\r\n * @return {Number} Index of the beginning or end of a word\r\n */\r\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\r\n const text = this._text;\r\n // if we land on a space we move the cursor backwards\r\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\r\n let index =\r\n selectionStart > 0 &&\r\n this._reSpace.test(text[selectionStart]) &&\r\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\r\n ? selectionStart - 1\r\n : selectionStart,\r\n _char = text[index];\r\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\r\n index += direction;\r\n _char = text[index];\r\n }\r\n if (direction === -1 && reNonWord.test(_char)) {\r\n index++;\r\n }\r\n return index;\r\n }\r\n\r\n /**\r\n * Selects the word that contains the char at index selectionStart\r\n * @param {Number} selectionStart Index of a character\r\n */\r\n selectWord(selectionStart?: number) {\r\n selectionStart = selectionStart ?? this.selectionStart;\r\n // search backwards\r\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\r\n // search forward\r\n newSelectionEnd = Math.max(\r\n newSelectionStart,\r\n this.searchWordBoundary(selectionStart, 1),\r\n );\r\n\r\n this.selectionStart = newSelectionStart;\r\n this.selectionEnd = newSelectionEnd;\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n // remove next major, for now it renders twice :(\r\n this.renderCursorOrSelection();\r\n }\r\n\r\n /**\r\n * Selects the line that contains selectionStart\r\n * @param {Number} selectionStart Index of a character\r\n */\r\n selectLine(selectionStart?: number) {\r\n selectionStart = selectionStart ?? this.selectionStart;\r\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\r\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\r\n\r\n this.selectionStart = newSelectionStart;\r\n this.selectionEnd = newSelectionEnd;\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n }\r\n\r\n /**\r\n * Enters editing state\r\n */\r\n enterEditing(e?: TPointerEvent) {\r\n if (this.isEditing || !this.editable) {\r\n return;\r\n }\r\n this.enterEditingImpl();\r\n this.fire('editing:entered', e ? { e } : undefined);\r\n this._fireSelectionChanged();\r\n if (this.canvas) {\r\n this.canvas.fire('text:editing:entered', {\r\n target: this as unknown as IText,\r\n e,\r\n });\r\n this.canvas.requestRenderAll();\r\n }\r\n }\r\n\r\n /**\r\n * runs the actual logic that enter from editing state, see {@link enterEditing}\r\n */\r\n enterEditingImpl() {\r\n if (this.canvas) {\r\n this.canvas.calcOffset();\r\n this.canvas.textEditingManager.exitTextEditing();\r\n }\r\n\r\n this.isEditing = true;\r\n\r\n // Check if using overlay editing\r\n if ((this as any).useOverlayEditing) {\r\n this.enterOverlayEditing();\r\n } else {\r\n this.initHiddenTextarea();\r\n this.hiddenTextarea!.focus();\r\n this.hiddenTextarea!.value = this.text;\r\n this._updateTextarea();\r\n this._saveEditingProps();\r\n this._setEditingProps();\r\n this._textBeforeEdit = this.text;\r\n this._tick();\r\n }\r\n }\r\n\r\n /**\r\n * Enter overlay editing mode using DOM textarea overlay\r\n */\r\n private enterOverlayEditing() {\r\n this._saveEditingProps();\r\n this._setEditingProps();\r\n this._textBeforeEdit = this.text;\r\n\r\n if (!this.canvas) {\r\n return;\r\n }\r\n\r\n // Create overlay editor\r\n enterTextOverlayEdit(this.canvas, this as any, {\r\n onCommit: (text: string) => {\r\n this.commitOverlayEdit(text);\r\n },\r\n onCancel: () => {\r\n this.cancelOverlayEdit();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Commit overlay editing changes\r\n */\r\n private commitOverlayEdit(text: string) {\r\n \r\n const overlayEditor = (this as any).__overlayEditor;\r\n \r\n if (overlayEditor) {\r\n // Extract browser lines for pixel-perfect rendering\r\n try {\r\n const result = extractLinesFromDOM(overlayEditor.textareaElement);\r\n storeBrowserLines(this, result.lines);\r\n } catch (error) {\r\n console.warn('Failed to extract browser lines:', error);\r\n }\r\n }\r\n\r\n // Update text content and trigger layout recalculation\r\n this.text = text;\r\n this.dirty = true;\r\n this.initDimensions();\r\n this.setCoords();\r\n this.exitEditing();\r\n this.fire('changed');\r\n this.canvas && this.canvas.requestRenderAll();\r\n }\r\n\r\n /**\r\n * Cancel overlay editing without changes\r\n */\r\n private cancelOverlayEdit() {\r\n // Restore original text\r\n this.text = this._textBeforeEdit || this.text;\r\n this.exitEditing();\r\n }\r\n\r\n /**\r\n * called by {@link Canvas#textEditingManager}\r\n */\r\n updateSelectionOnMouseMove(e: TPointerEvent) {\r\n if (this.getActiveControl()) {\r\n return;\r\n }\r\n\r\n const el = this.hiddenTextarea!;\r\n // regain focus\r\n getDocumentFromElement(el).activeElement !== el && el.focus();\r\n\r\n const newSelectionStart = this.getSelectionStartFromPointer(e),\r\n currentStart = this.selectionStart,\r\n currentEnd = this.selectionEnd;\r\n if (\r\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\r\n currentStart === currentEnd) &&\r\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\r\n ) {\r\n return;\r\n }\r\n\r\n // Always ensure selectionStart <= selectionEnd for proper text selection\r\n const startIndex = Math.min(\r\n newSelectionStart,\r\n this.__selectionStartOnMouseDown,\r\n );\r\n const endIndex = Math.max(\r\n newSelectionStart,\r\n this.__selectionStartOnMouseDown,\r\n );\r\n\r\n this.selectionStart = startIndex;\r\n this.selectionEnd = endIndex;\r\n\r\n if (\r\n this.selectionStart !== currentStart ||\r\n this.selectionEnd !== currentEnd\r\n ) {\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n this.renderCursorOrSelection();\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _setEditingProps() {\r\n this.hoverCursor = 'text';\r\n\r\n if (this.canvas) {\r\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\r\n }\r\n\r\n this.borderColor = this.editingBorderColor;\r\n this.hasControls = this.selectable = false;\r\n this.lockMovementX = this.lockMovementY = true;\r\n }\r\n\r\n /**\r\n * convert from textarea to grapheme indexes\r\n */\r\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\r\n const smallerTextStart = text.slice(0, start),\r\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\r\n if (start === end) {\r\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\r\n }\r\n const smallerTextEnd = text.slice(start, end),\r\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\r\n return {\r\n selectionStart: graphemeStart,\r\n selectionEnd: graphemeStart + graphemeEnd,\r\n };\r\n }\r\n\r\n /**\r\n * convert from fabric to textarea values\r\n */\r\n fromGraphemeToStringSelection(\r\n start: number,\r\n end: number,\r\n graphemes: string[],\r\n ) {\r\n const smallerTextStart = graphemes.slice(0, start),\r\n graphemeStart = smallerTextStart.join('').length;\r\n if (start === end) {\r\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\r\n }\r\n const smallerTextEnd = graphemes.slice(start, end),\r\n graphemeEnd = smallerTextEnd.join('').length;\r\n return {\r\n selectionStart: graphemeStart,\r\n selectionEnd: graphemeStart + graphemeEnd,\r\n };\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _updateTextarea() {\r\n this.cursorOffsetCache = {};\r\n if (!this.hiddenTextarea) {\r\n return;\r\n }\r\n if (!this.inCompositionMode) {\r\n const newSelection = this.fromGraphemeToStringSelection(\r\n this.selectionStart,\r\n this.selectionEnd,\r\n this._text,\r\n );\r\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\r\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\r\n }\r\n this.updateTextareaPosition();\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n updateFromTextArea() {\r\n if (!this.hiddenTextarea) {\r\n return;\r\n }\r\n this.cursorOffsetCache = {};\r\n const textarea = this.hiddenTextarea;\r\n this.text = textarea.value;\r\n this.set('dirty', true);\r\n this.initDimensions();\r\n this.setCoords();\r\n const newSelection = this.fromStringToGraphemeSelection(\r\n textarea.selectionStart,\r\n textarea.selectionEnd,\r\n textarea.value,\r\n );\r\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\r\n if (!this.inCompositionMode) {\r\n this.selectionStart = newSelection.selectionStart;\r\n }\r\n this.updateTextareaPosition();\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n updateTextareaPosition() {\r\n if (this.selectionStart === this.selectionEnd) {\r\n const style = this._calcTextareaPosition();\r\n this.hiddenTextarea!.style.left = style.left;\r\n this.hiddenTextarea!.style.top = style.top;\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @return {Object} style contains style for hiddenTextarea\r\n */\r\n _calcTextareaPosition() {\r\n if (!this.canvas) {\r\n return { left: '1px', top: '1px' };\r\n }\r\n const desiredPosition = this.inCompositionMode\r\n ? this.compositionStart\r\n : this.selectionStart,\r\n boundaries = this._getCursorBoundaries(desiredPosition),\r\n cursorLocation = this.get2DCursorLocation(desiredPosition),\r\n lineIndex = cursorLocation.lineIndex,\r\n charIndex = cursorLocation.charIndex,\r\n charHeight =\r\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\r\n this.lineHeight,\r\n leftOffset = boundaries.leftOffset,\r\n retinaScaling = this.getCanvasRetinaScaling(),\r\n upperCanvas = this.canvas.upperCanvasEl,\r\n upperCanvasWidth = upperCanvas.width / retinaScaling,\r\n upperCanvasHeight = upperCanvas.height / retinaScaling,\r\n maxWidth = upperCanvasWidth - charHeight,\r\n maxHeight = upperCanvasHeight - charHeight;\r\n\r\n const p = new Point(\r\n boundaries.left + leftOffset,\r\n boundaries.top + boundaries.topOffset + charHeight,\r\n )\r\n .transform(this.calcTransformMatrix())\r\n .transform(this.canvas.viewportTransform)\r\n .multiply(\r\n new Point(\r\n upperCanvas.clientWidth / upperCanvasWidth,\r\n upperCanvas.clientHeight / upperCanvasHeight,\r\n ),\r\n );\r\n\r\n if (p.x < 0) {\r\n p.x = 0;\r\n }\r\n if (p.x > maxWidth) {\r\n p.x = maxWidth;\r\n }\r\n if (p.y < 0) {\r\n p.y = 0;\r\n }\r\n if (p.y > maxHeight) {\r\n p.y = maxHeight;\r\n }\r\n\r\n // add canvas offset on document\r\n p.x += this.canvas._offset.left;\r\n p.y += this.canvas._offset.top;\r\n\r\n return {\r\n left: `${p.x}px`,\r\n top: `${p.y}px`,\r\n fontSize: `${charHeight}px`,\r\n charHeight: charHeight,\r\n };\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _saveEditingProps() {\r\n this._savedProps = {\r\n hasControls: this.hasControls,\r\n borderColor: this.borderColor,\r\n lockMovementX: this.lockMovementX,\r\n lockMovementY: this.lockMovementY,\r\n // For textboxes, hoverCursor should be null when not editing (falls back to canvas hoverCursor = 'move')\r\n hoverCursor: null,\r\n selectable: this.selectable,\r\n // Always save known good defaults for canvas cursors instead of potentially corrupted current values\r\n defaultCursor: 'default',\r\n moveCursor: 'move',\r\n };\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _restoreEditingProps() {\r\n if (!this._savedProps) {\r\n return;\r\n }\r\n\r\n this.hoverCursor = this._savedProps.hoverCursor;\r\n this.hasControls = this._savedProps.hasControls;\r\n this.borderColor = this._savedProps.borderColor;\r\n this.selectable = this._savedProps.selectable;\r\n this.lockMovementX = this._savedProps.lockMovementX;\r\n this.lockMovementY = this._savedProps.lockMovementY;\r\n\r\n if (this.canvas) {\r\n this.canvas.defaultCursor =\r\n this._savedProps.defaultCursor ?? 'default';\r\n this.canvas.moveCursor =\r\n this._savedProps.moveCursor ?? 'move';\r\n }\r\n\r\n delete this._savedProps;\r\n }\r\n\r\n /**\r\n * runs the actual logic that exits from editing state, see {@link exitEditing}\r\n * But it does not fire events\r\n */\r\n exitEditingImpl() {\r\n const hiddenTextarea = this.hiddenTextarea;\r\n this.selected = false;\r\n this.isEditing = false;\r\n\r\n if (hiddenTextarea) {\r\n hiddenTextarea.blur && hiddenTextarea.blur();\r\n hiddenTextarea.parentNode &&\r\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\r\n }\r\n this.hiddenTextarea = null;\r\n this.abortCursorAnimation();\r\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\r\n this.selectionEnd = this.selectionStart;\r\n this._restoreEditingProps();\r\n if (this._forceClearCache) {\r\n this.initDimensions();\r\n this.setCoords();\r\n }\r\n }\r\n\r\n /**\r\n * Exits from editing state and fires relevant events\r\n */\r\n exitEditing() {\r\n const isTextChanged = this._textBeforeEdit !== this.text;\r\n this.exitEditingImpl();\r\n\r\n this.fire('editing:exited');\r\n isTextChanged && this.fire(MODIFIED);\r\n if (this.canvas) {\r\n this.canvas.fire('text:editing:exited', {\r\n target: this as unknown as IText,\r\n });\r\n // todo: evaluate add an action to this event\r\n isTextChanged && this.canvas.fire('object:modified', { target: this });\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _removeExtraneousStyles() {\r\n for (const prop in this.styles) {\r\n if (!this._textLines[prop as unknown as number]) {\r\n delete this.styles[prop];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * remove and reflow a style block from start to end.\r\n * @param {Number} start linear start position for removal (included in removal)\r\n * @param {Number} end linear end position for removal ( excluded from removal )\r\n */\r\n removeStyleFromTo(start: number, end: number) {\r\n const { lineIndex: lineStart, charIndex: charStart } =\r\n this.get2DCursorLocation(start, true),\r\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\r\n end,\r\n true,\r\n );\r\n if (lineStart !== lineEnd) {\r\n // step1 remove the trailing of lineStart\r\n if (this.styles[lineStart]) {\r\n for (\r\n let i = charStart;\r\n i < this._unwrappedTextLines[lineStart].length;\r\n i++\r\n ) {\r\n delete this.styles[lineStart][i];\r\n }\r\n }\r\n // step2 move the trailing of lineEnd to lineStart if needed\r\n if (this.styles[lineEnd]) {\r\n for (\r\n let i = charEnd;\r\n i < this._unwrappedTextLines[lineEnd].length;\r\n i++\r\n ) {\r\n const styleObj = this.styles[lineEnd][i];\r\n if (styleObj) {\r\n this.styles[lineStart] || (this.styles[lineStart] = {});\r\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\r\n }\r\n }\r\n }\r\n // step3 detects lines will be completely removed.\r\n for (let i = lineStart + 1; i <= lineEnd; i++) {\r\n delete this.styles[i];\r\n }\r\n // step4 shift remaining lines.\r\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\r\n } else {\r\n // remove and shift left on the same line\r\n if (this.styles[lineStart]) {\r\n const styleObj = this.styles[lineStart];\r\n const diff = charEnd - charStart;\r\n for (let i = charStart; i < charEnd; i++) {\r\n delete styleObj[i];\r\n }\r\n for (const char in this.styles[lineStart]) {\r\n const numericChar = parseInt(char, 10);\r\n if (numericChar >= charEnd) {\r\n styleObj[numericChar - diff] = styleObj[char];\r\n delete styleObj[char];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Shifts line styles up or down\r\n * @param {Number} lineIndex Index of a line\r\n * @param {Number} offset Can any number?\r\n */\r\n shiftLineStyles(lineIndex: number, offset: number) {\r\n const clonedStyles = Object.assign({}, this.styles);\r\n for (const line in this.styles) {\r\n const numericLine = parseInt(line, 10);\r\n if (numericLine > lineIndex) {\r\n this.styles[numericLine + offset] = clonedStyles[numericLine];\r\n if (!clonedStyles[numericLine - offset]) {\r\n delete this.styles[numericLine];\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle insertion of more consecutive style lines for when one or more\r\n * newlines gets added to the text. Since current style needs to be shifted\r\n * first we shift the current style of the number lines needed, then we add\r\n * new lines from the last to the first.\r\n * @param {Number} lineIndex Index of a line\r\n * @param {Number} charIndex Index of a char\r\n * @param {Number} qty number of lines to add\r\n * @param {Array} copiedStyle Array of objects styles\r\n */\r\n insertNewlineStyleObject(\r\n lineIndex: number,\r\n charIndex: number,\r\n qty: number,\r\n copiedStyle?: { [index: number]: TextStyleDeclaration },\r\n ) {\r\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\r\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\r\n const isEndOfLine = originalLineLength === charIndex;\r\n\r\n let someStyleIsCarryingOver = false;\r\n qty || (qty = 1);\r\n this.shiftLineStyles(lineIndex, qty);\r\n const currentCharStyle = this.styles[lineIndex]\r\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\r\n : undefined;\r\n\r\n // we clone styles of all chars\r\n // after cursor onto the current line\r\n for (const index in this.styles[lineIndex]) {\r\n const numIndex = parseInt(index, 10);\r\n if (numIndex >= charIndex) {\r\n someStyleIsCarryingOver = true;\r\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\r\n // remove lines from the previous line since they're on a new line now\r\n if (!(isEndOfLine && charIndex === 0)) {\r\n delete this.styles[lineIndex][index];\r\n }\r\n }\r\n }\r\n let styleCarriedOver = false;\r\n if (someStyleIsCarryingOver && !isEndOfLine) {\r\n // if is end of line, the extra style we copied\r\n // is probably not something we want\r\n this.styles[lineIndex + qty] = newLineStyles;\r\n styleCarriedOver = true;\r\n }\r\n if (styleCarriedOver || originalLineLength > charIndex) {\r\n // skip the last line of since we already prepared it.\r\n // or contains text without style that we don't want to style\r\n // just because it changed lines\r\n qty--;\r\n }\r\n // for the all the lines or all the other lines\r\n // we clone current char style onto the next (otherwise empty) line\r\n while (qty > 0) {\r\n if (copiedStyle && copiedStyle[qty - 1]) {\r\n this.styles[lineIndex + qty] = {\r\n 0: { ...copiedStyle[qty - 1] },\r\n };\r\n } else if (currentCharStyle) {\r\n this.styles[lineIndex + qty] = {\r\n 0: { ...currentCharStyle },\r\n };\r\n } else {\r\n delete this.styles[lineIndex + qty];\r\n }\r\n qty--;\r\n }\r\n this._forceClearCache = true;\r\n }\r\n\r\n /**\r\n * Inserts style object for a given line/char index\r\n * @param {Number} lineIndex Index of a line\r\n * @param {Number} charIndex Index of a char\r\n * @param {Number} quantity number Style object to insert, if given\r\n * @param {Array} copiedStyle array of style objects\r\n */\r\n insertCharStyleObject(\r\n lineIndex: number,\r\n charIndex: number,\r\n quantity: number,\r\n copiedStyle?: TextStyleDeclaration[],\r\n ) {\r\n if (!this.styles) {\r\n this.styles = {};\r\n }\r\n const currentLineStyles = this.styles[lineIndex],\r\n currentLineStylesCloned = currentLineStyles\r\n ? { ...currentLineStyles }\r\n : {};\r\n\r\n quantity || (quantity = 1);\r\n // shift all char styles by quantity forward\r\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\r\n for (const index in currentLineStylesCloned) {\r\n const numericIndex = parseInt(index, 10);\r\n if (numericIndex >= charIndex) {\r\n currentLineStyles[numericIndex + quantity] =\r\n currentLineStylesCloned[numericIndex];\r\n // only delete the style if there was nothing moved there\r\n if (!currentLineStylesCloned[numericIndex - quantity]) {\r\n delete currentLineStyles[numericIndex];\r\n }\r\n }\r\n }\r\n this._forceClearCache = true;\r\n if (copiedStyle) {\r\n while (quantity--) {\r\n if (!Object.keys(copiedStyle[quantity]).length) {\r\n continue;\r\n }\r\n if (!this.styles[lineIndex]) {\r\n this.styles[lineIndex] = {};\r\n }\r\n this.styles[lineIndex][charIndex + quantity] = {\r\n ...copiedStyle[quantity],\r\n };\r\n }\r\n return;\r\n }\r\n if (!currentLineStyles) {\r\n return;\r\n }\r\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\r\n while (newStyle && quantity--) {\r\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\r\n }\r\n }\r\n\r\n /**\r\n * Inserts style object(s)\r\n * @param {Array} insertedText Characters at the location where style is inserted\r\n * @param {Number} start cursor index for inserting style\r\n * @param {Array} [copiedStyle] array of style objects to insert.\r\n */\r\n insertNewStyleBlock(\r\n insertedText: string[],\r\n start: number,\r\n copiedStyle?: TextStyleDeclaration[],\r\n ) {\r\n const cursorLoc = this.get2DCursorLocation(start, true),\r\n addedLines = [0];\r\n let linesLength = 0;\r\n // get an array of how many char per lines are being added.\r\n for (let i = 0; i < insertedText.length; i++) {\r\n if (insertedText[i] === '\\n') {\r\n linesLength++;\r\n addedLines[linesLength] = 0;\r\n } else {\r\n addedLines[linesLength]++;\r\n }\r\n }\r\n // for the first line copy the style from the current char position.\r\n if (addedLines[0] > 0) {\r\n this.insertCharStyleObject(\r\n cursorLoc.lineIndex,\r\n cursorLoc.charIndex,\r\n addedLines[0],\r\n copiedStyle,\r\n );\r\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\r\n }\r\n linesLength &&\r\n this.insertNewlineStyleObject(\r\n cursorLoc.lineIndex,\r\n cursorLoc.charIndex + addedLines[0],\r\n linesLength,\r\n );\r\n let i;\r\n for (i = 1; i < linesLength; i++) {\r\n if (addedLines[i] > 0) {\r\n this.insertCharStyleObject(\r\n cursorLoc.lineIndex + i,\r\n 0,\r\n addedLines[i],\r\n copiedStyle,\r\n );\r\n } else if (copiedStyle) {\r\n // this test is required in order to close #6841\r\n // when a pasted buffer begins with a newline then\r\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\r\n // may be undefined for some reason\r\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\r\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\r\n }\r\n }\r\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\r\n }\r\n if (addedLines[i] > 0) {\r\n this.insertCharStyleObject(\r\n cursorLoc.lineIndex + i,\r\n 0,\r\n addedLines[i],\r\n copiedStyle,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Removes characters from start/end\r\n * start/end ar per grapheme position in _text array.\r\n *\r\n * @param {Number} start\r\n * @param {Number} end default to start + 1\r\n */\r\n removeChars(start: number, end: number = start + 1) {\r\n this.removeStyleFromTo(start, end);\r\n this._text.splice(start, end - start);\r\n this.text = this._text.join('');\r\n this.set('dirty', true);\r\n this.initDimensions();\r\n this.setCoords();\r\n this._removeExtraneousStyles();\r\n }\r\n\r\n /**\r\n * insert characters at start position, before start position.\r\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\r\n * if style array is provided, it must be as the same length of text in graphemes\r\n * if end is provided and is bigger than start, old text is replaced.\r\n * start/end ar per grapheme position in _text array.\r\n *\r\n * @param {String} text text to insert\r\n * @param {Array} style array of style objects\r\n * @param {Number} start\r\n * @param {Number} end default to start + 1\r\n */\r\n insertChars(\r\n text: string,\r\n style: TextStyleDeclaration[] | undefined,\r\n start: number,\r\n end: number = start,\r\n ) {\r\n if (end > start) {\r\n this.removeStyleFromTo(start, end);\r\n }\r\n const graphemes = this.graphemeSplit(text);\r\n this.insertNewStyleBlock(graphemes, start, style);\r\n this._text = [\r\n ...this._text.slice(0, start),\r\n ...graphemes,\r\n ...this._text.slice(end),\r\n ];\r\n this.text = this._text.join('');\r\n this.set('dirty', true);\r\n this.initDimensions();\r\n this.setCoords();\r\n this._removeExtraneousStyles();\r\n }\r\n\r\n /**\r\n * Set the selectionStart and selectionEnd according to the new position of cursor\r\n * mimic the key - mouse navigation when shift is pressed.\r\n */\r\n setSelectionStartEndWithShift(\r\n start: number,\r\n end: number,\r\n newSelection: number,\r\n ) {\r\n if (newSelection <= start) {\r\n if (end === start) {\r\n this._selectionDirection = LEFT;\r\n } else if (this._selectionDirection === RIGHT) {\r\n this._selectionDirection = LEFT;\r\n this.selectionEnd = start;\r\n }\r\n this.selectionStart = newSelection;\r\n } else if (newSelection > start && newSelection < end) {\r\n if (this._selectionDirection === RIGHT) {\r\n this.selectionEnd = newSelection;\r\n } else {\r\n this.selectionStart = newSelection;\r\n }\r\n } else {\r\n // newSelection is > selection start and end\r\n if (end === start) {\r\n this._selectionDirection = RIGHT;\r\n } else if (this._selectionDirection === LEFT) {\r\n this._selectionDirection = RIGHT;\r\n this.selectionStart = end;\r\n }\r\n this.selectionEnd = newSelection;\r\n }\r\n }\r\n}"],"names":["reNonWord","ITextBehavior","FabricText","constructor","arguments","_defineProperty","initBehavior","_tick","bind","_onTickComplete","updateSelectionOnMouseMove","onDeselect","options","isEditing","exitEditing","selected","_animateCursor","_ref","toValue","duration","delay","onComplete","animate","startValue","_currentCursorOpacity","endValue","abort","canvas","selectionStart","selectionEnd","onChange","value","renderCursorOrSelection","_currentTickState","cursorDuration","Math","max","_this$_currentTickCom","_currentTickCompleteState","initDelayedCursor","restart","abortCursorAnimation","cursorDelay","shouldClear","forEach","cursorAnimation","isDone","clearContextTop","restartCursorIfNeeded","some","selectAll","_text","length","_fireSelectionChanged","_updateTextarea","cmdAll","getSelectedText","slice","join","findWordBoundaryLeft","startFrom","offset","index","_reSpace","test","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","text","reNewline","_char","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","e","editable","enterEditingImpl","fire","undefined","target","requestRenderAll","calcOffset","textEditingManager","exitTextEditing","useOverlayEditing","enterOverlayEditing","initHiddenTextarea","hiddenTextarea","focus","_saveEditingProps","_setEditingProps","_textBeforeEdit","enterTextOverlayEdit","onCommit","commitOverlayEdit","onCancel","cancelOverlayEdit","overlayEditor","__overlayEditor","result","extractLinesFromDOM","textareaElement","storeBrowserLines","lines","error","console","warn","dirty","initDimensions","setCoords","getActiveControl","el","getDocumentFromElement","activeElement","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","startIndex","min","endIndex","hoverCursor","defaultCursor","moveCursor","borderColor","editingBorderColor","hasControls","selectable","lockMovementX","lockMovementY","fromStringToGraphemeSelection","start","end","smallerTextStart","graphemeStart","graphemeSplit","smallerTextEnd","graphemeEnd","fromGraphemeToStringSelection","graphemes","cursorOffsetCache","inCompositionMode","newSelection","updateTextareaPosition","updateFromTextArea","textarea","set","style","_calcTextareaPosition","left","top","desiredPosition","compositionStart","boundaries","_getCursorBoundaries","cursorLocation","get2DCursorLocation","lineIndex","charIndex","charHeight","getValueOfPropertyAt","lineHeight","leftOffset","retinaScaling","getCanvasRetinaScaling","upperCanvas","upperCanvasEl","upperCanvasWidth","width","upperCanvasHeight","height","maxWidth","maxHeight","p","Point","topOffset","transform","calcTransformMatrix","viewportTransform","multiply","clientWidth","clientHeight","x","y","_offset","fontSize","_savedProps","_restoreEditingProps","_this$_savedProps$def","_this$_savedProps$mov","exitEditingImpl","blur","parentNode","removeChild","_forceClearCache","isTextChanged","MODIFIED","_removeExtraneousStyles","prop","styles","_textLines","removeStyleFromTo","lineStart","charStart","lineEnd","charEnd","i","_unwrappedTextLines","styleObj","shiftLineStyles","diff","char","numericChar","parseInt","clonedStyles","Object","assign","line","numericLine","insertNewlineStyleObject","qty","copiedStyle","newLineStyles","originalLineLength","isEndOfLine","someStyleIsCarryingOver","currentCharStyle","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","keys","newStyle","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","removeChars","splice","insertChars","setSelectionStartEndWithShift","_selectionDirection","LEFT","RIGHT"],"mappings":"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"}
1
+ {"version":3,"file":"ITextBehavior.mjs","sources":["../../../../src/shapes/IText/ITextBehavior.ts"],"sourcesContent":["import type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';\r\nimport { Point } from '../../Point';\r\nimport type { FabricObject } from '../Object/FabricObject';\r\nimport { FabricText } from '../Text/Text';\r\nimport { animate } from '../../util/animation/animate';\r\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\r\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\r\nimport type { TextStyleDeclaration } from '../Text/StyledText';\r\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\r\nimport type { TOptions } from '../../typedefs';\r\nimport { getDocumentFromElement } from '../../util/dom_misc';\r\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\r\nimport type { IText } from './IText';\r\nimport { enterTextOverlayEdit } from '../../text/overlayEditor';\r\nimport { extractLinesFromDOM, storeBrowserLines } from '../../text/browserLines';\r\n\r\n/**\r\n * extend this regex to support non english languages\r\n *\r\n * - ` ` Matches a SPACE character (char code 32).\r\n * - `\\n` Matches a LINE FEED character (char code 10).\r\n * - `.` Matches a \".\" character (char code 46).\r\n * - `,` Matches a \",\" character (char code 44).\r\n * - `;` Matches a \";\" character (char code 59).\r\n * - `!` Matches a \"!\" character (char code 33).\r\n * - `\\?` Matches a \"?\" character (char code 63).\r\n * - `\\-` Matches a \"-\" character (char code 45).\r\n */\r\n// eslint-disable-next-line no-useless-escape\r\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\r\n\r\nexport type ITextEvents = ObjectEvents & {\r\n 'selection:changed': never;\r\n changed: never | { index: number; action: string };\r\n 'editing:entered': never | { e: TPointerEvent };\r\n 'editing:exited': never;\r\n};\r\n\r\nexport abstract class ITextBehavior<\r\n Props extends TOptions<TextProps> = Partial<TextProps>,\r\n SProps extends SerializedTextProps = SerializedTextProps,\r\n EventSpec extends ITextEvents = ITextEvents,\r\n> extends FabricText<Props, SProps, EventSpec> {\r\n declare abstract isEditing: boolean;\r\n declare abstract cursorDelay: number;\r\n declare abstract selectionStart: number;\r\n declare abstract selectionEnd: number;\r\n declare abstract cursorDuration: number;\r\n declare abstract editable: boolean;\r\n declare abstract editingBorderColor: string;\r\n\r\n declare abstract compositionStart: number;\r\n declare abstract compositionEnd: number;\r\n\r\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\r\n\r\n /**\r\n * Helps determining when the text is in composition, so that the cursor\r\n * rendering is altered.\r\n */\r\n declare protected inCompositionMode: boolean;\r\n\r\n declare protected _reSpace: RegExp;\r\n declare private _currentTickState?: ValueAnimation;\r\n declare private _currentTickCompleteState?: ValueAnimation;\r\n protected _currentCursorOpacity = 1;\r\n declare private _textBeforeEdit: string;\r\n declare protected __selectionStartOnMouseDown: number;\r\n\r\n /**\r\n * Keeps track if the IText object was selected before the actual click.\r\n * This because we want to delay enter editing by a click.\r\n */\r\n declare protected selected: boolean;\r\n declare protected cursorOffsetCache: { left?: number; top?: number };\r\n declare protected _savedProps?: {\r\n hasControls: boolean;\r\n borderColor: string;\r\n lockMovementX: boolean;\r\n lockMovementY: boolean;\r\n selectable: boolean;\r\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\r\n defaultCursor?: CSSStyleDeclaration['cursor'];\r\n moveCursor?: CSSStyleDeclaration['cursor'];\r\n };\r\n declare protected _selectionDirection: 'left' | 'right' | null;\r\n\r\n abstract initHiddenTextarea(): void;\r\n abstract _fireSelectionChanged(): void;\r\n abstract renderCursorOrSelection(): void;\r\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\r\n abstract _getCursorBoundaries(\r\n index: number,\r\n skipCaching?: boolean,\r\n ): {\r\n left: number;\r\n top: number;\r\n leftOffset: number;\r\n topOffset: number;\r\n };\r\n\r\n /**\r\n * Initializes all the interactive behavior of IText\r\n */\r\n initBehavior() {\r\n this._tick = this._tick.bind(this);\r\n this._onTickComplete = this._onTickComplete.bind(this);\r\n this.updateSelectionOnMouseMove =\r\n this.updateSelectionOnMouseMove.bind(this);\r\n }\r\n\r\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\r\n this.isEditing && this.exitEditing();\r\n this.selected = false;\r\n return super.onDeselect(options);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _animateCursor({\r\n toValue,\r\n duration,\r\n delay,\r\n onComplete,\r\n }: {\r\n toValue: number;\r\n duration: number;\r\n delay?: number;\r\n onComplete?: TOnAnimationChangeCallback<number>;\r\n }) {\r\n return animate({\r\n startValue: this._currentCursorOpacity,\r\n endValue: toValue,\r\n duration,\r\n delay,\r\n onComplete,\r\n abort: () =>\r\n !this.canvas ||\r\n // we do not want to animate a selection, only cursor\r\n this.selectionStart !== this.selectionEnd,\r\n onChange: (value) => {\r\n this._currentCursorOpacity = value;\r\n this.renderCursorOrSelection();\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * changes the cursor from visible to invisible\r\n */\r\n private _tick(delay?: number) {\r\n this._currentTickState = this._animateCursor({\r\n toValue: 0,\r\n duration: this.cursorDuration / 2,\r\n delay: Math.max(delay || 0, 100),\r\n onComplete: this._onTickComplete,\r\n });\r\n }\r\n\r\n /**\r\n * Changes the cursor from invisible to visible\r\n */\r\n private _onTickComplete() {\r\n this._currentTickCompleteState?.abort();\r\n this._currentTickCompleteState = this._animateCursor({\r\n toValue: 1,\r\n duration: this.cursorDuration,\r\n onComplete: this._tick,\r\n });\r\n }\r\n\r\n /**\r\n * Initializes delayed cursor\r\n */\r\n initDelayedCursor(restart?: boolean) {\r\n this.abortCursorAnimation();\r\n this._tick(restart ? 0 : this.cursorDelay);\r\n }\r\n\r\n /**\r\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\r\n */\r\n abortCursorAnimation() {\r\n let shouldClear = false;\r\n [this._currentTickState, this._currentTickCompleteState].forEach(\r\n (cursorAnimation) => {\r\n if (cursorAnimation && !cursorAnimation.isDone()) {\r\n shouldClear = true;\r\n cursorAnimation.abort();\r\n }\r\n },\r\n );\r\n\r\n this._currentCursorOpacity = 1;\r\n\r\n // make sure we clear context even if instance is not editing\r\n if (shouldClear) {\r\n this.clearContextTop();\r\n }\r\n }\r\n\r\n /**\r\n * Restart tue cursor animation if either is in complete state ( between animations )\r\n * or if it never started before\r\n */\r\n restartCursorIfNeeded() {\r\n if (\r\n [this._currentTickState, this._currentTickCompleteState].some(\r\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone(),\r\n )\r\n ) {\r\n this.initDelayedCursor();\r\n }\r\n }\r\n\r\n /**\r\n * Selects entire text\r\n */\r\n selectAll() {\r\n this.selectionStart = 0;\r\n this.selectionEnd = this._text.length;\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n return this;\r\n }\r\n\r\n /**\r\n * Selects entire text and updates the visual state\r\n */\r\n cmdAll() {\r\n this.selectAll();\r\n this.renderCursorOrSelection();\r\n }\r\n\r\n /**\r\n * Returns selected text\r\n * @return {String}\r\n */\r\n getSelectedText(): string {\r\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\r\n }\r\n\r\n /**\r\n * Find new selection index representing start of current word according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findWordBoundaryLeft(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom - 1;\r\n\r\n // remove space before cursor first\r\n if (this._reSpace.test(this._text[index])) {\r\n while (this._reSpace.test(this._text[index])) {\r\n offset++;\r\n index--;\r\n }\r\n }\r\n while (/S/.test(this._text[index]) && index > -1) {\r\n offset++;\r\n index--;\r\n }\r\n\r\n return startFrom - offset;\r\n }\r\n\r\n /**\r\n * Find new selection index representing end of current word according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findWordBoundaryRight(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom;\r\n\r\n // remove space after cursor first\r\n if (this._reSpace.test(this._text[index])) {\r\n while (this._reSpace.test(this._text[index])) {\r\n offset++;\r\n index++;\r\n }\r\n }\r\n while (/S/.test(this._text[index]) && index < this._text.length) {\r\n offset++;\r\n index++;\r\n }\r\n\r\n return startFrom + offset;\r\n }\r\n\r\n /**\r\n * Find new selection index representing start of current line according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findLineBoundaryLeft(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom - 1;\r\n\r\n while (!/\\n/.test(this._text[index]) && index > -1) {\r\n offset++;\r\n index--;\r\n }\r\n\r\n return startFrom - offset;\r\n }\r\n\r\n /**\r\n * Find new selection index representing end of current line according to current selection index\r\n * @param {Number} startFrom Current selection index\r\n * @return {Number} New selection index\r\n */\r\n findLineBoundaryRight(startFrom: number): number {\r\n let offset = 0,\r\n index = startFrom;\r\n\r\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\r\n offset++;\r\n index++;\r\n }\r\n\r\n return startFrom + offset;\r\n }\r\n\r\n /**\r\n * Finds index corresponding to beginning or end of a word\r\n * @param {Number} selectionStart Index of a character\r\n * @param {Number} direction 1 or -1\r\n * @return {Number} Index of the beginning or end of a word\r\n */\r\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\r\n const text = this._text;\r\n // if we land on a space we move the cursor backwards\r\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\r\n let index =\r\n selectionStart > 0 &&\r\n this._reSpace.test(text[selectionStart]) &&\r\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\r\n ? selectionStart - 1\r\n : selectionStart,\r\n _char = text[index];\r\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\r\n index += direction;\r\n _char = text[index];\r\n }\r\n if (direction === -1 && reNonWord.test(_char)) {\r\n index++;\r\n }\r\n return index;\r\n }\r\n\r\n /**\r\n * Selects the word that contains the char at index selectionStart\r\n * @param {Number} selectionStart Index of a character\r\n */\r\n selectWord(selectionStart?: number) {\r\n selectionStart = selectionStart ?? this.selectionStart;\r\n // search backwards\r\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\r\n // search forward\r\n newSelectionEnd = Math.max(\r\n newSelectionStart,\r\n this.searchWordBoundary(selectionStart, 1),\r\n );\r\n\r\n this.selectionStart = newSelectionStart;\r\n this.selectionEnd = newSelectionEnd;\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n // remove next major, for now it renders twice :(\r\n this.renderCursorOrSelection();\r\n }\r\n\r\n /**\r\n * Selects the line that contains selectionStart\r\n * @param {Number} selectionStart Index of a character\r\n */\r\n selectLine(selectionStart?: number) {\r\n selectionStart = selectionStart ?? this.selectionStart;\r\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\r\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\r\n\r\n this.selectionStart = newSelectionStart;\r\n this.selectionEnd = newSelectionEnd;\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n }\r\n\r\n /**\r\n * Enters editing state\r\n */\r\n enterEditing(e?: TPointerEvent) {\r\n if (this.isEditing || !this.editable) {\r\n return;\r\n }\r\n this.enterEditingImpl();\r\n this.fire('editing:entered', e ? { e } : undefined);\r\n this._fireSelectionChanged();\r\n if (this.canvas) {\r\n this.canvas.fire('text:editing:entered', {\r\n target: this as unknown as IText,\r\n e,\r\n });\r\n this.canvas.requestRenderAll();\r\n }\r\n }\r\n\r\n /**\r\n * runs the actual logic that enter from editing state, see {@link enterEditing}\r\n */\r\n enterEditingImpl() {\r\n if (this.canvas) {\r\n this.canvas.calcOffset();\r\n this.canvas.textEditingManager.exitTextEditing();\r\n }\r\n\r\n this.isEditing = true;\r\n\r\n // Check if using overlay editing\r\n if ((this as any).useOverlayEditing) {\r\n this.enterOverlayEditing();\r\n } else {\r\n this.initHiddenTextarea();\r\n this.hiddenTextarea!.focus();\r\n this.hiddenTextarea!.value = this.text;\r\n this._updateTextarea();\r\n this._saveEditingProps();\r\n this._setEditingProps();\r\n this._textBeforeEdit = this.text;\r\n this._tick();\r\n }\r\n }\r\n\r\n /**\r\n * Enter overlay editing mode using DOM textarea overlay\r\n */\r\n private enterOverlayEditing() {\r\n this._saveEditingProps();\r\n this._setEditingProps();\r\n this._textBeforeEdit = this.text;\r\n\r\n if (!this.canvas) {\r\n return;\r\n }\r\n\r\n // Create overlay editor\r\n enterTextOverlayEdit(this.canvas, this as any, {\r\n onCommit: (text: string) => {\r\n this.commitOverlayEdit(text);\r\n },\r\n onCancel: () => {\r\n this.cancelOverlayEdit();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Commit overlay editing changes\r\n */\r\n private commitOverlayEdit(text: string) {\r\n \r\n const overlayEditor = (this as any).__overlayEditor;\r\n \r\n if (overlayEditor) {\r\n // Extract browser lines for pixel-perfect rendering\r\n try {\r\n const result = extractLinesFromDOM(overlayEditor.textareaElement);\r\n storeBrowserLines(this, result.lines);\r\n } catch (error) {\r\n console.warn('Failed to extract browser lines:', error);\r\n }\r\n }\r\n\r\n // Update text content and trigger layout recalculation\r\n this.text = text;\r\n this.dirty = true;\r\n this.initDimensions();\r\n this.setCoords();\r\n this.exitEditing();\r\n this.fire('changed');\r\n this.canvas && this.canvas.requestRenderAll();\r\n }\r\n\r\n /**\r\n * Cancel overlay editing without changes\r\n */\r\n private cancelOverlayEdit() {\r\n // Restore original text\r\n this.text = this._textBeforeEdit || this.text;\r\n this.exitEditing();\r\n }\r\n\r\n /**\r\n * called by {@link Canvas#textEditingManager}\r\n */\r\n updateSelectionOnMouseMove(e: TPointerEvent) {\r\n if (this.getActiveControl()) {\r\n return;\r\n }\r\n\r\n const el = this.hiddenTextarea!;\r\n // regain focus\r\n getDocumentFromElement(el).activeElement !== el && el.focus();\r\n\r\n const newSelectionStart = this.getSelectionStartFromPointer(e),\r\n currentStart = this.selectionStart,\r\n currentEnd = this.selectionEnd;\r\n if (\r\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\r\n currentStart === currentEnd) &&\r\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\r\n ) {\r\n return;\r\n }\r\n\r\n // Always ensure selectionStart <= selectionEnd for proper text selection\r\n const startIndex = Math.min(\r\n newSelectionStart,\r\n this.__selectionStartOnMouseDown,\r\n );\r\n const endIndex = Math.max(\r\n newSelectionStart,\r\n this.__selectionStartOnMouseDown,\r\n );\r\n\r\n this.selectionStart = startIndex;\r\n this.selectionEnd = endIndex;\r\n\r\n if (\r\n this.selectionStart !== currentStart ||\r\n this.selectionEnd !== currentEnd\r\n ) {\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n this.renderCursorOrSelection();\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _setEditingProps() {\r\n this.hoverCursor = 'text';\r\n\r\n if (this.canvas) {\r\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\r\n }\r\n\r\n this.borderColor = this.editingBorderColor;\r\n this.hasControls = this.selectable = false;\r\n this.lockMovementX = this.lockMovementY = true;\r\n }\r\n\r\n /**\r\n * convert from textarea to grapheme indexes\r\n */\r\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\r\n const smallerTextStart = text.slice(0, start),\r\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\r\n if (start === end) {\r\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\r\n }\r\n const smallerTextEnd = text.slice(start, end),\r\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\r\n return {\r\n selectionStart: graphemeStart,\r\n selectionEnd: graphemeStart + graphemeEnd,\r\n };\r\n }\r\n\r\n /**\r\n * convert from fabric to textarea values\r\n */\r\n fromGraphemeToStringSelection(\r\n start: number,\r\n end: number,\r\n graphemes: string[],\r\n ) {\r\n const smallerTextStart = graphemes.slice(0, start),\r\n graphemeStart = smallerTextStart.join('').length;\r\n if (start === end) {\r\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\r\n }\r\n const smallerTextEnd = graphemes.slice(start, end),\r\n graphemeEnd = smallerTextEnd.join('').length;\r\n return {\r\n selectionStart: graphemeStart,\r\n selectionEnd: graphemeStart + graphemeEnd,\r\n };\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _updateTextarea() {\r\n console.log('🔤 _updateTextarea called with fabric text:', this.text);\r\n this.cursorOffsetCache = {};\r\n if (!this.hiddenTextarea) {\r\n return;\r\n }\r\n \r\n // Sync textarea content with fabric text to prevent double-keypress issues\r\n const currentFabricText = this.text;\r\n if (this.hiddenTextarea.value !== currentFabricText) {\r\n console.log('🔤 _updateTextarea: syncing textarea to fabric text');\r\n console.log('🔤 _updateTextarea: textarea was:', this.hiddenTextarea.value);\r\n console.log('🔤 _updateTextarea: fabric is:', currentFabricText);\r\n this.hiddenTextarea.value = currentFabricText;\r\n }\r\n \r\n if (!this.inCompositionMode) {\r\n const newSelection = this.fromGraphemeToStringSelection(\r\n this.selectionStart,\r\n this.selectionEnd,\r\n this._text,\r\n );\r\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\r\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\r\n }\r\n this.updateTextareaPosition();\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n updateFromTextArea() {\r\n if (!this.hiddenTextarea) {\r\n return;\r\n }\r\n this.cursorOffsetCache = {};\r\n const textarea = this.hiddenTextarea;\r\n this.text = textarea.value;\r\n this.set('dirty', true);\r\n this.initDimensions();\r\n this.setCoords();\r\n const newSelection = this.fromStringToGraphemeSelection(\r\n textarea.selectionStart,\r\n textarea.selectionEnd,\r\n textarea.value,\r\n );\r\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\r\n if (!this.inCompositionMode) {\r\n this.selectionStart = newSelection.selectionStart;\r\n }\r\n this.updateTextareaPosition();\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n updateTextareaPosition() {\r\n if (this.selectionStart === this.selectionEnd) {\r\n const style = this._calcTextareaPosition();\r\n this.hiddenTextarea!.style.left = style.left;\r\n this.hiddenTextarea!.style.top = style.top;\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @return {Object} style contains style for hiddenTextarea\r\n */\r\n _calcTextareaPosition() {\r\n if (!this.canvas) {\r\n return { left: '1px', top: '1px' };\r\n }\r\n const desiredPosition = this.inCompositionMode\r\n ? this.compositionStart\r\n : this.selectionStart,\r\n boundaries = this._getCursorBoundaries(desiredPosition),\r\n cursorLocation = this.get2DCursorLocation(desiredPosition),\r\n lineIndex = cursorLocation.lineIndex,\r\n charIndex = cursorLocation.charIndex,\r\n charHeight =\r\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\r\n this.lineHeight,\r\n leftOffset = boundaries.leftOffset,\r\n retinaScaling = this.getCanvasRetinaScaling(),\r\n upperCanvas = this.canvas.upperCanvasEl,\r\n upperCanvasWidth = upperCanvas.width / retinaScaling,\r\n upperCanvasHeight = upperCanvas.height / retinaScaling,\r\n maxWidth = upperCanvasWidth - charHeight,\r\n maxHeight = upperCanvasHeight - charHeight;\r\n\r\n const p = new Point(\r\n boundaries.left + leftOffset,\r\n boundaries.top + boundaries.topOffset + charHeight,\r\n )\r\n .transform(this.calcTransformMatrix())\r\n .transform(this.canvas.viewportTransform)\r\n .multiply(\r\n new Point(\r\n upperCanvas.clientWidth / upperCanvasWidth,\r\n upperCanvas.clientHeight / upperCanvasHeight,\r\n ),\r\n );\r\n\r\n if (p.x < 0) {\r\n p.x = 0;\r\n }\r\n if (p.x > maxWidth) {\r\n p.x = maxWidth;\r\n }\r\n if (p.y < 0) {\r\n p.y = 0;\r\n }\r\n if (p.y > maxHeight) {\r\n p.y = maxHeight;\r\n }\r\n\r\n // add canvas offset on document\r\n p.x += this.canvas._offset.left;\r\n p.y += this.canvas._offset.top;\r\n\r\n return {\r\n left: `${p.x}px`,\r\n top: `${p.y}px`,\r\n fontSize: `${charHeight}px`,\r\n charHeight: charHeight,\r\n };\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _saveEditingProps() {\r\n this._savedProps = {\r\n hasControls: this.hasControls,\r\n borderColor: this.borderColor,\r\n lockMovementX: this.lockMovementX,\r\n lockMovementY: this.lockMovementY,\r\n // For textboxes, hoverCursor should be null when not editing (falls back to canvas hoverCursor = 'move')\r\n hoverCursor: null,\r\n selectable: this.selectable,\r\n // Always save known good defaults for canvas cursors instead of potentially corrupted current values\r\n defaultCursor: 'default',\r\n moveCursor: 'move',\r\n };\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _restoreEditingProps() {\r\n if (!this._savedProps) {\r\n return;\r\n }\r\n\r\n this.hoverCursor = this._savedProps.hoverCursor;\r\n this.hasControls = this._savedProps.hasControls;\r\n this.borderColor = this._savedProps.borderColor;\r\n this.selectable = this._savedProps.selectable;\r\n this.lockMovementX = this._savedProps.lockMovementX;\r\n this.lockMovementY = this._savedProps.lockMovementY;\r\n\r\n if (this.canvas) {\r\n this.canvas.defaultCursor =\r\n this._savedProps.defaultCursor ?? 'default';\r\n this.canvas.moveCursor =\r\n this._savedProps.moveCursor ?? 'move';\r\n }\r\n\r\n delete this._savedProps;\r\n }\r\n\r\n /**\r\n * runs the actual logic that exits from editing state, see {@link exitEditing}\r\n * But it does not fire events\r\n */\r\n exitEditingImpl() {\r\n const hiddenTextarea = this.hiddenTextarea;\r\n this.selected = false;\r\n this.isEditing = false;\r\n\r\n if (hiddenTextarea) {\r\n hiddenTextarea.blur && hiddenTextarea.blur();\r\n hiddenTextarea.parentNode &&\r\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\r\n }\r\n this.hiddenTextarea = null;\r\n this.abortCursorAnimation();\r\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\r\n this.selectionEnd = this.selectionStart;\r\n this._restoreEditingProps();\r\n if (this._forceClearCache) {\r\n this.initDimensions();\r\n this.setCoords();\r\n }\r\n }\r\n\r\n /**\r\n * Exits from editing state and fires relevant events\r\n */\r\n exitEditing() {\r\n const isTextChanged = this._textBeforeEdit !== this.text;\r\n this.exitEditingImpl();\r\n\r\n this.fire('editing:exited');\r\n isTextChanged && this.fire(MODIFIED);\r\n if (this.canvas) {\r\n this.canvas.fire('text:editing:exited', {\r\n target: this as unknown as IText,\r\n });\r\n // todo: evaluate add an action to this event\r\n isTextChanged && this.canvas.fire('object:modified', { target: this });\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _removeExtraneousStyles() {\r\n for (const prop in this.styles) {\r\n if (!this._textLines[prop as unknown as number]) {\r\n delete this.styles[prop];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * remove and reflow a style block from start to end.\r\n * @param {Number} start linear start position for removal (included in removal)\r\n * @param {Number} end linear end position for removal ( excluded from removal )\r\n */\r\n removeStyleFromTo(start: number, end: number) {\r\n const { lineIndex: lineStart, charIndex: charStart } =\r\n this.get2DCursorLocation(start, true),\r\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\r\n end,\r\n true,\r\n );\r\n if (lineStart !== lineEnd) {\r\n // step1 remove the trailing of lineStart\r\n if (this.styles[lineStart]) {\r\n for (\r\n let i = charStart;\r\n i < this._unwrappedTextLines[lineStart].length;\r\n i++\r\n ) {\r\n delete this.styles[lineStart][i];\r\n }\r\n }\r\n // step2 move the trailing of lineEnd to lineStart if needed\r\n if (this.styles[lineEnd]) {\r\n for (\r\n let i = charEnd;\r\n i < this._unwrappedTextLines[lineEnd].length;\r\n i++\r\n ) {\r\n const styleObj = this.styles[lineEnd][i];\r\n if (styleObj) {\r\n this.styles[lineStart] || (this.styles[lineStart] = {});\r\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\r\n }\r\n }\r\n }\r\n // step3 detects lines will be completely removed.\r\n for (let i = lineStart + 1; i <= lineEnd; i++) {\r\n delete this.styles[i];\r\n }\r\n // step4 shift remaining lines.\r\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\r\n } else {\r\n // remove and shift left on the same line\r\n if (this.styles[lineStart]) {\r\n const styleObj = this.styles[lineStart];\r\n const diff = charEnd - charStart;\r\n for (let i = charStart; i < charEnd; i++) {\r\n delete styleObj[i];\r\n }\r\n for (const char in this.styles[lineStart]) {\r\n const numericChar = parseInt(char, 10);\r\n if (numericChar >= charEnd) {\r\n styleObj[numericChar - diff] = styleObj[char];\r\n delete styleObj[char];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Shifts line styles up or down\r\n * @param {Number} lineIndex Index of a line\r\n * @param {Number} offset Can any number?\r\n */\r\n shiftLineStyles(lineIndex: number, offset: number) {\r\n const clonedStyles = Object.assign({}, this.styles);\r\n for (const line in this.styles) {\r\n const numericLine = parseInt(line, 10);\r\n if (numericLine > lineIndex) {\r\n this.styles[numericLine + offset] = clonedStyles[numericLine];\r\n if (!clonedStyles[numericLine - offset]) {\r\n delete this.styles[numericLine];\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle insertion of more consecutive style lines for when one or more\r\n * newlines gets added to the text. Since current style needs to be shifted\r\n * first we shift the current style of the number lines needed, then we add\r\n * new lines from the last to the first.\r\n * @param {Number} lineIndex Index of a line\r\n * @param {Number} charIndex Index of a char\r\n * @param {Number} qty number of lines to add\r\n * @param {Array} copiedStyle Array of objects styles\r\n */\r\n insertNewlineStyleObject(\r\n lineIndex: number,\r\n charIndex: number,\r\n qty: number,\r\n copiedStyle?: { [index: number]: TextStyleDeclaration },\r\n ) {\r\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\r\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\r\n const isEndOfLine = originalLineLength === charIndex;\r\n\r\n let someStyleIsCarryingOver = false;\r\n qty || (qty = 1);\r\n this.shiftLineStyles(lineIndex, qty);\r\n const currentCharStyle = this.styles[lineIndex]\r\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\r\n : undefined;\r\n\r\n // we clone styles of all chars\r\n // after cursor onto the current line\r\n for (const index in this.styles[lineIndex]) {\r\n const numIndex = parseInt(index, 10);\r\n if (numIndex >= charIndex) {\r\n someStyleIsCarryingOver = true;\r\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\r\n // remove lines from the previous line since they're on a new line now\r\n if (!(isEndOfLine && charIndex === 0)) {\r\n delete this.styles[lineIndex][index];\r\n }\r\n }\r\n }\r\n let styleCarriedOver = false;\r\n if (someStyleIsCarryingOver && !isEndOfLine) {\r\n // if is end of line, the extra style we copied\r\n // is probably not something we want\r\n this.styles[lineIndex + qty] = newLineStyles;\r\n styleCarriedOver = true;\r\n }\r\n if (styleCarriedOver || originalLineLength > charIndex) {\r\n // skip the last line of since we already prepared it.\r\n // or contains text without style that we don't want to style\r\n // just because it changed lines\r\n qty--;\r\n }\r\n // for the all the lines or all the other lines\r\n // we clone current char style onto the next (otherwise empty) line\r\n while (qty > 0) {\r\n if (copiedStyle && copiedStyle[qty - 1]) {\r\n this.styles[lineIndex + qty] = {\r\n 0: { ...copiedStyle[qty - 1] },\r\n };\r\n } else if (currentCharStyle) {\r\n this.styles[lineIndex + qty] = {\r\n 0: { ...currentCharStyle },\r\n };\r\n } else {\r\n delete this.styles[lineIndex + qty];\r\n }\r\n qty--;\r\n }\r\n this._forceClearCache = true;\r\n }\r\n\r\n /**\r\n * Inserts style object for a given line/char index\r\n * @param {Number} lineIndex Index of a line\r\n * @param {Number} charIndex Index of a char\r\n * @param {Number} quantity number Style object to insert, if given\r\n * @param {Array} copiedStyle array of style objects\r\n */\r\n insertCharStyleObject(\r\n lineIndex: number,\r\n charIndex: number,\r\n quantity: number,\r\n copiedStyle?: TextStyleDeclaration[],\r\n ) {\r\n if (!this.styles) {\r\n this.styles = {};\r\n }\r\n const currentLineStyles = this.styles[lineIndex],\r\n currentLineStylesCloned = currentLineStyles\r\n ? { ...currentLineStyles }\r\n : {};\r\n\r\n quantity || (quantity = 1);\r\n // shift all char styles by quantity forward\r\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\r\n for (const index in currentLineStylesCloned) {\r\n const numericIndex = parseInt(index, 10);\r\n if (numericIndex >= charIndex) {\r\n currentLineStyles[numericIndex + quantity] =\r\n currentLineStylesCloned[numericIndex];\r\n // only delete the style if there was nothing moved there\r\n if (!currentLineStylesCloned[numericIndex - quantity]) {\r\n delete currentLineStyles[numericIndex];\r\n }\r\n }\r\n }\r\n this._forceClearCache = true;\r\n if (copiedStyle) {\r\n while (quantity--) {\r\n if (!Object.keys(copiedStyle[quantity]).length) {\r\n continue;\r\n }\r\n if (!this.styles[lineIndex]) {\r\n this.styles[lineIndex] = {};\r\n }\r\n this.styles[lineIndex][charIndex + quantity] = {\r\n ...copiedStyle[quantity],\r\n };\r\n }\r\n return;\r\n }\r\n if (!currentLineStyles) {\r\n return;\r\n }\r\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\r\n while (newStyle && quantity--) {\r\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\r\n }\r\n }\r\n\r\n /**\r\n * Inserts style object(s)\r\n * @param {Array} insertedText Characters at the location where style is inserted\r\n * @param {Number} start cursor index for inserting style\r\n * @param {Array} [copiedStyle] array of style objects to insert.\r\n */\r\n insertNewStyleBlock(\r\n insertedText: string[],\r\n start: number,\r\n copiedStyle?: TextStyleDeclaration[],\r\n ) {\r\n const cursorLoc = this.get2DCursorLocation(start, true),\r\n addedLines = [0];\r\n let linesLength = 0;\r\n // get an array of how many char per lines are being added.\r\n for (let i = 0; i < insertedText.length; i++) {\r\n if (insertedText[i] === '\\n') {\r\n linesLength++;\r\n addedLines[linesLength] = 0;\r\n } else {\r\n addedLines[linesLength]++;\r\n }\r\n }\r\n // for the first line copy the style from the current char position.\r\n if (addedLines[0] > 0) {\r\n this.insertCharStyleObject(\r\n cursorLoc.lineIndex,\r\n cursorLoc.charIndex,\r\n addedLines[0],\r\n copiedStyle,\r\n );\r\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\r\n }\r\n linesLength &&\r\n this.insertNewlineStyleObject(\r\n cursorLoc.lineIndex,\r\n cursorLoc.charIndex + addedLines[0],\r\n linesLength,\r\n );\r\n let i;\r\n for (i = 1; i < linesLength; i++) {\r\n if (addedLines[i] > 0) {\r\n this.insertCharStyleObject(\r\n cursorLoc.lineIndex + i,\r\n 0,\r\n addedLines[i],\r\n copiedStyle,\r\n );\r\n } else if (copiedStyle) {\r\n // this test is required in order to close #6841\r\n // when a pasted buffer begins with a newline then\r\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\r\n // may be undefined for some reason\r\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\r\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\r\n }\r\n }\r\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\r\n }\r\n if (addedLines[i] > 0) {\r\n this.insertCharStyleObject(\r\n cursorLoc.lineIndex + i,\r\n 0,\r\n addedLines[i],\r\n copiedStyle,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Removes characters from start/end\r\n * start/end ar per grapheme position in _text array.\r\n *\r\n * @param {Number} start\r\n * @param {Number} end default to start + 1\r\n */\r\n removeChars(start: number, end: number = start + 1) {\r\n this.removeStyleFromTo(start, end);\r\n this._text.splice(start, end - start);\r\n this.text = this._text.join('');\r\n this.set('dirty', true);\r\n this.initDimensions();\r\n this.setCoords();\r\n this._removeExtraneousStyles();\r\n }\r\n\r\n /**\r\n * insert characters at start position, before start position.\r\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\r\n * if style array is provided, it must be as the same length of text in graphemes\r\n * if end is provided and is bigger than start, old text is replaced.\r\n * start/end ar per grapheme position in _text array.\r\n *\r\n * @param {String} text text to insert\r\n * @param {Array} style array of style objects\r\n * @param {Number} start\r\n * @param {Number} end default to start + 1\r\n */\r\n insertChars(\r\n text: string,\r\n style: TextStyleDeclaration[] | undefined,\r\n start: number,\r\n end: number = start,\r\n ) {\r\n if (end > start) {\r\n this.removeStyleFromTo(start, end);\r\n }\r\n const graphemes = this.graphemeSplit(text);\r\n this.insertNewStyleBlock(graphemes, start, style);\r\n this._text = [\r\n ...this._text.slice(0, start),\r\n ...graphemes,\r\n ...this._text.slice(end),\r\n ];\r\n this.text = this._text.join('');\r\n this.set('dirty', true);\r\n this.initDimensions();\r\n this.setCoords();\r\n this._removeExtraneousStyles();\r\n }\r\n\r\n /**\r\n * Set the selectionStart and selectionEnd according to the new position of cursor\r\n * mimic the key - mouse navigation when shift is pressed.\r\n */\r\n setSelectionStartEndWithShift(\r\n start: number,\r\n end: number,\r\n newSelection: number,\r\n ) {\r\n if (newSelection <= start) {\r\n if (end === start) {\r\n this._selectionDirection = LEFT;\r\n } else if (this._selectionDirection === RIGHT) {\r\n this._selectionDirection = LEFT;\r\n this.selectionEnd = start;\r\n }\r\n this.selectionStart = newSelection;\r\n } else if (newSelection > start && newSelection < end) {\r\n if (this._selectionDirection === RIGHT) {\r\n this.selectionEnd = newSelection;\r\n } else {\r\n this.selectionStart = newSelection;\r\n }\r\n } else {\r\n // newSelection is > selection start and end\r\n if (end === start) {\r\n this._selectionDirection = RIGHT;\r\n } else if (this._selectionDirection === LEFT) {\r\n this._selectionDirection = RIGHT;\r\n this.selectionStart = end;\r\n }\r\n this.selectionEnd = newSelection;\r\n }\r\n }\r\n}"],"names":["reNonWord","ITextBehavior","FabricText","constructor","arguments","_defineProperty","initBehavior","_tick","bind","_onTickComplete","updateSelectionOnMouseMove","onDeselect","options","isEditing","exitEditing","selected","_animateCursor","_ref","toValue","duration","delay","onComplete","animate","startValue","_currentCursorOpacity","endValue","abort","canvas","selectionStart","selectionEnd","onChange","value","renderCursorOrSelection","_currentTickState","cursorDuration","Math","max","_this$_currentTickCom","_currentTickCompleteState","initDelayedCursor","restart","abortCursorAnimation","cursorDelay","shouldClear","forEach","cursorAnimation","isDone","clearContextTop","restartCursorIfNeeded","some","selectAll","_text","length","_fireSelectionChanged","_updateTextarea","cmdAll","getSelectedText","slice","join","findWordBoundaryLeft","startFrom","offset","index","_reSpace","test","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","text","reNewline","_char","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","e","editable","enterEditingImpl","fire","undefined","target","requestRenderAll","calcOffset","textEditingManager","exitTextEditing","useOverlayEditing","enterOverlayEditing","initHiddenTextarea","hiddenTextarea","focus","_saveEditingProps","_setEditingProps","_textBeforeEdit","enterTextOverlayEdit","onCommit","commitOverlayEdit","onCancel","cancelOverlayEdit","overlayEditor","__overlayEditor","result","extractLinesFromDOM","textareaElement","storeBrowserLines","lines","error","console","warn","dirty","initDimensions","setCoords","getActiveControl","el","getDocumentFromElement","activeElement","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","startIndex","min","endIndex","hoverCursor","defaultCursor","moveCursor","borderColor","editingBorderColor","hasControls","selectable","lockMovementX","lockMovementY","fromStringToGraphemeSelection","start","end","smallerTextStart","graphemeStart","graphemeSplit","smallerTextEnd","graphemeEnd","fromGraphemeToStringSelection","graphemes","log","cursorOffsetCache","currentFabricText","inCompositionMode","newSelection","updateTextareaPosition","updateFromTextArea","textarea","set","style","_calcTextareaPosition","left","top","desiredPosition","compositionStart","boundaries","_getCursorBoundaries","cursorLocation","get2DCursorLocation","lineIndex","charIndex","charHeight","getValueOfPropertyAt","lineHeight","leftOffset","retinaScaling","getCanvasRetinaScaling","upperCanvas","upperCanvasEl","upperCanvasWidth","width","upperCanvasHeight","height","maxWidth","maxHeight","p","Point","topOffset","transform","calcTransformMatrix","viewportTransform","multiply","clientWidth","clientHeight","x","y","_offset","fontSize","_savedProps","_restoreEditingProps","_this$_savedProps$def","_this$_savedProps$mov","exitEditingImpl","blur","parentNode","removeChild","_forceClearCache","isTextChanged","MODIFIED","_removeExtraneousStyles","prop","styles","_textLines","removeStyleFromTo","lineStart","charStart","lineEnd","charEnd","i","_unwrappedTextLines","styleObj","shiftLineStyles","diff","char","numericChar","parseInt","clonedStyles","Object","assign","line","numericLine","insertNewlineStyleObject","qty","copiedStyle","newLineStyles","originalLineLength","isEndOfLine","someStyleIsCarryingOver","currentCharStyle","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","keys","newStyle","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","removeChars","splice","insertChars","setSelectionStartEndWithShift","_selectionDirection","LEFT","RIGHT"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ITextKeyBehavior.d.ts","sourceRoot":"","sources":["../../../../src/shapes/IText/ITextKeyBehavior.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ITextKeyBehavior.d.ts","sourceRoot":"","sources":["../../../../src/shapes/IText/ITextKeyBehavior.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{config as t}from"../../config.min.mjs";import{getFabricDocument as e,getEnv as i}from"../../env/index.min.mjs";import{capValue as s}from"../../util/misc/capValue.min.mjs";import{ITextBehavior as o}from"./ITextBehavior.min.mjs";import{getDocumentFromElement as n}from"../../util/dom_misc.min.mjs";import{RIGHT as r,LEFT as h,CHANGED as c}from"../../constants.min.mjs";class a extends o{initHiddenTextarea(){const t=this.canvas&&n(this.canvas.getElement())||e(),i=t.createElement("textarea");Object.entries({autocapitalize:"off",autocorrect:"off",autocomplete:"off",spellcheck:"false","data-fabric":"textarea",wrap:"off"}).map(t=>{let[e,s]=t;return i.setAttribute(e,s)});const{top:s,left:o,fontSize:r}=this._calcTextareaPosition();i.style.cssText=`position: absolute; top: ${s}; left: ${o}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${r};`,(this.hiddenTextareaContainer||t.body).appendChild(i),Object.entries({blur:"blur",keydown:"onKeyDown",keyup:"onKeyUp",input:"onInput",copy:"copy",cut:"copy",paste:"paste",compositionstart:"onCompositionStart",compositionupdate:"onCompositionUpdate",compositionend:"onCompositionEnd"}).map(t=>{let[e,s]=t;return i.addEventListener(e,this[s].bind(this))}),this.hiddenTextarea=i}blur(){this.abortCursorAnimation()}onKeyDown(t){if(!this.isEditing)return;const e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown)||!t.ctrlKey&&!t.metaKey)return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),t.keyCode>=33&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}onKeyUp(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())}onInput(e){const s=this.fromPaste,{value:o,selectionStart:n,selectionEnd:r}=this.hiddenTextarea;if(this.fromPaste=!1,e&&e.stopPropagation(),!this.isEditing)return;const h=()=>{this.updateFromTextArea(),this.fire(c),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())};if(""===this.hiddenTextarea.value)return this.styles={},void h();const a=this._splitTextIntoLines(o).graphemeText,l=this._text.length,d=a.length,m=this.selectionStart,f=this.selectionEnd,p=m!==f;let u,g,S,_,y=d-l;const C=this.fromStringToGraphemeSelection(n,r,o),x=m>C.selectionStart;p?(g=this._text.slice(m,f),y+=f-m):d<l&&(g=x?this._text.slice(f+y,f):this._text.slice(m,m-y));const v=a.slice(C.selectionEnd-y,C.selectionEnd);if(g&&g.length&&(v.length&&(u=this.getSelectionStyles(m,m+1,!1),u=v.map(()=>u[0])),p?(S=m,_=f):x?(S=f-g.length,_=f):(S=f,_=f+g.length),this.removeStyleFromTo(S,_)),v.length){const{copyPasteData:e}=i();s&&v.join("")===e.copiedText&&!t.disableStyleCopyPaste&&(u=e.copiedTextStyle),this.insertNewStyleBlock(v,m,u)}h()}onCompositionStart(){this.inCompositionMode=!0}onCompositionEnd(){this.inCompositionMode=!1}onCompositionUpdate(t){let{target:e}=t;const{selectionStart:i,selectionEnd:s}=e;this.compositionStart=i,this.compositionEnd=s,this.updateTextareaPosition()}copy(){if(this.selectionStart===this.selectionEnd)return;const{copyPasteData:e}=i();e.copiedText=this.getSelectedText(),t.disableStyleCopyPaste?e.copiedTextStyle=void 0:e.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd,!0),this._copyDone=!0}paste(){this.fromPaste=!0}_getWidthBeforeCursor(t,e){let i,s=this._getLineLeftOffset(t);return e>0&&(i=this.__charBounds[t][e-1],s+=i.left+i.width),s}getDownCursorOffset(t,e){const i=this._getSelectionForOffset(t,e),s=this.get2DCursorLocation(i),o=s.lineIndex;if(o===this._textLines.length-1||t.metaKey||34===t.keyCode)return this._text.length-i;const n=s.charIndex,r=this._getWidthBeforeCursor(o,n),h=this._getIndexOnLine(o+1,r);return this._textLines[o].slice(n).length+h+1+this.missingNewlineOffset(o)}_getSelectionForOffset(t,e){return t.shiftKey&&this.selectionStart!==this.selectionEnd&&e?this.selectionEnd:this.selectionStart}getUpCursorOffset(t,e){const i=this._getSelectionForOffset(t,e),s=this.get2DCursorLocation(i),o=s.lineIndex;if(0===o||t.metaKey||33===t.keyCode)return-i;const n=s.charIndex,r=this._getWidthBeforeCursor(o,n),h=this._getIndexOnLine(o-1,r),c=this._textLines[o].slice(0,n),a=this.missingNewlineOffset(o-1);return-this._textLines[o-1].length+h-c.length+(1-a)}_getIndexOnLine(t,e){const i=this._textLines[t];let s,o,n=this._getLineLeftOffset(t),r=0;for(let h=0,c=i.length;h<c;h++)if(s=this.__charBounds[t][h].width,n+=s,n>e){o=!0;const t=n-s,i=n,c=Math.abs(t-e);r=Math.abs(i-e)<c?h:h-1;break}return o||(r=i.length-1),r}moveCursorDown(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)}moveCursorUp(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)}_moveCursorUpOrDown(t,e){const i=this[`get${t}CursorOffset`](e,this._selectionDirection===r);if(e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i){const t=this.text.length;this.selectionStart=s(0,this.selectionStart,t),this.selectionEnd=s(0,this.selectionEnd,t),this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea()}}moveCursorWithShift(t){const e=this._selectionDirection===h?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t}moveCursorWithoutShift(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t}moveCursorLeft(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)}_move(t,e,i){let s;if(t.altKey)s=this[`findWordBoundary${i}`](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;s=this[`findLineBoundary${i}`](this[e])}return void 0!==s&&this[e]!==s&&(this[e]=s,!0)}_moveLeft(t,e){return this._move(t,e,"Left")}_moveRight(t,e){return this._move(t,e,"Right")}moveCursorLeftWithoutShift(t){let e=!0;return this._selectionDirection=h,this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e}moveCursorLeftWithShift(t){return this._selectionDirection===r&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection=h,this._moveLeft(t,"selectionStart")):void 0}moveCursorRight(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)}_moveCursorLeftOrRight(t,e){const i=`moveCursor${t}${e.shiftKey?"WithShift":"WithoutShift"}`;this._currentCursorOpacity=1,this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())}moveCursorRightWithShift(t){return this._selectionDirection===h&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection=r,this._moveRight(t,"selectionEnd")):void 0}moveCursorRightWithoutShift(t){let e=!0;return this._selectionDirection=r,this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e}}export{a as ITextKeyBehavior};
1
+ import{config as t}from"../../config.min.mjs";import{getFabricDocument as e,getEnv as i}from"../../env/index.min.mjs";import{capValue as s}from"../../util/misc/capValue.min.mjs";import{ITextBehavior as o}from"./ITextBehavior.min.mjs";import{getDocumentFromElement as n}from"../../util/dom_misc.min.mjs";import{CHANGED as r,RIGHT as h,LEFT as a}from"../../constants.min.mjs";class c extends o{initHiddenTextarea(){const t=this.canvas&&n(this.canvas.getElement())||e(),i=t.createElement("textarea");Object.entries({autocapitalize:"off",autocorrect:"off",autocomplete:"off",spellcheck:"false","data-fabric":"textarea",wrap:"off"}).map(t=>{let[e,s]=t;return i.setAttribute(e,s)});const{top:s,left:o,fontSize:r}=this._calcTextareaPosition();i.style.cssText=`position: absolute; top: ${s}; left: ${o}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${r};`,(this.hiddenTextareaContainer||t.body).appendChild(i),Object.entries({blur:"blur",keydown:"onKeyDown",keyup:"onKeyUp",input:"onInput",copy:"copy",cut:"copy",paste:"paste",compositionstart:"onCompositionStart",compositionupdate:"onCompositionUpdate",compositionend:"onCompositionEnd"}).map(t=>{let[e,s]=t;return i.addEventListener(e,this[s].bind(this))}),this.hiddenTextarea=i}blur(){this.abortCursorAnimation()}onKeyDown(t){if(!this.isEditing)return;const e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown)||!t.ctrlKey&&!t.metaKey)return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),t.keyCode>=33&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}onKeyUp(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())}onInput(e){const s=this.fromPaste,{value:o,selectionStart:n,selectionEnd:h}=this.hiddenTextarea;if(this.fromPaste=!1,e&&e.stopPropagation(),!this.isEditing)return;if(console.log("🔤 onInput debug:",{fabricText:this.text,textareaValue:o,fabricSelection:{start:this.selectionStart,end:this.selectionEnd},textareaSelection:{start:n,end:h},fromPaste:s,inComposition:this.inCompositionMode}),this.text!==o&&!this.inCompositionMode)return console.log("🔤 Immediate sync: fabric text differs from textarea, syncing immediately"),console.log("🔤 Before sync - fabric text:",this.text),console.log("🔤 Before sync - textarea value:",o),console.log("🔤 fromPaste:",s),this.cursorOffsetCache={},this._browserWrapCache=null,this._lastDimensionState=null,this._forceClearCache=!0,console.log("🔤 Cleared all caches"),this.updateFromTextArea(),this.fire(r),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.renderAll()),console.log("🔤 After updateFromTextArea - fabric text:",this.text),void console.log("🔤 Sync complete, caches cleared, synchronous render only");const a=()=>{this.updateFromTextArea(),this.fire(r),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())};if(""===this.hiddenTextarea.value)return this.styles={},void a();const c=this._splitTextIntoLines(o).graphemeText,l=this._text.length,d=c.length,f=this.selectionStart,m=this.selectionEnd,p=f!==m;let u,g,S,y,C=d-l;const x=this.fromStringToGraphemeSelection(n,h,o),_=f>x.selectionStart;p?(g=this._text.slice(f,m),C+=m-f):d<l&&(g=_?this._text.slice(m+C,m):this._text.slice(f,f-C));const v=c.slice(x.selectionEnd-C,x.selectionEnd);if(g&&g.length&&(v.length&&(u=this.getSelectionStyles(f,f+1,!1),u=v.map(()=>u[0])),p?(S=f,y=m):_?(S=m-g.length,y=m):(S=m,y=m+g.length),this.removeStyleFromTo(S,y)),v.length){const{copyPasteData:e}=i();s&&v.join("")===e.copiedText&&!t.disableStyleCopyPaste&&(u=e.copiedTextStyle),this.insertNewStyleBlock(v,f,u)}a()}onCompositionStart(){this.inCompositionMode=!0}onCompositionEnd(){this.inCompositionMode=!1}onCompositionUpdate(t){let{target:e}=t;const{selectionStart:i,selectionEnd:s}=e;this.compositionStart=i,this.compositionEnd=s,this.updateTextareaPosition()}copy(){if(this.selectionStart===this.selectionEnd)return;const{copyPasteData:e}=i();e.copiedText=this.getSelectedText(),t.disableStyleCopyPaste?e.copiedTextStyle=void 0:e.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd,!0),this._copyDone=!0}paste(){this.fromPaste=!0}_getWidthBeforeCursor(t,e){let i,s=this._getLineLeftOffset(t);return e>0&&(i=this.__charBounds[t][e-1],s+=i.left+i.width),s}getDownCursorOffset(t,e){const i=this._getSelectionForOffset(t,e),s=this.get2DCursorLocation(i),o=s.lineIndex;if(o===this._textLines.length-1||t.metaKey||34===t.keyCode)return this._text.length-i;const n=s.charIndex,r=this._getWidthBeforeCursor(o,n),h=this._getIndexOnLine(o+1,r);return this._textLines[o].slice(n).length+h+1+this.missingNewlineOffset(o)}_getSelectionForOffset(t,e){return t.shiftKey&&this.selectionStart!==this.selectionEnd&&e?this.selectionEnd:this.selectionStart}getUpCursorOffset(t,e){const i=this._getSelectionForOffset(t,e),s=this.get2DCursorLocation(i),o=s.lineIndex;if(0===o||t.metaKey||33===t.keyCode)return-i;const n=s.charIndex,r=this._getWidthBeforeCursor(o,n),h=this._getIndexOnLine(o-1,r),a=this._textLines[o].slice(0,n),c=this.missingNewlineOffset(o-1);return-this._textLines[o-1].length+h-a.length+(1-c)}_getIndexOnLine(t,e){const i=this._textLines[t];let s,o,n=this._getLineLeftOffset(t),r=0;for(let h=0,a=i.length;h<a;h++)if(s=this.__charBounds[t][h].width,n+=s,n>e){o=!0;const t=n-s,i=n,a=Math.abs(t-e);r=Math.abs(i-e)<a?h:h-1;break}return o||(r=i.length-1),r}moveCursorDown(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)}moveCursorUp(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)}_moveCursorUpOrDown(t,e){const i=this[`get${t}CursorOffset`](e,this._selectionDirection===h);if(e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i){const t=this.text.length;this.selectionStart=s(0,this.selectionStart,t),this.selectionEnd=s(0,this.selectionEnd,t),this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea()}}moveCursorWithShift(t){const e=this._selectionDirection===a?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t}moveCursorWithoutShift(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t}moveCursorLeft(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)}_move(t,e,i){let s;if(t.altKey)s=this[`findWordBoundary${i}`](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;s=this[`findLineBoundary${i}`](this[e])}return void 0!==s&&this[e]!==s&&(this[e]=s,!0)}_moveLeft(t,e){return this._move(t,e,"Left")}_moveRight(t,e){return this._move(t,e,"Right")}moveCursorLeftWithoutShift(t){let e=!0;return this._selectionDirection=a,this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e}moveCursorLeftWithShift(t){return this._selectionDirection===h&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection=a,this._moveLeft(t,"selectionStart")):void 0}moveCursorRight(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)}_moveCursorLeftOrRight(t,e){const i=`moveCursor${t}${e.shiftKey?"WithShift":"WithoutShift"}`;this._currentCursorOpacity=1,this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())}moveCursorRightWithShift(t){return this._selectionDirection===a&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection=h,this._moveRight(t,"selectionEnd")):void 0}moveCursorRightWithoutShift(t){let e=!0;return this._selectionDirection=h,this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e}}export{c as ITextKeyBehavior};
2
2
  //# sourceMappingURL=ITextKeyBehavior.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ITextKeyBehavior.min.mjs","sources":["../../../../src/shapes/IText/ITextKeyBehavior.ts"],"sourcesContent":["import { config } from '../../config';\nimport { getFabricDocument, getEnv } from '../../env';\nimport { capValue } from '../../util/misc/capValue';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextBehavior } from './ITextBehavior';\nimport type { TKeyMapIText } from './constants';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, LEFT, RIGHT } from '../../constants';\nimport type { IText } from './IText';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\n\nexport abstract class ITextKeyBehavior<\n Props extends TOptions<TextProps> = Partial<TextProps>,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextBehavior<Props, SProps, EventSpec> {\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behavior for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the IText or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = Object.assign({}, this.keysMap);\n * The function must be in IText.prototype.myFunction And will receive event as args[0]\n */\n declare keysMap: TKeyMapIText;\n\n declare keysMapRtl: TKeyMapIText;\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n declare ctrlKeysMapUp: TKeyMapIText;\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n declare ctrlKeysMapDown: TKeyMapIText;\n\n declare hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * DOM container to append the hiddenTextarea.\n * An alternative to attaching to the document.body.\n * Useful to reduce laggish redraw of the full document.body tree and\n * also with modals event capturing that won't let the textarea take focus.\n * @type HTMLElement\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n declare private _clickHandlerInitialized: boolean;\n declare private _copyDone: boolean;\n declare private fromPaste: boolean;\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea() {\n const doc =\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument();\n const textarea = doc.createElement('textarea');\n Object.entries({\n autocapitalize: 'off',\n autocorrect: 'off',\n autocomplete: 'off',\n spellcheck: 'false',\n 'data-fabric': 'textarea',\n wrap: 'off',\n }).map(([attribute, value]) => textarea.setAttribute(attribute, value));\n const { top, left, fontSize } = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n textarea.style.cssText = `position: absolute; top: ${top}; left: ${left}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${fontSize};`;\n\n (this.hiddenTextareaContainer || doc.body).appendChild(textarea);\n\n Object.entries({\n blur: 'blur',\n keydown: 'onKeyDown',\n keyup: 'onKeyUp',\n input: 'onInput',\n copy: 'copy',\n cut: 'copy',\n paste: 'paste',\n compositionstart: 'onCompositionStart',\n compositionupdate: 'onCompositionUpdate',\n compositionend: 'onCompositionEnd',\n } as Record<string, keyof this>).map(([eventName, handler]) =>\n textarea.addEventListener(\n eventName,\n (this[handler] as EventListener).bind(this),\n ),\n );\n this.hiddenTextarea = textarea;\n }\n\n /**\n * Override this method to customize cursor behavior on textbox blur\n */\n blur() {\n this.abortCursorAnimation();\n }\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {KeyboardEvent} e Event object\n */\n onKeyDown(e: KeyboardEvent) {\n if (!this.isEditing) {\n return;\n }\n const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;\n if (e.keyCode in keyMap) {\n (this[keyMap[e.keyCode] as keyof this] as (arg: KeyboardEvent) => void)(\n e,\n );\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n (\n this[this.ctrlKeysMapDown[e.keyCode] as keyof this] as (\n arg: KeyboardEvent,\n ) => void\n )(e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n } else {\n this.canvas && this.canvas.requestRenderAll();\n }\n }\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {KeyboardEvent} e Event object\n */\n onKeyUp(e: KeyboardEvent) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n (\n this[this.ctrlKeysMapUp[e.keyCode] as keyof this] as (\n arg: KeyboardEvent,\n ) => void\n )(e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n }\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {\n const fromPaste = this.fromPaste;\n const { value, selectionStart, selectionEnd } = this.hiddenTextarea;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n const updateAndFire = () => {\n this.updateFromTextArea();\n this.fire(CHANGED);\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this as unknown as IText });\n this.canvas.requestRenderAll();\n }\n };\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n updateAndFire();\n return;\n }\n // decisions about style changes.\n const nextText = this._splitTextIntoLines(value).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n _selectionStart = this.selectionStart,\n _selectionEnd = this.selectionEnd,\n selection = _selectionStart !== _selectionEnd;\n let copiedStyle: TextStyleDeclaration[] | undefined,\n removedText,\n charDiff = nextCharCount - charCount,\n removeFrom,\n removeTo;\n\n const textareaSelection = this.fromStringToGraphemeSelection(\n selectionStart,\n selectionEnd,\n value,\n );\n const backDelete = _selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(_selectionStart, _selectionEnd);\n charDiff += _selectionEnd - _selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(_selectionEnd + charDiff, _selectionEnd);\n } else {\n removedText = this._text.slice(\n _selectionStart,\n _selectionStart - charDiff,\n );\n }\n }\n const insertedText = nextText.slice(\n textareaSelection.selectionEnd - charDiff,\n textareaSelection.selectionEnd,\n );\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(\n _selectionStart,\n _selectionStart + 1,\n false,\n );\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(\n () =>\n // this return an array of references, but that is fine since we are\n // copying the style later.\n copiedStyle![0],\n );\n }\n if (selection) {\n removeFrom = _selectionStart;\n removeTo = _selectionEnd;\n } else if (backDelete) {\n // detect differences between forwardDelete and backDelete\n removeFrom = _selectionEnd - removedText.length;\n removeTo = _selectionEnd;\n } else {\n removeFrom = _selectionEnd;\n removeTo = _selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n const { copyPasteData } = getEnv();\n if (\n fromPaste &&\n insertedText.join('') === copyPasteData.copiedText &&\n !config.disableStyleCopyPaste\n ) {\n copiedStyle = copyPasteData.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, _selectionStart, copiedStyle);\n }\n updateAndFire();\n }\n\n /**\n * Composition start\n */\n onCompositionStart() {\n this.inCompositionMode = true;\n }\n\n /**\n * Composition end\n */\n onCompositionEnd() {\n this.inCompositionMode = false;\n }\n\n onCompositionUpdate({ target }: CompositionEvent) {\n const { selectionStart, selectionEnd } = target as HTMLTextAreaElement;\n this.compositionStart = selectionStart;\n this.compositionEnd = selectionEnd;\n this.updateTextareaPosition();\n }\n\n /**\n * Copies selected text\n */\n copy() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n const { copyPasteData } = getEnv();\n copyPasteData.copiedText = this.getSelectedText();\n if (!config.disableStyleCopyPaste) {\n copyPasteData.copiedTextStyle = this.getSelectionStyles(\n this.selectionStart,\n this.selectionEnd,\n true,\n );\n } else {\n copyPasteData.copiedTextStyle = undefined;\n }\n this._copyDone = true;\n }\n\n /**\n * Pastes text\n */\n paste() {\n this.fromPaste = true;\n }\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor(lineIndex: number, charIndex: number): number {\n let widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n }\n\n /**\n * Gets start offset of a selection\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (\n lineIndex === this._textLines.length - 1 ||\n e.metaKey ||\n e.keyCode === 34\n ) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return (\n textAfterCursor.length +\n indexOnOtherLine +\n 1 +\n this.missingNewlineOffset(lineIndex)\n );\n }\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset(e: KeyboardEvent, isRight: boolean): number {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n } else {\n return this.selectionStart;\n }\n }\n\n /**\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return (\n -this._textLines[lineIndex - 1].length +\n indexOnOtherLine -\n textBeforeCursor.length +\n (1 - missingNewlineOffset)\n );\n }\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine(lineIndex: number, width: number) {\n const line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n let widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n const leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n }\n\n /**\n * Moves cursor down\n * @param {KeyboardEvent} e Event object\n */\n moveCursorDown(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n }\n\n /**\n * Moves cursor up\n * @param {KeyboardEvent} e Event object\n */\n moveCursorUp(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n }\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorUpOrDown(direction: 'Up' | 'Down', e: KeyboardEvent) {\n const offset = this[`get${direction}CursorOffset`](\n e,\n this._selectionDirection === RIGHT,\n );\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n const max = this.text.length;\n this.selectionStart = capValue(0, this.selectionStart, max);\n this.selectionEnd = capValue(0, this.selectionEnd, max);\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift(offset: number) {\n const newSelection =\n this._selectionDirection === LEFT\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(\n this.selectionStart,\n this.selectionEnd,\n newSelection,\n );\n return offset !== 0;\n }\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift(offset: number) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n }\n\n /**\n * Moves cursor left\n * @param {KeyboardEvent} e Event object\n */\n moveCursorLeft(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n }\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n *\n * @todo refactor not to use method name composition\n */\n _move(\n e: KeyboardEvent,\n prop: 'selectionStart' | 'selectionEnd',\n direction: 'Left' | 'Right',\n ): boolean {\n let newValue: number | undefined;\n if (e.altKey) {\n newValue = this[`findWordBoundary${direction}`](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this[`findLineBoundary${direction}`](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== 'undefined' && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n return false;\n }\n\n /**\n * @private\n */\n _moveLeft(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Left');\n }\n\n /**\n * @private\n */\n _moveRight(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Right');\n }\n\n /**\n * Moves cursor left without keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithoutShift(e: KeyboardEvent) {\n let change = true;\n this._selectionDirection = LEFT;\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (\n this.selectionEnd === this.selectionStart &&\n this.selectionStart !== 0\n ) {\n change = this._moveLeft(e, 'selectionStart');\n }\n this.selectionEnd = this.selectionStart;\n return change;\n }\n\n /**\n * Moves cursor left while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === RIGHT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveLeft(e, 'selectionEnd');\n } else if (this.selectionStart !== 0) {\n this._selectionDirection = LEFT;\n return this._moveLeft(e, 'selectionStart');\n }\n }\n\n /**\n * Moves cursor right\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRight(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n }\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorLeftOrRight(direction: 'Left' | 'Right', e: KeyboardEvent) {\n const actionName = `moveCursor${direction}${\n e.shiftKey ? 'WithShift' : 'WithoutShift'\n }` as const;\n this._currentCursorOpacity = 1;\n if (this[actionName](e)) {\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor right while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorRightWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === LEFT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveRight(e, 'selectionStart');\n } else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = RIGHT;\n return this._moveRight(e, 'selectionEnd');\n }\n }\n\n /**\n * Moves cursor right without keeping selection\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRightWithoutShift(e: KeyboardEvent) {\n let changed = true;\n this._selectionDirection = RIGHT;\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n }\n}\n"],"names":["ITextKeyBehavior","ITextBehavior","initHiddenTextarea","doc","this","canvas","getDocumentFromElement","getElement","getFabricDocument","textarea","createElement","Object","entries","autocapitalize","autocorrect","autocomplete","spellcheck","wrap","map","_ref","attribute","value","setAttribute","top","left","fontSize","_calcTextareaPosition","style","cssText","hiddenTextareaContainer","body","appendChild","blur","keydown","keyup","input","copy","cut","paste","compositionstart","compositionupdate","compositionend","_ref2","eventName","handler","addEventListener","bind","hiddenTextarea","abortCursorAnimation","onKeyDown","e","isEditing","keyMap","direction","keysMapRtl","keysMap","keyCode","ctrlKeysMapDown","ctrlKey","metaKey","stopImmediatePropagation","preventDefault","inCompositionMode","clearContextTop","renderCursorOrSelection","requestRenderAll","onKeyUp","_copyDone","ctrlKeysMapUp","onInput","fromPaste","selectionStart","selectionEnd","stopPropagation","updateAndFire","updateFromTextArea","fire","CHANGED","target","styles","nextText","_splitTextIntoLines","graphemeText","charCount","_text","length","nextCharCount","_selectionStart","_selectionEnd","selection","copiedStyle","removedText","removeFrom","removeTo","charDiff","textareaSelection","fromStringToGraphemeSelection","backDelete","slice","insertedText","getSelectionStyles","removeStyleFromTo","copyPasteData","getEnv","join","copiedText","config","disableStyleCopyPaste","copiedTextStyle","insertNewStyleBlock","onCompositionStart","onCompositionEnd","onCompositionUpdate","_ref3","compositionStart","compositionEnd","updateTextareaPosition","getSelectedText","undefined","_getWidthBeforeCursor","lineIndex","charIndex","bound","widthBeforeCursor","_getLineLeftOffset","__charBounds","width","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","cursorLocation","get2DCursorLocation","_textLines","indexOnOtherLine","_getIndexOnLine","missingNewlineOffset","shiftKey","getUpCursorOffset","textBeforeCursor","line","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","j","jlen","leftEdge","rightEdge","offsetFromLeftEdge","Math","abs","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","offset","_selectionDirection","RIGHT","moveCursorWithShift","moveCursorWithoutShift","max","text","capValue","initDelayedCursor","_fireSelectionChanged","_updateTextarea","newSelection","LEFT","setSelectionStartEndWithShift","moveCursorLeft","_moveCursorLeftOrRight","_move","prop","newValue","altKey","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","actionName","_currentCursorOpacity","moveCursorRightWithShift","moveCursorRightWithoutShift","changed"],"mappings":"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"}
1
+ {"version":3,"file":"ITextKeyBehavior.min.mjs","sources":["../../../../src/shapes/IText/ITextKeyBehavior.ts"],"sourcesContent":["import { config } from '../../config';\r\nimport { getFabricDocument, getEnv } from '../../env';\r\nimport { capValue } from '../../util/misc/capValue';\r\nimport type { ITextEvents } from './ITextBehavior';\r\nimport { ITextBehavior } from './ITextBehavior';\r\nimport type { TKeyMapIText } from './constants';\r\nimport type { TOptions } from '../../typedefs';\r\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\r\nimport { getDocumentFromElement } from '../../util/dom_misc';\r\nimport { CHANGED, LEFT, RIGHT } from '../../constants';\r\nimport type { IText } from './IText';\r\nimport type { TextStyleDeclaration } from '../Text/StyledText';\r\n\r\nexport abstract class ITextKeyBehavior<\r\n Props extends TOptions<TextProps> = Partial<TextProps>,\r\n SProps extends SerializedTextProps = SerializedTextProps,\r\n EventSpec extends ITextEvents = ITextEvents,\r\n> extends ITextBehavior<Props, SProps, EventSpec> {\r\n /**\r\n * For functionalities on keyDown\r\n * Map a special key to a function of the instance/prototype\r\n * If you need different behavior for ESC or TAB or arrows, you have to change\r\n * this map setting the name of a function that you build on the IText or\r\n * your prototype.\r\n * the map change will affect all Instances unless you need for only some text Instances\r\n * in that case you have to clone this object and assign your Instance.\r\n * this.keysMap = Object.assign({}, this.keysMap);\r\n * The function must be in IText.prototype.myFunction And will receive event as args[0]\r\n */\r\n declare keysMap: TKeyMapIText;\r\n\r\n declare keysMapRtl: TKeyMapIText;\r\n\r\n /**\r\n * For functionalities on keyUp + ctrl || cmd\r\n */\r\n declare ctrlKeysMapUp: TKeyMapIText;\r\n\r\n /**\r\n * For functionalities on keyDown + ctrl || cmd\r\n */\r\n declare ctrlKeysMapDown: TKeyMapIText;\r\n\r\n declare hiddenTextarea: HTMLTextAreaElement | null;\r\n\r\n /**\r\n * DOM container to append the hiddenTextarea.\r\n * An alternative to attaching to the document.body.\r\n * Useful to reduce laggish redraw of the full document.body tree and\r\n * also with modals event capturing that won't let the textarea take focus.\r\n * @type HTMLElement\r\n */\r\n declare hiddenTextareaContainer?: HTMLElement | null;\r\n\r\n declare private _clickHandlerInitialized: boolean;\r\n declare private _copyDone: boolean;\r\n declare private fromPaste: boolean;\r\n\r\n /**\r\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\r\n */\r\n initHiddenTextarea() {\r\n const doc =\r\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\r\n getFabricDocument();\r\n const textarea = doc.createElement('textarea');\r\n Object.entries({\r\n autocapitalize: 'off',\r\n autocorrect: 'off',\r\n autocomplete: 'off',\r\n spellcheck: 'false',\r\n 'data-fabric': 'textarea',\r\n wrap: 'off',\r\n }).map(([attribute, value]) => textarea.setAttribute(attribute, value));\r\n const { top, left, fontSize } = this._calcTextareaPosition();\r\n // line-height: 1px; was removed from the style to fix this:\r\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\r\n textarea.style.cssText = `position: absolute; top: ${top}; left: ${left}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${fontSize};`;\r\n\r\n (this.hiddenTextareaContainer || doc.body).appendChild(textarea);\r\n\r\n Object.entries({\r\n blur: 'blur',\r\n keydown: 'onKeyDown',\r\n keyup: 'onKeyUp',\r\n input: 'onInput',\r\n copy: 'copy',\r\n cut: 'copy',\r\n paste: 'paste',\r\n compositionstart: 'onCompositionStart',\r\n compositionupdate: 'onCompositionUpdate',\r\n compositionend: 'onCompositionEnd',\r\n } as Record<string, keyof this>).map(([eventName, handler]) =>\r\n textarea.addEventListener(\r\n eventName,\r\n (this[handler] as EventListener).bind(this),\r\n ),\r\n );\r\n this.hiddenTextarea = textarea;\r\n }\r\n\r\n /**\r\n * Override this method to customize cursor behavior on textbox blur\r\n */\r\n blur() {\r\n this.abortCursorAnimation();\r\n }\r\n\r\n /**\r\n * Handles keydown event\r\n * only used for arrows and combination of modifier keys.\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n onKeyDown(e: KeyboardEvent) {\r\n if (!this.isEditing) {\r\n return;\r\n }\r\n const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;\r\n if (e.keyCode in keyMap) {\r\n (this[keyMap[e.keyCode] as keyof this] as (arg: KeyboardEvent) => void)(\r\n e,\r\n );\r\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\r\n (\r\n this[this.ctrlKeysMapDown[e.keyCode] as keyof this] as (\r\n arg: KeyboardEvent,\r\n ) => void\r\n )(e);\r\n } else {\r\n return;\r\n }\r\n e.stopImmediatePropagation();\r\n e.preventDefault();\r\n if (e.keyCode >= 33 && e.keyCode <= 40) {\r\n // if i press an arrow key just update selection\r\n this.inCompositionMode = false;\r\n this.clearContextTop();\r\n this.renderCursorOrSelection();\r\n } else {\r\n this.canvas && this.canvas.requestRenderAll();\r\n }\r\n }\r\n\r\n /**\r\n * Handles keyup event\r\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\r\n * if a copy/cut event fired, keyup is dismissed\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n onKeyUp(e: KeyboardEvent) {\r\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\r\n this._copyDone = false;\r\n return;\r\n }\r\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\r\n (\r\n this[this.ctrlKeysMapUp[e.keyCode] as keyof this] as (\r\n arg: KeyboardEvent,\r\n ) => void\r\n )(e);\r\n } else {\r\n return;\r\n }\r\n e.stopImmediatePropagation();\r\n e.preventDefault();\r\n this.canvas && this.canvas.requestRenderAll();\r\n }\r\n\r\n /**\r\n * Handles onInput event\r\n * @param {Event} e Event object\r\n */\r\n onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {\r\n const fromPaste = this.fromPaste;\r\n const { value, selectionStart, selectionEnd } = this.hiddenTextarea;\r\n this.fromPaste = false;\r\n e && e.stopPropagation();\r\n if (!this.isEditing) {\r\n return;\r\n }\r\n \r\n // Debug log to track the double keypress issue\r\n console.log('🔤 onInput debug:', {\r\n fabricText: this.text,\r\n textareaValue: value,\r\n fabricSelection: { start: this.selectionStart, end: this.selectionEnd },\r\n textareaSelection: { start: selectionStart, end: selectionEnd },\r\n fromPaste,\r\n inComposition: this.inCompositionMode\r\n });\r\n \r\n // Immediate sync for simple character replacement - fix for double keypress issue\r\n if (this.text !== value && !this.inCompositionMode) {\r\n console.log('🔤 Immediate sync: fabric text differs from textarea, syncing immediately');\r\n console.log('🔤 Before sync - fabric text:', this.text);\r\n console.log('🔤 Before sync - textarea value:', value);\r\n console.log('🔤 fromPaste:', fromPaste);\r\n \r\n // Clear all relevant caches that might prevent visual updates\r\n this.cursorOffsetCache = {};\r\n (this as any)._browserWrapCache = null;\r\n (this as any)._lastDimensionState = null;\r\n this._forceClearCache = true;\r\n \r\n console.log('🔤 Cleared all caches');\r\n \r\n // Use the same logic as updateAndFire but immediately\r\n this.updateFromTextArea();\r\n this.fire(CHANGED);\r\n if (this.canvas) {\r\n this.canvas.fire('text:changed', { target: this as unknown as IText });\r\n // ONLY use synchronous rendering to avoid race conditions\r\n // Remove requestRenderAll() which queues for next animation frame\r\n this.canvas.renderAll();\r\n }\r\n \r\n console.log('🔤 After updateFromTextArea - fabric text:', this.text);\r\n console.log('🔤 Sync complete, caches cleared, synchronous render only');\r\n return;\r\n }\r\n \r\n const updateAndFire = () => {\r\n this.updateFromTextArea();\r\n this.fire(CHANGED);\r\n if (this.canvas) {\r\n this.canvas.fire('text:changed', { target: this as unknown as IText });\r\n this.canvas.requestRenderAll();\r\n }\r\n };\r\n if (this.hiddenTextarea.value === '') {\r\n this.styles = {};\r\n updateAndFire();\r\n return;\r\n }\r\n // decisions about style changes.\r\n const nextText = this._splitTextIntoLines(value).graphemeText,\r\n charCount = this._text.length,\r\n nextCharCount = nextText.length,\r\n _selectionStart = this.selectionStart,\r\n _selectionEnd = this.selectionEnd,\r\n selection = _selectionStart !== _selectionEnd;\r\n let copiedStyle: TextStyleDeclaration[] | undefined,\r\n removedText,\r\n charDiff = nextCharCount - charCount,\r\n removeFrom,\r\n removeTo;\r\n\r\n const textareaSelection = this.fromStringToGraphemeSelection(\r\n selectionStart,\r\n selectionEnd,\r\n value,\r\n );\r\n const backDelete = _selectionStart > textareaSelection.selectionStart;\r\n\r\n if (selection) {\r\n removedText = this._text.slice(_selectionStart, _selectionEnd);\r\n charDiff += _selectionEnd - _selectionStart;\r\n } else if (nextCharCount < charCount) {\r\n if (backDelete) {\r\n removedText = this._text.slice(_selectionEnd + charDiff, _selectionEnd);\r\n } else {\r\n removedText = this._text.slice(\r\n _selectionStart,\r\n _selectionStart - charDiff,\r\n );\r\n }\r\n }\r\n const insertedText = nextText.slice(\r\n textareaSelection.selectionEnd - charDiff,\r\n textareaSelection.selectionEnd,\r\n );\r\n if (removedText && removedText.length) {\r\n if (insertedText.length) {\r\n // let's copy some style before deleting.\r\n // we want to copy the style before the cursor OR the style at the cursor if selection\r\n // is bigger than 0.\r\n copiedStyle = this.getSelectionStyles(\r\n _selectionStart,\r\n _selectionStart + 1,\r\n false,\r\n );\r\n // now duplicate the style one for each inserted text.\r\n copiedStyle = insertedText.map(\r\n () =>\r\n // this return an array of references, but that is fine since we are\r\n // copying the style later.\r\n copiedStyle![0],\r\n );\r\n }\r\n if (selection) {\r\n removeFrom = _selectionStart;\r\n removeTo = _selectionEnd;\r\n } else if (backDelete) {\r\n // detect differences between forwardDelete and backDelete\r\n removeFrom = _selectionEnd - removedText.length;\r\n removeTo = _selectionEnd;\r\n } else {\r\n removeFrom = _selectionEnd;\r\n removeTo = _selectionEnd + removedText.length;\r\n }\r\n this.removeStyleFromTo(removeFrom, removeTo);\r\n }\r\n if (insertedText.length) {\r\n const { copyPasteData } = getEnv();\r\n if (\r\n fromPaste &&\r\n insertedText.join('') === copyPasteData.copiedText &&\r\n !config.disableStyleCopyPaste\r\n ) {\r\n copiedStyle = copyPasteData.copiedTextStyle;\r\n }\r\n this.insertNewStyleBlock(insertedText, _selectionStart, copiedStyle);\r\n }\r\n updateAndFire();\r\n }\r\n\r\n /**\r\n * Composition start\r\n */\r\n onCompositionStart() {\r\n this.inCompositionMode = true;\r\n }\r\n\r\n /**\r\n * Composition end\r\n */\r\n onCompositionEnd() {\r\n this.inCompositionMode = false;\r\n }\r\n\r\n onCompositionUpdate({ target }: CompositionEvent) {\r\n const { selectionStart, selectionEnd } = target as HTMLTextAreaElement;\r\n this.compositionStart = selectionStart;\r\n this.compositionEnd = selectionEnd;\r\n this.updateTextareaPosition();\r\n }\r\n\r\n /**\r\n * Copies selected text\r\n */\r\n copy() {\r\n if (this.selectionStart === this.selectionEnd) {\r\n //do not cut-copy if no selection\r\n return;\r\n }\r\n const { copyPasteData } = getEnv();\r\n copyPasteData.copiedText = this.getSelectedText();\r\n if (!config.disableStyleCopyPaste) {\r\n copyPasteData.copiedTextStyle = this.getSelectionStyles(\r\n this.selectionStart,\r\n this.selectionEnd,\r\n true,\r\n );\r\n } else {\r\n copyPasteData.copiedTextStyle = undefined;\r\n }\r\n this._copyDone = true;\r\n }\r\n\r\n /**\r\n * Pastes text\r\n */\r\n paste() {\r\n this.fromPaste = true;\r\n }\r\n\r\n /**\r\n * Finds the width in pixels before the cursor on the same line\r\n * @private\r\n * @param {Number} lineIndex\r\n * @param {Number} charIndex\r\n * @return {Number} widthBeforeCursor width before cursor\r\n */\r\n _getWidthBeforeCursor(lineIndex: number, charIndex: number): number {\r\n let widthBeforeCursor = this._getLineLeftOffset(lineIndex),\r\n bound;\r\n\r\n if (charIndex > 0) {\r\n bound = this.__charBounds[lineIndex][charIndex - 1];\r\n widthBeforeCursor += bound.left + bound.width;\r\n }\r\n return widthBeforeCursor;\r\n }\r\n\r\n /**\r\n * Gets start offset of a selection\r\n * @param {KeyboardEvent} e Event object\r\n * @param {Boolean} isRight\r\n * @return {Number}\r\n */\r\n getDownCursorOffset(e: KeyboardEvent, isRight: boolean): number {\r\n const selectionProp = this._getSelectionForOffset(e, isRight),\r\n cursorLocation = this.get2DCursorLocation(selectionProp),\r\n lineIndex = cursorLocation.lineIndex;\r\n // if on last line, down cursor goes to end of line\r\n if (\r\n lineIndex === this._textLines.length - 1 ||\r\n e.metaKey ||\r\n e.keyCode === 34\r\n ) {\r\n // move to the end of a text\r\n return this._text.length - selectionProp;\r\n }\r\n const charIndex = cursorLocation.charIndex,\r\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\r\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\r\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\r\n return (\r\n textAfterCursor.length +\r\n indexOnOtherLine +\r\n 1 +\r\n this.missingNewlineOffset(lineIndex)\r\n );\r\n }\r\n\r\n /**\r\n * private\r\n * Helps finding if the offset should be counted from Start or End\r\n * @param {KeyboardEvent} e Event object\r\n * @param {Boolean} isRight\r\n * @return {Number}\r\n */\r\n _getSelectionForOffset(e: KeyboardEvent, isRight: boolean): number {\r\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\r\n return this.selectionEnd;\r\n } else {\r\n return this.selectionStart;\r\n }\r\n }\r\n\r\n /**\r\n * @param {KeyboardEvent} e Event object\r\n * @param {Boolean} isRight\r\n * @return {Number}\r\n */\r\n getUpCursorOffset(e: KeyboardEvent, isRight: boolean): number {\r\n const selectionProp = this._getSelectionForOffset(e, isRight),\r\n cursorLocation = this.get2DCursorLocation(selectionProp),\r\n lineIndex = cursorLocation.lineIndex;\r\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\r\n // if on first line, up cursor goes to start of line\r\n return -selectionProp;\r\n }\r\n const charIndex = cursorLocation.charIndex,\r\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\r\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\r\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\r\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\r\n // return a negative offset\r\n return (\r\n -this._textLines[lineIndex - 1].length +\r\n indexOnOtherLine -\r\n textBeforeCursor.length +\r\n (1 - missingNewlineOffset)\r\n );\r\n }\r\n\r\n /**\r\n * for a given width it founds the matching character.\r\n * @private\r\n */\r\n _getIndexOnLine(lineIndex: number, width: number) {\r\n const line = this._textLines[lineIndex],\r\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\r\n let widthOfCharsOnLine = lineLeftOffset,\r\n indexOnLine = 0,\r\n charWidth,\r\n foundMatch;\r\n\r\n for (let j = 0, jlen = line.length; j < jlen; j++) {\r\n charWidth = this.__charBounds[lineIndex][j].width;\r\n widthOfCharsOnLine += charWidth;\r\n if (widthOfCharsOnLine > width) {\r\n foundMatch = true;\r\n const leftEdge = widthOfCharsOnLine - charWidth,\r\n rightEdge = widthOfCharsOnLine,\r\n offsetFromLeftEdge = Math.abs(leftEdge - width),\r\n offsetFromRightEdge = Math.abs(rightEdge - width);\r\n\r\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\r\n break;\r\n }\r\n }\r\n\r\n // reached end\r\n if (!foundMatch) {\r\n indexOnLine = line.length - 1;\r\n }\r\n\r\n return indexOnLine;\r\n }\r\n\r\n /**\r\n * Moves cursor down\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n moveCursorDown(e: KeyboardEvent) {\r\n if (\r\n this.selectionStart >= this._text.length &&\r\n this.selectionEnd >= this._text.length\r\n ) {\r\n return;\r\n }\r\n this._moveCursorUpOrDown('Down', e);\r\n }\r\n\r\n /**\r\n * Moves cursor up\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n moveCursorUp(e: KeyboardEvent) {\r\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\r\n return;\r\n }\r\n this._moveCursorUpOrDown('Up', e);\r\n }\r\n\r\n /**\r\n * Moves cursor up or down, fires the events\r\n * @param {String} direction 'Up' or 'Down'\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n _moveCursorUpOrDown(direction: 'Up' | 'Down', e: KeyboardEvent) {\r\n const offset = this[`get${direction}CursorOffset`](\r\n e,\r\n this._selectionDirection === RIGHT,\r\n );\r\n if (e.shiftKey) {\r\n this.moveCursorWithShift(offset);\r\n } else {\r\n this.moveCursorWithoutShift(offset);\r\n }\r\n if (offset !== 0) {\r\n const max = this.text.length;\r\n this.selectionStart = capValue(0, this.selectionStart, max);\r\n this.selectionEnd = capValue(0, this.selectionEnd, max);\r\n // TODO fix: abort and init should be an alternative depending\r\n // on selectionStart/End being equal or different\r\n this.abortCursorAnimation();\r\n this.initDelayedCursor();\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n }\r\n }\r\n\r\n /**\r\n * Moves cursor with shift\r\n * @param {Number} offset\r\n */\r\n moveCursorWithShift(offset: number) {\r\n const newSelection =\r\n this._selectionDirection === LEFT\r\n ? this.selectionStart + offset\r\n : this.selectionEnd + offset;\r\n this.setSelectionStartEndWithShift(\r\n this.selectionStart,\r\n this.selectionEnd,\r\n newSelection,\r\n );\r\n return offset !== 0;\r\n }\r\n\r\n /**\r\n * Moves cursor up without shift\r\n * @param {Number} offset\r\n */\r\n moveCursorWithoutShift(offset: number) {\r\n if (offset < 0) {\r\n this.selectionStart += offset;\r\n this.selectionEnd = this.selectionStart;\r\n } else {\r\n this.selectionEnd += offset;\r\n this.selectionStart = this.selectionEnd;\r\n }\r\n return offset !== 0;\r\n }\r\n\r\n /**\r\n * Moves cursor left\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n moveCursorLeft(e: KeyboardEvent) {\r\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\r\n return;\r\n }\r\n this._moveCursorLeftOrRight('Left', e);\r\n }\r\n\r\n /**\r\n * @private\r\n * @return {Boolean} true if a change happened\r\n *\r\n * @todo refactor not to use method name composition\r\n */\r\n _move(\r\n e: KeyboardEvent,\r\n prop: 'selectionStart' | 'selectionEnd',\r\n direction: 'Left' | 'Right',\r\n ): boolean {\r\n let newValue: number | undefined;\r\n if (e.altKey) {\r\n newValue = this[`findWordBoundary${direction}`](this[prop]);\r\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\r\n newValue = this[`findLineBoundary${direction}`](this[prop]);\r\n } else {\r\n this[prop] += direction === 'Left' ? -1 : 1;\r\n return true;\r\n }\r\n if (typeof newValue !== 'undefined' && this[prop] !== newValue) {\r\n this[prop] = newValue;\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _moveLeft(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\r\n return this._move(e, prop, 'Left');\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _moveRight(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\r\n return this._move(e, prop, 'Right');\r\n }\r\n\r\n /**\r\n * Moves cursor left without keeping selection\r\n * @param {KeyboardEvent} e\r\n */\r\n moveCursorLeftWithoutShift(e: KeyboardEvent) {\r\n let change = true;\r\n this._selectionDirection = LEFT;\r\n\r\n // only move cursor when there is no selection,\r\n // otherwise we discard it, and leave cursor on same place\r\n if (\r\n this.selectionEnd === this.selectionStart &&\r\n this.selectionStart !== 0\r\n ) {\r\n change = this._moveLeft(e, 'selectionStart');\r\n }\r\n this.selectionEnd = this.selectionStart;\r\n return change;\r\n }\r\n\r\n /**\r\n * Moves cursor left while keeping selection\r\n * @param {KeyboardEvent} e\r\n */\r\n moveCursorLeftWithShift(e: KeyboardEvent) {\r\n if (\r\n this._selectionDirection === RIGHT &&\r\n this.selectionStart !== this.selectionEnd\r\n ) {\r\n return this._moveLeft(e, 'selectionEnd');\r\n } else if (this.selectionStart !== 0) {\r\n this._selectionDirection = LEFT;\r\n return this._moveLeft(e, 'selectionStart');\r\n }\r\n }\r\n\r\n /**\r\n * Moves cursor right\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n moveCursorRight(e: KeyboardEvent) {\r\n if (\r\n this.selectionStart >= this._text.length &&\r\n this.selectionEnd >= this._text.length\r\n ) {\r\n return;\r\n }\r\n this._moveCursorLeftOrRight('Right', e);\r\n }\r\n\r\n /**\r\n * Moves cursor right or Left, fires event\r\n * @param {String} direction 'Left', 'Right'\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n _moveCursorLeftOrRight(direction: 'Left' | 'Right', e: KeyboardEvent) {\r\n const actionName = `moveCursor${direction}${\r\n e.shiftKey ? 'WithShift' : 'WithoutShift'\r\n }` as const;\r\n this._currentCursorOpacity = 1;\r\n if (this[actionName](e)) {\r\n // TODO fix: abort and init should be an alternative depending\r\n // on selectionStart/End being equal or different\r\n this.abortCursorAnimation();\r\n this.initDelayedCursor();\r\n this._fireSelectionChanged();\r\n this._updateTextarea();\r\n }\r\n }\r\n\r\n /**\r\n * Moves cursor right while keeping selection\r\n * @param {KeyboardEvent} e\r\n */\r\n moveCursorRightWithShift(e: KeyboardEvent) {\r\n if (\r\n this._selectionDirection === LEFT &&\r\n this.selectionStart !== this.selectionEnd\r\n ) {\r\n return this._moveRight(e, 'selectionStart');\r\n } else if (this.selectionEnd !== this._text.length) {\r\n this._selectionDirection = RIGHT;\r\n return this._moveRight(e, 'selectionEnd');\r\n }\r\n }\r\n\r\n /**\r\n * Moves cursor right without keeping selection\r\n * @param {KeyboardEvent} e Event object\r\n */\r\n moveCursorRightWithoutShift(e: KeyboardEvent) {\r\n let changed = true;\r\n this._selectionDirection = RIGHT;\r\n\r\n if (this.selectionStart === this.selectionEnd) {\r\n changed = this._moveRight(e, 'selectionStart');\r\n this.selectionEnd = this.selectionStart;\r\n } else {\r\n this.selectionStart = this.selectionEnd;\r\n }\r\n return changed;\r\n }\r\n}\r\n"],"names":["ITextKeyBehavior","ITextBehavior","initHiddenTextarea","doc","this","canvas","getDocumentFromElement","getElement","getFabricDocument","textarea","createElement","Object","entries","autocapitalize","autocorrect","autocomplete","spellcheck","wrap","map","_ref","attribute","value","setAttribute","top","left","fontSize","_calcTextareaPosition","style","cssText","hiddenTextareaContainer","body","appendChild","blur","keydown","keyup","input","copy","cut","paste","compositionstart","compositionupdate","compositionend","_ref2","eventName","handler","addEventListener","bind","hiddenTextarea","abortCursorAnimation","onKeyDown","e","isEditing","keyMap","direction","keysMapRtl","keysMap","keyCode","ctrlKeysMapDown","ctrlKey","metaKey","stopImmediatePropagation","preventDefault","inCompositionMode","clearContextTop","renderCursorOrSelection","requestRenderAll","onKeyUp","_copyDone","ctrlKeysMapUp","onInput","fromPaste","selectionStart","selectionEnd","stopPropagation","console","log","fabricText","text","textareaValue","fabricSelection","start","end","textareaSelection","inComposition","cursorOffsetCache","_browserWrapCache","_lastDimensionState","_forceClearCache","updateFromTextArea","fire","CHANGED","target","renderAll","updateAndFire","styles","nextText","_splitTextIntoLines","graphemeText","charCount","_text","length","nextCharCount","_selectionStart","_selectionEnd","selection","copiedStyle","removedText","removeFrom","removeTo","charDiff","fromStringToGraphemeSelection","backDelete","slice","insertedText","getSelectionStyles","removeStyleFromTo","copyPasteData","getEnv","join","copiedText","config","disableStyleCopyPaste","copiedTextStyle","insertNewStyleBlock","onCompositionStart","onCompositionEnd","onCompositionUpdate","_ref3","compositionStart","compositionEnd","updateTextareaPosition","getSelectedText","undefined","_getWidthBeforeCursor","lineIndex","charIndex","bound","widthBeforeCursor","_getLineLeftOffset","__charBounds","width","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","cursorLocation","get2DCursorLocation","_textLines","indexOnOtherLine","_getIndexOnLine","missingNewlineOffset","shiftKey","getUpCursorOffset","textBeforeCursor","line","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","j","jlen","leftEdge","rightEdge","offsetFromLeftEdge","Math","abs","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","offset","_selectionDirection","RIGHT","moveCursorWithShift","moveCursorWithoutShift","max","capValue","initDelayedCursor","_fireSelectionChanged","_updateTextarea","newSelection","LEFT","setSelectionStartEndWithShift","moveCursorLeft","_moveCursorLeftOrRight","_move","prop","newValue","altKey","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","actionName","_currentCursorOpacity","moveCursorRightWithShift","moveCursorRightWithoutShift","changed"],"mappings":"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"}