fabric 6.0.0 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +8 -18
- package/dist/fabric.d.ts +4 -0
- package/dist/fabric.d.ts.map +1 -1
- package/dist/fabric.min.mjs +1 -1
- package/dist/fabric.mjs +1 -0
- package/dist/fabric.mjs.map +1 -1
- package/dist/index.js +146 -107
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +146 -108
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +146 -107
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +146 -108
- package/dist/index.node.mjs.map +1 -1
- package/dist/package.json.min.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/EventTypeDefs.d.ts +2 -1
- package/dist/src/EventTypeDefs.d.ts.map +1 -1
- package/dist/src/LayoutManager/LayoutManager.d.ts.map +1 -1
- package/dist/src/LayoutManager/LayoutManager.min.mjs +1 -1
- package/dist/src/LayoutManager/LayoutManager.min.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutManager.mjs +13 -8
- package/dist/src/LayoutManager/LayoutManager.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.min.mjs +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.min.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.mjs +3 -3
- package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.d.ts +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.d.ts.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.min.mjs +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.min.mjs.map +1 -1
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.mjs +15 -9
- package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.mjs.map +1 -1
- package/dist/src/Observable.d.ts +8 -0
- package/dist/src/Observable.d.ts.map +1 -1
- package/dist/src/Observable.min.mjs.map +1 -1
- package/dist/src/Observable.mjs +8 -0
- package/dist/src/Observable.mjs.map +1 -1
- package/dist/src/canvas/SelectableCanvas.d.ts.map +1 -1
- package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
- package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
- package/dist/src/canvas/SelectableCanvas.mjs +5 -5
- package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvas.d.ts +1 -1
- package/dist/src/constants.d.ts +16 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.min.mjs +1 -1
- package/dist/src/constants.min.mjs.map +1 -1
- package/dist/src/constants.mjs +17 -1
- package/dist/src/constants.mjs.map +1 -1
- package/dist/src/controls/Control.d.ts.map +1 -1
- package/dist/src/controls/Control.min.mjs +1 -1
- package/dist/src/controls/Control.min.mjs.map +1 -1
- package/dist/src/controls/Control.mjs +2 -1
- package/dist/src/controls/Control.mjs.map +1 -1
- package/dist/src/controls/changeWidth.min.mjs +1 -1
- package/dist/src/controls/changeWidth.min.mjs.map +1 -1
- package/dist/src/controls/changeWidth.mjs +2 -2
- package/dist/src/controls/changeWidth.mjs.map +1 -1
- package/dist/src/controls/commonControls.d.ts.map +1 -1
- package/dist/src/controls/commonControls.min.mjs +1 -1
- package/dist/src/controls/commonControls.min.mjs.map +1 -1
- package/dist/src/controls/commonControls.mjs +4 -3
- package/dist/src/controls/commonControls.mjs.map +1 -1
- package/dist/src/controls/controlRendering.min.mjs +1 -1
- package/dist/src/controls/controlRendering.min.mjs.map +1 -1
- package/dist/src/controls/controlRendering.mjs +3 -3
- package/dist/src/controls/controlRendering.mjs.map +1 -1
- package/dist/src/controls/drag.min.mjs +1 -1
- package/dist/src/controls/drag.min.mjs.map +1 -1
- package/dist/src/controls/drag.mjs +2 -2
- package/dist/src/controls/drag.mjs.map +1 -1
- package/dist/src/controls/polyControl.d.ts.map +1 -1
- package/dist/src/controls/polyControl.min.mjs +1 -1
- package/dist/src/controls/polyControl.min.mjs.map +1 -1
- package/dist/src/controls/polyControl.mjs +2 -1
- package/dist/src/controls/polyControl.mjs.map +1 -1
- package/dist/src/controls/rotate.d.ts.map +1 -1
- package/dist/src/controls/rotate.min.mjs +1 -1
- package/dist/src/controls/rotate.min.mjs.map +1 -1
- package/dist/src/controls/rotate.mjs +2 -1
- package/dist/src/controls/rotate.mjs.map +1 -1
- package/dist/src/controls/scale.d.ts.map +1 -1
- package/dist/src/controls/scale.min.mjs +1 -1
- package/dist/src/controls/scale.min.mjs.map +1 -1
- package/dist/src/controls/scale.mjs +8 -7
- package/dist/src/controls/scale.mjs.map +1 -1
- package/dist/src/controls/scaleSkew.d.ts.map +1 -1
- package/dist/src/controls/scaleSkew.min.mjs +1 -1
- package/dist/src/controls/scaleSkew.min.mjs.map +1 -1
- package/dist/src/controls/scaleSkew.mjs +3 -2
- package/dist/src/controls/scaleSkew.mjs.map +1 -1
- package/dist/src/controls/skew.d.ts.map +1 -1
- package/dist/src/controls/skew.min.mjs +1 -1
- package/dist/src/controls/skew.min.mjs.map +1 -1
- package/dist/src/controls/skew.mjs +7 -7
- package/dist/src/controls/skew.mjs.map +1 -1
- package/dist/src/filters/Blur.min.mjs +1 -1
- package/dist/src/filters/Blur.min.mjs.map +1 -1
- package/dist/src/filters/Blur.mjs +1 -1
- package/dist/src/filters/Blur.mjs.map +1 -1
- package/dist/src/filters/Pixelate.min.mjs +1 -1
- package/dist/src/filters/Pixelate.min.mjs.map +1 -1
- package/dist/src/filters/Pixelate.mjs +1 -1
- package/dist/src/filters/Pixelate.mjs.map +1 -1
- package/dist/src/parser/attributes.d.ts.map +1 -1
- package/dist/src/parser/attributes.min.mjs +1 -1
- package/dist/src/parser/attributes.min.mjs.map +1 -1
- package/dist/src/parser/attributes.mjs +3 -1
- package/dist/src/parser/attributes.mjs.map +1 -1
- package/dist/src/parser/elements_parser.min.mjs +1 -1
- package/dist/src/parser/elements_parser.min.mjs.map +1 -1
- package/dist/src/parser/elements_parser.mjs +3 -3
- package/dist/src/parser/elements_parser.mjs.map +1 -1
- package/dist/src/parser/normalizeValue.min.mjs +1 -1
- package/dist/src/parser/normalizeValue.min.mjs.map +1 -1
- package/dist/src/parser/normalizeValue.mjs +7 -7
- package/dist/src/parser/normalizeValue.mjs.map +1 -1
- package/dist/src/parser/parseTransformAttribute.min.mjs +1 -1
- package/dist/src/parser/parseTransformAttribute.min.mjs.map +1 -1
- package/dist/src/parser/parseTransformAttribute.mjs +5 -5
- package/dist/src/parser/parseTransformAttribute.mjs.map +1 -1
- package/dist/src/shapes/Circle.d.ts.map +1 -1
- package/dist/src/shapes/Circle.min.mjs +1 -1
- package/dist/src/shapes/Circle.min.mjs.map +1 -1
- package/dist/src/shapes/Circle.mjs +3 -2
- package/dist/src/shapes/Circle.mjs.map +1 -1
- package/dist/src/shapes/Ellipse.min.mjs +1 -1
- package/dist/src/shapes/Ellipse.min.mjs.map +1 -1
- package/dist/src/shapes/Ellipse.mjs +3 -3
- package/dist/src/shapes/Ellipse.mjs.map +1 -1
- package/dist/src/shapes/IText/DraggableTextDelegate.min.mjs +1 -1
- package/dist/src/shapes/IText/DraggableTextDelegate.min.mjs.map +1 -1
- package/dist/src/shapes/IText/DraggableTextDelegate.mjs +3 -3
- package/dist/src/shapes/IText/DraggableTextDelegate.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.min.mjs +1 -1
- package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.mjs +3 -3
- package/dist/src/shapes/IText/IText.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextBehavior.min.mjs +1 -1
- package/dist/src/shapes/IText/ITextBehavior.min.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextBehavior.mjs +2 -2
- package/dist/src/shapes/IText/ITextBehavior.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs +1 -1
- package/dist/src/shapes/IText/ITextKeyBehavior.min.mjs.map +1 -1
- package/dist/src/shapes/IText/ITextKeyBehavior.mjs +2 -2
- package/dist/src/shapes/IText/ITextKeyBehavior.mjs.map +1 -1
- package/dist/src/shapes/Image.min.mjs +1 -1
- package/dist/src/shapes/Image.min.mjs.map +1 -1
- package/dist/src/shapes/Image.mjs +2 -2
- package/dist/src/shapes/Image.mjs.map +1 -1
- package/dist/src/shapes/Object/AnimatableObject.d.ts.map +1 -1
- package/dist/src/shapes/Object/AnimatableObject.min.mjs +1 -1
- package/dist/src/shapes/Object/AnimatableObject.min.mjs.map +1 -1
- package/dist/src/shapes/Object/AnimatableObject.mjs +2 -1
- package/dist/src/shapes/Object/AnimatableObject.mjs.map +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs.map +1 -1
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs +4 -4
- package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.min.mjs +1 -1
- package/dist/src/shapes/Object/InteractiveObject.min.mjs.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.mjs +2 -1
- package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
- package/dist/src/shapes/Object/Object.d.ts +9 -7
- package/dist/src/shapes/Object/Object.d.ts.map +1 -1
- package/dist/src/shapes/Object/Object.min.mjs +1 -1
- package/dist/src/shapes/Object/Object.min.mjs.map +1 -1
- package/dist/src/shapes/Object/Object.mjs +14 -12
- package/dist/src/shapes/Object/Object.mjs.map +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.min.mjs +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.min.mjs.map +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.mjs +3 -3
- package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
- package/dist/src/shapes/Object/defaultValues.d.ts.map +1 -1
- package/dist/src/shapes/Object/defaultValues.min.mjs +1 -1
- package/dist/src/shapes/Object/defaultValues.min.mjs.map +1 -1
- package/dist/src/shapes/Object/defaultValues.mjs +4 -4
- package/dist/src/shapes/Object/defaultValues.mjs.map +1 -1
- package/dist/src/shapes/Object/types/ControlProps.d.ts +4 -3
- package/dist/src/shapes/Object/types/ControlProps.d.ts.map +1 -1
- package/dist/src/shapes/Polyline.d.ts.map +1 -1
- package/dist/src/shapes/Polyline.min.mjs +1 -1
- package/dist/src/shapes/Polyline.min.mjs.map +1 -1
- package/dist/src/shapes/Polyline.mjs +3 -3
- package/dist/src/shapes/Polyline.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.d.ts +2 -2
- package/dist/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist/src/shapes/Text/Text.min.mjs +1 -1
- package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.mjs +5 -5
- package/dist/src/shapes/Text/Text.mjs.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs +2 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
- package/dist/src/shapes/Text/constants.min.mjs +1 -1
- package/dist/src/shapes/Text/constants.min.mjs.map +1 -1
- package/dist/src/shapes/Text/constants.mjs +2 -2
- package/dist/src/shapes/Text/constants.mjs.map +1 -1
- package/dist/src/util/misc/objectEnlive.d.ts +1 -0
- package/dist/src/util/misc/objectEnlive.d.ts.map +1 -1
- package/dist/src/util/misc/objectEnlive.min.mjs.map +1 -1
- package/dist/src/util/misc/objectEnlive.mjs +1 -0
- package/dist/src/util/misc/objectEnlive.mjs.map +1 -1
- package/dist/src/util/misc/svgParsing.min.mjs +1 -1
- package/dist/src/util/misc/svgParsing.min.mjs.map +1 -1
- package/dist/src/util/misc/svgParsing.mjs +2 -2
- package/dist/src/util/misc/svgParsing.mjs.map +1 -1
- package/dist/src/util/transform_matrix_removal.min.mjs +1 -1
- package/dist/src/util/transform_matrix_removal.min.mjs.map +1 -1
- package/dist/src/util/transform_matrix_removal.mjs +3 -3
- package/dist/src/util/transform_matrix_removal.mjs.map +1 -1
- package/fabric.ts +4 -0
- package/package.json +1 -1
- package/src/EventTypeDefs.ts +14 -6
- package/src/LayoutManager/LayoutManager.ts +28 -19
- package/src/LayoutManager/LayoutStrategies/ClipPathLayout.ts +2 -2
- package/src/LayoutManager/LayoutStrategies/LayoutStrategy.ts +7 -7
- package/src/Observable.ts +8 -0
- package/src/canvas/SelectableCanvas.ts +25 -11
- package/src/canvas/canvas_gestures.mixin.ts +6 -5
- package/src/constants.ts +17 -0
- package/src/controls/Control.ts +2 -1
- package/src/controls/changeWidth.ts +2 -2
- package/src/controls/commonControls.ts +4 -3
- package/src/controls/controlRendering.ts +3 -3
- package/src/controls/drag.ts +2 -2
- package/src/controls/polyControl.ts +2 -1
- package/src/controls/rotate.ts +2 -1
- package/src/controls/scale.ts +8 -7
- package/src/controls/scaleSkew.ts +3 -2
- package/src/controls/skew.ts +14 -7
- package/src/filters/Blur.ts +1 -1
- package/src/filters/Pixelate.ts +1 -1
- package/src/parser/attributes.ts +4 -2
- package/src/parser/elements_parser.ts +3 -3
- package/src/parser/normalizeValue.ts +7 -7
- package/src/parser/parseTransformAttribute.ts +5 -5
- package/src/shapes/Circle.ts +3 -2
- package/src/shapes/Ellipse.ts +3 -3
- package/src/shapes/IText/DraggableTextDelegate.ts +3 -3
- package/src/shapes/IText/IText.ts +3 -3
- package/src/shapes/IText/ITextBehavior.ts +2 -2
- package/src/shapes/IText/ITextKeyBehavior.ts +2 -2
- package/src/shapes/Image.ts +2 -2
- package/src/shapes/Object/AnimatableObject.ts +2 -1
- package/src/shapes/Object/FabricObjectSVGExportMixin.ts +4 -6
- package/src/shapes/Object/InteractiveObject.ts +2 -1
- package/src/shapes/Object/Object.ts +16 -11
- package/src/shapes/Object/ObjectGeometry.ts +3 -3
- package/src/shapes/Object/defaultValues.ts +17 -8
- package/src/shapes/Object/types/ControlProps.ts +4 -3
- package/src/shapes/Polyline.spec.ts +0 -1
- package/src/shapes/Polyline.ts +12 -4
- package/src/shapes/Text/Text.ts +7 -7
- package/src/shapes/Text/TextSVGExportMixin.ts +3 -2
- package/src/shapes/Text/constants.ts +3 -3
- package/src/util/misc/objectEnlive.ts +1 -0
- package/src/util/misc/svgParsing.ts +2 -2
- package/src/util/transform_matrix_removal.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ITextBehavior.mjs","sources":["../../../../src/shapes/IText/ITextBehavior.ts"],"sourcesContent":["import type {\n ObjectEvents,\n TPointerEvent,\n TPointerEventInfo,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { FabricObject } from '../Object/FabricObject';\nimport { FabricText } from '../Text/Text';\nimport { animate } from '../../util/animation/animate';\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport type { TOptions } from '../../typedefs';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { LEFT, RIGHT, reNewline } from '../../constants';\nimport type { IText } from './IText';\n\n/**\n * extend this regex to support non english languages\n *\n * - ` ` Matches a SPACE character (char code 32).\n * - `\\n` Matches a LINE FEED character (char code 10).\n * - `\\.` Matches a \".\" character (char code 46).\n * - `,` Matches a \",\" character (char code 44).\n * - `;` Matches a \";\" character (char code 59).\n * - `!` Matches a \"!\" character (char code 33).\n * - `\\?` Matches a \"?\" character (char code 63).\n * - `\\-` Matches a \"-\" character (char code 45).\n */\n// eslint-disable-next-line no-useless-escape\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\nexport type ITextEvents = ObjectEvents & {\n 'selection:changed': never;\n changed: never | { index: number; action: string };\n tripleclick: TPointerEventInfo;\n 'editing:entered': never | { e: TPointerEvent };\n 'editing:exited': never;\n};\n\nexport abstract class ITextBehavior<\n Props extends TOptions<TextProps> = Partial<TextProps>,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents\n> extends FabricText<Props, SProps, EventSpec> {\n declare abstract isEditing: boolean;\n declare abstract cursorDelay: number;\n declare abstract selectionStart: number;\n declare abstract selectionEnd: number;\n declare abstract cursorDuration: number;\n declare abstract editable: boolean;\n declare abstract editingBorderColor: string;\n\n declare abstract compositionStart: number;\n declare abstract compositionEnd: number;\n\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n protected declare inCompositionMode: boolean;\n\n protected declare _reSpace: RegExp;\n private declare _currentTickState?: ValueAnimation;\n private declare _currentTickCompleteState?: ValueAnimation;\n protected _currentCursorOpacity = 1;\n private declare _textBeforeEdit: string;\n protected declare __selectionStartOnMouseDown: number;\n\n protected declare selected: boolean;\n protected declare cursorOffsetCache: { left?: number; top?: number };\n protected declare _savedProps?: {\n hasControls: boolean;\n borderColor: string;\n lockMovementX: boolean;\n lockMovementY: boolean;\n selectable: boolean;\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\n defaultCursor?: CSSStyleDeclaration['cursor'];\n moveCursor?: CSSStyleDeclaration['cursor'];\n };\n protected declare _selectionDirection: 'left' | 'right' | null;\n\n abstract initHiddenTextarea(): void;\n abstract _fireSelectionChanged(): void;\n abstract renderCursorOrSelection(): void;\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\n abstract _getCursorBoundaries(\n index: number,\n skipCaching?: boolean\n ): {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n };\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior() {\n this._tick = this._tick.bind(this);\n this._onTickComplete = this._onTickComplete.bind(this);\n this.updateSelectionOnMouseMove =\n this.updateSelectionOnMouseMove.bind(this);\n }\n\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\n this.isEditing && this.exitEditing();\n this.selected = false;\n return super.onDeselect(options);\n }\n\n /**\n * @private\n */\n _animateCursor({\n toValue,\n duration,\n delay,\n onComplete,\n }: {\n toValue: number;\n duration: number;\n delay?: number;\n onComplete?: TOnAnimationChangeCallback<number, void>;\n }) {\n return animate({\n startValue: this._currentCursorOpacity,\n endValue: toValue,\n duration,\n delay,\n onComplete,\n abort: () =>\n !this.canvas ||\n // we do not want to animate a selection, only cursor\n this.selectionStart !== this.selectionEnd,\n onChange: (value) => {\n this._currentCursorOpacity = value;\n this.renderCursorOrSelection();\n },\n });\n }\n\n /**\n * changes the cursor from visible to invisible\n */\n private _tick(delay?: number) {\n this._currentTickState = this._animateCursor({\n toValue: 0,\n duration: this.cursorDuration / 2,\n delay: Math.max(delay || 0, 100),\n onComplete: this._onTickComplete,\n });\n }\n\n /**\n * Changes the cursor from invisible to visible\n */\n private _onTickComplete() {\n this._currentTickCompleteState?.abort();\n this._currentTickCompleteState = this._animateCursor({\n toValue: 1,\n duration: this.cursorDuration,\n onComplete: this._tick,\n });\n }\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor(restart?: boolean) {\n this.abortCursorAnimation();\n this._tick(restart ? 0 : this.cursorDelay);\n }\n\n /**\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\n */\n abortCursorAnimation() {\n let shouldClear = false;\n [this._currentTickState, this._currentTickCompleteState].forEach(\n (cursorAnimation) => {\n if (cursorAnimation && !cursorAnimation.isDone()) {\n shouldClear = true;\n cursorAnimation.abort();\n }\n }\n );\n\n this._currentCursorOpacity = 1;\n\n // make sure we clear context even if instance is not editing\n if (shouldClear) {\n this.clearContextTop();\n }\n }\n\n /**\n * Restart tue cursor animation if either is in complete state ( between animations )\n * or if it never started before\n */\n restartCursorIfNeeded() {\n if (\n [this._currentTickState, this._currentTickCompleteState].some(\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone()\n )\n ) {\n this.initDelayedCursor();\n }\n }\n\n /**\n * Selects entire text\n */\n selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText(): string {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n }\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\n const text = this._text;\n // if we land on a space we move the cursor backwards\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\n let index =\n selectionStart > 0 &&\n this._reSpace.test(text[selectionStart]) &&\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\n ? selectionStart - 1\n : selectionStart,\n _char = text[index];\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\n index += direction;\n _char = text[index];\n }\n if (direction === -1 && reNonWord.test(_char)) {\n index++;\n }\n return index;\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n // search backwards\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n // search forward\n newSelectionEnd = Math.max(\n newSelectionStart,\n this.searchWordBoundary(selectionStart, 1)\n );\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Enters editing state\n */\n enterEditing(e?: TPointerEvent) {\n if (this.isEditing || !this.editable) {\n return;\n }\n if (this.canvas) {\n this.canvas.calcOffset();\n this.canvas.textEditingManager.exitTextEditing();\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea();\n this.hiddenTextarea!.focus();\n this.hiddenTextarea!.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered', e ? { e } : undefined);\n this._fireSelectionChanged();\n if (this.canvas) {\n // @ts-expect-error in reality it is an IText instance\n this.canvas.fire('text:editing:entered', { target: this, e });\n this.canvas.requestRenderAll();\n }\n }\n\n /**\n * called by {@link Canvas#textEditingManager}\n */\n updateSelectionOnMouseMove(e: TPointerEvent) {\n if (this.getActiveControl()) {\n return;\n }\n\n const el = this.hiddenTextarea!;\n // regain focus\n getDocumentFromElement(el).activeElement !== el && el.focus();\n\n const newSelectionStart = this.getSelectionStartFromPointer(e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\n currentStart === currentEnd) &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (\n this.selectionStart !== currentStart ||\n this.selectionEnd !== currentEnd\n ) {\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * @private\n */\n _setEditingProps() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n }\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\n const smallerTextStart = text.slice(0, start),\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = text.slice(start, end),\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection(\n start: number,\n end: number,\n graphemes: string[]\n ) {\n const smallerTextStart = graphemes.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = graphemes.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * @private\n */\n _updateTextarea() {\n this.cursorOffsetCache = {};\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n const newSelection = this.fromGraphemeToStringSelection(\n this.selectionStart,\n this.selectionEnd,\n this._text\n );\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = {};\n const textarea = this.hiddenTextarea;\n this.text = textarea.value;\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n const newSelection = this.fromStringToGraphemeSelection(\n textarea.selectionStart,\n textarea.selectionEnd,\n textarea.value\n );\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n const style = this._calcTextareaPosition();\n this.hiddenTextarea!.style.left = style.left;\n this.hiddenTextarea!.style.top = style.top;\n }\n }\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition() {\n if (!this.canvas) {\n return { left: '1px', top: '1px' };\n }\n const desiredPosition = this.inCompositionMode\n ? this.compositionStart\n : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight =\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\n this.lineHeight,\n leftOffset = boundaries.leftOffset,\n retinaScaling = this.getCanvasRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight;\n\n const p = new Point(\n boundaries.left + leftOffset,\n boundaries.top + boundaries.topOffset + charHeight\n )\n .transform(this.calcTransformMatrix())\n .transform(this.canvas.viewportTransform)\n .multiply(\n new Point(\n upperCanvas.clientWidth / upperCanvasWidth,\n upperCanvas.clientHeight / upperCanvasHeight\n )\n );\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return {\n left: `${p.x}px`,\n top: `${p.y}px`,\n fontSize: `${charHeight}px`,\n charHeight: charHeight,\n };\n }\n\n /**\n * @private\n */\n _saveEditingProps() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor,\n };\n }\n\n /**\n * @private\n */\n _restoreEditingProps() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor =\n this._savedProps.defaultCursor || this.canvas.defaultCursor;\n this.canvas.moveCursor =\n this._savedProps.moveCursor || this.canvas.moveCursor;\n }\n\n delete this._savedProps;\n }\n\n /**\n * runs the actual logic that exits from editing state, see {@link exitEditing}\n */\n protected _exitEditing() {\n const hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode &&\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\n }\n\n /**\n * Exits from editing state and fires relevant events\n */\n exitEditing() {\n const isTextChanged = this._textBeforeEdit !== this.text;\n this._exitEditing();\n this.selectionEnd = this.selectionStart;\n this._restoreEditingProps();\n if (this._forceClearCache) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n if (this.canvas) {\n this.canvas.fire('text:editing:exited', {\n target: this as unknown as IText,\n });\n // todo: evaluate add an action to this event\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n }\n\n /**\n * @private\n */\n _removeExtraneousStyles() {\n for (const prop in this.styles) {\n if (!this._textLines[prop as unknown as number]) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo(start: number, end: number) {\n const { lineIndex: lineStart, charIndex: charStart } =\n this.get2DCursorLocation(start, true),\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\n end,\n true\n );\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (\n let i = charStart;\n i < this._unwrappedTextLines[lineStart].length;\n i++\n ) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (\n let i = charEnd;\n i < this._unwrappedTextLines[lineEnd].length;\n i++\n ) {\n const styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (let i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n const styleObj = this.styles[lineStart];\n const diff = charEnd - charStart;\n for (let i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (const char in this.styles[lineStart]) {\n const numericChar = parseInt(char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[char];\n delete styleObj[char];\n }\n }\n }\n }\n }\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles(lineIndex: number, offset: number) {\n const clonedStyles = Object.assign({}, this.styles);\n for (const line in this.styles) {\n const numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n }\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject(\n lineIndex: number,\n charIndex: number,\n qty: number,\n copiedStyle?: { [index: number]: TextStyleDeclaration }\n ) {\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\n const isEndOfLine = originalLineLength === charIndex;\n\n let someStyleIsCarryingOver = false;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n const currentCharStyle = this.styles[lineIndex]\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\n : undefined;\n\n // we clone styles of all chars\n // after cursor onto the current line\n for (const index in this.styles[lineIndex]) {\n const numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n someStyleIsCarryingOver = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n let styleCarriedOver = false;\n if (someStyleIsCarryingOver && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver || originalLineLength > charIndex) {\n // skip the last line of since we already prepared it.\n // or contains text without style that we don't want to style\n // just because it changed lines\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: { ...copiedStyle[qty - 1] },\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: { ...currentCharStyle },\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n }\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject(\n lineIndex: number,\n charIndex: number,\n quantity: number,\n copiedStyle?: TextStyleDeclaration[]\n ) {\n if (!this.styles) {\n this.styles = {};\n }\n const currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles\n ? { ...currentLineStyles }\n : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (const index in currentLineStylesCloned) {\n const numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] =\n currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = {\n ...copiedStyle[quantity],\n };\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\n }\n }\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock(\n insertedText: string[],\n start: number,\n copiedStyle?: TextStyleDeclaration[]\n ) {\n const cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0];\n let linesLength = 0;\n // get an array of how many char per lines are being added.\n for (let i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex,\n addedLines[0],\n copiedStyle\n );\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength &&\n this.insertNewlineStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex + addedLines[0],\n linesLength\n );\n let i;\n for (i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle\n );\n } else if (copiedStyle) {\n // this test is required in order to close #6841\n // when a pasted buffer begins with a newline then\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\n // may be undefined for some reason\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle\n );\n }\n }\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars(start: number, end: number = start + 1) {\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars(\n text: string,\n style: TextStyleDeclaration[] | undefined,\n start: number,\n end: number = start\n ) {\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n const graphemes = this.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [\n ...this._text.slice(0, start),\n ...graphemes,\n ...this._text.slice(end),\n ];\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift(\n start: number,\n end: number,\n newSelection: number\n ) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = LEFT;\n } else if (this._selectionDirection === RIGHT) {\n this._selectionDirection = LEFT;\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === RIGHT) {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = RIGHT;\n } else if (this._selectionDirection === LEFT) {\n this._selectionDirection = RIGHT;\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n }\n}\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","getSelectedText","slice","join","findWordBoundaryLeft","startFrom","offset","index","_reSpace","test","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","text","reNewline","_char","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","e","editable","calcOffset","textEditingManager","exitTextEditing","initHiddenTextarea","hiddenTextarea","focus","_saveEditingProps","_setEditingProps","_textBeforeEdit","fire","undefined","target","requestRenderAll","getActiveControl","el","getDocumentFromElement","activeElement","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","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","initDimensions","setCoords","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","concat","fontSize","_savedProps","_restoreEditingProps","_exitEditing","blur","parentNode","removeChild","isTextChanged","_forceClearCache","_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","_objectSpread","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 {\n ObjectEvents,\n TPointerEvent,\n TPointerEventInfo,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { FabricObject } from '../Object/FabricObject';\nimport { FabricText } from '../Text/Text';\nimport { animate } from '../../util/animation/animate';\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport type { TOptions } from '../../typedefs';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\nimport type { IText } from './IText';\n\n/**\n * extend this regex to support non english languages\n *\n * - ` ` Matches a SPACE character (char code 32).\n * - `\\n` Matches a LINE FEED character (char code 10).\n * - `\\.` Matches a \".\" character (char code 46).\n * - `,` Matches a \",\" character (char code 44).\n * - `;` Matches a \";\" character (char code 59).\n * - `!` Matches a \"!\" character (char code 33).\n * - `\\?` Matches a \"?\" character (char code 63).\n * - `\\-` Matches a \"-\" character (char code 45).\n */\n// eslint-disable-next-line no-useless-escape\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\nexport type ITextEvents = ObjectEvents & {\n 'selection:changed': never;\n changed: never | { index: number; action: string };\n tripleclick: TPointerEventInfo;\n 'editing:entered': never | { e: TPointerEvent };\n 'editing:exited': never;\n};\n\nexport abstract class ITextBehavior<\n Props extends TOptions<TextProps> = Partial<TextProps>,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents\n> extends FabricText<Props, SProps, EventSpec> {\n declare abstract isEditing: boolean;\n declare abstract cursorDelay: number;\n declare abstract selectionStart: number;\n declare abstract selectionEnd: number;\n declare abstract cursorDuration: number;\n declare abstract editable: boolean;\n declare abstract editingBorderColor: string;\n\n declare abstract compositionStart: number;\n declare abstract compositionEnd: number;\n\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n protected declare inCompositionMode: boolean;\n\n protected declare _reSpace: RegExp;\n private declare _currentTickState?: ValueAnimation;\n private declare _currentTickCompleteState?: ValueAnimation;\n protected _currentCursorOpacity = 1;\n private declare _textBeforeEdit: string;\n protected declare __selectionStartOnMouseDown: number;\n\n protected declare selected: boolean;\n protected declare cursorOffsetCache: { left?: number; top?: number };\n protected declare _savedProps?: {\n hasControls: boolean;\n borderColor: string;\n lockMovementX: boolean;\n lockMovementY: boolean;\n selectable: boolean;\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\n defaultCursor?: CSSStyleDeclaration['cursor'];\n moveCursor?: CSSStyleDeclaration['cursor'];\n };\n protected declare _selectionDirection: 'left' | 'right' | null;\n\n abstract initHiddenTextarea(): void;\n abstract _fireSelectionChanged(): void;\n abstract renderCursorOrSelection(): void;\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\n abstract _getCursorBoundaries(\n index: number,\n skipCaching?: boolean\n ): {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n };\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior() {\n this._tick = this._tick.bind(this);\n this._onTickComplete = this._onTickComplete.bind(this);\n this.updateSelectionOnMouseMove =\n this.updateSelectionOnMouseMove.bind(this);\n }\n\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\n this.isEditing && this.exitEditing();\n this.selected = false;\n return super.onDeselect(options);\n }\n\n /**\n * @private\n */\n _animateCursor({\n toValue,\n duration,\n delay,\n onComplete,\n }: {\n toValue: number;\n duration: number;\n delay?: number;\n onComplete?: TOnAnimationChangeCallback<number, void>;\n }) {\n return animate({\n startValue: this._currentCursorOpacity,\n endValue: toValue,\n duration,\n delay,\n onComplete,\n abort: () =>\n !this.canvas ||\n // we do not want to animate a selection, only cursor\n this.selectionStart !== this.selectionEnd,\n onChange: (value) => {\n this._currentCursorOpacity = value;\n this.renderCursorOrSelection();\n },\n });\n }\n\n /**\n * changes the cursor from visible to invisible\n */\n private _tick(delay?: number) {\n this._currentTickState = this._animateCursor({\n toValue: 0,\n duration: this.cursorDuration / 2,\n delay: Math.max(delay || 0, 100),\n onComplete: this._onTickComplete,\n });\n }\n\n /**\n * Changes the cursor from invisible to visible\n */\n private _onTickComplete() {\n this._currentTickCompleteState?.abort();\n this._currentTickCompleteState = this._animateCursor({\n toValue: 1,\n duration: this.cursorDuration,\n onComplete: this._tick,\n });\n }\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor(restart?: boolean) {\n this.abortCursorAnimation();\n this._tick(restart ? 0 : this.cursorDelay);\n }\n\n /**\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\n */\n abortCursorAnimation() {\n let shouldClear = false;\n [this._currentTickState, this._currentTickCompleteState].forEach(\n (cursorAnimation) => {\n if (cursorAnimation && !cursorAnimation.isDone()) {\n shouldClear = true;\n cursorAnimation.abort();\n }\n }\n );\n\n this._currentCursorOpacity = 1;\n\n // make sure we clear context even if instance is not editing\n if (shouldClear) {\n this.clearContextTop();\n }\n }\n\n /**\n * Restart tue cursor animation if either is in complete state ( between animations )\n * or if it never started before\n */\n restartCursorIfNeeded() {\n if (\n [this._currentTickState, this._currentTickCompleteState].some(\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone()\n )\n ) {\n this.initDelayedCursor();\n }\n }\n\n /**\n * Selects entire text\n */\n selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText(): string {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n }\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\n const text = this._text;\n // if we land on a space we move the cursor backwards\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\n let index =\n selectionStart > 0 &&\n this._reSpace.test(text[selectionStart]) &&\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\n ? selectionStart - 1\n : selectionStart,\n _char = text[index];\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\n index += direction;\n _char = text[index];\n }\n if (direction === -1 && reNonWord.test(_char)) {\n index++;\n }\n return index;\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n // search backwards\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n // search forward\n newSelectionEnd = Math.max(\n newSelectionStart,\n this.searchWordBoundary(selectionStart, 1)\n );\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Enters editing state\n */\n enterEditing(e?: TPointerEvent) {\n if (this.isEditing || !this.editable) {\n return;\n }\n if (this.canvas) {\n this.canvas.calcOffset();\n this.canvas.textEditingManager.exitTextEditing();\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea();\n this.hiddenTextarea!.focus();\n this.hiddenTextarea!.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered', e ? { e } : undefined);\n this._fireSelectionChanged();\n if (this.canvas) {\n // @ts-expect-error in reality it is an IText instance\n this.canvas.fire('text:editing:entered', { target: this, e });\n this.canvas.requestRenderAll();\n }\n }\n\n /**\n * called by {@link Canvas#textEditingManager}\n */\n updateSelectionOnMouseMove(e: TPointerEvent) {\n if (this.getActiveControl()) {\n return;\n }\n\n const el = this.hiddenTextarea!;\n // regain focus\n getDocumentFromElement(el).activeElement !== el && el.focus();\n\n const newSelectionStart = this.getSelectionStartFromPointer(e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\n currentStart === currentEnd) &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (\n this.selectionStart !== currentStart ||\n this.selectionEnd !== currentEnd\n ) {\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * @private\n */\n _setEditingProps() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n }\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\n const smallerTextStart = text.slice(0, start),\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = text.slice(start, end),\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection(\n start: number,\n end: number,\n graphemes: string[]\n ) {\n const smallerTextStart = graphemes.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = graphemes.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * @private\n */\n _updateTextarea() {\n this.cursorOffsetCache = {};\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n const newSelection = this.fromGraphemeToStringSelection(\n this.selectionStart,\n this.selectionEnd,\n this._text\n );\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = {};\n const textarea = this.hiddenTextarea;\n this.text = textarea.value;\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n const newSelection = this.fromStringToGraphemeSelection(\n textarea.selectionStart,\n textarea.selectionEnd,\n textarea.value\n );\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n const style = this._calcTextareaPosition();\n this.hiddenTextarea!.style.left = style.left;\n this.hiddenTextarea!.style.top = style.top;\n }\n }\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition() {\n if (!this.canvas) {\n return { left: '1px', top: '1px' };\n }\n const desiredPosition = this.inCompositionMode\n ? this.compositionStart\n : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight =\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\n this.lineHeight,\n leftOffset = boundaries.leftOffset,\n retinaScaling = this.getCanvasRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight;\n\n const p = new Point(\n boundaries.left + leftOffset,\n boundaries.top + boundaries.topOffset + charHeight\n )\n .transform(this.calcTransformMatrix())\n .transform(this.canvas.viewportTransform)\n .multiply(\n new Point(\n upperCanvas.clientWidth / upperCanvasWidth,\n upperCanvas.clientHeight / upperCanvasHeight\n )\n );\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return {\n left: `${p.x}px`,\n top: `${p.y}px`,\n fontSize: `${charHeight}px`,\n charHeight: charHeight,\n };\n }\n\n /**\n * @private\n */\n _saveEditingProps() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor,\n };\n }\n\n /**\n * @private\n */\n _restoreEditingProps() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor =\n this._savedProps.defaultCursor || this.canvas.defaultCursor;\n this.canvas.moveCursor =\n this._savedProps.moveCursor || this.canvas.moveCursor;\n }\n\n delete this._savedProps;\n }\n\n /**\n * runs the actual logic that exits from editing state, see {@link exitEditing}\n */\n protected _exitEditing() {\n const hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode &&\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\n }\n\n /**\n * Exits from editing state and fires relevant events\n */\n exitEditing() {\n const isTextChanged = this._textBeforeEdit !== this.text;\n this._exitEditing();\n this.selectionEnd = this.selectionStart;\n this._restoreEditingProps();\n if (this._forceClearCache) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire(MODIFIED);\n if (this.canvas) {\n this.canvas.fire('text:editing:exited', {\n target: this as unknown as IText,\n });\n // todo: evaluate add an action to this event\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n }\n\n /**\n * @private\n */\n _removeExtraneousStyles() {\n for (const prop in this.styles) {\n if (!this._textLines[prop as unknown as number]) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo(start: number, end: number) {\n const { lineIndex: lineStart, charIndex: charStart } =\n this.get2DCursorLocation(start, true),\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\n end,\n true\n );\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (\n let i = charStart;\n i < this._unwrappedTextLines[lineStart].length;\n i++\n ) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (\n let i = charEnd;\n i < this._unwrappedTextLines[lineEnd].length;\n i++\n ) {\n const styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (let i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n const styleObj = this.styles[lineStart];\n const diff = charEnd - charStart;\n for (let i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (const char in this.styles[lineStart]) {\n const numericChar = parseInt(char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[char];\n delete styleObj[char];\n }\n }\n }\n }\n }\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles(lineIndex: number, offset: number) {\n const clonedStyles = Object.assign({}, this.styles);\n for (const line in this.styles) {\n const numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n }\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject(\n lineIndex: number,\n charIndex: number,\n qty: number,\n copiedStyle?: { [index: number]: TextStyleDeclaration }\n ) {\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\n const isEndOfLine = originalLineLength === charIndex;\n\n let someStyleIsCarryingOver = false;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n const currentCharStyle = this.styles[lineIndex]\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\n : undefined;\n\n // we clone styles of all chars\n // after cursor onto the current line\n for (const index in this.styles[lineIndex]) {\n const numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n someStyleIsCarryingOver = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n let styleCarriedOver = false;\n if (someStyleIsCarryingOver && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver || originalLineLength > charIndex) {\n // skip the last line of since we already prepared it.\n // or contains text without style that we don't want to style\n // just because it changed lines\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: { ...copiedStyle[qty - 1] },\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: { ...currentCharStyle },\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n }\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject(\n lineIndex: number,\n charIndex: number,\n quantity: number,\n copiedStyle?: TextStyleDeclaration[]\n ) {\n if (!this.styles) {\n this.styles = {};\n }\n const currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles\n ? { ...currentLineStyles }\n : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (const index in currentLineStylesCloned) {\n const numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] =\n currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = {\n ...copiedStyle[quantity],\n };\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\n }\n }\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock(\n insertedText: string[],\n start: number,\n copiedStyle?: TextStyleDeclaration[]\n ) {\n const cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0];\n let linesLength = 0;\n // get an array of how many char per lines are being added.\n for (let i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex,\n addedLines[0],\n copiedStyle\n );\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength &&\n this.insertNewlineStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex + addedLines[0],\n linesLength\n );\n let i;\n for (i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle\n );\n } else if (copiedStyle) {\n // this test is required in order to close #6841\n // when a pasted buffer begins with a newline then\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\n // may be undefined for some reason\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle\n );\n }\n }\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars(start: number, end: number = start + 1) {\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars(\n text: string,\n style: TextStyleDeclaration[] | undefined,\n start: number,\n end: number = start\n ) {\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n const graphemes = this.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [\n ...this._text.slice(0, start),\n ...graphemes,\n ...this._text.slice(end),\n ];\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift(\n start: number,\n end: number,\n newSelection: number\n ) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = LEFT;\n } else if (this._selectionDirection === RIGHT) {\n this._selectionDirection = LEFT;\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === RIGHT) {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = RIGHT;\n } else if (this._selectionDirection === LEFT) {\n this._selectionDirection = RIGHT;\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n }\n}\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","getSelectedText","slice","join","findWordBoundaryLeft","startFrom","offset","index","_reSpace","test","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","text","reNewline","_char","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","e","editable","calcOffset","textEditingManager","exitTextEditing","initHiddenTextarea","hiddenTextarea","focus","_saveEditingProps","_setEditingProps","_textBeforeEdit","fire","undefined","target","requestRenderAll","getActiveControl","el","getDocumentFromElement","activeElement","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","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","initDimensions","setCoords","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","concat","fontSize","_savedProps","_restoreEditingProps","_exitEditing","blur","parentNode","removeChild","isTextChanged","_forceClearCache","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","_objectSpread","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,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}from"../../constants.min.mjs";class
|
|
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: ".concat(s,"; left: ").concat(o,"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ").concat(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;if(this.fromPaste=!1,e&&e.stopPropagation(),!this.isEditing)return;const o=()=>{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 o();const n=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,r=this._text.length,h=n.length,a=this.selectionStart,l=this.selectionEnd,d=a!==l;let m,f,p,u,g=h-r;const S=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),_=a>S.selectionStart;d?(f=this._text.slice(a,l),g+=l-a):h<r&&(f=_?this._text.slice(l+g,l):this._text.slice(a,a-g));const y=n.slice(S.selectionEnd-g,S.selectionEnd);if(f&&f.length&&(y.length&&(m=this.getSelectionStyles(a,a+1,!1),m=y.map((()=>m[0]))),d?(p=a,u=l):_?(p=l-f.length,u=l):(p=l,u=l+f.length),this.removeStyleFromTo(p,u)),y.length){const{copyPasteData:e}=i();s&&y.join("")===e.copiedText&&!t.disableStyleCopyPaste&&(m=e.copiedTextStyle),this.insertNewStyleBlock(y,a,m)}o()}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".concat(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".concat(i)](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;s=this["findLineBoundary".concat(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".concat(t).concat(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};
|
|
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 { 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 * @default\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n private declare _clickHandlerInitialized: boolean;\n private declare _copyDone: boolean;\n private declare 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 Function).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 // @ts-expect-error legacy method calling pattern\n this[keyMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapDown[e.keyCode]](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 // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapUp[e.keyCode]](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 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(\n this.hiddenTextarea.value\n ).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 this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.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","concat","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","stopPropagation","updateAndFire","updateFromTextArea","fire","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';\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 * @default\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n private declare _clickHandlerInitialized: boolean;\n private declare _copyDone: boolean;\n private declare 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 Function).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 // @ts-expect-error legacy method calling pattern\n this[keyMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapDown[e.keyCode]](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 // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapUp[e.keyCode]](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 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(\n this.hiddenTextarea.value\n ).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 this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.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","concat","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","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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"}
|
|
@@ -3,7 +3,7 @@ import { getFabricDocument, getEnv } from '../../env/index.mjs';
|
|
|
3
3
|
import { capValue } from '../../util/misc/capValue.mjs';
|
|
4
4
|
import { ITextBehavior } from './ITextBehavior.mjs';
|
|
5
5
|
import { getDocumentFromElement } from '../../util/dom_misc.mjs';
|
|
6
|
-
import { RIGHT, LEFT } from '../../constants.mjs';
|
|
6
|
+
import { RIGHT, LEFT, CHANGED } from '../../constants.mjs';
|
|
7
7
|
|
|
8
8
|
class ITextKeyBehavior extends ITextBehavior {
|
|
9
9
|
/**
|
|
@@ -152,7 +152,7 @@ class ITextKeyBehavior extends ITextBehavior {
|
|
|
152
152
|
}
|
|
153
153
|
const updateAndFire = () => {
|
|
154
154
|
this.updateFromTextArea();
|
|
155
|
-
this.fire(
|
|
155
|
+
this.fire(CHANGED);
|
|
156
156
|
if (this.canvas) {
|
|
157
157
|
this.canvas.fire('text:changed', {
|
|
158
158
|
target: this
|