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
|
@@ -4,7 +4,7 @@ import { ITextClickBehavior } from './ITextClickBehavior.mjs';
|
|
|
4
4
|
import { keysMap, keysMapRtl, ctrlKeysMapDown, ctrlKeysMapUp } from './constants.mjs';
|
|
5
5
|
import { classRegistry } from '../../ClassRegistry.mjs';
|
|
6
6
|
import { JUSTIFY, JUSTIFY_RIGHT, JUSTIFY_LEFT, JUSTIFY_CENTER } from '../Text/constants.mjs';
|
|
7
|
-
import { RIGHT, LEFT, CENTER } from '../../constants.mjs';
|
|
7
|
+
import { RIGHT, LEFT, CENTER, FILL } from '../../constants.mjs';
|
|
8
8
|
|
|
9
9
|
// Declare IText protected properties to workaround TS
|
|
10
10
|
const protectedDefaultValues = {
|
|
@@ -360,7 +360,7 @@ class IText extends ITextClickBehavior {
|
|
|
360
360
|
// and why can't happen at the top of the function
|
|
361
361
|
this.renderSelection(ctx, boundaries);
|
|
362
362
|
}
|
|
363
|
-
ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex,
|
|
363
|
+
ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, FILL);
|
|
364
364
|
ctx.globalAlpha = this._currentCursorOpacity;
|
|
365
365
|
ctx.fillRect(boundaries.left + boundaries.leftOffset - cursorWidth / 2, topOffset + boundaries.top + dy, cursorWidth, charHeight);
|
|
366
366
|
}
|
|
@@ -477,7 +477,7 @@ class IText extends ITextClickBehavior {
|
|
|
477
477
|
*/
|
|
478
478
|
getCurrentCharColor() {
|
|
479
479
|
const cp = this._getCurrentCharIndex();
|
|
480
|
-
return this.getValueOfPropertyAt(cp.l, cp.c,
|
|
480
|
+
return this.getValueOfPropertyAt(cp.l, cp.c, FILL);
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IText.mjs","sources":["../../../../src/shapes/IText/IText.ts"],"sourcesContent":["import { Canvas } from '../../canvas/Canvas';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextClickBehavior } from './ITextClickBehavior';\nimport {\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n keysMap,\n keysMapRtl,\n} from './constants';\nimport type { TClassProperties, TFiller, TOptions } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport {\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from '../Text/constants';\nimport { CENTER, LEFT, RIGHT } from '../../constants';\nimport type { ObjectToCanvasElementOptions } from '../Object/Object';\n\ntype CursorBoundaries = {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n};\n\n// Declare IText protected properties to workaround TS\nconst protectedDefaultValues = {\n _selectionDirection: null,\n _reSpace: /\\s|\\r?\\n/,\n inCompositionMode: false,\n};\n\nexport const iTextDefaultValues: Partial<TClassProperties<IText>> = {\n selectionStart: 0,\n selectionEnd: 0,\n selectionColor: 'rgba(17,119,255,0.3)',\n isEditing: false,\n editable: true,\n editingBorderColor: 'rgba(102,153,255,0.25)',\n cursorWidth: 2,\n cursorColor: '',\n cursorDelay: 1000,\n cursorDuration: 600,\n caching: true,\n hiddenTextareaContainer: null,\n keysMap,\n keysMapRtl,\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n ...protectedDefaultValues,\n};\n\n// @TODO this is not complete\ninterface UniqueITextProps {\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface SerializedITextProps\n extends SerializedTextProps,\n UniqueITextProps {}\n\nexport interface ITextProps extends TextProps, UniqueITextProps {}\n\n/**\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n * @fires dragstart\n * @fires drag drag event firing on the drag source\n * @fires dragend\n * @fires copy\n * @fires cut\n * @fires paste\n *\n * #### Supported key combinations\n * ```\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * ```\n *\n * #### Supported mouse/touch combination\n * ```\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * ```\n */\nexport class IText<\n Props extends TOptions<ITextProps> = Partial<ITextProps>,\n SProps extends SerializedITextProps = SerializedITextProps,\n EventSpec extends ITextEvents = ITextEvents\n >\n extends ITextClickBehavior<Props, SProps, EventSpec>\n implements UniqueITextProps\n{\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n declare selectionStart: number;\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n declare selectionEnd: number;\n\n declare compositionStart: number;\n\n declare compositionEnd: number;\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n declare selectionColor: string;\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n declare isEditing: boolean;\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n declare editable: boolean;\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n declare editingBorderColor: string;\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n declare cursorWidth: number;\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n declare cursorColor: string;\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n declare cursorDelay: number;\n\n /**\n * Duration of cursor fade in (in ms)\n * @type Number\n * @default\n */\n declare cursorDuration: number;\n\n declare compositionColor: string;\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n declare caching: boolean;\n\n static ownDefaults = iTextDefaultValues;\n\n static getDefaults(): Record<string, any> {\n return { ...super.getDefaults(), ...IText.ownDefaults };\n }\n\n static type = 'IText';\n\n get type() {\n const type = super.type;\n // backward compatibility\n return type === 'itext' ? 'i-text' : type;\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...IText.ownDefaults, ...options } as Props);\n this.initBehavior();\n }\n\n /**\n * While editing handle differently\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (this.isEditing && this._savedProps && key in this._savedProps) {\n // @ts-expect-error irritating TS\n this._savedProps[key] = value;\n return this;\n }\n if (key === 'canvas') {\n this.canvas instanceof Canvas &&\n this.canvas.textEditingManager.remove(this);\n value instanceof Canvas && value.textEditingManager.add(this);\n }\n return super._set(key, value);\n }\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart(index: number) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n }\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd(index: number) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n }\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n protected _updateAndFire(\n property: 'selectionStart' | 'selectionEnd',\n index: number\n ) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n }\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n }\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions() {\n this.isEditing && this.initDelayedCursor();\n super.initDimensions();\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n complete?: boolean\n ) {\n return super.getSelectionStyles(startIndex, endIndex, complete);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n */\n setSelectionStyles(\n styles: object,\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd\n ) {\n return super.setSelectionStyles(styles, startIndex, endIndex);\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(\n selectionStart = this.selectionStart,\n skipWrapping?: boolean\n ) {\n return super.get2DCursorLocation(selectionStart, skipWrapping);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n super.render(ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n }\n\n /**\n * @override block cursor/selection logic while rendering the exported canvas\n * @todo this workaround should be replaced with a more robust solution\n */\n toCanvasElement(options?: ObjectToCanvasElementOptions): HTMLCanvasElement {\n const isEditing = this.isEditing;\n this.isEditing = false;\n const canvas = super.toCanvasElement(options);\n this.isEditing = isEditing;\n return canvas;\n }\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection() {\n if (!this.isEditing) {\n return;\n }\n const ctx = this.clearContextTop(true);\n if (!ctx) {\n return;\n }\n const boundaries = this._getCursorBoundaries();\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(ctx, boundaries);\n } else {\n this.renderSelection(ctx, boundaries);\n }\n this.canvas!.contextTopDirty = true;\n ctx.restore();\n }\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * left/top are left/top of entire text box\n * leftOffset/topOffset are offset from that left/top point of a text box\n * @private\n * @param {number} [index] index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundaries(\n index: number = this.selectionStart,\n skipCaching?: boolean\n ): CursorBoundaries {\n const left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(index, skipCaching);\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top,\n };\n }\n\n /**\n * Caches and returns cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundariesOffsets(\n index: number,\n skipCaching?: boolean\n ): { left: number; top: number } {\n if (skipCaching) {\n return this.__getCursorBoundariesOffsets(index);\n }\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache as { left: number; top: number };\n }\n return (this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index));\n }\n\n /**\n * Calculates cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n */\n __getCursorBoundariesOffsets(index: number) {\n let topOffset = 0,\n leftOffset = 0;\n const { charIndex, lineIndex } = this.get2DCursorLocation(index);\n\n for (let i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n const lineLeftOffset = this._getLineLeftOffset(lineIndex);\n const bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (\n this.charSpacing !== 0 &&\n charIndex === this._textLines[lineIndex].length\n ) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n const boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n boundaries.left *= -1;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n }\n }\n return boundaries;\n }\n\n /**\n * Renders cursor on context Top, outside the animation cycle, on request\n * Used for the drag/drop effect.\n * If contextTop is not available, do nothing.\n */\n renderCursorAt(selectionStart: number) {\n const boundaries = this._getCursorBoundaries(selectionStart, true);\n this._renderCursor(this.canvas!.contextTop, boundaries, selectionStart);\n }\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n this._renderCursor(ctx, boundaries, this.selectionStart);\n }\n\n _renderCursor(\n ctx: CanvasRenderingContext2D,\n boundaries: CursorBoundaries,\n selectionStart: number\n ) {\n const cursorLocation = this.get2DCursorLocation(selectionStart),\n lineIndex = cursorLocation.lineIndex,\n charIndex =\n cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.getObjectScaling().x * this.canvas!.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'),\n topOffset =\n boundaries.topOffset +\n ((1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex)) /\n this.lineHeight -\n charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n // TODO: investigate why there isn't a return inside the if,\n // and why can't happen at the top of the function\n this.renderSelection(ctx, boundaries);\n }\n ctx.fillStyle =\n this.cursorColor ||\n (this.getValueOfPropertyAt(lineIndex, charIndex, 'fill') as string);\n ctx.globalAlpha = this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight\n );\n }\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n const selection = {\n selectionStart: this.inCompositionMode\n ? this.hiddenTextarea!.selectionStart\n : this.selectionStart,\n selectionEnd: this.inCompositionMode\n ? this.hiddenTextarea!.selectionEnd\n : this.selectionEnd,\n };\n this._renderSelection(ctx, selection, boundaries);\n }\n\n /**\n * Renders drag start text selection\n */\n renderDragSourceEffect() {\n const dragStartSelection =\n this.draggableTextDelegate.getDragStartSelection()!;\n this._renderSelection(\n this.canvas!.contextTop,\n dragStartSelection,\n this._getCursorBoundaries(dragStartSelection.selectionStart, true)\n );\n }\n\n renderDropTargetEffect(e: DragEvent) {\n const dragSelection = this.getSelectionStartFromPointer(e);\n this.renderCursorAt(dragSelection);\n }\n\n /**\n * Renders text selection\n * @private\n * @param {{ selectionStart: number, selectionEnd: number }} selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n _renderSelection(\n ctx: CanvasRenderingContext2D,\n selection: { selectionStart: number; selectionEnd: number },\n boundaries: CursorBoundaries\n ) {\n const selectionStart = selection.selectionStart,\n selectionEnd = selection.selectionEnd,\n isJustify = this.textAlign.includes(JUSTIFY),\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (let i = startLine; i <= endLine; i++) {\n const lineOffset = this._getLineLeftOffset(i) || 0;\n let lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd =\n isJustify && !this.isEndOfWrapping(i)\n ? this.width\n : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n const charSpacing = this._getWidthOfCharSpacing();\n boxEnd =\n this.__charBounds[endLine][endChar - 1].left +\n this.__charBounds[endLine][endChar - 1].width -\n charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n let drawStart = boundaries.left + lineOffset + boxStart,\n drawHeight = lineHeight,\n extraTop = 0;\n const drawWidth = boxEnd - boxStart;\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n drawHeight = 1;\n extraTop = lineHeight;\n } else {\n ctx.fillStyle = this.selectionColor;\n }\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n drawStart = this.width - drawStart - drawWidth;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n }\n }\n ctx.fillRect(\n drawStart,\n boundaries.top + boundaries.topOffset + extraTop,\n drawWidth,\n drawHeight\n );\n boundaries.topOffset += realLineHeight;\n }\n }\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize(): number {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n }\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * if the text object has a pattern or gradient for filler, it will return that.\n * Unused by the library, is for the end user\n * @return {String | TFiller} Character color (fill)\n */\n getCurrentCharColor(): string | TFiller | null {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');\n }\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex() {\n const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex =\n cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n\n dispose() {\n this._exitEditing();\n this.draggableTextDelegate.dispose();\n super.dispose();\n }\n}\n\nclassRegistry.setClass(IText);\n// legacy\nclassRegistry.setClass(IText, 'i-text');\n"],"names":["protectedDefaultValues","_selectionDirection","_reSpace","inCompositionMode","iTextDefaultValues","_objectSpread","selectionStart","selectionEnd","selectionColor","isEditing","editable","editingBorderColor","cursorWidth","cursorColor","cursorDelay","cursorDuration","caching","hiddenTextareaContainer","keysMap","keysMapRtl","ctrlKeysMapDown","ctrlKeysMapUp","IText","ITextClickBehavior","getDefaults","ownDefaults","type","constructor","text","options","initBehavior","_set","key","value","_savedProps","canvas","Canvas","textEditingManager","remove","add","setSelectionStart","index","Math","max","_updateAndFire","setSelectionEnd","min","length","property","_fireSelectionChanged","_updateTextarea","fire","target","initDimensions","initDelayedCursor","getSelectionStyles","startIndex","arguments","undefined","endIndex","complete","setSelectionStyles","styles","get2DCursorLocation","skipWrapping","render","ctx","cursorOffsetCache","renderCursorOrSelection","toCanvasElement","clearContextTop","boundaries","_getCursorBoundaries","renderCursor","renderSelection","contextTopDirty","restore","skipCaching","left","_getLeftOffset","top","_getTopOffset","offsets","_getCursorBoundariesOffsets","leftOffset","topOffset","__getCursorBoundariesOffsets","charIndex","lineIndex","i","getHeightOfLine","lineLeftOffset","_getLineLeftOffset","bound","__charBounds","charSpacing","_textLines","_getWidthOfCharSpacing","direction","textAlign","RIGHT","JUSTIFY","JUSTIFY_RIGHT","LEFT","JUSTIFY_LEFT","CENTER","JUSTIFY_CENTER","renderCursorAt","_renderCursor","contextTop","cursorLocation","charHeight","getValueOfPropertyAt","multiplier","getObjectScaling","x","getZoom","dy","_fontSizeFraction","lineHeight","fillStyle","globalAlpha","_currentCursorOpacity","fillRect","selection","hiddenTextarea","_renderSelection","renderDragSourceEffect","dragStartSelection","draggableTextDelegate","getDragStartSelection","renderDropTargetEffect","e","dragSelection","getSelectionStartFromPointer","isJustify","includes","start","end","startLine","endLine","startChar","endChar","lineOffset","realLineHeight","boxStart","boxEnd","isEndOfWrapping","width","getLineWidth","drawStart","drawHeight","extraTop","drawWidth","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","l","c","getCurrentCharColor","cursorPosition","dispose","_exitEditing","_defineProperty","classRegistry","setClass"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IText.mjs","sources":["../../../../src/shapes/IText/IText.ts"],"sourcesContent":["import { Canvas } from '../../canvas/Canvas';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextClickBehavior } from './ITextClickBehavior';\nimport {\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n keysMap,\n keysMapRtl,\n} from './constants';\nimport type { TClassProperties, TFiller, TOptions } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport {\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from '../Text/constants';\nimport { CENTER, FILL, LEFT, RIGHT } from '../../constants';\nimport type { ObjectToCanvasElementOptions } from '../Object/Object';\n\ntype CursorBoundaries = {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n};\n\n// Declare IText protected properties to workaround TS\nconst protectedDefaultValues = {\n _selectionDirection: null,\n _reSpace: /\\s|\\r?\\n/,\n inCompositionMode: false,\n};\n\nexport const iTextDefaultValues: Partial<TClassProperties<IText>> = {\n selectionStart: 0,\n selectionEnd: 0,\n selectionColor: 'rgba(17,119,255,0.3)',\n isEditing: false,\n editable: true,\n editingBorderColor: 'rgba(102,153,255,0.25)',\n cursorWidth: 2,\n cursorColor: '',\n cursorDelay: 1000,\n cursorDuration: 600,\n caching: true,\n hiddenTextareaContainer: null,\n keysMap,\n keysMapRtl,\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n ...protectedDefaultValues,\n};\n\n// @TODO this is not complete\ninterface UniqueITextProps {\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface SerializedITextProps\n extends SerializedTextProps,\n UniqueITextProps {}\n\nexport interface ITextProps extends TextProps, UniqueITextProps {}\n\n/**\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n * @fires dragstart\n * @fires drag drag event firing on the drag source\n * @fires dragend\n * @fires copy\n * @fires cut\n * @fires paste\n *\n * #### Supported key combinations\n * ```\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * ```\n *\n * #### Supported mouse/touch combination\n * ```\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * ```\n */\nexport class IText<\n Props extends TOptions<ITextProps> = Partial<ITextProps>,\n SProps extends SerializedITextProps = SerializedITextProps,\n EventSpec extends ITextEvents = ITextEvents\n >\n extends ITextClickBehavior<Props, SProps, EventSpec>\n implements UniqueITextProps\n{\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n declare selectionStart: number;\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n declare selectionEnd: number;\n\n declare compositionStart: number;\n\n declare compositionEnd: number;\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n declare selectionColor: string;\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n declare isEditing: boolean;\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n declare editable: boolean;\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n declare editingBorderColor: string;\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n declare cursorWidth: number;\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n declare cursorColor: string;\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n declare cursorDelay: number;\n\n /**\n * Duration of cursor fade in (in ms)\n * @type Number\n * @default\n */\n declare cursorDuration: number;\n\n declare compositionColor: string;\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n declare caching: boolean;\n\n static ownDefaults = iTextDefaultValues;\n\n static getDefaults(): Record<string, any> {\n return { ...super.getDefaults(), ...IText.ownDefaults };\n }\n\n static type = 'IText';\n\n get type() {\n const type = super.type;\n // backward compatibility\n return type === 'itext' ? 'i-text' : type;\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...IText.ownDefaults, ...options } as Props);\n this.initBehavior();\n }\n\n /**\n * While editing handle differently\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (this.isEditing && this._savedProps && key in this._savedProps) {\n // @ts-expect-error irritating TS\n this._savedProps[key] = value;\n return this;\n }\n if (key === 'canvas') {\n this.canvas instanceof Canvas &&\n this.canvas.textEditingManager.remove(this);\n value instanceof Canvas && value.textEditingManager.add(this);\n }\n return super._set(key, value);\n }\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart(index: number) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n }\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd(index: number) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n }\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n protected _updateAndFire(\n property: 'selectionStart' | 'selectionEnd',\n index: number\n ) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n }\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n }\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions() {\n this.isEditing && this.initDelayedCursor();\n super.initDimensions();\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n complete?: boolean\n ) {\n return super.getSelectionStyles(startIndex, endIndex, complete);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n */\n setSelectionStyles(\n styles: object,\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd\n ) {\n return super.setSelectionStyles(styles, startIndex, endIndex);\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(\n selectionStart = this.selectionStart,\n skipWrapping?: boolean\n ) {\n return super.get2DCursorLocation(selectionStart, skipWrapping);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n super.render(ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n }\n\n /**\n * @override block cursor/selection logic while rendering the exported canvas\n * @todo this workaround should be replaced with a more robust solution\n */\n toCanvasElement(options?: ObjectToCanvasElementOptions): HTMLCanvasElement {\n const isEditing = this.isEditing;\n this.isEditing = false;\n const canvas = super.toCanvasElement(options);\n this.isEditing = isEditing;\n return canvas;\n }\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection() {\n if (!this.isEditing) {\n return;\n }\n const ctx = this.clearContextTop(true);\n if (!ctx) {\n return;\n }\n const boundaries = this._getCursorBoundaries();\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(ctx, boundaries);\n } else {\n this.renderSelection(ctx, boundaries);\n }\n this.canvas!.contextTopDirty = true;\n ctx.restore();\n }\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * left/top are left/top of entire text box\n * leftOffset/topOffset are offset from that left/top point of a text box\n * @private\n * @param {number} [index] index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundaries(\n index: number = this.selectionStart,\n skipCaching?: boolean\n ): CursorBoundaries {\n const left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(index, skipCaching);\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top,\n };\n }\n\n /**\n * Caches and returns cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundariesOffsets(\n index: number,\n skipCaching?: boolean\n ): { left: number; top: number } {\n if (skipCaching) {\n return this.__getCursorBoundariesOffsets(index);\n }\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache as { left: number; top: number };\n }\n return (this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index));\n }\n\n /**\n * Calculates cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n */\n __getCursorBoundariesOffsets(index: number) {\n let topOffset = 0,\n leftOffset = 0;\n const { charIndex, lineIndex } = this.get2DCursorLocation(index);\n\n for (let i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n const lineLeftOffset = this._getLineLeftOffset(lineIndex);\n const bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (\n this.charSpacing !== 0 &&\n charIndex === this._textLines[lineIndex].length\n ) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n const boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n boundaries.left *= -1;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n }\n }\n return boundaries;\n }\n\n /**\n * Renders cursor on context Top, outside the animation cycle, on request\n * Used for the drag/drop effect.\n * If contextTop is not available, do nothing.\n */\n renderCursorAt(selectionStart: number) {\n const boundaries = this._getCursorBoundaries(selectionStart, true);\n this._renderCursor(this.canvas!.contextTop, boundaries, selectionStart);\n }\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n this._renderCursor(ctx, boundaries, this.selectionStart);\n }\n\n _renderCursor(\n ctx: CanvasRenderingContext2D,\n boundaries: CursorBoundaries,\n selectionStart: number\n ) {\n const cursorLocation = this.get2DCursorLocation(selectionStart),\n lineIndex = cursorLocation.lineIndex,\n charIndex =\n cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.getObjectScaling().x * this.canvas!.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'),\n topOffset =\n boundaries.topOffset +\n ((1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex)) /\n this.lineHeight -\n charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n // TODO: investigate why there isn't a return inside the if,\n // and why can't happen at the top of the function\n this.renderSelection(ctx, boundaries);\n }\n ctx.fillStyle =\n this.cursorColor ||\n (this.getValueOfPropertyAt(lineIndex, charIndex, FILL) as string);\n ctx.globalAlpha = this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight\n );\n }\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n const selection = {\n selectionStart: this.inCompositionMode\n ? this.hiddenTextarea!.selectionStart\n : this.selectionStart,\n selectionEnd: this.inCompositionMode\n ? this.hiddenTextarea!.selectionEnd\n : this.selectionEnd,\n };\n this._renderSelection(ctx, selection, boundaries);\n }\n\n /**\n * Renders drag start text selection\n */\n renderDragSourceEffect() {\n const dragStartSelection =\n this.draggableTextDelegate.getDragStartSelection()!;\n this._renderSelection(\n this.canvas!.contextTop,\n dragStartSelection,\n this._getCursorBoundaries(dragStartSelection.selectionStart, true)\n );\n }\n\n renderDropTargetEffect(e: DragEvent) {\n const dragSelection = this.getSelectionStartFromPointer(e);\n this.renderCursorAt(dragSelection);\n }\n\n /**\n * Renders text selection\n * @private\n * @param {{ selectionStart: number, selectionEnd: number }} selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n _renderSelection(\n ctx: CanvasRenderingContext2D,\n selection: { selectionStart: number; selectionEnd: number },\n boundaries: CursorBoundaries\n ) {\n const selectionStart = selection.selectionStart,\n selectionEnd = selection.selectionEnd,\n isJustify = this.textAlign.includes(JUSTIFY),\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (let i = startLine; i <= endLine; i++) {\n const lineOffset = this._getLineLeftOffset(i) || 0;\n let lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd =\n isJustify && !this.isEndOfWrapping(i)\n ? this.width\n : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n const charSpacing = this._getWidthOfCharSpacing();\n boxEnd =\n this.__charBounds[endLine][endChar - 1].left +\n this.__charBounds[endLine][endChar - 1].width -\n charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n let drawStart = boundaries.left + lineOffset + boxStart,\n drawHeight = lineHeight,\n extraTop = 0;\n const drawWidth = boxEnd - boxStart;\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n drawHeight = 1;\n extraTop = lineHeight;\n } else {\n ctx.fillStyle = this.selectionColor;\n }\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n drawStart = this.width - drawStart - drawWidth;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n }\n }\n ctx.fillRect(\n drawStart,\n boundaries.top + boundaries.topOffset + extraTop,\n drawWidth,\n drawHeight\n );\n boundaries.topOffset += realLineHeight;\n }\n }\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize(): number {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n }\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * if the text object has a pattern or gradient for filler, it will return that.\n * Unused by the library, is for the end user\n * @return {String | TFiller} Character color (fill)\n */\n getCurrentCharColor(): string | TFiller | null {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, FILL);\n }\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex() {\n const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex =\n cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n\n dispose() {\n this._exitEditing();\n this.draggableTextDelegate.dispose();\n super.dispose();\n }\n}\n\nclassRegistry.setClass(IText);\n// legacy\nclassRegistry.setClass(IText, 'i-text');\n"],"names":["protectedDefaultValues","_selectionDirection","_reSpace","inCompositionMode","iTextDefaultValues","_objectSpread","selectionStart","selectionEnd","selectionColor","isEditing","editable","editingBorderColor","cursorWidth","cursorColor","cursorDelay","cursorDuration","caching","hiddenTextareaContainer","keysMap","keysMapRtl","ctrlKeysMapDown","ctrlKeysMapUp","IText","ITextClickBehavior","getDefaults","ownDefaults","type","constructor","text","options","initBehavior","_set","key","value","_savedProps","canvas","Canvas","textEditingManager","remove","add","setSelectionStart","index","Math","max","_updateAndFire","setSelectionEnd","min","length","property","_fireSelectionChanged","_updateTextarea","fire","target","initDimensions","initDelayedCursor","getSelectionStyles","startIndex","arguments","undefined","endIndex","complete","setSelectionStyles","styles","get2DCursorLocation","skipWrapping","render","ctx","cursorOffsetCache","renderCursorOrSelection","toCanvasElement","clearContextTop","boundaries","_getCursorBoundaries","renderCursor","renderSelection","contextTopDirty","restore","skipCaching","left","_getLeftOffset","top","_getTopOffset","offsets","_getCursorBoundariesOffsets","leftOffset","topOffset","__getCursorBoundariesOffsets","charIndex","lineIndex","i","getHeightOfLine","lineLeftOffset","_getLineLeftOffset","bound","__charBounds","charSpacing","_textLines","_getWidthOfCharSpacing","direction","textAlign","RIGHT","JUSTIFY","JUSTIFY_RIGHT","LEFT","JUSTIFY_LEFT","CENTER","JUSTIFY_CENTER","renderCursorAt","_renderCursor","contextTop","cursorLocation","charHeight","getValueOfPropertyAt","multiplier","getObjectScaling","x","getZoom","dy","_fontSizeFraction","lineHeight","fillStyle","FILL","globalAlpha","_currentCursorOpacity","fillRect","selection","hiddenTextarea","_renderSelection","renderDragSourceEffect","dragStartSelection","draggableTextDelegate","getDragStartSelection","renderDropTargetEffect","e","dragSelection","getSelectionStartFromPointer","isJustify","includes","start","end","startLine","endLine","startChar","endChar","lineOffset","realLineHeight","boxStart","boxEnd","isEndOfWrapping","width","getLineWidth","drawStart","drawHeight","extraTop","drawWidth","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","l","c","getCurrentCharColor","cursorPosition","dispose","_exitEditing","_defineProperty","classRegistry","setClass"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{defineProperty as t,objectSpread2 as e}from"../../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{Point as s}from"../../Point.min.mjs";import{FabricText as i}from"../Text/Text.min.mjs";import{animate as n}from"../../util/animation/animate.min.mjs";import{getDocumentFromElement as o}from"../../util/dom_misc.min.mjs";import{reNewline as r,LEFT as h,RIGHT as a}from"../../constants.min.mjs";const l=/[ \n\.,;!\?\-]/;class c extends i{constructor(){super(...arguments),t(this,"_currentCursorOpacity",1)}initBehavior(){this._tick=this._tick.bind(this),this._onTickComplete=this._onTickComplete.bind(this),this.updateSelectionOnMouseMove=this.updateSelectionOnMouseMove.bind(this)}onDeselect(t){return this.isEditing&&this.exitEditing(),this.selected=!1,super.onDeselect(t)}_animateCursor(t){let{toValue:e,duration:s,delay:i,onComplete:o}=t;return n({startValue:this._currentCursorOpacity,endValue:e,duration:s,delay:i,onComplete:o,abort:()=>!this.canvas||this.selectionStart!==this.selectionEnd,onChange:t=>{this._currentCursorOpacity=t,this.renderCursorOrSelection()}})}_tick(t){this._currentTickState=this._animateCursor({toValue:0,duration:this.cursorDuration/2,delay:Math.max(t||0,100),onComplete:this._onTickComplete})}_onTickComplete(){var t;null===(t=this._currentTickCompleteState)||void 0===t||t.abort(),this._currentTickCompleteState=this._animateCursor({toValue:1,duration:this.cursorDuration,onComplete:this._tick})}initDelayedCursor(t){this.abortCursorAnimation(),this._tick(t?0:this.cursorDelay)}abortCursorAnimation(){let t=!1;[this._currentTickState,this._currentTickCompleteState].forEach((e=>{e&&!e.isDone()&&(t=!0,e.abort())})),this._currentCursorOpacity=1,t&&this.clearContextTop()}restartCursorIfNeeded(){[this._currentTickState,this._currentTickCompleteState].some((t=>!t||t.isDone()))&&this.initDelayedCursor()}selectAll(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this}getSelectedText(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")}findWordBoundaryLeft(t){let e=0,s=t-1;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s--;for(;/\S/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findWordBoundaryRight(t){let e=0,s=t;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s++;for(;/\S/.test(this._text[s])&&s<this._text.length;)e++,s++;return t+e}findLineBoundaryLeft(t){let e=0,s=t-1;for(;!/\n/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findLineBoundaryRight(t){let e=0,s=t;for(;!/\n/.test(this._text[s])&&s<this._text.length;)e++,s++;return t+e}searchWordBoundary(t,e){const s=this._text;let i=t>0&&this._reSpace.test(s[t])&&(-1===e||!r.test(s[t-1]))?t-1:t,n=s[i];for(;i>0&&i<s.length&&!l.test(n);)i+=e,n=s[i];return-1===e&&l.test(n)&&i++,i}selectWord(t){t=t||this.selectionStart;const e=this.searchWordBoundary(t,-1),s=Math.max(e,this.searchWordBoundary(t,1));this.selectionStart=e,this.selectionEnd=s,this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()}selectLine(t){t=t||this.selectionStart;const e=this.findLineBoundaryLeft(t),s=this.findLineBoundaryRight(t);return this.selectionStart=e,this.selectionEnd=s,this._fireSelectionChanged(),this._updateTextarea(),this}enterEditing(t){!this.isEditing&&this.editable&&(this.canvas&&(this.canvas.calcOffset(),this.canvas.textEditingManager.exitTextEditing()),this.isEditing=!0,this.initHiddenTextarea(),this.hiddenTextarea.focus(),this.hiddenTextarea.value=this.text,this._updateTextarea(),this._saveEditingProps(),this._setEditingProps(),this._textBeforeEdit=this.text,this._tick(),this.fire("editing:entered",t?{e:t}:void 0),this._fireSelectionChanged(),this.canvas&&(this.canvas.fire("text:editing:entered",{target:this,e:t}),this.canvas.requestRenderAll()))}updateSelectionOnMouseMove(t){if(this.getActiveControl())return;const e=this.hiddenTextarea;o(e).activeElement!==e&&e.focus();const s=this.getSelectionStartFromPointer(t),i=this.selectionStart,n=this.selectionEnd;(s===this.__selectionStartOnMouseDown&&i!==n||i!==s&&n!==s)&&(s>this.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=s):(this.selectionStart=s,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===n||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}_setEditingProps(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0}fromStringToGraphemeSelection(t,e,s){const i=s.slice(0,t),n=this.graphemeSplit(i).length;if(t===e)return{selectionStart:n,selectionEnd:n};const o=s.slice(t,e);return{selectionStart:n,selectionEnd:n+this.graphemeSplit(o).length}}fromGraphemeToStringSelection(t,e,s){const i=s.slice(0,t).join("").length;if(t===e)return{selectionStart:i,selectionEnd:i};return{selectionStart:i,selectionEnd:i+s.slice(t,e).join("").length}}_updateTextarea(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){const t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}}updateFromTextArea(){if(!this.hiddenTextarea)return;this.cursorOffsetCache={};const t=this.hiddenTextarea;this.text=t.value,this.set("dirty",!0),this.initDimensions(),this.setCoords();const e=this.fromStringToGraphemeSelection(t.selectionStart,t.selectionEnd,t.value);this.selectionEnd=this.selectionStart=e.selectionEnd,this.inCompositionMode||(this.selectionStart=e.selectionStart),this.updateTextareaPosition()}updateTextareaPosition(){if(this.selectionStart===this.selectionEnd){const t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}}_calcTextareaPosition(){if(!this.canvas)return{left:"1px",top:"1px"};const t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),n=i.lineIndex,o=i.charIndex,r=this.getValueOfPropertyAt(n,o,"fontSize")*this.lineHeight,h=e.leftOffset,a=this.getCanvasRetinaScaling(),l=this.canvas.upperCanvasEl,c=l.width/a,d=l.height/a,u=c-r,f=d-r,_=new s(e.left+h,e.top+e.topOffset+r).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new s(l.clientWidth/c,l.clientHeight/d));return _.x<0&&(_.x=0),_.x>u&&(_.x=u),_.y<0&&(_.y=0),_.y>f&&(_.y=f),_.x+=this.canvas._offset.left,_.y+=this.canvas._offset.top,{left:"".concat(_.x,"px"),top:"".concat(_.y,"px"),fontSize:"".concat(r,"px"),charHeight:r}}_saveEditingProps(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}}_restoreEditingProps(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor||this.canvas.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor||this.canvas.moveCursor),delete this._savedProps)}_exitEditing(){const t=this.hiddenTextarea;this.selected=!1,this.isEditing=!1,t&&(t.blur&&t.blur(),t.parentNode&&t.parentNode.removeChild(t)),this.hiddenTextarea=null,this.abortCursorAnimation(),this.selectionStart!==this.selectionEnd&&this.clearContextTop()}exitEditing(){const t=this._textBeforeEdit!==this.text;return this._exitEditing(),this.selectionEnd=this.selectionStart,this._restoreEditingProps(),this._forceClearCache&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this}_removeExtraneousStyles(){for(const t in this.styles)this._textLines[t]||delete this.styles[t]}removeStyleFromTo(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t,!0),{lineIndex:n,charIndex:o}=this.get2DCursorLocation(e,!0);if(s!==n){if(this.styles[s])for(let t=i;t<this._unwrappedTextLines[s].length;t++)delete this.styles[s][t];if(this.styles[n])for(let t=o;t<this._unwrappedTextLines[n].length;t++){const e=this.styles[n][t];e&&(this.styles[s]||(this.styles[s]={}),this.styles[s][i+t-o]=e)}for(let t=s+1;t<=n;t++)delete this.styles[t];this.shiftLineStyles(n,s-n)}else if(this.styles[s]){const t=this.styles[s],e=o-i;for(let e=i;e<o;e++)delete t[e];for(const i in this.styles[s]){const s=parseInt(i,10);s>=o&&(t[s-e]=t[i],delete t[i])}}}shiftLineStyles(t,e){const s=Object.assign({},this.styles);for(const i in this.styles){const n=parseInt(i,10);n>t&&(this.styles[n+e]=s[n],s[n-e]||delete this.styles[n])}}insertNewlineStyleObject(t,s,i,n){const o={},r=this._unwrappedTextLines[t].length,h=r===s;let a=!1;i||(i=1),this.shiftLineStyles(t,i);const l=this.styles[t]?this.styles[t][0===s?s:s-1]:void 0;for(const e in this.styles[t]){const i=parseInt(e,10);i>=s&&(a=!0,o[i-s]=this.styles[t][e],h&&0===s||delete this.styles[t][e])}let c=!1;for(a&&!h&&(this.styles[t+i]=o,c=!0),(c||r>s)&&i--;i>0;)n&&n[i-1]?this.styles[t+i]={0:e({},n[i-1])}:l?this.styles[t+i]={0:e({},l)}:delete this.styles[t+i],i--;this._forceClearCache=!0}insertCharStyleObject(t,s,i,n){this.styles||(this.styles={});const o=this.styles[t],r=o?e({},o):{};i||(i=1);for(const t in r){const e=parseInt(t,10);e>=s&&(o[e+i]=r[e],r[e-i]||delete o[e])}if(this._forceClearCache=!0,n){for(;i--;)Object.keys(n[i]).length&&(this.styles[t]||(this.styles[t]={}),this.styles[t][s+i]=e({},n[i]));return}if(!o)return;const h=o[s?s-1:1];for(;h&&i--;)this.styles[t][s+i]=e({},h)}insertNewStyleBlock(t,e,s){const i=this.get2DCursorLocation(e,!0),n=[0];let o,r=0;for(let e=0;e<t.length;e++)"\n"===t[e]?(r++,n[r]=0):n[r]++;for(n[0]>0&&(this.insertCharStyleObject(i.lineIndex,i.charIndex,n[0],s),s=s&&s.slice(n[0]+1)),r&&this.insertNewlineStyleObject(i.lineIndex,i.charIndex+n[0],r),o=1;o<r;o++)n[o]>0?this.insertCharStyleObject(i.lineIndex+o,0,n[o],s):s&&this.styles[i.lineIndex+o]&&s[0]&&(this.styles[i.lineIndex+o][0]=s[0]),s=s&&s.slice(n[o]+1);n[o]>0&&this.insertCharStyleObject(i.lineIndex+o,0,n[o],s)}removeChars(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t+1;this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}insertChars(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s;i>s&&this.removeStyleFromTo(s,i);const n=this.graphemeSplit(t);this.insertNewStyleBlock(n,s,e),this._text=[...this._text.slice(0,s),...n,...this._text.slice(i)],this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}setSelectionStartEndWithShift(t,e,s){s<=t?(e===t?this._selectionDirection=h:this._selectionDirection===a&&(this._selectionDirection=h,this.selectionEnd=t),this.selectionStart=s):s>t&&s<e?this._selectionDirection===a?this.selectionEnd=s:this.selectionStart=s:(e===t?this._selectionDirection=a:this._selectionDirection===h&&(this._selectionDirection=a,this.selectionStart=e),this.selectionEnd=s)}}export{c as ITextBehavior};
|
|
1
|
+
import{defineProperty as t,objectSpread2 as e}from"../../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{Point as s}from"../../Point.min.mjs";import{FabricText as i}from"../Text/Text.min.mjs";import{animate as n}from"../../util/animation/animate.min.mjs";import{getDocumentFromElement as o}from"../../util/dom_misc.min.mjs";import{reNewline as r,MODIFIED as h,LEFT as a,RIGHT as l}from"../../constants.min.mjs";const c=/[ \n\.,;!\?\-]/;class d extends i{constructor(){super(...arguments),t(this,"_currentCursorOpacity",1)}initBehavior(){this._tick=this._tick.bind(this),this._onTickComplete=this._onTickComplete.bind(this),this.updateSelectionOnMouseMove=this.updateSelectionOnMouseMove.bind(this)}onDeselect(t){return this.isEditing&&this.exitEditing(),this.selected=!1,super.onDeselect(t)}_animateCursor(t){let{toValue:e,duration:s,delay:i,onComplete:o}=t;return n({startValue:this._currentCursorOpacity,endValue:e,duration:s,delay:i,onComplete:o,abort:()=>!this.canvas||this.selectionStart!==this.selectionEnd,onChange:t=>{this._currentCursorOpacity=t,this.renderCursorOrSelection()}})}_tick(t){this._currentTickState=this._animateCursor({toValue:0,duration:this.cursorDuration/2,delay:Math.max(t||0,100),onComplete:this._onTickComplete})}_onTickComplete(){var t;null===(t=this._currentTickCompleteState)||void 0===t||t.abort(),this._currentTickCompleteState=this._animateCursor({toValue:1,duration:this.cursorDuration,onComplete:this._tick})}initDelayedCursor(t){this.abortCursorAnimation(),this._tick(t?0:this.cursorDelay)}abortCursorAnimation(){let t=!1;[this._currentTickState,this._currentTickCompleteState].forEach((e=>{e&&!e.isDone()&&(t=!0,e.abort())})),this._currentCursorOpacity=1,t&&this.clearContextTop()}restartCursorIfNeeded(){[this._currentTickState,this._currentTickCompleteState].some((t=>!t||t.isDone()))&&this.initDelayedCursor()}selectAll(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this}getSelectedText(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")}findWordBoundaryLeft(t){let e=0,s=t-1;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s--;for(;/\S/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findWordBoundaryRight(t){let e=0,s=t;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s++;for(;/\S/.test(this._text[s])&&s<this._text.length;)e++,s++;return t+e}findLineBoundaryLeft(t){let e=0,s=t-1;for(;!/\n/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findLineBoundaryRight(t){let e=0,s=t;for(;!/\n/.test(this._text[s])&&s<this._text.length;)e++,s++;return t+e}searchWordBoundary(t,e){const s=this._text;let i=t>0&&this._reSpace.test(s[t])&&(-1===e||!r.test(s[t-1]))?t-1:t,n=s[i];for(;i>0&&i<s.length&&!c.test(n);)i+=e,n=s[i];return-1===e&&c.test(n)&&i++,i}selectWord(t){t=t||this.selectionStart;const e=this.searchWordBoundary(t,-1),s=Math.max(e,this.searchWordBoundary(t,1));this.selectionStart=e,this.selectionEnd=s,this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()}selectLine(t){t=t||this.selectionStart;const e=this.findLineBoundaryLeft(t),s=this.findLineBoundaryRight(t);return this.selectionStart=e,this.selectionEnd=s,this._fireSelectionChanged(),this._updateTextarea(),this}enterEditing(t){!this.isEditing&&this.editable&&(this.canvas&&(this.canvas.calcOffset(),this.canvas.textEditingManager.exitTextEditing()),this.isEditing=!0,this.initHiddenTextarea(),this.hiddenTextarea.focus(),this.hiddenTextarea.value=this.text,this._updateTextarea(),this._saveEditingProps(),this._setEditingProps(),this._textBeforeEdit=this.text,this._tick(),this.fire("editing:entered",t?{e:t}:void 0),this._fireSelectionChanged(),this.canvas&&(this.canvas.fire("text:editing:entered",{target:this,e:t}),this.canvas.requestRenderAll()))}updateSelectionOnMouseMove(t){if(this.getActiveControl())return;const e=this.hiddenTextarea;o(e).activeElement!==e&&e.focus();const s=this.getSelectionStartFromPointer(t),i=this.selectionStart,n=this.selectionEnd;(s===this.__selectionStartOnMouseDown&&i!==n||i!==s&&n!==s)&&(s>this.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=s):(this.selectionStart=s,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===n||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}_setEditingProps(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0}fromStringToGraphemeSelection(t,e,s){const i=s.slice(0,t),n=this.graphemeSplit(i).length;if(t===e)return{selectionStart:n,selectionEnd:n};const o=s.slice(t,e);return{selectionStart:n,selectionEnd:n+this.graphemeSplit(o).length}}fromGraphemeToStringSelection(t,e,s){const i=s.slice(0,t).join("").length;if(t===e)return{selectionStart:i,selectionEnd:i};return{selectionStart:i,selectionEnd:i+s.slice(t,e).join("").length}}_updateTextarea(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){const t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}}updateFromTextArea(){if(!this.hiddenTextarea)return;this.cursorOffsetCache={};const t=this.hiddenTextarea;this.text=t.value,this.set("dirty",!0),this.initDimensions(),this.setCoords();const e=this.fromStringToGraphemeSelection(t.selectionStart,t.selectionEnd,t.value);this.selectionEnd=this.selectionStart=e.selectionEnd,this.inCompositionMode||(this.selectionStart=e.selectionStart),this.updateTextareaPosition()}updateTextareaPosition(){if(this.selectionStart===this.selectionEnd){const t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}}_calcTextareaPosition(){if(!this.canvas)return{left:"1px",top:"1px"};const t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),n=i.lineIndex,o=i.charIndex,r=this.getValueOfPropertyAt(n,o,"fontSize")*this.lineHeight,h=e.leftOffset,a=this.getCanvasRetinaScaling(),l=this.canvas.upperCanvasEl,c=l.width/a,d=l.height/a,u=c-r,f=d-r,_=new s(e.left+h,e.top+e.topOffset+r).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new s(l.clientWidth/c,l.clientHeight/d));return _.x<0&&(_.x=0),_.x>u&&(_.x=u),_.y<0&&(_.y=0),_.y>f&&(_.y=f),_.x+=this.canvas._offset.left,_.y+=this.canvas._offset.top,{left:"".concat(_.x,"px"),top:"".concat(_.y,"px"),fontSize:"".concat(r,"px"),charHeight:r}}_saveEditingProps(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}}_restoreEditingProps(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor||this.canvas.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor||this.canvas.moveCursor),delete this._savedProps)}_exitEditing(){const t=this.hiddenTextarea;this.selected=!1,this.isEditing=!1,t&&(t.blur&&t.blur(),t.parentNode&&t.parentNode.removeChild(t)),this.hiddenTextarea=null,this.abortCursorAnimation(),this.selectionStart!==this.selectionEnd&&this.clearContextTop()}exitEditing(){const t=this._textBeforeEdit!==this.text;return this._exitEditing(),this.selectionEnd=this.selectionStart,this._restoreEditingProps(),this._forceClearCache&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire(h),this.canvas&&(this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this}_removeExtraneousStyles(){for(const t in this.styles)this._textLines[t]||delete this.styles[t]}removeStyleFromTo(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t,!0),{lineIndex:n,charIndex:o}=this.get2DCursorLocation(e,!0);if(s!==n){if(this.styles[s])for(let t=i;t<this._unwrappedTextLines[s].length;t++)delete this.styles[s][t];if(this.styles[n])for(let t=o;t<this._unwrappedTextLines[n].length;t++){const e=this.styles[n][t];e&&(this.styles[s]||(this.styles[s]={}),this.styles[s][i+t-o]=e)}for(let t=s+1;t<=n;t++)delete this.styles[t];this.shiftLineStyles(n,s-n)}else if(this.styles[s]){const t=this.styles[s],e=o-i;for(let e=i;e<o;e++)delete t[e];for(const i in this.styles[s]){const s=parseInt(i,10);s>=o&&(t[s-e]=t[i],delete t[i])}}}shiftLineStyles(t,e){const s=Object.assign({},this.styles);for(const i in this.styles){const n=parseInt(i,10);n>t&&(this.styles[n+e]=s[n],s[n-e]||delete this.styles[n])}}insertNewlineStyleObject(t,s,i,n){const o={},r=this._unwrappedTextLines[t].length,h=r===s;let a=!1;i||(i=1),this.shiftLineStyles(t,i);const l=this.styles[t]?this.styles[t][0===s?s:s-1]:void 0;for(const e in this.styles[t]){const i=parseInt(e,10);i>=s&&(a=!0,o[i-s]=this.styles[t][e],h&&0===s||delete this.styles[t][e])}let c=!1;for(a&&!h&&(this.styles[t+i]=o,c=!0),(c||r>s)&&i--;i>0;)n&&n[i-1]?this.styles[t+i]={0:e({},n[i-1])}:l?this.styles[t+i]={0:e({},l)}:delete this.styles[t+i],i--;this._forceClearCache=!0}insertCharStyleObject(t,s,i,n){this.styles||(this.styles={});const o=this.styles[t],r=o?e({},o):{};i||(i=1);for(const t in r){const e=parseInt(t,10);e>=s&&(o[e+i]=r[e],r[e-i]||delete o[e])}if(this._forceClearCache=!0,n){for(;i--;)Object.keys(n[i]).length&&(this.styles[t]||(this.styles[t]={}),this.styles[t][s+i]=e({},n[i]));return}if(!o)return;const h=o[s?s-1:1];for(;h&&i--;)this.styles[t][s+i]=e({},h)}insertNewStyleBlock(t,e,s){const i=this.get2DCursorLocation(e,!0),n=[0];let o,r=0;for(let e=0;e<t.length;e++)"\n"===t[e]?(r++,n[r]=0):n[r]++;for(n[0]>0&&(this.insertCharStyleObject(i.lineIndex,i.charIndex,n[0],s),s=s&&s.slice(n[0]+1)),r&&this.insertNewlineStyleObject(i.lineIndex,i.charIndex+n[0],r),o=1;o<r;o++)n[o]>0?this.insertCharStyleObject(i.lineIndex+o,0,n[o],s):s&&this.styles[i.lineIndex+o]&&s[0]&&(this.styles[i.lineIndex+o][0]=s[0]),s=s&&s.slice(n[o]+1);n[o]>0&&this.insertCharStyleObject(i.lineIndex+o,0,n[o],s)}removeChars(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t+1;this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}insertChars(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s;i>s&&this.removeStyleFromTo(s,i);const n=this.graphemeSplit(t);this.insertNewStyleBlock(n,s,e),this._text=[...this._text.slice(0,s),...n,...this._text.slice(i)],this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}setSelectionStartEndWithShift(t,e,s){s<=t?(e===t?this._selectionDirection=a:this._selectionDirection===l&&(this._selectionDirection=a,this.selectionEnd=t),this.selectionStart=s):s>t&&s<e?this._selectionDirection===l?this.selectionEnd=s:this.selectionStart=s:(e===t?this._selectionDirection=l:this._selectionDirection===a&&(this._selectionDirection=l,this.selectionStart=e),this.selectionEnd=s)}}export{d as ITextBehavior};
|
|
2
2
|
//# sourceMappingURL=ITextBehavior.min.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ITextBehavior.min.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","super","arguments","_defineProperty","initBehavior","this","_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","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.min.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","super","arguments","_defineProperty","initBehavior","this","_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","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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"}
|
|
@@ -3,7 +3,7 @@ import { Point } from '../../Point.mjs';
|
|
|
3
3
|
import { FabricText } from '../Text/Text.mjs';
|
|
4
4
|
import { animate } from '../../util/animation/animate.mjs';
|
|
5
5
|
import { getDocumentFromElement } from '../../util/dom_misc.mjs';
|
|
6
|
-
import { reNewline, LEFT, RIGHT } from '../../constants.mjs';
|
|
6
|
+
import { reNewline, MODIFIED, LEFT, RIGHT } from '../../constants.mjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* extend this regex to support non english languages
|
|
@@ -560,7 +560,7 @@ class ITextBehavior extends FabricText {
|
|
|
560
560
|
this.setCoords();
|
|
561
561
|
}
|
|
562
562
|
this.fire('editing:exited');
|
|
563
|
-
isTextChanged && this.fire(
|
|
563
|
+
isTextChanged && this.fire(MODIFIED);
|
|
564
564
|
if (this.canvas) {
|
|
565
565
|
this.canvas.fire('text:editing:exited', {
|
|
566
566
|
target: this
|