fabric 7.1.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 +13 -0
- package/dist/extensions/cropping_controls/croppingControls.d.ts +12 -8
- package/dist/extensions/cropping_controls/croppingControls.d.ts.map +1 -1
- package/dist/extensions/cropping_controls/croppingHandlers.d.ts +19 -1
- package/dist/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -1
- package/dist/extensions/cropping_controls/enterCropMode.d.ts.map +1 -1
- package/dist/index.js +189 -160
- 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 +189 -160
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +189 -160
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +189 -160
- 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 +3 -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 +6 -1
- 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/controls/Control.d.ts +9 -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 +8 -0
- package/dist/src/controls/Control.mjs.map +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/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/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.min.mjs +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
- package/dist/src/shapes/Text/TextSVGExportMixin.mjs +5 -5
- 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 +39 -9
- package/dist-extensions/cropping_controls/croppingControls.mjs.map +1 -1
- package/dist-extensions/cropping_controls/croppingHandlers.mjs +84 -2
- package/dist-extensions/cropping_controls/croppingHandlers.mjs.map +1 -1
- package/dist-extensions/cropping_controls/enterCropMode.mjs +7 -2
- package/dist-extensions/cropping_controls/enterCropMode.mjs.map +1 -1
- package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts +12 -8
- package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts.map +1 -1
- package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts +19 -1
- package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -1
- package/dist-extensions/extensions/cropping_controls/enterCropMode.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/src/EventTypeDefs.d.ts +3 -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/controls/Control.d.ts +9 -1
- package/dist-extensions/src/controls/Control.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/Text.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 +65 -27
- package/extensions/cropping_controls/croppingControls.ts +40 -8
- package/extensions/cropping_controls/croppingHandlers.spec.ts +355 -46
- package/extensions/cropping_controls/croppingHandlers.ts +123 -0
- package/extensions/cropping_controls/enterCropMode.ts +6 -2
- package/package.json +17 -8
- package/src/ClassRegistry.spec.ts +18 -19
- package/src/EventTypeDefs.ts +13 -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 +11 -4
- package/src/canvas/StaticCanvas.spec.ts +20 -0
- package/src/canvas/StaticCanvas.ts +7 -4
- package/src/canvas/StaticCanvasOptions.ts +1 -3
- package/src/controls/Control.ts +24 -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/__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/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/Text.spec.ts +3 -32
- package/src/shapes/Text/Text.ts +5 -6
- package/src/shapes/Text/TextSVGExportMixin.ts +14 -14
- package/src/shapes/Text/__snapshots__/Text.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
package/dist/index.js
CHANGED
|
@@ -362,7 +362,7 @@
|
|
|
362
362
|
}
|
|
363
363
|
const cache = new Cache();
|
|
364
364
|
|
|
365
|
-
var version = "7.
|
|
365
|
+
var version = "7.2.0";
|
|
366
366
|
|
|
367
367
|
// use this syntax so babel plugin see this import here
|
|
368
368
|
const VERSION = version;
|
|
@@ -2197,6 +2197,111 @@
|
|
|
2197
2197
|
patternQuality: 'best'
|
|
2198
2198
|
};
|
|
2199
2199
|
|
|
2200
|
+
/**
|
|
2201
|
+
* Capitalizes a string
|
|
2202
|
+
* @param {String} string String to capitalize
|
|
2203
|
+
* @param {Boolean} [firstLetterOnly] If true only first letter is capitalized
|
|
2204
|
+
* and other letters stay untouched, if false first letter is capitalized
|
|
2205
|
+
* and other letters are converted to lowercase.
|
|
2206
|
+
* @return {String} Capitalized version of a string
|
|
2207
|
+
*/
|
|
2208
|
+
const capitalize = function (string) {
|
|
2209
|
+
let firstLetterOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
2210
|
+
return `${string.charAt(0).toUpperCase()}${firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()}`;
|
|
2211
|
+
};
|
|
2212
|
+
|
|
2213
|
+
/**
|
|
2214
|
+
* Escapes XML in a string
|
|
2215
|
+
* @param {String} string String to escape
|
|
2216
|
+
* @return {String} Escaped version of a string
|
|
2217
|
+
*/
|
|
2218
|
+
const escapeXml = stringOrNumber => stringOrNumber.toString().replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
|
|
2219
|
+
let segmenter;
|
|
2220
|
+
const getSegmenter = () => {
|
|
2221
|
+
if (!segmenter) {
|
|
2222
|
+
segmenter = 'Intl' in getFabricWindow() && 'Segmenter' in Intl && new Intl.Segmenter(undefined, {
|
|
2223
|
+
granularity: 'grapheme'
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
return segmenter;
|
|
2227
|
+
};
|
|
2228
|
+
|
|
2229
|
+
/**
|
|
2230
|
+
* Divide a string in the user perceived single units
|
|
2231
|
+
* @param {String} textstring String to escape
|
|
2232
|
+
* @return {Array} array containing the graphemes
|
|
2233
|
+
*/
|
|
2234
|
+
const graphemeSplit = textstring => {
|
|
2235
|
+
segmenter || getSegmenter();
|
|
2236
|
+
if (segmenter) {
|
|
2237
|
+
const segments = segmenter.segment(textstring);
|
|
2238
|
+
return Array.from(segments).map(_ref => {
|
|
2239
|
+
let {
|
|
2240
|
+
segment
|
|
2241
|
+
} = _ref;
|
|
2242
|
+
return segment;
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
//Fallback
|
|
2247
|
+
return graphemeSplitImpl(textstring);
|
|
2248
|
+
};
|
|
2249
|
+
const graphemeSplitImpl = textstring => {
|
|
2250
|
+
const graphemes = [];
|
|
2251
|
+
for (let i = 0, chr; i < textstring.length; i++) {
|
|
2252
|
+
if ((chr = getWholeChar(textstring, i)) === false) {
|
|
2253
|
+
continue;
|
|
2254
|
+
}
|
|
2255
|
+
graphemes.push(chr);
|
|
2256
|
+
}
|
|
2257
|
+
return graphemes;
|
|
2258
|
+
};
|
|
2259
|
+
|
|
2260
|
+
// taken from mdn in the charAt doc page.
|
|
2261
|
+
const getWholeChar = (str, i) => {
|
|
2262
|
+
const code = str.charCodeAt(i);
|
|
2263
|
+
if (isNaN(code)) {
|
|
2264
|
+
return ''; // Position not found
|
|
2265
|
+
}
|
|
2266
|
+
if (code < 0xd800 || code > 0xdfff) {
|
|
2267
|
+
return str.charAt(i);
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
// High surrogate (could change last hex to 0xDB7F to treat high private
|
|
2271
|
+
// surrogates as single characters)
|
|
2272
|
+
if (0xd800 <= code && code <= 0xdbff) {
|
|
2273
|
+
if (str.length <= i + 1) {
|
|
2274
|
+
throw 'High surrogate without following low surrogate';
|
|
2275
|
+
}
|
|
2276
|
+
const next = str.charCodeAt(i + 1);
|
|
2277
|
+
if (0xdc00 > next || next > 0xdfff) {
|
|
2278
|
+
throw 'High surrogate without following low surrogate';
|
|
2279
|
+
}
|
|
2280
|
+
return str.charAt(i) + str.charAt(i + 1);
|
|
2281
|
+
}
|
|
2282
|
+
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
|
|
2283
|
+
if (i === 0) {
|
|
2284
|
+
throw 'Low surrogate without preceding high surrogate';
|
|
2285
|
+
}
|
|
2286
|
+
const prev = str.charCodeAt(i - 1);
|
|
2287
|
+
|
|
2288
|
+
// (could change last hex to 0xDB7F to treat high private
|
|
2289
|
+
// surrogates as single characters)
|
|
2290
|
+
if (0xd800 > prev || prev > 0xdbff) {
|
|
2291
|
+
throw 'Low surrogate without preceding high surrogate';
|
|
2292
|
+
}
|
|
2293
|
+
// We can pass over low surrogates now as the second component
|
|
2294
|
+
// in a pair which we have already processed
|
|
2295
|
+
return false;
|
|
2296
|
+
};
|
|
2297
|
+
|
|
2298
|
+
var lang_string = /*#__PURE__*/Object.freeze({
|
|
2299
|
+
__proto__: null,
|
|
2300
|
+
capitalize: capitalize,
|
|
2301
|
+
escapeXml: escapeXml,
|
|
2302
|
+
graphemeSplit: graphemeSplit
|
|
2303
|
+
});
|
|
2304
|
+
|
|
2200
2305
|
/**
|
|
2201
2306
|
* Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset
|
|
2202
2307
|
* Better try to restrict with types to avoid confusion.
|
|
@@ -2966,7 +3071,8 @@
|
|
|
2966
3071
|
this._setSVGPreamble(markup, options);
|
|
2967
3072
|
this._setSVGHeader(markup, options);
|
|
2968
3073
|
if (this.clipPath) {
|
|
2969
|
-
|
|
3074
|
+
var _this$clipPath$clipPa;
|
|
3075
|
+
markup.push(`<g clip-path="url(#${escapeXml((_this$clipPath$clipPa = this.clipPath.clipPathId) !== null && _this$clipPath$clipPa !== void 0 ? _this$clipPath$clipPa : '')})" >\n`);
|
|
2970
3076
|
}
|
|
2971
3077
|
this._setSVGBgOverlayColor(markup, 'background');
|
|
2972
3078
|
this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);
|
|
@@ -4593,7 +4699,7 @@
|
|
|
4593
4699
|
if (!value) {
|
|
4594
4700
|
colorValue = 'none';
|
|
4595
4701
|
} else if (value.toLive) {
|
|
4596
|
-
colorValue = `url(#SVGID_${value.id})`;
|
|
4702
|
+
colorValue = `url(#SVGID_${escapeXml(value.id)})`;
|
|
4597
4703
|
} else {
|
|
4598
4704
|
const color = new Color(value),
|
|
4599
4705
|
opacity = color.getAlpha();
|
|
@@ -4646,7 +4752,7 @@
|
|
|
4646
4752
|
filter = skipShadow ? '' : this.getSvgFilter(),
|
|
4647
4753
|
fill = colorPropToSVG(FILL, this.fill),
|
|
4648
4754
|
stroke = colorPropToSVG(STROKE, this.stroke);
|
|
4649
|
-
return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].join('');
|
|
4755
|
+
return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].map(v => escapeXml(v)).join('');
|
|
4650
4756
|
}
|
|
4651
4757
|
|
|
4652
4758
|
/**
|
|
@@ -4654,7 +4760,7 @@
|
|
|
4654
4760
|
* @return {String}
|
|
4655
4761
|
*/
|
|
4656
4762
|
getSvgFilter() {
|
|
4657
|
-
return this.shadow ? `filter: url(#SVGID_${this.shadow.id});` : '';
|
|
4763
|
+
return this.shadow ? `filter: url(#SVGID_${escapeXml(this.shadow.id)});` : '';
|
|
4658
4764
|
}
|
|
4659
4765
|
|
|
4660
4766
|
/**
|
|
@@ -4662,7 +4768,7 @@
|
|
|
4662
4768
|
* @return {String}
|
|
4663
4769
|
*/
|
|
4664
4770
|
getSvgCommons() {
|
|
4665
|
-
return [this.id ? `id="${this.id}" ` : '', this.clipPath ? `clip-path="url(#${this.clipPath.clipPathId})" ` : ''].join('');
|
|
4771
|
+
return [this.id ? `id="${escapeXml(String(this.id))}" ` : '', this.clipPath ? `clip-path="url(#${this.clipPath.clipPathId})" ` : ''].join('');
|
|
4666
4772
|
}
|
|
4667
4773
|
|
|
4668
4774
|
/**
|
|
@@ -4775,7 +4881,7 @@
|
|
|
4775
4881
|
return reviver ? reviver(markup.join('')) : markup.join('');
|
|
4776
4882
|
}
|
|
4777
4883
|
addPaintOrder() {
|
|
4778
|
-
return this.paintFirst !== FILL ? ` paint-order="${this.paintFirst}" ` : '';
|
|
4884
|
+
return this.paintFirst !== FILL ? ` paint-order="${escapeXml(this.paintFirst)}" ` : '';
|
|
4779
4885
|
}
|
|
4780
4886
|
}
|
|
4781
4887
|
|
|
@@ -4913,7 +5019,6 @@
|
|
|
4913
5019
|
|
|
4914
5020
|
(?:$|\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.
|
|
4915
5021
|
*/
|
|
4916
|
-
// eslint-disable-next-line max-len
|
|
4917
5022
|
|
|
4918
5023
|
const shadowOffsetRegex = '(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?';
|
|
4919
5024
|
const reOffsetsAndBlur = new RegExp('(?:\\s|^)' + shadowOffsetRegex + shadowOffsetRegex + '(' + reNum + '?(?:px)?)?(?:\\s?|$)(?:$|\\s)');
|
|
@@ -4972,14 +5077,15 @@
|
|
|
4972
5077
|
toSVG(object) {
|
|
4973
5078
|
const offset = rotateVector(new Point(this.offsetX, this.offsetY), degreesToRadians(-object.angle)),
|
|
4974
5079
|
BLUR_BOX = 20,
|
|
5080
|
+
NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,
|
|
4975
5081
|
color = new Color(this.color);
|
|
4976
5082
|
let fBoxX = 40,
|
|
4977
5083
|
fBoxY = 40;
|
|
4978
5084
|
if (object.width && object.height) {
|
|
4979
5085
|
//http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
|
|
4980
5086
|
// we add some extra space to filter box to contain the blur ( 20 )
|
|
4981
|
-
fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width,
|
|
4982
|
-
fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height,
|
|
5087
|
+
fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
|
|
5088
|
+
fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
|
|
4983
5089
|
}
|
|
4984
5090
|
if (object.flipX) {
|
|
4985
5091
|
offset.x *= -1;
|
|
@@ -4987,7 +5093,7 @@
|
|
|
4987
5093
|
if (object.flipY) {
|
|
4988
5094
|
offset.y *= -1;
|
|
4989
5095
|
}
|
|
4990
|
-
return `<filter id="SVGID_${this.id}" y="-${fBoxY}%" height="${100 + 2 * fBoxY}%" x="-${fBoxX}%" width="${100 + 2 * fBoxX}%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="${toFixed(this.blur ? this.blur / 2 : 0,
|
|
5096
|
+
return `<filter id="SVGID_${escapeXml(this.id)}" y="-${fBoxY}%" height="${100 + 2 * fBoxY}%" x="-${fBoxX}%" width="${100 + 2 * fBoxX}%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="${toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS)}"></feGaussianBlur>\n\t<feOffset dx="${toFixed(offset.x, NUM_FRACTION_DIGITS)}" dy="${toFixed(offset.y, NUM_FRACTION_DIGITS)}" result="oBlur" ></feOffset>\n\t<feFlood flood-color="${color.toRgb()}" flood-opacity="${color.getAlpha()}"/>\n\t<feComposite in2="oBlur" operator="in" />\n\t<feMerge>\n\t\t<feMergeNode></feMergeNode>\n\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n\t</feMerge>\n</filter>\n`;
|
|
4991
5097
|
}
|
|
4992
5098
|
|
|
4993
5099
|
/**
|
|
@@ -7138,6 +7244,9 @@
|
|
|
7138
7244
|
} else {
|
|
7139
7245
|
this._renderBackground(ctx);
|
|
7140
7246
|
}
|
|
7247
|
+
this.fire('before:render', {
|
|
7248
|
+
ctx
|
|
7249
|
+
});
|
|
7141
7250
|
this._render(ctx);
|
|
7142
7251
|
this._drawClipPath(ctx, this.clipPath, context);
|
|
7143
7252
|
this.fill = originalFill;
|
|
@@ -8428,6 +8537,14 @@
|
|
|
8428
8537
|
_defineProperty(this, "withConnection", false);
|
|
8429
8538
|
Object.assign(this, options);
|
|
8430
8539
|
}
|
|
8540
|
+
getTransformAnchorPoint() {
|
|
8541
|
+
var _this$transformAnchor;
|
|
8542
|
+
return (// return the control transformAnchorPoint
|
|
8543
|
+
(_this$transformAnchor = this.transformAnchorPoint) !== null && _this$transformAnchor !== void 0 ? _this$transformAnchor :
|
|
8544
|
+
// otherwise will return the opposite origin of where the control is located.
|
|
8545
|
+
new Point(-this.x + 0.5, -this.y + 0.5)
|
|
8546
|
+
);
|
|
8547
|
+
}
|
|
8431
8548
|
|
|
8432
8549
|
/**
|
|
8433
8550
|
* The control actionHandler, provide one to handle action ( control being moved )
|
|
@@ -10243,111 +10360,6 @@
|
|
|
10243
10360
|
return newObj;
|
|
10244
10361
|
};
|
|
10245
10362
|
|
|
10246
|
-
/**
|
|
10247
|
-
* Capitalizes a string
|
|
10248
|
-
* @param {String} string String to capitalize
|
|
10249
|
-
* @param {Boolean} [firstLetterOnly] If true only first letter is capitalized
|
|
10250
|
-
* and other letters stay untouched, if false first letter is capitalized
|
|
10251
|
-
* and other letters are converted to lowercase.
|
|
10252
|
-
* @return {String} Capitalized version of a string
|
|
10253
|
-
*/
|
|
10254
|
-
const capitalize = function (string) {
|
|
10255
|
-
let firstLetterOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
10256
|
-
return `${string.charAt(0).toUpperCase()}${firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()}`;
|
|
10257
|
-
};
|
|
10258
|
-
|
|
10259
|
-
/**
|
|
10260
|
-
* Escapes XML in a string
|
|
10261
|
-
* @param {String} string String to escape
|
|
10262
|
-
* @return {String} Escaped version of a string
|
|
10263
|
-
*/
|
|
10264
|
-
const escapeXml = string => string.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
|
|
10265
|
-
let segmenter;
|
|
10266
|
-
const getSegmenter = () => {
|
|
10267
|
-
if (!segmenter) {
|
|
10268
|
-
segmenter = 'Intl' in getFabricWindow() && 'Segmenter' in Intl && new Intl.Segmenter(undefined, {
|
|
10269
|
-
granularity: 'grapheme'
|
|
10270
|
-
});
|
|
10271
|
-
}
|
|
10272
|
-
return segmenter;
|
|
10273
|
-
};
|
|
10274
|
-
|
|
10275
|
-
/**
|
|
10276
|
-
* Divide a string in the user perceived single units
|
|
10277
|
-
* @param {String} textstring String to escape
|
|
10278
|
-
* @return {Array} array containing the graphemes
|
|
10279
|
-
*/
|
|
10280
|
-
const graphemeSplit = textstring => {
|
|
10281
|
-
segmenter || getSegmenter();
|
|
10282
|
-
if (segmenter) {
|
|
10283
|
-
const segments = segmenter.segment(textstring);
|
|
10284
|
-
return Array.from(segments).map(_ref => {
|
|
10285
|
-
let {
|
|
10286
|
-
segment
|
|
10287
|
-
} = _ref;
|
|
10288
|
-
return segment;
|
|
10289
|
-
});
|
|
10290
|
-
}
|
|
10291
|
-
|
|
10292
|
-
//Fallback
|
|
10293
|
-
return graphemeSplitImpl(textstring);
|
|
10294
|
-
};
|
|
10295
|
-
const graphemeSplitImpl = textstring => {
|
|
10296
|
-
const graphemes = [];
|
|
10297
|
-
for (let i = 0, chr; i < textstring.length; i++) {
|
|
10298
|
-
if ((chr = getWholeChar(textstring, i)) === false) {
|
|
10299
|
-
continue;
|
|
10300
|
-
}
|
|
10301
|
-
graphemes.push(chr);
|
|
10302
|
-
}
|
|
10303
|
-
return graphemes;
|
|
10304
|
-
};
|
|
10305
|
-
|
|
10306
|
-
// taken from mdn in the charAt doc page.
|
|
10307
|
-
const getWholeChar = (str, i) => {
|
|
10308
|
-
const code = str.charCodeAt(i);
|
|
10309
|
-
if (isNaN(code)) {
|
|
10310
|
-
return ''; // Position not found
|
|
10311
|
-
}
|
|
10312
|
-
if (code < 0xd800 || code > 0xdfff) {
|
|
10313
|
-
return str.charAt(i);
|
|
10314
|
-
}
|
|
10315
|
-
|
|
10316
|
-
// High surrogate (could change last hex to 0xDB7F to treat high private
|
|
10317
|
-
// surrogates as single characters)
|
|
10318
|
-
if (0xd800 <= code && code <= 0xdbff) {
|
|
10319
|
-
if (str.length <= i + 1) {
|
|
10320
|
-
throw 'High surrogate without following low surrogate';
|
|
10321
|
-
}
|
|
10322
|
-
const next = str.charCodeAt(i + 1);
|
|
10323
|
-
if (0xdc00 > next || next > 0xdfff) {
|
|
10324
|
-
throw 'High surrogate without following low surrogate';
|
|
10325
|
-
}
|
|
10326
|
-
return str.charAt(i) + str.charAt(i + 1);
|
|
10327
|
-
}
|
|
10328
|
-
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
|
|
10329
|
-
if (i === 0) {
|
|
10330
|
-
throw 'Low surrogate without preceding high surrogate';
|
|
10331
|
-
}
|
|
10332
|
-
const prev = str.charCodeAt(i - 1);
|
|
10333
|
-
|
|
10334
|
-
// (could change last hex to 0xDB7F to treat high private
|
|
10335
|
-
// surrogates as single characters)
|
|
10336
|
-
if (0xd800 > prev || prev > 0xdbff) {
|
|
10337
|
-
throw 'Low surrogate without preceding high surrogate';
|
|
10338
|
-
}
|
|
10339
|
-
// We can pass over low surrogates now as the second component
|
|
10340
|
-
// in a pair which we have already processed
|
|
10341
|
-
return false;
|
|
10342
|
-
};
|
|
10343
|
-
|
|
10344
|
-
var lang_string = /*#__PURE__*/Object.freeze({
|
|
10345
|
-
__proto__: null,
|
|
10346
|
-
capitalize: capitalize,
|
|
10347
|
-
escapeXml: escapeXml,
|
|
10348
|
-
graphemeSplit: graphemeSplit
|
|
10349
|
-
});
|
|
10350
|
-
|
|
10351
10363
|
/**
|
|
10352
10364
|
* @param {Object} prevStyle first style to compare
|
|
10353
10365
|
* @param {Object} thisStyle second style to compare
|
|
@@ -10931,7 +10943,7 @@
|
|
|
10931
10943
|
rx,
|
|
10932
10944
|
ry
|
|
10933
10945
|
} = this;
|
|
10934
|
-
return ['<rect ', 'COMMON_PARTS', `x="${-width / 2}" y="${-height / 2}" rx="${rx}" ry="${ry}" width="${width}" height="${height}" />\n`];
|
|
10946
|
+
return ['<rect ', 'COMMON_PARTS', `x="${-width / 2}" y="${-height / 2}" rx="${escapeXml(rx)}" ry="${escapeXml(ry)}" width="${escapeXml(width)}" height="${escapeXml(height)}" />\n`];
|
|
10935
10947
|
}
|
|
10936
10948
|
|
|
10937
10949
|
/**
|
|
@@ -11896,7 +11908,7 @@
|
|
|
11896
11908
|
* @return {String}
|
|
11897
11909
|
*/
|
|
11898
11910
|
getSvgStyles() {
|
|
11899
|
-
const opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? `opacity: ${this.opacity};` : '',
|
|
11911
|
+
const opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? `opacity: ${escapeXml(this.opacity)};` : '',
|
|
11900
11912
|
visibility = this.visible ? '' : ' visibility: hidden;';
|
|
11901
11913
|
return [opacity, this.getSvgFilter(), visibility].join('');
|
|
11902
11914
|
}
|
|
@@ -13850,11 +13862,13 @@
|
|
|
13850
13862
|
* Given the control clicked, determine the origin of the transform.
|
|
13851
13863
|
* This is bad because controls can totally have custom names
|
|
13852
13864
|
* should disappear before release 4.0
|
|
13865
|
+
* Fabric 7.1, jan 2026 we are still using this.
|
|
13866
|
+
* Needs to go.
|
|
13853
13867
|
* @private
|
|
13854
13868
|
* @deprecated
|
|
13855
13869
|
*/
|
|
13856
13870
|
_getOriginFromCorner(target, controlName) {
|
|
13857
|
-
const origin = {
|
|
13871
|
+
const origin = controlName ? target.controls[controlName].getTransformAnchorPoint() : {
|
|
13858
13872
|
x: target.originX,
|
|
13859
13873
|
y: target.originY
|
|
13860
13874
|
};
|
|
@@ -13862,6 +13876,9 @@
|
|
|
13862
13876
|
return origin;
|
|
13863
13877
|
}
|
|
13864
13878
|
|
|
13879
|
+
// this part down here is deprecated.
|
|
13880
|
+
// It is left to do not change the standard behavior in the middle of a major version
|
|
13881
|
+
// but when possible `getTransformAnchorPoint` will be the only source of truth
|
|
13865
13882
|
// is a left control ?
|
|
13866
13883
|
if (['ml', 'tl', 'bl'].includes(controlName)) {
|
|
13867
13884
|
origin.x = RIGHT;
|
|
@@ -16359,7 +16376,8 @@
|
|
|
16359
16376
|
}
|
|
16360
16377
|
transform[4] -= offsetX;
|
|
16361
16378
|
transform[5] -= offsetY;
|
|
16362
|
-
const commonAttributes = [`id="SVGID_${this.id}"`, `gradientUnits="${gradientUnits}"`, `gradientTransform="${preTransform ? preTransform + ' ' : ''}${matrixToSVG(transform)}"`, ''].join(' ');
|
|
16379
|
+
const commonAttributes = [`id="SVGID_${escapeXml(String(this.id))}"`, `gradientUnits="${gradientUnits}"`, `gradientTransform="${preTransform ? preTransform + ' ' : ''}${matrixToSVG(transform)}"`, ''].join(' ');
|
|
16380
|
+
const sanitizeCoord = value => parseFloat(String(value));
|
|
16363
16381
|
if (this.type === 'linear') {
|
|
16364
16382
|
const {
|
|
16365
16383
|
x1,
|
|
@@ -16367,7 +16385,11 @@
|
|
|
16367
16385
|
x2,
|
|
16368
16386
|
y2
|
|
16369
16387
|
} = this.coords;
|
|
16370
|
-
|
|
16388
|
+
const sx1 = sanitizeCoord(x1);
|
|
16389
|
+
const sy1 = sanitizeCoord(y1);
|
|
16390
|
+
const sx2 = sanitizeCoord(x2);
|
|
16391
|
+
const sy2 = sanitizeCoord(y2);
|
|
16392
|
+
markup.push('<linearGradient ', commonAttributes, ' x1="', sx1, '" y1="', sy1, '" x2="', sx2, '" y2="', sy2, '">\n');
|
|
16371
16393
|
} else if (this.type === 'radial') {
|
|
16372
16394
|
const {
|
|
16373
16395
|
x1,
|
|
@@ -16377,9 +16399,15 @@
|
|
|
16377
16399
|
r1,
|
|
16378
16400
|
r2
|
|
16379
16401
|
} = this.coords;
|
|
16380
|
-
const
|
|
16402
|
+
const sx1 = sanitizeCoord(x1);
|
|
16403
|
+
const sy1 = sanitizeCoord(y1);
|
|
16404
|
+
const sx2 = sanitizeCoord(x2);
|
|
16405
|
+
const sy2 = sanitizeCoord(y2);
|
|
16406
|
+
const sr1 = sanitizeCoord(r1);
|
|
16407
|
+
const sr2 = sanitizeCoord(r2);
|
|
16408
|
+
const needsSwap = sr1 > sr2;
|
|
16381
16409
|
// svg radial gradient has just 1 radius. the biggest.
|
|
16382
|
-
markup.push('<radialGradient ', commonAttributes, ' cx="', needsSwap ?
|
|
16410
|
+
markup.push('<radialGradient ', commonAttributes, ' cx="', needsSwap ? sx1 : sx2, '" cy="', needsSwap ? sy1 : sy2, '" r="', needsSwap ? sr1 : sr2, '" fx="', needsSwap ? sx2 : sx1, '" fy="', needsSwap ? sy2 : sy1, '">\n');
|
|
16383
16411
|
if (needsSwap) {
|
|
16384
16412
|
// svg goes from internal to external radius. if radius are inverted, swap color stops.
|
|
16385
16413
|
colorStops.reverse(); // mutates array
|
|
@@ -16387,16 +16415,17 @@
|
|
|
16387
16415
|
colorStop.offset = 1 - colorStop.offset;
|
|
16388
16416
|
});
|
|
16389
16417
|
}
|
|
16390
|
-
const minRadius = Math.min(
|
|
16418
|
+
const minRadius = Math.min(sr1, sr2);
|
|
16391
16419
|
if (minRadius > 0) {
|
|
16392
16420
|
// i have to shift all colorStops and add new one in 0.
|
|
16393
|
-
const maxRadius = Math.max(
|
|
16421
|
+
const maxRadius = Math.max(sr1, sr2),
|
|
16394
16422
|
percentageShift = minRadius / maxRadius;
|
|
16395
16423
|
colorStops.forEach(colorStop => {
|
|
16396
16424
|
colorStop.offset += percentageShift * (1 - colorStop.offset);
|
|
16397
16425
|
});
|
|
16398
16426
|
}
|
|
16399
16427
|
}
|
|
16428
|
+
// todo make a malicious script tag injection test with color and also apply a fix with escapeXml
|
|
16400
16429
|
colorStops.forEach(_ref => {
|
|
16401
16430
|
let {
|
|
16402
16431
|
color,
|
|
@@ -16712,7 +16741,7 @@
|
|
|
16712
16741
|
patternOffsetY = ifNaN(this.offsetY / height, 0),
|
|
16713
16742
|
patternWidth = repeat === 'repeat-y' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetX || 0) : ifNaN(patternSource.width / width, 0),
|
|
16714
16743
|
patternHeight = repeat === 'repeat-x' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetY || 0) : ifNaN(patternSource.height / height, 0);
|
|
16715
|
-
return [`<pattern id="SVGID_${id}" x="${patternOffsetX}" y="${patternOffsetY}" width="${patternWidth}" height="${patternHeight}">`, `<image x="0" y="0" width="${patternSource.width}" height="${patternSource.height}" xlink:href="${this.sourceToString()}"></image>`, `</pattern>`, ''].join('\n');
|
|
16744
|
+
return [`<pattern id="SVGID_${escapeXml(id)}" x="${patternOffsetX}" y="${patternOffsetY}" width="${patternWidth}" height="${patternHeight}">`, `<image x="0" y="0" width="${patternSource.width}" height="${patternSource.height}" xlink:href="${escapeXml(this.sourceToString())}"></image>`, `</pattern>`, ''].join('\n');
|
|
16716
16745
|
}
|
|
16717
16746
|
/* _TO_SVG_END_ */
|
|
16718
16747
|
|
|
@@ -16994,8 +17023,7 @@
|
|
|
16994
17023
|
* of the instance
|
|
16995
17024
|
*/
|
|
16996
17025
|
_toSVG() {
|
|
16997
|
-
|
|
16998
|
-
return ['<path ', 'COMMON_PARTS', `d="${path}" stroke-linecap="round" />\n`];
|
|
17026
|
+
return ['<path ', 'COMMON_PARTS', `d="${joinPath(this.path, config.NUM_FRACTION_DIGITS)}" stroke-linecap="round" />\n`];
|
|
16999
17027
|
}
|
|
17000
17028
|
|
|
17001
17029
|
/**
|
|
@@ -17546,15 +17574,17 @@
|
|
|
17546
17574
|
* of the instance
|
|
17547
17575
|
*/
|
|
17548
17576
|
_toSVG() {
|
|
17549
|
-
const
|
|
17577
|
+
const {
|
|
17578
|
+
radius,
|
|
17579
|
+
startAngle,
|
|
17580
|
+
endAngle
|
|
17581
|
+
} = this;
|
|
17582
|
+
const angle = (endAngle - startAngle) % 360;
|
|
17550
17583
|
if (angle === 0) {
|
|
17551
|
-
return ['<circle ', 'COMMON_PARTS', 'cx="0" cy="0" ', 'r="', `${
|
|
17584
|
+
return ['<circle ', 'COMMON_PARTS', 'cx="0" cy="0" ', 'r="', `${escapeXml(radius)}`, '" />\n'];
|
|
17552
17585
|
} else {
|
|
17553
|
-
const
|
|
17554
|
-
|
|
17555
|
-
} = this;
|
|
17556
|
-
const start = degreesToRadians(this.startAngle),
|
|
17557
|
-
end = degreesToRadians(this.endAngle),
|
|
17586
|
+
const start = degreesToRadians(startAngle),
|
|
17587
|
+
end = degreesToRadians(endAngle),
|
|
17558
17588
|
startX = cos(start) * radius,
|
|
17559
17589
|
startY = sin(start) * radius,
|
|
17560
17590
|
endX = cos(end) * radius,
|
|
@@ -18126,17 +18156,13 @@
|
|
|
18126
18156
|
width,
|
|
18127
18157
|
height
|
|
18128
18158
|
} = this;
|
|
18129
|
-
const xMult = _x1 <= _x2 ? -
|
|
18130
|
-
yMult = _y1 <= _y2 ? -
|
|
18131
|
-
x1 = xMult * width / 2,
|
|
18132
|
-
y1 = yMult * height / 2,
|
|
18133
|
-
x2 = xMult * -width / 2,
|
|
18134
|
-
y2 = yMult * -height / 2;
|
|
18159
|
+
const xMult = _x1 <= _x2 ? -0.5 : 0.5,
|
|
18160
|
+
yMult = _y1 <= _y2 ? -0.5 : 0.5;
|
|
18135
18161
|
return {
|
|
18136
|
-
x1,
|
|
18137
|
-
x2,
|
|
18138
|
-
y1,
|
|
18139
|
-
y2
|
|
18162
|
+
x1: xMult * width,
|
|
18163
|
+
x2: xMult * -width,
|
|
18164
|
+
y1: yMult * height,
|
|
18165
|
+
y2: yMult * -height
|
|
18140
18166
|
};
|
|
18141
18167
|
}
|
|
18142
18168
|
|
|
@@ -18354,7 +18380,7 @@
|
|
|
18354
18380
|
* of the instance
|
|
18355
18381
|
*/
|
|
18356
18382
|
_toSVG() {
|
|
18357
|
-
return ['<ellipse ', 'COMMON_PARTS', `cx="0" cy="0" rx="${this.rx}" ry="${this.ry}" />\n`];
|
|
18383
|
+
return ['<ellipse ', 'COMMON_PARTS', `cx="0" cy="0" rx="${escapeXml(this.rx)}" ry="${escapeXml(this.ry)}" />\n`];
|
|
18358
18384
|
}
|
|
18359
18385
|
|
|
18360
18386
|
/**
|
|
@@ -18672,14 +18698,17 @@
|
|
|
18672
18698
|
* of the instance
|
|
18673
18699
|
*/
|
|
18674
18700
|
_toSVG() {
|
|
18675
|
-
const
|
|
18676
|
-
diffX = this.pathOffset.x,
|
|
18701
|
+
const diffX = this.pathOffset.x,
|
|
18677
18702
|
diffY = this.pathOffset.y,
|
|
18678
18703
|
NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18704
|
+
const points = this.points.map(_ref2 => {
|
|
18705
|
+
let {
|
|
18706
|
+
x,
|
|
18707
|
+
y
|
|
18708
|
+
} = _ref2;
|
|
18709
|
+
return `${toFixed(x - diffX, NUM_FRACTION_DIGITS)},${toFixed(y - diffY, NUM_FRACTION_DIGITS)}`;
|
|
18710
|
+
}).join(' ');
|
|
18711
|
+
return [`<${escapeXml(this.constructor.type).toLowerCase()} `, 'COMMON_PARTS', `points="${points}" />\n`];
|
|
18683
18712
|
}
|
|
18684
18713
|
|
|
18685
18714
|
/**
|
|
@@ -19103,7 +19132,7 @@
|
|
|
19103
19132
|
} = _ref;
|
|
19104
19133
|
const noShadow = true,
|
|
19105
19134
|
textDecoration = this.getSvgTextDecoration(this);
|
|
19106
|
-
return [textBgRects.join(''), '\t\t<text xml:space="preserve" ', `font-family="${this.fontFamily.replace(dblQuoteRegex, "'")}" `, `font-size="${this.fontSize}" `, this.fontStyle ? `font-style="${this.fontStyle}" ` : '', this.fontWeight ? `font-weight="${this.fontWeight}" ` : '', textDecoration ? `text-decoration="${textDecoration}" ` : '', this.direction === 'rtl' ? `direction="
|
|
19135
|
+
return [textBgRects.join(''), '\t\t<text xml:space="preserve" ', `font-family="${escapeXml(this.fontFamily.replace(dblQuoteRegex, "'"))}" `, `font-size="${escapeXml(this.fontSize)}" `, this.fontStyle ? `font-style="${escapeXml(this.fontStyle)}" ` : '', this.fontWeight ? `font-weight="${escapeXml(this.fontWeight)}" ` : '', textDecoration ? `text-decoration="${textDecoration}" ` : '', this.direction === 'rtl' ? `direction="rtl" ` : '', 'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >', textSpans.join(''), '</text>\n'];
|
|
19107
19136
|
}
|
|
19108
19137
|
|
|
19109
19138
|
/**
|
|
@@ -19119,7 +19148,7 @@
|
|
|
19119
19148
|
lineOffset;
|
|
19120
19149
|
|
|
19121
19150
|
// bounding-box background
|
|
19122
|
-
this.backgroundColor && textBgRects.push(
|
|
19151
|
+
this.backgroundColor && textBgRects.push(createSVGInlineRect(this.backgroundColor, -this.width / 2, -this.height / 2, this.width, this.height));
|
|
19123
19152
|
|
|
19124
19153
|
// text and text-background
|
|
19125
19154
|
for (let i = 0, len = this._textLines.length; i < len; i++) {
|
|
@@ -19227,7 +19256,7 @@
|
|
|
19227
19256
|
} = this.__charBounds[i][j];
|
|
19228
19257
|
currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');
|
|
19229
19258
|
if (currentColor !== lastColor) {
|
|
19230
|
-
lastColor && textBgRects.push(
|
|
19259
|
+
lastColor && textBgRects.push(createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine));
|
|
19231
19260
|
boxStart = left;
|
|
19232
19261
|
boxWidth = width;
|
|
19233
19262
|
lastColor = currentColor;
|
|
@@ -19235,7 +19264,7 @@
|
|
|
19235
19264
|
boxWidth += kernedWidth;
|
|
19236
19265
|
}
|
|
19237
19266
|
}
|
|
19238
|
-
currentColor && textBgRects.push(
|
|
19267
|
+
currentColor && textBgRects.push(createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine));
|
|
19239
19268
|
}
|
|
19240
19269
|
|
|
19241
19270
|
/**
|
|
@@ -19273,7 +19302,7 @@
|
|
|
19273
19302
|
linethrough: linethrough !== null && linethrough !== void 0 ? linethrough : this.linethrough
|
|
19274
19303
|
});
|
|
19275
19304
|
const thickness = textDecorationThickness || this.textDecorationThickness;
|
|
19276
|
-
return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? `stroke-width: ${strokeWidth}; ` : '', fontFamily ? `font-family: ${!fontFamily.includes("'") && !fontFamily.includes('"') ? `'${fontFamily}'` : fontFamily}; ` : '', fontSize ? `font-size: ${fontSize}px; ` : '', fontStyle ? `font-style: ${fontStyle}; ` : '', fontWeight ? `font-weight: ${fontWeight}; ` : '', textDecoration ? `text-decoration: ${textDecoration}; text-decoration-thickness: ${toFixed(thickness * this.getObjectScaling().y / 10, config.NUM_FRACTION_DIGITS)}%; ` : '', fill ? colorPropToSVG(FILL, fill) : '', useWhiteSpace ? 'white-space: pre; ' : ''].join('');
|
|
19305
|
+
return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? `stroke-width: ${escapeXml(strokeWidth)}; ` : '', fontFamily ? `font-family: ${!fontFamily.includes("'") && !fontFamily.includes('"') ? `'${escapeXml(fontFamily)}'` : escapeXml(fontFamily)}; ` : '', fontSize ? `font-size: ${escapeXml(fontSize)}px; ` : '', fontStyle ? `font-style: ${escapeXml(fontStyle)}; ` : '', fontWeight ? `font-weight: ${escapeXml(fontWeight)}; ` : '', textDecoration ? `text-decoration: ${textDecoration}; text-decoration-thickness: ${toFixed(thickness * this.getObjectScaling().y / 10, config.NUM_FRACTION_DIGITS)}%; ` : '', fill ? colorPropToSVG(FILL, fill) : '', useWhiteSpace ? 'white-space: pre; ' : ''].join('');
|
|
19277
19306
|
}
|
|
19278
19307
|
|
|
19279
19308
|
/**
|
|
@@ -24837,13 +24866,13 @@
|
|
|
24837
24866
|
}
|
|
24838
24867
|
if (this.hasCrop()) {
|
|
24839
24868
|
const clipPathId = uid();
|
|
24840
|
-
svgString.push('<clipPath id="imageCrop_' + clipPathId + '">\n', '\t<rect x="' + x + '" y="' + y + '" width="' + this.width + '" height="' + this.height + '" />\n', '</clipPath>\n');
|
|
24869
|
+
svgString.push('<clipPath id="imageCrop_' + clipPathId + '">\n', '\t<rect x="' + x + '" y="' + y + '" width="' + escapeXml(this.width) + '" height="' + escapeXml(this.height) + '" />\n', '</clipPath>\n');
|
|
24841
24870
|
clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" ';
|
|
24842
24871
|
}
|
|
24843
24872
|
if (!this.imageSmoothing) {
|
|
24844
24873
|
imageRendering = ' image-rendering="optimizeSpeed"';
|
|
24845
24874
|
}
|
|
24846
|
-
imageMarkup.push('\t<image ', 'COMMON_PARTS', `xlink:href="${this.
|
|
24875
|
+
imageMarkup.push('\t<image ', 'COMMON_PARTS', `xlink:href="${escapeXml(this.getSrc(true))}" x="${x - this.cropX}" y="${y - this.cropY
|
|
24847
24876
|
// we're essentially moving origin of transformation from top/left corner to the center of the shape
|
|
24848
24877
|
// by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
|
|
24849
24878
|
// so that object's center aligns with container's left/top
|
|
@@ -24851,7 +24880,7 @@
|
|
|
24851
24880
|
if (this.stroke || this.strokeDashArray) {
|
|
24852
24881
|
const origFill = this.fill;
|
|
24853
24882
|
this.fill = null;
|
|
24854
|
-
strokeSvg = [`\t<rect x="${x}" y="${y}" width="${this.width}" height="${this.height}" style="${this.getSvgStyles()}" />\n`];
|
|
24883
|
+
strokeSvg = [`\t<rect x="${x}" y="${y}" width="${escapeXml(this.width)}" height="${escapeXml(this.height)}" style="${this.getSvgStyles()}" />\n`];
|
|
24855
24884
|
this.fill = origFill;
|
|
24856
24885
|
}
|
|
24857
24886
|
if (this.paintFirst !== FILL) {
|