@configuratorware/configurator-admingui 1.37.0 → 1.37.1
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/Screens/Designer/SubScreens/DesignAreas/Components/MaskEditorField/MaskEditorField.js +66 -14
- package/Screens/Designer/SubScreens/DesignAreas/Translations.js +4 -2
- package/Utils/Events/pointerEvent.js +6 -0
- package/package.json +2 -2
- package/src/Screens/Designer/SubScreens/DesignAreas/Components/MaskEditorField/MaskEditorField.js +52 -15
- package/src/Screens/Designer/SubScreens/DesignAreas/Translations.js +8 -2
- package/src/Utils/Events/pointerEvent.js +5 -0
package/Screens/Designer/SubScreens/DesignAreas/Components/MaskEditorField/MaskEditorField.js
CHANGED
|
@@ -71,19 +71,45 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
71
71
|
|
|
72
72
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
73
73
|
|
|
74
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
75
|
-
|
|
76
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
77
|
-
|
|
78
74
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
79
75
|
|
|
80
76
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
81
77
|
|
|
78
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
79
|
+
|
|
80
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
81
|
+
|
|
82
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
83
|
+
|
|
82
84
|
var maskTypeValues = Object.values(_maskTypes.maskTypes);
|
|
83
85
|
var defaultValue = {
|
|
84
86
|
maskType: (0, _first["default"])(maskTypeValues),
|
|
85
87
|
maskData: {}
|
|
86
88
|
};
|
|
89
|
+
var safeClipElements = ['ellipse', 'circle', 'rect', 'line', 'polygon', 'polyline', 'path'];
|
|
90
|
+
|
|
91
|
+
var getUnsafeElements = function getUnsafeElements(svgString) {
|
|
92
|
+
var matchedElements = svgString.matchAll(/<((?!svg)\w+)/g);
|
|
93
|
+
var unsafeElements = [];
|
|
94
|
+
|
|
95
|
+
var _iterator = _createForOfIteratorHelper(matchedElements),
|
|
96
|
+
_step;
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
100
|
+
var match = _step.value;
|
|
101
|
+
var tagName = match[1];
|
|
102
|
+
!safeClipElements.includes(tagName) && !unsafeElements.includes(tagName) && unsafeElements.push(tagName);
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
_iterator.e(err);
|
|
106
|
+
} finally {
|
|
107
|
+
_iterator.f();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return unsafeElements;
|
|
111
|
+
};
|
|
112
|
+
|
|
87
113
|
var UploadStatus = (0, _withStyles["default"])({
|
|
88
114
|
uploadStatusContainer: {
|
|
89
115
|
textAlign: 'right'
|
|
@@ -113,6 +139,16 @@ var styles = {
|
|
|
113
139
|
}
|
|
114
140
|
}
|
|
115
141
|
};
|
|
142
|
+
var StyledDialog = (0, _withStyles["default"])({
|
|
143
|
+
dialogContentTextRoot: {
|
|
144
|
+
display: 'flex',
|
|
145
|
+
'& canvas': {
|
|
146
|
+
margin: 'auto',
|
|
147
|
+
maxHeight: '100%',
|
|
148
|
+
maxWidth: '100%'
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
})(_Dialog["default"]);
|
|
116
152
|
var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.withFileUpload)(function (_ref2) {
|
|
117
153
|
var value = _ref2.value,
|
|
118
154
|
_ref2$ratio = _ref2.ratio,
|
|
@@ -144,7 +180,7 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
144
180
|
freeFormFile = _useState6[0],
|
|
145
181
|
setFreeFormFile = _useState6[1];
|
|
146
182
|
|
|
147
|
-
var _useState7 = (0, _react.useState)(false),
|
|
183
|
+
var _useState7 = (0, _react.useState)((initialValue === null || initialValue === void 0 ? void 0 : initialValue.maskDataUrl) || false),
|
|
148
184
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
149
185
|
dataUrl = _useState8[0],
|
|
150
186
|
setDataUrl = _useState8[1];
|
|
@@ -154,6 +190,11 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
154
190
|
embeddedImageError = _useState10[0],
|
|
155
191
|
setEmbeddedImageError = _useState10[1];
|
|
156
192
|
|
|
193
|
+
var _useState11 = (0, _react.useState)([]),
|
|
194
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
195
|
+
unsafeElements = _useState12[0],
|
|
196
|
+
setUnsafeElements = _useState12[1];
|
|
197
|
+
|
|
157
198
|
var maskType = currentValue.maskType,
|
|
158
199
|
maskData = currentValue.maskData;
|
|
159
200
|
|
|
@@ -173,7 +214,7 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
173
214
|
|
|
174
215
|
var resetState = function resetState() {
|
|
175
216
|
setFreeFormFile(false);
|
|
176
|
-
setDataUrl(false);
|
|
217
|
+
setDataUrl((initialValue === null || initialValue === void 0 ? void 0 : initialValue.maskDataUrl) || false);
|
|
177
218
|
setEmbeddedImageError(false);
|
|
178
219
|
};
|
|
179
220
|
|
|
@@ -191,15 +232,20 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
191
232
|
|
|
192
233
|
if (embeddedImageIndex !== -1) {
|
|
193
234
|
setEmbeddedImageError(true);
|
|
194
|
-
|
|
195
|
-
setDataUrl(reader.result);
|
|
196
|
-
setFreeFormFile(file);
|
|
197
|
-
clearMaskData();
|
|
235
|
+
return;
|
|
198
236
|
}
|
|
237
|
+
|
|
238
|
+
setUnsafeElements(getUnsafeElements(svgString));
|
|
239
|
+
setDataUrl(reader.result);
|
|
240
|
+
setFreeFormFile(file);
|
|
241
|
+
clearMaskData();
|
|
199
242
|
}, false);
|
|
200
243
|
reader.readAsDataURL(file);
|
|
201
244
|
};
|
|
202
245
|
|
|
246
|
+
(0, _react.useEffect)(function () {
|
|
247
|
+
(initialValue === null || initialValue === void 0 ? void 0 : initialValue.maskDataUrl) && setDataUrl(initialValue.maskDataUrl);
|
|
248
|
+
}, [initialValue]);
|
|
203
249
|
(0, _react.useEffect)(function () {
|
|
204
250
|
// update the current value explicitly with the value prop (eg. the changes has been saved)
|
|
205
251
|
if ((0, _size["default"])(value) > 0) {
|
|
@@ -224,9 +270,9 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
224
270
|
return function (maskType) {
|
|
225
271
|
var _maskTypes$none$maskT;
|
|
226
272
|
|
|
227
|
-
return showDialog && (_maskTypes$none$maskT = {}, _defineProperty(_maskTypes$none$maskT, _maskTypes.maskTypes.none, false), _defineProperty(_maskTypes$none$maskT, _maskTypes.maskTypes.circle, _circle["default"]), _defineProperty(_maskTypes$none$maskT, _maskTypes.maskTypes.freeForm,
|
|
273
|
+
return showDialog && (_maskTypes$none$maskT = {}, _defineProperty(_maskTypes$none$maskT, _maskTypes.maskTypes.none, false), _defineProperty(_maskTypes$none$maskT, _maskTypes.maskTypes.circle, _circle["default"]), _defineProperty(_maskTypes$none$maskT, _maskTypes.maskTypes.freeForm, dataUrl || "".concat(freeFormUrl, "?v=").concat(Math.random())), _maskTypes$none$maskT)[maskType];
|
|
228
274
|
};
|
|
229
|
-
}, [freeFormUrl, dataUrl, showDialog
|
|
275
|
+
}, [freeFormUrl, dataUrl, showDialog]);
|
|
230
276
|
var getMaskDataRef = (0, _react.useRef)(function () {});
|
|
231
277
|
|
|
232
278
|
var onOkClick = /*#__PURE__*/function () {
|
|
@@ -289,7 +335,7 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
289
335
|
color: "primary"
|
|
290
336
|
}),
|
|
291
337
|
label: (0, _i18n.t)('maskEditor.checkboxLabel')
|
|
292
|
-
})), /*#__PURE__*/_react["default"].createElement(
|
|
338
|
+
})), /*#__PURE__*/_react["default"].createElement(StyledDialog, {
|
|
293
339
|
title: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("div", {
|
|
294
340
|
className: classes.inlineFormWrapper
|
|
295
341
|
}, (0, _i18n.T)('mask editor'), /*#__PURE__*/_react["default"].createElement(_SelectField["default"], {
|
|
@@ -314,7 +360,13 @@ var MaskEditorField = (0, _withStyles["default"])(styles)((0, _withFileUpload.wi
|
|
|
314
360
|
})), embeddedImageError && /*#__PURE__*/_react["default"].createElement(_Typography["default"], {
|
|
315
361
|
variant: "body1",
|
|
316
362
|
color: "error"
|
|
317
|
-
}, (0, _i18n.t)('maskEditor.embeddedImageError'))
|
|
363
|
+
}, (0, _i18n.t)('maskEditor.embeddedImageError')), unsafeElements.length > 0 && /*#__PURE__*/_react["default"].createElement(_Typography["default"], {
|
|
364
|
+
variant: "body1",
|
|
365
|
+
color: "error"
|
|
366
|
+
}, (0, _i18n.T)('maskEditor.unsafeElementsError', {
|
|
367
|
+
unsafeElements: unsafeElements.join(', '),
|
|
368
|
+
safeClipElements: safeClipElements.join(', ')
|
|
369
|
+
}))),
|
|
318
370
|
open: showDialog,
|
|
319
371
|
maxWidth: 'xl',
|
|
320
372
|
fullWidth: false,
|
|
@@ -44,7 +44,8 @@ require("../../../../App/i18n").use({
|
|
|
44
44
|
uploadAndSave: 'Upload and save',
|
|
45
45
|
uploadFailed: 'Failed to upload the SVG',
|
|
46
46
|
uploadInProgress: 'Upload in progress, please wait...',
|
|
47
|
-
embeddedImageError: 'The provided file contains an embedded raster graphic. Please use plain / vector only svg files.'
|
|
47
|
+
embeddedImageError: 'The provided file contains an embedded raster graphic. Please use plain / vector only svg files.',
|
|
48
|
+
unsafeElementsError: 'The provided file contains elements that are not safe to be used for clipping. Please consider using only the following safe elements: %{safeClipElements}'
|
|
48
49
|
},
|
|
49
50
|
validation: {
|
|
50
51
|
designProductionMethod: {
|
|
@@ -106,7 +107,8 @@ require("../../../../App/i18n").use({
|
|
|
106
107
|
uploadAndSave: 'Hochladen und speichern',
|
|
107
108
|
uploadFailed: 'Fehler beim Hochladen von SVG',
|
|
108
109
|
uploadInProgress: 'Upload läuft, bitte warten...',
|
|
109
|
-
embeddedImageError: 'Die gewählte Datei enthält eingebettete Pixelgrafiken und kann nicht verwendet werden. Bitte wähle eine Datei, die ausschließlich Vektordaten enthält.'
|
|
110
|
+
embeddedImageError: 'Die gewählte Datei enthält eingebettete Pixelgrafiken und kann nicht verwendet werden. Bitte wähle eine Datei, die ausschließlich Vektordaten enthält.',
|
|
111
|
+
unsafeElementsError: 'Die verwendete Datei beinhaltet Elemente, die für das Beschneiden nicht verwendet werden können. Bitte verwenden Sie nur folgende Elemente: %{safeClipElements}'
|
|
110
112
|
},
|
|
111
113
|
validation: {
|
|
112
114
|
designProductionMethod: {
|
|
@@ -31,6 +31,12 @@ var getPointFromPointerEvent = function getPointFromPointerEvent(evt) {
|
|
|
31
31
|
y -= top;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
if (relativeTo.width) {
|
|
35
|
+
var scaling = relativeTo.getBoundingClientRect().width / relativeTo.width;
|
|
36
|
+
x *= 1 / scaling;
|
|
37
|
+
y *= 1 / scaling;
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
return {
|
|
35
41
|
x: x,
|
|
36
42
|
y: y
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configuratorware/configurator-admingui",
|
|
3
|
-
"version": "1.37.
|
|
3
|
+
"version": "1.37.1",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"private": false,
|
|
6
6
|
"dependencies": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"react-redux-i18n": "^1.9.3",
|
|
30
30
|
"react-router": "^3.2.6",
|
|
31
31
|
"react-sortable-hoc": "^1.11.0",
|
|
32
|
-
"redhotmagma-visualization": "1.37.
|
|
32
|
+
"redhotmagma-visualization": "1.37.1",
|
|
33
33
|
"redux": "^4.1.0",
|
|
34
34
|
"redux-logger": "^3.0.6",
|
|
35
35
|
"redux-persist": "^5.10.0",
|
package/src/Screens/Designer/SubScreens/DesignAreas/Components/MaskEditorField/MaskEditorField.js
CHANGED
|
@@ -25,6 +25,20 @@ const defaultValue = {
|
|
|
25
25
|
maskData: {},
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
const safeClipElements = ['ellipse', 'circle', 'rect', 'line', 'polygon', 'polyline', 'path'];
|
|
29
|
+
|
|
30
|
+
const getUnsafeElements = svgString => {
|
|
31
|
+
const matchedElements = svgString.matchAll(/<((?!svg)\w+)/g);
|
|
32
|
+
const unsafeElements = [];
|
|
33
|
+
for (const match of matchedElements) {
|
|
34
|
+
const tagName = match[1];
|
|
35
|
+
!safeClipElements.includes(tagName) &&
|
|
36
|
+
!unsafeElements.includes(tagName) &&
|
|
37
|
+
unsafeElements.push(tagName);
|
|
38
|
+
}
|
|
39
|
+
return unsafeElements;
|
|
40
|
+
};
|
|
41
|
+
|
|
28
42
|
const UploadStatus = withStyles({
|
|
29
43
|
uploadStatusContainer: {
|
|
30
44
|
textAlign: 'right',
|
|
@@ -58,6 +72,17 @@ const styles = {
|
|
|
58
72
|
},
|
|
59
73
|
};
|
|
60
74
|
|
|
75
|
+
const StyledDialog = withStyles({
|
|
76
|
+
dialogContentTextRoot: {
|
|
77
|
+
display: 'flex',
|
|
78
|
+
'& canvas': {
|
|
79
|
+
margin: 'auto',
|
|
80
|
+
maxHeight: '100%',
|
|
81
|
+
maxWidth: '100%',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
})(Dialog);
|
|
85
|
+
|
|
61
86
|
export const MaskEditorField = withStyles(styles)(
|
|
62
87
|
withFileUpload(
|
|
63
88
|
({
|
|
@@ -78,8 +103,9 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
78
103
|
const [showDialog, toggleDialog] = useState(false);
|
|
79
104
|
const [currentValue, setCurrentValue] = useState(initialValue);
|
|
80
105
|
const [freeFormFile, setFreeFormFile] = useState(false);
|
|
81
|
-
const [dataUrl, setDataUrl] = useState(false);
|
|
106
|
+
const [dataUrl, setDataUrl] = useState(initialValue?.maskDataUrl || false);
|
|
82
107
|
const [embeddedImageError, setEmbeddedImageError] = useState(false);
|
|
108
|
+
const [unsafeElements, setUnsafeElements] = useState([]);
|
|
83
109
|
|
|
84
110
|
const { maskType, maskData } = currentValue;
|
|
85
111
|
|
|
@@ -88,10 +114,10 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
88
114
|
setCurrentValue({ ...currentValue, maskType, maskData: {} });
|
|
89
115
|
resetState();
|
|
90
116
|
};
|
|
91
|
-
|
|
117
|
+
|
|
92
118
|
const resetState = () => {
|
|
93
119
|
setFreeFormFile(false);
|
|
94
|
-
setDataUrl(false);
|
|
120
|
+
setDataUrl(initialValue?.maskDataUrl || false);
|
|
95
121
|
setEmbeddedImageError(false);
|
|
96
122
|
};
|
|
97
123
|
|
|
@@ -108,18 +134,22 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
108
134
|
const embeddedImageIndex = svgString.search('<image');
|
|
109
135
|
if (embeddedImageIndex !== -1) {
|
|
110
136
|
setEmbeddedImageError(true);
|
|
137
|
+
return;
|
|
111
138
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
139
|
+
setUnsafeElements(getUnsafeElements(svgString));
|
|
140
|
+
setDataUrl(reader.result);
|
|
141
|
+
setFreeFormFile(file);
|
|
142
|
+
clearMaskData();
|
|
117
143
|
},
|
|
118
144
|
false
|
|
119
145
|
);
|
|
120
146
|
reader.readAsDataURL(file);
|
|
121
147
|
};
|
|
122
148
|
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
initialValue?.maskDataUrl && setDataUrl(initialValue.maskDataUrl);
|
|
151
|
+
}, [initialValue]);
|
|
152
|
+
|
|
123
153
|
useEffect(() => {
|
|
124
154
|
// update the current value explicitly with the value prop (eg. the changes has been saved)
|
|
125
155
|
if (size(value) > 0) {
|
|
@@ -148,10 +178,9 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
148
178
|
{
|
|
149
179
|
[maskTypes.none]: false,
|
|
150
180
|
[maskTypes.circle]: circleMask,
|
|
151
|
-
[maskTypes.freeForm]:
|
|
152
|
-
initialValue.maskDataUrl || dataUrl || `${freeFormUrl}?v=${Math.random()}`,
|
|
181
|
+
[maskTypes.freeForm]: dataUrl || `${freeFormUrl}?v=${Math.random()}`,
|
|
153
182
|
}[maskType],
|
|
154
|
-
[freeFormUrl, dataUrl, showDialog
|
|
183
|
+
[freeFormUrl, dataUrl, showDialog]
|
|
155
184
|
);
|
|
156
185
|
|
|
157
186
|
const getMaskDataRef = useRef(() => {});
|
|
@@ -194,7 +223,7 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
194
223
|
label={t('maskEditor.checkboxLabel')}
|
|
195
224
|
/>
|
|
196
225
|
</Grid>
|
|
197
|
-
<
|
|
226
|
+
<StyledDialog
|
|
198
227
|
title={
|
|
199
228
|
<React.Fragment>
|
|
200
229
|
<div className={classes.inlineFormWrapper}>
|
|
@@ -227,11 +256,19 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
227
256
|
/>
|
|
228
257
|
)}
|
|
229
258
|
</div>
|
|
230
|
-
{embeddedImageError &&
|
|
259
|
+
{embeddedImageError && (
|
|
231
260
|
<Typography variant="body1" color="error">
|
|
232
261
|
{t('maskEditor.embeddedImageError')}
|
|
233
262
|
</Typography>
|
|
234
|
-
}
|
|
263
|
+
)}
|
|
264
|
+
{unsafeElements.length > 0 && (
|
|
265
|
+
<Typography variant="body1" color="error">
|
|
266
|
+
{T('maskEditor.unsafeElementsError', {
|
|
267
|
+
unsafeElements: unsafeElements.join(', '),
|
|
268
|
+
safeClipElements: safeClipElements.join(', '),
|
|
269
|
+
})}
|
|
270
|
+
</Typography>
|
|
271
|
+
)}
|
|
235
272
|
</React.Fragment>
|
|
236
273
|
}
|
|
237
274
|
open={showDialog}
|
|
@@ -261,7 +298,7 @@ export const MaskEditorField = withStyles(styles)(
|
|
|
261
298
|
/>
|
|
262
299
|
|
|
263
300
|
<UploadStatus uploadStatus={uploadStatus} />
|
|
264
|
-
</
|
|
301
|
+
</StyledDialog>
|
|
265
302
|
</React.Fragment>
|
|
266
303
|
);
|
|
267
304
|
}
|
|
@@ -44,7 +44,10 @@ require('../../../../App/i18n').use(
|
|
|
44
44
|
uploadAndSave: 'Upload and save',
|
|
45
45
|
uploadFailed: 'Failed to upload the SVG',
|
|
46
46
|
uploadInProgress: 'Upload in progress, please wait...',
|
|
47
|
-
embeddedImageError:
|
|
47
|
+
embeddedImageError:
|
|
48
|
+
'The provided file contains an embedded raster graphic. Please use plain / vector only svg files.',
|
|
49
|
+
unsafeElementsError:
|
|
50
|
+
'The provided file contains elements that are not safe to be used for clipping. Please consider using only the following safe elements: %{safeClipElements}',
|
|
48
51
|
},
|
|
49
52
|
validation: {
|
|
50
53
|
designProductionMethod: {
|
|
@@ -109,7 +112,10 @@ require('../../../../App/i18n').use(
|
|
|
109
112
|
uploadAndSave: 'Hochladen und speichern',
|
|
110
113
|
uploadFailed: 'Fehler beim Hochladen von SVG',
|
|
111
114
|
uploadInProgress: 'Upload läuft, bitte warten...',
|
|
112
|
-
embeddedImageError:
|
|
115
|
+
embeddedImageError:
|
|
116
|
+
'Die gewählte Datei enthält eingebettete Pixelgrafiken und kann nicht verwendet werden. Bitte wähle eine Datei, die ausschließlich Vektordaten enthält.',
|
|
117
|
+
unsafeElementsError:
|
|
118
|
+
'Die verwendete Datei beinhaltet Elemente, die für das Beschneiden nicht verwendet werden können. Bitte verwenden Sie nur folgende Elemente: %{safeClipElements}',
|
|
113
119
|
},
|
|
114
120
|
validation: {
|
|
115
121
|
designProductionMethod: {
|
|
@@ -18,6 +18,11 @@ export const getPointFromPointerEvent = (evt, relativeTo = false) => {
|
|
|
18
18
|
x -= left;
|
|
19
19
|
y -= top;
|
|
20
20
|
}
|
|
21
|
+
if (relativeTo.width) {
|
|
22
|
+
const scaling = relativeTo.getBoundingClientRect().width / relativeTo.width;
|
|
23
|
+
x *= 1 / scaling;
|
|
24
|
+
y *= 1 / scaling;
|
|
25
|
+
}
|
|
21
26
|
return { x, y };
|
|
22
27
|
};
|
|
23
28
|
|