fabric 7.0.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.husky/pre-commit +1 -0
- package/CHANGELOG.md +21 -0
- package/dist/extensions/cropping_controls/croppingControls.d.ts +16 -0
- package/dist/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
- package/dist/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
- package/dist/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
- package/dist/extensions/cropping_controls/enterCropMode.d.ts +7 -0
- package/dist/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
- package/dist/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
- package/dist/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/fabric.d.ts +1 -0
- package/dist/fabric.d.ts.map +1 -1
- package/dist/index.js +628 -537
- 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 +628 -537
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +628 -537
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +628 -537
- 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 +5 -0
- package/dist/src/EventTypeDefs.d.ts.map +1 -1
- package/dist/src/Pattern/Pattern.d.ts.map +1 -1
- package/dist/src/Pattern/Pattern.min.mjs +1 -1
- package/dist/src/Pattern/Pattern.min.mjs.map +1 -1
- package/dist/src/Pattern/Pattern.mjs +2 -1
- package/dist/src/Pattern/Pattern.mjs.map +1 -1
- package/dist/src/Shadow.d.ts +1 -1
- package/dist/src/Shadow.d.ts.map +1 -1
- package/dist/src/Shadow.min.mjs +1 -1
- package/dist/src/Shadow.min.mjs.map +1 -1
- package/dist/src/Shadow.mjs +5 -4
- package/dist/src/Shadow.mjs.map +1 -1
- package/dist/src/canvas/CanvasOptions.d.ts.map +1 -1
- package/dist/src/canvas/CanvasOptions.min.mjs.map +1 -1
- package/dist/src/canvas/CanvasOptions.mjs.map +1 -1
- package/dist/src/canvas/SelectableCanvas.d.ts +2 -0
- 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 +33 -13
- package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
- package/dist/src/canvas/StaticCanvas.min.mjs +1 -1
- package/dist/src/canvas/StaticCanvas.min.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvas.mjs +3 -1
- package/dist/src/canvas/StaticCanvas.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
- package/dist/src/canvas/StaticCanvasOptions.min.mjs.map +1 -1
- package/dist/src/canvas/StaticCanvasOptions.mjs.map +1 -1
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.min.mjs.map +1 -1
- package/dist/src/constants.mjs.map +1 -1
- package/dist/src/controls/Control.d.ts +22 -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 +45 -1
- package/dist/src/controls/Control.mjs.map +1 -1
- package/dist/src/controls/changeWidth.d.ts +22 -0
- package/dist/src/controls/changeWidth.d.ts.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 +46 -18
- package/dist/src/controls/changeWidth.mjs.map +1 -1
- package/dist/src/controls/controlRendering.d.ts.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 +18 -34
- package/dist/src/controls/controlRendering.mjs.map +1 -1
- package/dist/src/controls/index.d.ts +2 -1
- package/dist/src/controls/index.d.ts.map +1 -1
- package/dist/src/controls/index.min.mjs +1 -1
- package/dist/src/controls/index.mjs +1 -1
- package/dist/src/gradient/Gradient.d.ts.map +1 -1
- package/dist/src/gradient/Gradient.min.mjs +1 -1
- package/dist/src/gradient/Gradient.min.mjs.map +1 -1
- package/dist/src/gradient/Gradient.mjs +19 -6
- package/dist/src/gradient/Gradient.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 +10 -7
- package/dist/src/shapes/Circle.mjs.map +1 -1
- package/dist/src/shapes/Ellipse.d.ts.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 +2 -1
- package/dist/src/shapes/Ellipse.mjs.map +1 -1
- package/dist/src/shapes/Group.d.ts.map +1 -1
- package/dist/src/shapes/Group.min.mjs +1 -1
- package/dist/src/shapes/Group.min.mjs.map +1 -1
- package/dist/src/shapes/Group.mjs +2 -1
- package/dist/src/shapes/Group.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.d.ts.map +1 -1
- package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
- package/dist/src/shapes/IText/IText.mjs.map +1 -1
- package/dist/src/shapes/Image.d.ts +1 -1
- package/dist/src/shapes/Image.d.ts.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 +4 -3
- package/dist/src/shapes/Image.mjs.map +1 -1
- package/dist/src/shapes/Line.d.ts.map +1 -1
- package/dist/src/shapes/Line.min.mjs +1 -1
- package/dist/src/shapes/Line.min.mjs.map +1 -1
- package/dist/src/shapes/Line.mjs +6 -10
- package/dist/src/shapes/Line.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 +5 -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.map +1 -1
- package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
- 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 +3 -0
- 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 +1 -1
- package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
- package/dist/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
- package/dist/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
- package/dist/src/shapes/Path.d.ts.map +1 -1
- package/dist/src/shapes/Path.min.mjs.map +1 -1
- package/dist/src/shapes/Path.mjs +1 -2
- package/dist/src/shapes/Path.mjs.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 +10 -6
- package/dist/src/shapes/Polyline.mjs.map +1 -1
- package/dist/src/shapes/Rect.d.ts.map +1 -1
- package/dist/src/shapes/Rect.min.mjs +1 -1
- package/dist/src/shapes/Rect.min.mjs.map +1 -1
- package/dist/src/shapes/Rect.mjs +2 -1
- package/dist/src/shapes/Rect.mjs.map +1 -1
- package/dist/src/shapes/Text/StyledText.d.ts.map +1 -1
- package/dist/src/shapes/Text/StyledText.min.mjs.map +1 -1
- package/dist/src/shapes/Text/StyledText.mjs +0 -3
- package/dist/src/shapes/Text/StyledText.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
- 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 +5 -6
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
- package/dist/src/shapes/Textbox.d.ts.map +1 -1
- package/dist/src/shapes/Textbox.min.mjs.map +1 -1
- package/dist/src/shapes/Textbox.mjs.map +1 -1
- package/dist/src/shapes/Triangle.d.ts.map +1 -1
- package/dist/src/shapes/Triangle.min.mjs.map +1 -1
- package/dist/src/shapes/Triangle.mjs.map +1 -1
- package/dist/src/util/lang_string.d.ts +1 -1
- package/dist/src/util/lang_string.d.ts.map +1 -1
- package/dist/src/util/lang_string.min.mjs +1 -1
- package/dist/src/util/lang_string.min.mjs.map +1 -1
- package/dist/src/util/lang_string.mjs +1 -1
- package/dist/src/util/lang_string.mjs.map +1 -1
- package/dist/src/util/misc/svgParsing.d.ts.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 -1
- package/dist/src/util/misc/svgParsing.mjs.map +1 -1
- package/dist-extensions/cropping_controls/croppingControls.mjs +140 -0
- package/dist-extensions/cropping_controls/croppingControls.mjs.map +1 -0
- package/dist-extensions/cropping_controls/croppingHandlers.mjs +228 -0
- package/dist-extensions/cropping_controls/croppingHandlers.mjs.map +1 -0
- package/dist-extensions/cropping_controls/enterCropMode.mjs +38 -0
- package/dist-extensions/cropping_controls/enterCropMode.mjs.map +1 -0
- package/dist-extensions/cropping_controls/renderCornerControl.mjs +45 -0
- package/dist-extensions/cropping_controls/renderCornerControl.mjs.map +1 -0
- package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts +16 -0
- package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
- package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
- package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
- package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts +7 -0
- package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
- package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
- package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
- package/dist-extensions/extensions/index.d.ts +3 -0
- package/dist-extensions/extensions/index.d.ts.map +1 -1
- package/dist-extensions/fabric-extensions.min.js +1 -1
- package/dist-extensions/fabric-extensions.min.js.map +1 -1
- package/dist-extensions/fabric.d.ts +1 -0
- package/dist-extensions/fabric.d.ts.map +1 -1
- package/dist-extensions/index.mjs +3 -0
- package/dist-extensions/index.mjs.map +1 -1
- package/dist-extensions/src/EventTypeDefs.d.ts +5 -0
- package/dist-extensions/src/EventTypeDefs.d.ts.map +1 -1
- package/dist-extensions/src/Pattern/Pattern.d.ts.map +1 -1
- package/dist-extensions/src/Shadow.d.ts +1 -1
- package/dist-extensions/src/Shadow.d.ts.map +1 -1
- package/dist-extensions/src/canvas/CanvasOptions.d.ts.map +1 -1
- package/dist-extensions/src/canvas/SelectableCanvas.d.ts +2 -0
- package/dist-extensions/src/canvas/SelectableCanvas.d.ts.map +1 -1
- package/dist-extensions/src/canvas/StaticCanvas.d.ts.map +1 -1
- package/dist-extensions/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
- package/dist-extensions/src/constants.d.ts +1 -0
- package/dist-extensions/src/constants.d.ts.map +1 -1
- package/dist-extensions/src/controls/Control.d.ts +22 -1
- package/dist-extensions/src/controls/Control.d.ts.map +1 -1
- package/dist-extensions/src/controls/changeWidth.d.ts +22 -0
- package/dist-extensions/src/controls/changeWidth.d.ts.map +1 -1
- package/dist-extensions/src/controls/controlRendering.d.ts.map +1 -1
- package/dist-extensions/src/controls/index.d.ts +2 -1
- package/dist-extensions/src/controls/index.d.ts.map +1 -1
- package/dist-extensions/src/gradient/Gradient.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Circle.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Ellipse.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Group.d.ts.map +1 -1
- package/dist-extensions/src/shapes/IText/IText.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Image.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/Object.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Path.d.ts +1 -1
- package/dist-extensions/src/shapes/Path.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Polyline.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Rect.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/StyledText.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Triangle.d.ts.map +1 -1
- package/dist-extensions/src/util/lang_string.d.ts +1 -1
- package/dist-extensions/src/util/lang_string.d.ts.map +1 -1
- package/dist-extensions/src/util/misc/svgParsing.d.ts.map +1 -1
- package/eslint.config.mjs +2 -0
- package/extensions/cropping_controls/croppingControls.spec.ts +115 -0
- package/extensions/cropping_controls/croppingControls.ts +150 -0
- package/extensions/cropping_controls/croppingHandlers.spec.ts +579 -0
- package/extensions/cropping_controls/croppingHandlers.ts +285 -0
- package/extensions/cropping_controls/enterCropMode.ts +30 -0
- package/extensions/cropping_controls/renderCornerControl.ts +53 -0
- package/extensions/index.ts +9 -0
- package/fabric.ts +1 -0
- package/package.json +17 -8
- package/src/ClassRegistry.spec.ts +18 -19
- package/src/EventTypeDefs.ts +15 -11
- package/src/Pattern/Pattern.spec.ts +12 -0
- package/src/Pattern/Pattern.ts +3 -2
- package/src/Shadow.ts +9 -8
- package/src/brushes/PencilBrush.spec.ts +11 -11
- package/src/canvas/Canvas-dispose.spec.ts +8 -7
- package/src/canvas/Canvas.spec.ts +27 -29
- package/src/canvas/CanvasOptions.ts +2 -1
- package/src/canvas/SelectableCanvas.ts +38 -15
- package/src/canvas/StaticCanvas.spec.ts +20 -0
- package/src/canvas/StaticCanvas.ts +7 -4
- package/src/canvas/StaticCanvasOptions.ts +1 -3
- package/src/constants.ts +1 -0
- package/src/controls/Control.spec.ts +102 -0
- package/src/controls/Control.ts +71 -2
- package/src/controls/changeHeight.spec.ts +147 -0
- package/src/controls/changeWidth.ts +68 -35
- package/src/controls/controlRendering.ts +20 -48
- package/src/controls/index.ts +7 -1
- package/src/gradient/Gradient.spec.ts +101 -46
- package/src/gradient/Gradient.ts +27 -14
- package/src/shapes/Circle.spec.ts +10 -39
- package/src/shapes/Circle.ts +11 -11
- package/src/shapes/Ellipse.spec.ts +8 -37
- package/src/shapes/Ellipse.ts +7 -7
- package/src/shapes/Group.ts +3 -3
- package/src/shapes/IText/IText-click-behavior.spec.ts +36 -49
- package/src/shapes/IText/IText.ts +5 -6
- package/src/shapes/IText/ITextKeyBehavior.test.ts +0 -1
- package/src/shapes/IText/__snapshots__/ITextBehavior.test.ts.snap +6 -6
- package/src/shapes/Image.spec.ts +17 -33
- package/src/shapes/Image.ts +15 -11
- package/src/shapes/Line.spec.ts +4 -30
- package/src/shapes/Line.ts +11 -16
- package/src/shapes/Object/FabricObjectSVGExportMixin.ts +11 -4
- package/src/shapes/Object/InteractiveObject.ts +4 -4
- package/src/shapes/Object/Object.ts +6 -5
- package/src/shapes/Object/ObjectGeometry.spec.ts +15 -0
- package/src/shapes/Object/ObjectGeometry.ts +1 -1
- package/src/shapes/Object/objectSvgExport.spec.ts +112 -0
- package/src/shapes/Object/types/FabricObjectProps.ts +1 -4
- package/src/shapes/Object/types/ObjectProps.ts +1 -3
- package/src/shapes/Path.spec.ts +4 -27
- package/src/shapes/Path.ts +2 -4
- package/src/shapes/Polygon.spec.ts +4 -31
- package/src/shapes/Polyline.spec.ts +4 -31
- package/src/shapes/Polyline.ts +11 -12
- package/src/shapes/Rect.spec.ts +25 -33
- package/src/shapes/Rect.ts +7 -7
- package/src/shapes/Text/StyledText.ts +0 -3
- package/src/shapes/Text/Text.spec.ts +3 -32
- package/src/shapes/Text/Text.ts +5 -6
- package/src/shapes/Text/TextSVGExportMixin.spec.ts +9 -0
- package/src/shapes/Text/TextSVGExportMixin.ts +14 -16
- package/src/shapes/Text/__snapshots__/Text.spec.ts.snap +1 -1
- package/src/shapes/Text/__snapshots__/TextSVGExportMixin.spec.ts.snap +1 -1
- package/src/shapes/Textbox.spec.ts +5 -5
- package/src/shapes/Textbox.ts +6 -5
- package/src/shapes/Triangle.ts +4 -4
- package/src/shapes/__snapshots__/Image.spec.ts.snap +4 -4
- package/src/shapes/__snapshots__/Textbox.spec.ts.snap +5 -5
- package/src/util/lang_string.ts +3 -2
- package/src/util/misc/svgParsing.ts +2 -1
- package/tsconfig.spec.json +1 -0
- package/vitest.config.ts +12 -2
- package/vitest.extend.ts +6 -2
|
@@ -13,10 +13,10 @@ import { Group } from '../Group';
|
|
|
13
13
|
import { config } from '../../config';
|
|
14
14
|
import type {
|
|
15
15
|
ObjectPointerEvents,
|
|
16
|
-
TPointerEvent,
|
|
17
16
|
TPointerEventInfo,
|
|
18
17
|
} from '../../EventTypeDefs';
|
|
19
18
|
import { Point } from '../../Point';
|
|
19
|
+
import { createPointerEvent } from '../../../test/utils';
|
|
20
20
|
|
|
21
21
|
describe('iText click interaction', () => {
|
|
22
22
|
let canvas: Canvas;
|
|
@@ -40,12 +40,11 @@ describe('iText click interaction', () => {
|
|
|
40
40
|
|
|
41
41
|
iText.canvas = canvas;
|
|
42
42
|
|
|
43
|
-
let eventData = {
|
|
44
|
-
which: 1,
|
|
43
|
+
let eventData = createPointerEvent({
|
|
45
44
|
target: canvas.upperCanvasEl,
|
|
46
45
|
clientX: 40,
|
|
47
46
|
clientY: 10,
|
|
48
|
-
}
|
|
47
|
+
});
|
|
49
48
|
|
|
50
49
|
iText.enterEditing();
|
|
51
50
|
|
|
@@ -56,12 +55,11 @@ describe('iText click interaction', () => {
|
|
|
56
55
|
expect(iText.selectionStart, 'dblClick selection start is').toBe(0);
|
|
57
56
|
expect(iText.selectionEnd, 'dblClick selection end is').toBe(4);
|
|
58
57
|
|
|
59
|
-
eventData = {
|
|
60
|
-
which: 1,
|
|
58
|
+
eventData = createPointerEvent({
|
|
61
59
|
target: canvas.upperCanvasEl,
|
|
62
60
|
clientX: 40,
|
|
63
61
|
clientY: 60,
|
|
64
|
-
}
|
|
62
|
+
});
|
|
65
63
|
|
|
66
64
|
iText.doubleClickHandler({
|
|
67
65
|
e: eventData,
|
|
@@ -76,12 +74,11 @@ describe('iText click interaction', () => {
|
|
|
76
74
|
|
|
77
75
|
iText.canvas = canvas;
|
|
78
76
|
|
|
79
|
-
const eventData = {
|
|
80
|
-
which: 1,
|
|
77
|
+
const eventData = createPointerEvent({
|
|
81
78
|
target: canvas.upperCanvasEl,
|
|
82
79
|
clientX: 40,
|
|
83
80
|
clientY: 10,
|
|
84
|
-
}
|
|
81
|
+
});
|
|
85
82
|
|
|
86
83
|
iText.doubleClickHandler({
|
|
87
84
|
e: eventData,
|
|
@@ -97,12 +94,11 @@ describe('iText click interaction', () => {
|
|
|
97
94
|
|
|
98
95
|
iText.canvas = canvas;
|
|
99
96
|
|
|
100
|
-
let eventData = {
|
|
101
|
-
which: 1,
|
|
97
|
+
let eventData = createPointerEvent({
|
|
102
98
|
target: canvas.upperCanvasEl,
|
|
103
99
|
clientX: 40,
|
|
104
100
|
clientY: 10,
|
|
105
|
-
}
|
|
101
|
+
});
|
|
106
102
|
|
|
107
103
|
iText.enterEditing();
|
|
108
104
|
|
|
@@ -113,12 +109,11 @@ describe('iText click interaction', () => {
|
|
|
113
109
|
expect(iText.selectionStart, 'tripleClick selection start is').toBe(0);
|
|
114
110
|
expect(iText.selectionEnd, 'tripleClick selection end is').toBe(19);
|
|
115
111
|
|
|
116
|
-
eventData = {
|
|
117
|
-
which: 1,
|
|
112
|
+
eventData = createPointerEvent({
|
|
118
113
|
target: canvas.upperCanvasEl,
|
|
119
114
|
clientX: 40,
|
|
120
115
|
clientY: 60,
|
|
121
|
-
}
|
|
116
|
+
});
|
|
122
117
|
|
|
123
118
|
iText.tripleClickHandler({
|
|
124
119
|
e: eventData,
|
|
@@ -137,12 +132,11 @@ describe('iText click interaction', () => {
|
|
|
137
132
|
|
|
138
133
|
iText.canvas = canvas;
|
|
139
134
|
|
|
140
|
-
const eventData = {
|
|
141
|
-
which: 1,
|
|
135
|
+
const eventData = createPointerEvent({
|
|
142
136
|
target: canvas.upperCanvasEl,
|
|
143
137
|
clientX: 40,
|
|
144
138
|
clientY: 10,
|
|
145
|
-
}
|
|
139
|
+
});
|
|
146
140
|
|
|
147
141
|
iText.tripleClickHandler({
|
|
148
142
|
e: eventData,
|
|
@@ -153,12 +147,11 @@ describe('iText click interaction', () => {
|
|
|
153
147
|
});
|
|
154
148
|
|
|
155
149
|
test('getSelectionStartFromPointer with scale', () => {
|
|
156
|
-
const eventData = {
|
|
157
|
-
which: 1,
|
|
150
|
+
const eventData = createPointerEvent({
|
|
158
151
|
target: canvas.upperCanvasEl,
|
|
159
152
|
clientX: 70,
|
|
160
153
|
clientY: 10,
|
|
161
|
-
}
|
|
154
|
+
});
|
|
162
155
|
|
|
163
156
|
const iText = new IText('test need some word\nsecond line', {
|
|
164
157
|
scaleX: 3,
|
|
@@ -186,10 +179,7 @@ describe('iText click interaction', () => {
|
|
|
186
179
|
|
|
187
180
|
expect(iText.getSelectionStartFromPointer(eventData), 'index').toBe(5);
|
|
188
181
|
expect(
|
|
189
|
-
iText.getSelectionStartFromPointer({
|
|
190
|
-
...eventData,
|
|
191
|
-
clientY: 20,
|
|
192
|
-
} as unknown as TPointerEvent),
|
|
182
|
+
iText.getSelectionStartFromPointer({ ...eventData, clientY: 20 }),
|
|
193
183
|
'index',
|
|
194
184
|
).toBe(5);
|
|
195
185
|
});
|
|
@@ -275,11 +265,11 @@ describe('iText click interaction', () => {
|
|
|
275
265
|
canvas.add(group);
|
|
276
266
|
// @ts-expect-error -- protected member
|
|
277
267
|
iText.selected = true;
|
|
278
|
-
const evt = {
|
|
268
|
+
const evt = createPointerEvent({
|
|
279
269
|
clientX: 1,
|
|
280
270
|
clientY: 1,
|
|
281
271
|
target: canvas.upperCanvasEl,
|
|
282
|
-
}
|
|
272
|
+
});
|
|
283
273
|
canvas._cacheTransformEventData(evt);
|
|
284
274
|
canvas.__onMouseUp(evt);
|
|
285
275
|
// @ts-expect-error -- protected member
|
|
@@ -309,11 +299,13 @@ describe('iText click interaction', () => {
|
|
|
309
299
|
// @ts-expect-error -- protected member
|
|
310
300
|
iText.selected = true;
|
|
311
301
|
|
|
312
|
-
canvas._onMouseUp(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
302
|
+
canvas._onMouseUp(
|
|
303
|
+
createPointerEvent({
|
|
304
|
+
clientX: 1,
|
|
305
|
+
clientY: 1,
|
|
306
|
+
target: canvas.upperCanvasEl,
|
|
307
|
+
}),
|
|
308
|
+
);
|
|
317
309
|
|
|
318
310
|
expect(iText.isEditing, 'iText should enter editing').toBe(true);
|
|
319
311
|
|
|
@@ -322,11 +314,13 @@ describe('iText click interaction', () => {
|
|
|
322
314
|
// @ts-expect-error -- protected member
|
|
323
315
|
iText.selected = true;
|
|
324
316
|
|
|
325
|
-
canvas._onMouseUp(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
317
|
+
canvas._onMouseUp(
|
|
318
|
+
createPointerEvent({
|
|
319
|
+
clientX: 1,
|
|
320
|
+
clientY: 1,
|
|
321
|
+
target: canvas.upperCanvasEl,
|
|
322
|
+
}),
|
|
323
|
+
);
|
|
330
324
|
|
|
331
325
|
expect(iText.isEditing, 'iText should not enter editing').toBe(false);
|
|
332
326
|
});
|
|
@@ -376,19 +370,12 @@ describe('iText click interaction', () => {
|
|
|
376
370
|
enableRetinaScaling,
|
|
377
371
|
});
|
|
378
372
|
|
|
379
|
-
eventData = {
|
|
380
|
-
which: 1,
|
|
373
|
+
eventData = createPointerEvent({
|
|
381
374
|
target: testCanvas.upperCanvasEl,
|
|
382
375
|
...(enableRetinaScaling
|
|
383
|
-
? {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
: {
|
|
388
|
-
clientX: 30,
|
|
389
|
-
clientY: 15,
|
|
390
|
-
}),
|
|
391
|
-
} as unknown as TPointerEvent;
|
|
376
|
+
? { clientX: 60, clientY: 30 }
|
|
377
|
+
: { clientX: 30, clientY: 15 }),
|
|
378
|
+
});
|
|
392
379
|
|
|
393
380
|
count = 0;
|
|
394
381
|
countCanvas = 0;
|
|
@@ -72,8 +72,7 @@ interface UniqueITextProps {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export interface SerializedITextProps
|
|
75
|
-
extends SerializedTextProps,
|
|
76
|
-
UniqueITextProps {}
|
|
75
|
+
extends SerializedTextProps, UniqueITextProps {}
|
|
77
76
|
|
|
78
77
|
export interface ITextProps extends TextProps, UniqueITextProps {}
|
|
79
78
|
|
|
@@ -121,10 +120,10 @@ export interface ITextProps extends TextProps, UniqueITextProps {}
|
|
|
121
120
|
* ```
|
|
122
121
|
*/
|
|
123
122
|
export class IText<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
Props extends TOptions<ITextProps> = Partial<ITextProps>,
|
|
124
|
+
SProps extends SerializedITextProps = SerializedITextProps,
|
|
125
|
+
EventSpec extends ITextEvents = ITextEvents,
|
|
126
|
+
>
|
|
128
127
|
extends ITextClickBehavior<Props, SProps, EventSpec>
|
|
129
128
|
implements UniqueITextProps
|
|
130
129
|
{
|
|
@@ -442,7 +442,7 @@ exports[`text imperative changes > insertChars 2`] = `
|
|
|
442
442
|
"text": "tabest",
|
|
443
443
|
"top": 0,
|
|
444
444
|
"type": "IText",
|
|
445
|
-
"width": 58,
|
|
445
|
+
"width": 58.31,
|
|
446
446
|
}
|
|
447
447
|
`;
|
|
448
448
|
|
|
@@ -563,7 +563,7 @@ exports[`text imperative changes > insertChars and removes chars 2`] = `
|
|
|
563
563
|
"text": "tabst",
|
|
564
564
|
"top": 0,
|
|
565
565
|
"type": "IText",
|
|
566
|
-
"width": 47,
|
|
566
|
+
"width": 47.22,
|
|
567
567
|
}
|
|
568
568
|
`;
|
|
569
569
|
|
|
@@ -646,7 +646,7 @@ exports[`text imperative changes > insertChars and removes chars 4`] = `
|
|
|
646
646
|
"text": "tab",
|
|
647
647
|
"top": 0,
|
|
648
648
|
"type": "IText",
|
|
649
|
-
"width":
|
|
649
|
+
"width": 30.54,
|
|
650
650
|
}
|
|
651
651
|
`;
|
|
652
652
|
|
|
@@ -853,7 +853,7 @@ exports[`text imperative changes > insertChars can accept some style for the new
|
|
|
853
853
|
aest",
|
|
854
854
|
"top": 0,
|
|
855
855
|
"type": "IText",
|
|
856
|
-
"width":
|
|
856
|
+
"width": 38.87,
|
|
857
857
|
}
|
|
858
858
|
`;
|
|
859
859
|
|
|
@@ -1027,7 +1027,7 @@ exports[`text imperative changes > insertChars handles new lines correctly 2`] =
|
|
|
1027
1027
|
est",
|
|
1028
1028
|
"top": 0,
|
|
1029
1029
|
"type": "IText",
|
|
1030
|
-
"width":
|
|
1030
|
+
"width": 30.54,
|
|
1031
1031
|
}
|
|
1032
1032
|
`;
|
|
1033
1033
|
|
|
@@ -1105,6 +1105,6 @@ exports[`text imperative changes > removeChars 2`] = `
|
|
|
1105
1105
|
"text": "tt",
|
|
1106
1106
|
"top": 0,
|
|
1107
1107
|
"type": "IText",
|
|
1108
|
-
"width":
|
|
1108
|
+
"width": 13.89,
|
|
1109
1109
|
}
|
|
1110
1110
|
`;
|
package/src/shapes/Image.spec.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
getFabricDocument,
|
|
14
14
|
getFilterBackend,
|
|
15
15
|
Rect,
|
|
16
|
-
version,
|
|
17
16
|
WebGLFilterBackend,
|
|
18
17
|
} from '../../fabric';
|
|
19
18
|
import { removeTransformMatrixForSvgParsing } from '../util';
|
|
@@ -21,6 +20,7 @@ import * as FilterBackend from '../filters/FilterBackend';
|
|
|
21
20
|
import { FabricError } from '../util/internals/console';
|
|
22
21
|
import TestImageGif from '../../test/fixtures/test_image.gif';
|
|
23
22
|
import { isJSDOM } from '../../vitest.extend';
|
|
23
|
+
import { createReferenceObject } from '../../test/utils';
|
|
24
24
|
|
|
25
25
|
const IMG_SRC = isJSDOM() ? 'test_image.gif' : TestImageGif;
|
|
26
26
|
const imgSrcUrl = new URL(IMG_SRC, import.meta.url).pathname;
|
|
@@ -29,44 +29,16 @@ const IMG_WIDTH = 276;
|
|
|
29
29
|
const IMG_HEIGHT = 110;
|
|
30
30
|
const IMG_URL_NON_EXISTING = 'http://www.google.com/non-existing';
|
|
31
31
|
|
|
32
|
-
const REFERENCE_IMG_OBJECT = {
|
|
33
|
-
version: version,
|
|
34
|
-
type: 'Image',
|
|
35
|
-
originX: 'center' as const,
|
|
36
|
-
originY: 'center' as const,
|
|
37
|
-
left: 0,
|
|
38
|
-
top: 0,
|
|
32
|
+
const REFERENCE_IMG_OBJECT = createReferenceObject('Image', {
|
|
39
33
|
width: IMG_WIDTH,
|
|
40
34
|
height: IMG_HEIGHT,
|
|
41
|
-
fill: 'rgb(0,0,0)',
|
|
42
|
-
stroke: null,
|
|
43
35
|
strokeWidth: 0,
|
|
44
|
-
strokeDashArray: null,
|
|
45
|
-
strokeLineCap: 'butt' as const,
|
|
46
|
-
strokeDashOffset: 0,
|
|
47
|
-
strokeLineJoin: 'miter' as const,
|
|
48
|
-
strokeMiterLimit: 4,
|
|
49
|
-
scaleX: 1,
|
|
50
|
-
scaleY: 1,
|
|
51
|
-
angle: 0,
|
|
52
|
-
flipX: false,
|
|
53
|
-
flipY: false,
|
|
54
|
-
opacity: 1,
|
|
55
36
|
src: IMG_SRC,
|
|
56
|
-
shadow: null,
|
|
57
|
-
visible: true,
|
|
58
|
-
backgroundColor: '',
|
|
59
37
|
filters: [],
|
|
60
|
-
fillRule: 'nonzero' as const,
|
|
61
|
-
paintFirst: 'fill' as const,
|
|
62
|
-
globalCompositeOperation: 'source-over' as const,
|
|
63
|
-
skewX: 0,
|
|
64
|
-
skewY: 0,
|
|
65
38
|
crossOrigin: null,
|
|
66
39
|
cropX: 0,
|
|
67
40
|
cropY: 0,
|
|
68
|
-
|
|
69
|
-
};
|
|
41
|
+
});
|
|
70
42
|
|
|
71
43
|
describe('FabricImage', () => {
|
|
72
44
|
describe('Svg export', () => {
|
|
@@ -88,7 +60,7 @@ describe('FabricImage', () => {
|
|
|
88
60
|
offsetY: 14,
|
|
89
61
|
}),
|
|
90
62
|
});
|
|
91
|
-
expect(img.toSVG()).
|
|
63
|
+
expect(img.toSVG()).toMatchSVGSnapshot();
|
|
92
64
|
});
|
|
93
65
|
});
|
|
94
66
|
|
|
@@ -108,7 +80,7 @@ describe('FabricImage', () => {
|
|
|
108
80
|
200,
|
|
109
81
|
200,
|
|
110
82
|
img.getElement(),
|
|
111
|
-
|
|
83
|
+
expect.stringMatching(/^texture\d+$/),
|
|
112
84
|
);
|
|
113
85
|
} finally {
|
|
114
86
|
mockApply.mockRestore();
|
|
@@ -1000,6 +972,18 @@ describe('FabricImage', () => {
|
|
|
1000
972
|
expect(img.scaleY).toBe(5);
|
|
1001
973
|
});
|
|
1002
974
|
});
|
|
975
|
+
|
|
976
|
+
describe('attribute injection', () => {
|
|
977
|
+
it('source injection', () => {
|
|
978
|
+
const element = newImg('javascript:alert(1)');
|
|
979
|
+
const img = new FabricImage(element, {
|
|
980
|
+
width: 100,
|
|
981
|
+
height: 100,
|
|
982
|
+
});
|
|
983
|
+
const svg = img.toSVG();
|
|
984
|
+
expect(svg).toContain('xlink:href="javascript:alert(1)"'); // Should be escaped
|
|
985
|
+
});
|
|
986
|
+
});
|
|
1003
987
|
});
|
|
1004
988
|
|
|
1005
989
|
export function newImg(src = IMG_SRC): HTMLImageElement {
|
package/src/shapes/Image.ts
CHANGED
|
@@ -31,6 +31,7 @@ import type { CSSRules } from '../parser/typedefs';
|
|
|
31
31
|
import type { Resize, ResizeSerializedProps } from '../filters/Resize';
|
|
32
32
|
import type { TCachedFabricObject } from './Object/Object';
|
|
33
33
|
import { log } from '../util/internals/console';
|
|
34
|
+
import { escapeXml } from '../util/lang_string';
|
|
34
35
|
|
|
35
36
|
// @todo Would be nice to have filtering code not imported directly.
|
|
36
37
|
|
|
@@ -86,10 +87,10 @@ const IMAGE_PROPS = ['cropX', 'cropY'] as const;
|
|
|
86
87
|
* @see {@link http://fabric5.fabricjs.com/fabric-intro-part-1#images}
|
|
87
88
|
*/
|
|
88
89
|
export class FabricImage<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
Props extends TOptions<ImageProps> = Partial<ImageProps>,
|
|
91
|
+
SProps extends SerializedImageProps = SerializedImageProps,
|
|
92
|
+
EventSpec extends ObjectEvents = ObjectEvents,
|
|
93
|
+
>
|
|
93
94
|
extends FabricObject<Props, SProps, EventSpec>
|
|
94
95
|
implements ImageProps
|
|
95
96
|
{
|
|
@@ -389,9 +390,9 @@ export class FabricImage<
|
|
|
389
390
|
'" y="' +
|
|
390
391
|
y +
|
|
391
392
|
'" width="' +
|
|
392
|
-
this.width +
|
|
393
|
+
escapeXml(this.width) +
|
|
393
394
|
'" height="' +
|
|
394
|
-
this.height +
|
|
395
|
+
escapeXml(this.height) +
|
|
395
396
|
'" />\n',
|
|
396
397
|
'</clipPath>\n',
|
|
397
398
|
);
|
|
@@ -403,7 +404,7 @@ export class FabricImage<
|
|
|
403
404
|
imageMarkup.push(
|
|
404
405
|
'\t<image ',
|
|
405
406
|
'COMMON_PARTS',
|
|
406
|
-
`xlink:href="${this.
|
|
407
|
+
`xlink:href="${escapeXml(this.getSrc(true))}" x="${x - this.cropX}" y="${
|
|
407
408
|
y - this.cropY
|
|
408
409
|
// we're essentially moving origin of transformation from top/left corner to the center of the shape
|
|
409
410
|
// by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
|
|
@@ -419,9 +420,9 @@ export class FabricImage<
|
|
|
419
420
|
const origFill = this.fill;
|
|
420
421
|
this.fill = null;
|
|
421
422
|
strokeSvg = [
|
|
422
|
-
`\t<rect x="${x}" y="${y}" width="${this.width}" height="${
|
|
423
|
-
this.height
|
|
424
|
-
}" style="${this.getSvgStyles()}" />\n`,
|
|
423
|
+
`\t<rect x="${x}" y="${y}" width="${escapeXml(this.width)}" height="${escapeXml(
|
|
424
|
+
this.height,
|
|
425
|
+
)}" style="${this.getSvgStyles()}" />\n`,
|
|
425
426
|
];
|
|
426
427
|
this.fill = origFill;
|
|
427
428
|
}
|
|
@@ -470,7 +471,10 @@ export class FabricImage<
|
|
|
470
471
|
* @param {String} src Source string (URL)
|
|
471
472
|
* @param {LoadImageOptions} [options] Options object
|
|
472
473
|
*/
|
|
473
|
-
setSrc(
|
|
474
|
+
setSrc(
|
|
475
|
+
src: string,
|
|
476
|
+
{ crossOrigin, signal }: LoadImageOptions = {},
|
|
477
|
+
): Promise<void> {
|
|
474
478
|
return loadImage(src, { crossOrigin, signal }).then((img) => {
|
|
475
479
|
typeof crossOrigin !== 'undefined' && this.set({ crossOrigin });
|
|
476
480
|
this.setElement(img);
|
package/src/shapes/Line.spec.ts
CHANGED
|
@@ -1,46 +1,20 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { Line } from './Line';
|
|
3
|
-
import { getFabricDocument
|
|
3
|
+
import { getFabricDocument } from '../../fabric';
|
|
4
4
|
import { FabricObject } from './Object/Object';
|
|
5
|
+
import { createReferenceObject } from '../../test/utils';
|
|
5
6
|
|
|
6
7
|
describe('Line', () => {
|
|
7
|
-
const LINE_OBJECT = {
|
|
8
|
-
version: version,
|
|
9
|
-
type: 'Line',
|
|
10
|
-
originX: 'center',
|
|
11
|
-
originY: 'center',
|
|
8
|
+
const LINE_OBJECT = createReferenceObject('Line', {
|
|
12
9
|
left: 12,
|
|
13
10
|
top: 13,
|
|
14
11
|
width: 2,
|
|
15
12
|
height: 2,
|
|
16
|
-
fill: 'rgb(0,0,0)',
|
|
17
|
-
stroke: null,
|
|
18
|
-
strokeWidth: 1,
|
|
19
|
-
strokeDashArray: null,
|
|
20
|
-
strokeLineCap: 'butt',
|
|
21
|
-
strokeDashOffset: 0,
|
|
22
|
-
strokeLineJoin: 'miter',
|
|
23
|
-
strokeMiterLimit: 4,
|
|
24
|
-
scaleX: 1,
|
|
25
|
-
scaleY: 1,
|
|
26
|
-
angle: 0,
|
|
27
|
-
flipX: false,
|
|
28
|
-
flipY: false,
|
|
29
|
-
opacity: 1,
|
|
30
13
|
x1: -1,
|
|
31
14
|
y1: -1,
|
|
32
15
|
x2: 1,
|
|
33
16
|
y2: 1,
|
|
34
|
-
|
|
35
|
-
visible: true,
|
|
36
|
-
backgroundColor: '',
|
|
37
|
-
fillRule: 'nonzero',
|
|
38
|
-
paintFirst: 'fill',
|
|
39
|
-
globalCompositeOperation: 'source-over',
|
|
40
|
-
skewX: 0,
|
|
41
|
-
skewY: 0,
|
|
42
|
-
strokeUniform: false,
|
|
43
|
-
} as const;
|
|
17
|
+
});
|
|
44
18
|
|
|
45
19
|
it('initializes constructor correctly', () => {
|
|
46
20
|
expect(Line).toBeTruthy();
|
package/src/shapes/Line.ts
CHANGED
|
@@ -23,8 +23,7 @@ interface UniqueLineProps {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export interface SerializedLineProps
|
|
26
|
-
extends SerializedObjectProps,
|
|
27
|
-
UniqueLineProps {}
|
|
26
|
+
extends SerializedObjectProps, UniqueLineProps {}
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* A Class to draw a line
|
|
@@ -34,10 +33,10 @@ export interface SerializedLineProps
|
|
|
34
33
|
* @deprecated
|
|
35
34
|
*/
|
|
36
35
|
export class Line<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,
|
|
37
|
+
SProps extends SerializedLineProps = SerializedLineProps,
|
|
38
|
+
EventSpec extends ObjectEvents = ObjectEvents,
|
|
39
|
+
>
|
|
41
40
|
extends FabricObject<Props, SProps, EventSpec>
|
|
42
41
|
implements UniqueLineProps
|
|
43
42
|
{
|
|
@@ -200,18 +199,14 @@ export class Line<
|
|
|
200
199
|
*/
|
|
201
200
|
calcLinePoints(): UniqueLineProps {
|
|
202
201
|
const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;
|
|
203
|
-
const xMult = _x1 <= _x2 ? -
|
|
204
|
-
yMult = _y1 <= _y2 ? -
|
|
205
|
-
x1 = (xMult * width) / 2,
|
|
206
|
-
y1 = (yMult * height) / 2,
|
|
207
|
-
x2 = (xMult * -width) / 2,
|
|
208
|
-
y2 = (yMult * -height) / 2;
|
|
202
|
+
const xMult = _x1 <= _x2 ? -0.5 : 0.5,
|
|
203
|
+
yMult = _y1 <= _y2 ? -0.5 : 0.5;
|
|
209
204
|
|
|
210
205
|
return {
|
|
211
|
-
x1,
|
|
212
|
-
x2,
|
|
213
|
-
y1,
|
|
214
|
-
y2,
|
|
206
|
+
x1: xMult * width,
|
|
207
|
+
x2: xMult * -width,
|
|
208
|
+
y1: yMult * height,
|
|
209
|
+
y2: yMult * -height,
|
|
215
210
|
};
|
|
216
211
|
}
|
|
217
212
|
|
|
@@ -5,6 +5,7 @@ import { FILL, NONE, STROKE } from '../../constants';
|
|
|
5
5
|
import type { FabricObject } from './FabricObject';
|
|
6
6
|
import { isFiller } from '../../util/typeAssertions';
|
|
7
7
|
import { matrixToSVG } from '../../util/misc/svgExport';
|
|
8
|
+
import { escapeXml } from '../../util/lang_string';
|
|
8
9
|
|
|
9
10
|
export class FabricObjectSVGExportMixin {
|
|
10
11
|
/**
|
|
@@ -67,7 +68,9 @@ export class FabricObjectSVGExportMixin {
|
|
|
67
68
|
';',
|
|
68
69
|
filter,
|
|
69
70
|
visibility,
|
|
70
|
-
]
|
|
71
|
+
]
|
|
72
|
+
.map((v) => escapeXml(v))
|
|
73
|
+
.join('');
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
/**
|
|
@@ -75,7 +78,9 @@ export class FabricObjectSVGExportMixin {
|
|
|
75
78
|
* @return {String}
|
|
76
79
|
*/
|
|
77
80
|
getSvgFilter(this: FabricObjectSVGExportMixin & FabricObject) {
|
|
78
|
-
return this.shadow
|
|
81
|
+
return this.shadow
|
|
82
|
+
? `filter: url(#SVGID_${escapeXml(this.shadow.id)});`
|
|
83
|
+
: '';
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
/**
|
|
@@ -86,7 +91,7 @@ export class FabricObjectSVGExportMixin {
|
|
|
86
91
|
this: FabricObjectSVGExportMixin & FabricObject & { id?: string },
|
|
87
92
|
) {
|
|
88
93
|
return [
|
|
89
|
-
this.id ? `id="${this.id}" ` : '',
|
|
94
|
+
this.id ? `id="${escapeXml(String(this.id))}" ` : '',
|
|
90
95
|
this.clipPath
|
|
91
96
|
? `clip-path="url(#${
|
|
92
97
|
(this.clipPath as FabricObjectSVGExportMixin & FabricObject)
|
|
@@ -248,6 +253,8 @@ export class FabricObjectSVGExportMixin {
|
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
addPaintOrder(this: FabricObjectSVGExportMixin & FabricObject) {
|
|
251
|
-
return this.paintFirst !== FILL
|
|
256
|
+
return this.paintFirst !== FILL
|
|
257
|
+
? ` paint-order="${escapeXml(this.paintFirst)}" `
|
|
258
|
+
: '';
|
|
252
259
|
}
|
|
253
260
|
}
|
|
@@ -41,10 +41,10 @@ export type TStyleOverride = ControlRenderingStyleOverride &
|
|
|
41
41
|
>;
|
|
42
42
|
|
|
43
43
|
export class InteractiveFabricObject<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
Props extends TFabricObjectProps = Partial<FabricObjectProps>,
|
|
45
|
+
SProps extends SerializedObjectProps = SerializedObjectProps,
|
|
46
|
+
EventSpec extends ObjectEvents = ObjectEvents,
|
|
47
|
+
>
|
|
48
48
|
extends FabricObject<Props, SProps, EventSpec>
|
|
49
49
|
implements FabricObjectProps
|
|
50
50
|
{
|
|
@@ -176,11 +176,11 @@ export type DrawContext =
|
|
|
176
176
|
* @fires drop
|
|
177
177
|
*/
|
|
178
178
|
export class FabricObject<
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
179
|
+
Props extends TOptions<ObjectProps> = Partial<ObjectProps>,
|
|
180
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
181
|
+
SProps extends SerializedObjectProps = SerializedObjectProps,
|
|
182
|
+
EventSpec extends ObjectEvents = ObjectEvents,
|
|
183
|
+
>
|
|
184
184
|
extends ObjectGeometry<EventSpec>
|
|
185
185
|
implements ObjectProps
|
|
186
186
|
{
|
|
@@ -834,6 +834,7 @@ export class FabricObject<
|
|
|
834
834
|
} else {
|
|
835
835
|
this._renderBackground(ctx);
|
|
836
836
|
}
|
|
837
|
+
this.fire('before:render', { ctx });
|
|
837
838
|
this._render(ctx);
|
|
838
839
|
this._drawClipPath(ctx, this.clipPath, context);
|
|
839
840
|
this.fill = originalFill;
|
|
@@ -692,6 +692,21 @@ describe('fabric.ObjectGeometry', () => {
|
|
|
692
692
|
]);
|
|
693
693
|
});
|
|
694
694
|
|
|
695
|
+
it('calcOwnMatrix is cached', () => {
|
|
696
|
+
const cObj = new FabricObject({
|
|
697
|
+
width: 10,
|
|
698
|
+
height: 15,
|
|
699
|
+
strokeWidth: 0,
|
|
700
|
+
originX: LEFT,
|
|
701
|
+
originY: TOP,
|
|
702
|
+
});
|
|
703
|
+
cObj.scaleX = 2;
|
|
704
|
+
cObj.scaleY = 3;
|
|
705
|
+
const expectedMatrix = cObj.calcOwnMatrix();
|
|
706
|
+
expect(expectedMatrix).toEqual([2, 0, 0, 3, 10, 22.5]);
|
|
707
|
+
expect(cObj.calcOwnMatrix()).toBe(expectedMatrix);
|
|
708
|
+
});
|
|
709
|
+
|
|
695
710
|
it('scaleToWidth', () => {
|
|
696
711
|
const cObj = new FabricObject({ width: 560, strokeWidth: 0 });
|
|
697
712
|
expect(cObj.scaleToWidth).toBeTypeOf('function');
|
|
@@ -513,7 +513,7 @@ export class ObjectGeometry<EventSpec extends ObjectEvents = ObjectEvents>
|
|
|
513
513
|
calcOwnMatrix(): TMat2D {
|
|
514
514
|
const key = this.transformMatrixKey(true),
|
|
515
515
|
cache = this.ownMatrixCache;
|
|
516
|
-
if (cache && cache.key === key) {
|
|
516
|
+
if (cache && cache.key.every((x, i) => x === key[i])) {
|
|
517
517
|
return cache.value;
|
|
518
518
|
}
|
|
519
519
|
const center = this.getRelativeCenterPoint(),
|