@node-projects/web-component-designer 0.2.18 → 0.2.19
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/dist/elements/documentContainer.d.ts +4 -1
- package/dist/elements/documentContainer.js +23 -7
- package/dist/elements/documentContainer.js.map +1 -1
- package/dist/elements/helper/getBoxQuads.js +37 -3
- package/dist/elements/helper/getBoxQuads.js.map +1 -1
- package/dist/elements/item/DesignItem.d.ts +1 -1
- package/dist/elements/services/DefaultServiceBootstrap.js +2 -0
- package/dist/elements/services/DefaultServiceBootstrap.js.map +1 -1
- package/dist/elements/services/ServiceContainer.d.ts +2 -0
- package/dist/elements/services/ServiceContainer.js +1 -0
- package/dist/elements/services/ServiceContainer.js.map +1 -1
- package/dist/elements/services/designItemDocumentPositionService/DesignItemDocumentPositionService.d.ts +10 -0
- package/dist/elements/services/designItemDocumentPositionService/DesignItemDocumentPositionService.js +47 -0
- package/dist/elements/services/designItemDocumentPositionService/DesignItemDocumentPositionService.js.map +1 -1
- package/dist/elements/services/designItemDocumentPositionService/IDesignItemDocumentPositionService.d.ts +7 -0
- package/dist/elements/services/htmlParserService/DefaultHtmlParserService.js +6 -1
- package/dist/elements/services/htmlParserService/DefaultHtmlParserService.js.map +1 -1
- package/dist/elements/services/htmlWriterService/AbstractHtmlWriterService.d.ts +3 -1
- package/dist/elements/services/htmlWriterService/AbstractHtmlWriterService.js +40 -5
- package/dist/elements/services/htmlWriterService/AbstractHtmlWriterService.js.map +1 -1
- package/dist/elements/services/htmlWriterService/HtmlWriterService.js +3 -1
- package/dist/elements/services/htmlWriterService/HtmlWriterService.js.map +1 -1
- package/dist/elements/services/propertiesService/services/AttributesPropertiesService.d.ts +2 -0
- package/dist/elements/services/propertiesService/services/AttributesPropertiesService.js +24 -0
- package/dist/elements/services/propertiesService/services/AttributesPropertiesService.js.map +1 -1
- package/dist/elements/services/selectionService/ISelectionChangedEvent.d.ts +3 -0
- package/dist/elements/services/selectionService/ISelectionRefreshEvent.d.ts +2 -0
- package/dist/elements/services/selectionService/ISelectionService.d.ts +4 -1
- package/dist/elements/services/selectionService/SelectionService.d.ts +7 -2
- package/dist/elements/services/selectionService/SelectionService.js +28 -6
- package/dist/elements/services/selectionService/SelectionService.js.map +1 -1
- package/dist/elements/services/sourceMapService/ISourceMapProvider.d.ts +15 -0
- package/dist/elements/services/sourceMapService/ISourceMapProvider.js +2 -0
- package/dist/elements/services/sourceMapService/ISourceMapProvider.js.map +1 -0
- package/dist/elements/services/sourceMapService/ISourcePart.d.ts +16 -0
- package/dist/elements/services/sourceMapService/ISourcePart.js +2 -0
- package/dist/elements/services/sourceMapService/ISourcePart.js.map +1 -0
- package/dist/elements/services/sourceMapService/SvgPathDataSourceMap.d.ts +8 -0
- package/dist/elements/services/sourceMapService/SvgPathDataSourceMap.js +120 -0
- package/dist/elements/services/sourceMapService/SvgPathDataSourceMap.js.map +1 -0
- package/dist/elements/services/sourceMapService/SvgPathSourceMapProvider.d.ts +7 -0
- package/dist/elements/services/sourceMapService/SvgPathSourceMapProvider.js +29 -0
- package/dist/elements/services/sourceMapService/SvgPathSourceMapProvider.js.map +1 -0
- package/dist/elements/widgets/designerView/extensions/svg/UnifiedGeometryExtension.d.ts +4 -0
- package/dist/elements/widgets/designerView/extensions/svg/UnifiedGeometryExtension.js +44 -3
- package/dist/elements/widgets/designerView/extensions/svg/UnifiedGeometryExtension.js.map +1 -1
- package/dist/elements/widgets/designerView/extensions/svg/UnifiedGeometryExtensionProvider.js +5 -0
- package/dist/elements/widgets/designerView/extensions/svg/UnifiedGeometryExtensionProvider.js.map +1 -1
- package/dist/index-min.js +13 -13
- package/dist/index-min.js.map +4 -4
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -19,18 +19,23 @@ function findDesignItem(designItem, position) {
|
|
|
19
19
|
export class SelectionService {
|
|
20
20
|
primarySelection;
|
|
21
21
|
selectedElements = [];
|
|
22
|
+
selectedPart;
|
|
22
23
|
_designerCanvas;
|
|
23
24
|
_undoSelectionChanges;
|
|
24
25
|
constructor(designerCanvas, undoSelectionChanges) {
|
|
25
26
|
this._designerCanvas = designerCanvas;
|
|
26
27
|
this._undoSelectionChanges = undoSelectionChanges;
|
|
27
28
|
}
|
|
28
|
-
setSelectedElements(designItems, event) {
|
|
29
|
+
setSelectedElements(designItems, event, selectedPart) {
|
|
30
|
+
this._setSelectedElements(designItems, event, selectedPart);
|
|
31
|
+
}
|
|
32
|
+
_setSelectedElements(designItems, event, selectedPart) {
|
|
29
33
|
if (designItems === null || designItems.length === 0)
|
|
30
34
|
designItems = [this._designerCanvas.rootDesignItem];
|
|
31
35
|
if (this.selectedElements != designItems && !(this.selectedElements.length === 0 && (designItems == null || designItems.length === 0))) {
|
|
32
36
|
if (this.selectedElements?.length === 1 && designItems?.length === 1 && designItems[0] === this.selectedElements[0]) {
|
|
33
|
-
this.
|
|
37
|
+
this._setSelectedPart(selectedPart);
|
|
38
|
+
this.onSelectionRefresh.emit({ selectedElements: this.selectedElements, selectedPart: this.selectedPart, event });
|
|
34
39
|
return;
|
|
35
40
|
}
|
|
36
41
|
if (this._undoSelectionChanges) {
|
|
@@ -38,22 +43,38 @@ export class SelectionService {
|
|
|
38
43
|
this._designerCanvas.instanceServiceContainer.undoService.execute(action);
|
|
39
44
|
}
|
|
40
45
|
else {
|
|
41
|
-
this._withoutUndoSetSelectedElements(designItems, event);
|
|
46
|
+
this._withoutUndoSetSelectedElements(designItems, event, selectedPart);
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
}
|
|
50
|
+
setSelectedPart(sourcePart, event) {
|
|
51
|
+
if (this._setSelectedPart(sourcePart))
|
|
52
|
+
this.onSelectionRefresh.emit({ selectedElements: this.selectedElements, selectedPart: this.selectedPart, event });
|
|
53
|
+
}
|
|
54
|
+
_setSelectedPart(sourcePart) {
|
|
55
|
+
const oldSelectedPart = this.selectedPart;
|
|
56
|
+
if (oldSelectedPart === sourcePart || (oldSelectedPart?.designItem === sourcePart?.designItem && oldSelectedPart?.key === sourcePart?.key))
|
|
57
|
+
return false;
|
|
58
|
+
this.selectedPart = sourcePart;
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
45
61
|
setSelectionByTextRange(positionStart, positionEnd) {
|
|
62
|
+
const sourcePart = this._designerCanvas.instanceServiceContainer.designItemDocumentPositionService?.getSourcePartAt(positionStart);
|
|
46
63
|
const item = findDesignItem(this._designerCanvas.rootDesignItem, positionStart);
|
|
47
64
|
if (item) {
|
|
48
65
|
if (this.selectedElements.length != 1 || this.primarySelection != item)
|
|
49
|
-
this.
|
|
66
|
+
this._setSelectedElements([item], undefined, sourcePart);
|
|
67
|
+
else
|
|
68
|
+
this.setSelectedPart(sourcePart);
|
|
50
69
|
}
|
|
51
70
|
}
|
|
52
|
-
_withoutUndoSetSelectedElements(designItems, event) {
|
|
71
|
+
_withoutUndoSetSelectedElements(designItems, event, selectedPart) {
|
|
53
72
|
let oldSelectedElements = this.selectedElements;
|
|
73
|
+
let oldSelectedPart = this.selectedPart;
|
|
54
74
|
if (!designItems) {
|
|
55
75
|
this.selectedElements = [];
|
|
56
76
|
this.primarySelection = null;
|
|
77
|
+
this.selectedPart = null;
|
|
57
78
|
}
|
|
58
79
|
else {
|
|
59
80
|
let newSelection = [];
|
|
@@ -66,8 +87,9 @@ export class SelectionService {
|
|
|
66
87
|
this.primarySelection = newSelection[0];
|
|
67
88
|
else
|
|
68
89
|
this.primarySelection = null;
|
|
90
|
+
this.selectedPart = selectedPart?.designItem === this.primarySelection ? selectedPart : null;
|
|
69
91
|
}
|
|
70
|
-
this.onSelectionChanged.emit({ selectedElements: this.selectedElements, oldSelectedElements: oldSelectedElements, event });
|
|
92
|
+
this.onSelectionChanged.emit({ selectedElements: this.selectedElements, oldSelectedElements: oldSelectedElements, selectedPart: this.selectedPart, oldSelectedPart, event });
|
|
71
93
|
}
|
|
72
94
|
clearSelectedElements() {
|
|
73
95
|
this.setSelectedElements([]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionService.js","sourceRoot":"","sources":["../../../../src/elements/services/selectionService/SelectionService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2DAA2D,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectionService.js","sourceRoot":"","sources":["../../../../src/elements/services/selectionService/SelectionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IDesignItem } from '../../item/IDesignItem.js';
|
|
2
|
+
import { IStringPosition } from '../htmlWriterService/IStringPosition.js';
|
|
3
|
+
import { ISourcePart } from './ISourcePart.js';
|
|
4
|
+
export type SourceMapContextKind = 'attribute' | 'style-declaration' | 'text-node';
|
|
5
|
+
export interface ISourceMapContext {
|
|
6
|
+
designItem: IDesignItem;
|
|
7
|
+
sourceKind: SourceMapContextKind;
|
|
8
|
+
name?: string;
|
|
9
|
+
value: string;
|
|
10
|
+
valueTextRange: IStringPosition;
|
|
11
|
+
}
|
|
12
|
+
export interface ISourceMapProvider {
|
|
13
|
+
canMap(context: ISourceMapContext): boolean;
|
|
14
|
+
map(context: ISourceMapContext): ISourcePart[];
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISourceMapProvider.js","sourceRoot":"","sources":["../../../../src/elements/services/sourceMapService/ISourceMapProvider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IDesignItem } from '../../item/IDesignItem.js';
|
|
2
|
+
import { IStringPosition } from '../htmlWriterService/IStringPosition.js';
|
|
3
|
+
export type SourcePartKind = 'attribute' | 'attribute-value' | 'style-declaration' | 'style-value' | 'svg-path-handle' | string;
|
|
4
|
+
export interface ISourcePart<TData = unknown> {
|
|
5
|
+
designItem: IDesignItem;
|
|
6
|
+
kind: SourcePartKind;
|
|
7
|
+
key: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
textRange: IStringPosition;
|
|
10
|
+
data?: TData;
|
|
11
|
+
}
|
|
12
|
+
export interface ISvgPathHandleSourcePartData {
|
|
13
|
+
attribute: 'd';
|
|
14
|
+
segmentIndex: number;
|
|
15
|
+
handleType: 'anchor' | 'cp1' | 'cp2';
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISourcePart.js","sourceRoot":"","sources":["../../../../src/elements/services/sourceMapService/ISourcePart.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type SvgPathHandleType = 'anchor' | 'cp1' | 'cp2';
|
|
2
|
+
export interface ISvgPathHandleRange {
|
|
3
|
+
segmentIndex: number;
|
|
4
|
+
handleType: SvgPathHandleType;
|
|
5
|
+
start: number;
|
|
6
|
+
length: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseSvgPathDataSourceMap(value: string): ISvgPathHandleRange[];
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const parameterCount = {
|
|
2
|
+
M: 2,
|
|
3
|
+
L: 2,
|
|
4
|
+
H: 1,
|
|
5
|
+
V: 1,
|
|
6
|
+
C: 6,
|
|
7
|
+
S: 4,
|
|
8
|
+
Q: 4,
|
|
9
|
+
T: 2,
|
|
10
|
+
A: 7,
|
|
11
|
+
Z: 0,
|
|
12
|
+
};
|
|
13
|
+
function isCommandToken(token) {
|
|
14
|
+
return 'command' in token;
|
|
15
|
+
}
|
|
16
|
+
function isNumberToken(token) {
|
|
17
|
+
return 'value' in token;
|
|
18
|
+
}
|
|
19
|
+
function tokenizePathData(value) {
|
|
20
|
+
const tokens = [];
|
|
21
|
+
const tokenRegex = /[AaCcHhLlMmQqSsTtVvZz]|[-+]?(?:(?:\d*\.\d+)|(?:\d+\.?))(?:[eE][-+]?\d+)?/g;
|
|
22
|
+
let match;
|
|
23
|
+
while ((match = tokenRegex.exec(value))) {
|
|
24
|
+
const token = match[0];
|
|
25
|
+
if (/^[AaCcHhLlMmQqSsTtVvZz]$/.test(token))
|
|
26
|
+
tokens.push({ command: token, start: match.index, end: match.index + token.length });
|
|
27
|
+
else
|
|
28
|
+
tokens.push({ value: Number(token), start: match.index, end: match.index + token.length });
|
|
29
|
+
}
|
|
30
|
+
return tokens;
|
|
31
|
+
}
|
|
32
|
+
function getRange(numbers, indexes) {
|
|
33
|
+
const selected = indexes.map(index => numbers[index]).filter(x => x);
|
|
34
|
+
const start = Math.min(...selected.map(x => x.start));
|
|
35
|
+
const end = Math.max(...selected.map(x => x.end));
|
|
36
|
+
return { start, length: end - start };
|
|
37
|
+
}
|
|
38
|
+
function addHandleRange(ranges, segmentIndex, handleType, numbers, indexes) {
|
|
39
|
+
const range = getRange(numbers, indexes);
|
|
40
|
+
ranges.push({ segmentIndex, handleType, start: range.start, length: range.length });
|
|
41
|
+
}
|
|
42
|
+
function addSegmentRanges(ranges, command, segmentIndex, numbers) {
|
|
43
|
+
switch (command.toUpperCase()) {
|
|
44
|
+
case 'M':
|
|
45
|
+
case 'L':
|
|
46
|
+
case 'T':
|
|
47
|
+
addHandleRange(ranges, segmentIndex, 'anchor', numbers, [0, 1]);
|
|
48
|
+
break;
|
|
49
|
+
case 'H':
|
|
50
|
+
case 'V':
|
|
51
|
+
addHandleRange(ranges, segmentIndex, 'anchor', numbers, [0]);
|
|
52
|
+
break;
|
|
53
|
+
case 'C':
|
|
54
|
+
addHandleRange(ranges, segmentIndex, 'cp1', numbers, [0, 1]);
|
|
55
|
+
addHandleRange(ranges, segmentIndex, 'cp2', numbers, [2, 3]);
|
|
56
|
+
addHandleRange(ranges, segmentIndex, 'anchor', numbers, [4, 5]);
|
|
57
|
+
break;
|
|
58
|
+
case 'S':
|
|
59
|
+
addHandleRange(ranges, segmentIndex, 'cp2', numbers, [0, 1]);
|
|
60
|
+
addHandleRange(ranges, segmentIndex, 'anchor', numbers, [2, 3]);
|
|
61
|
+
break;
|
|
62
|
+
case 'Q':
|
|
63
|
+
addHandleRange(ranges, segmentIndex, 'cp1', numbers, [0, 1]);
|
|
64
|
+
addHandleRange(ranges, segmentIndex, 'anchor', numbers, [2, 3]);
|
|
65
|
+
break;
|
|
66
|
+
case 'A':
|
|
67
|
+
addHandleRange(ranges, segmentIndex, 'anchor', numbers, [5, 6]);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function parseSvgPathDataSourceMap(value) {
|
|
72
|
+
const tokens = tokenizePathData(value);
|
|
73
|
+
const ranges = [];
|
|
74
|
+
let index = 0;
|
|
75
|
+
let command = null;
|
|
76
|
+
let segmentIndex = 0;
|
|
77
|
+
while (index < tokens.length) {
|
|
78
|
+
const token = tokens[index];
|
|
79
|
+
if (isCommandToken(token)) {
|
|
80
|
+
command = token.command;
|
|
81
|
+
index++;
|
|
82
|
+
if (command.toUpperCase() === 'Z') {
|
|
83
|
+
segmentIndex++;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else if (!command) {
|
|
88
|
+
index++;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
let effectiveCommand = command;
|
|
92
|
+
let parameters = parameterCount[effectiveCommand.toUpperCase()];
|
|
93
|
+
if (parameters == null || parameters === 0)
|
|
94
|
+
continue;
|
|
95
|
+
let firstMoveSegment = effectiveCommand.toUpperCase() === 'M';
|
|
96
|
+
while (index < tokens.length && !isCommandToken(tokens[index])) {
|
|
97
|
+
if (firstMoveSegment) {
|
|
98
|
+
effectiveCommand = command;
|
|
99
|
+
firstMoveSegment = false;
|
|
100
|
+
}
|
|
101
|
+
else if (command.toUpperCase() === 'M') {
|
|
102
|
+
effectiveCommand = command === command.toLowerCase() ? 'l' : 'L';
|
|
103
|
+
}
|
|
104
|
+
parameters = parameterCount[effectiveCommand.toUpperCase()];
|
|
105
|
+
const numbers = [];
|
|
106
|
+
for (let parameterIndex = 0; parameterIndex < parameters && index < tokens.length; parameterIndex++, index++) {
|
|
107
|
+
const numberToken = tokens[index];
|
|
108
|
+
if (!isNumberToken(numberToken))
|
|
109
|
+
break;
|
|
110
|
+
numbers.push(numberToken);
|
|
111
|
+
}
|
|
112
|
+
if (numbers.length !== parameters)
|
|
113
|
+
break;
|
|
114
|
+
addSegmentRanges(ranges, effectiveCommand, segmentIndex, numbers);
|
|
115
|
+
segmentIndex++;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return ranges;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=SvgPathDataSourceMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SvgPathDataSourceMap.js","sourceRoot":"","sources":["../../../../src/elements/services/sourceMapService/SvgPathDataSourceMap.ts"],"names":[],"mappings":"AAiBA,MAAM,cAAc,GAA2B;IAC7C,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;CACL,CAAC;AAEF,SAAS,cAAc,CAAC,KAAgB;IACtC,OAAO,SAAS,IAAI,KAAK,CAAC;AAC5B,CAAC;AAED,SAAS,aAAa,CAAC,KAAgB;IACrC,OAAO,OAAO,IAAI,KAAK,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa;IACrC,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,2EAA2E,CAAC;IAC/F,IAAI,KAAsB,CAAC;IAE3B,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;;YAErF,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,OAAsB,EAAE,OAAiB;IACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,KAAK,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,cAAc,CAAC,MAA6B,EAAE,YAAoB,EAAE,UAA6B,EAAE,OAAsB,EAAE,OAAiB;IACnJ,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,gBAAgB,CAAC,MAA6B,EAAE,OAAe,EAAE,YAAoB,EAAE,OAAsB;IACpH,QAAQ,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QAC9B,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,MAAM;QACR,KAAK,GAAG;YACN,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,GAAG;YACN,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,GAAG;YACN,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,GAAG;YACN,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;IACV,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAW,IAAI,CAAC;IAC3B,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,OAAO,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YACxB,KAAK,EAAE,CAAC;YAER,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;gBAClC,YAAY,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACpB,KAAK,EAAE,CAAC;YACR,SAAS;QACX,CAAC;QAED,IAAI,gBAAgB,GAAG,OAAO,CAAC;QAC/B,IAAI,UAAU,GAAG,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC;QAChE,IAAI,UAAU,IAAI,IAAI,IAAI,UAAU,KAAK,CAAC;YACxC,SAAS;QAEX,IAAI,gBAAgB,GAAG,gBAAgB,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC;QAC9D,OAAO,KAAK,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC/D,IAAI,gBAAgB,EAAE,CAAC;gBACrB,gBAAgB,GAAG,OAAO,CAAC;gBAC3B,gBAAgB,GAAG,KAAK,CAAC;YAC3B,CAAC;iBAAM,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;gBACzC,gBAAgB,GAAG,OAAO,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACnE,CAAC;YAED,UAAU,GAAG,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAkB,EAAE,CAAC;YAClC,KAAK,IAAI,cAAc,GAAG,CAAC,EAAE,cAAc,GAAG,UAAU,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC7G,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;oBAC7B,MAAM;gBACR,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC5B,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU;gBAC/B,MAAM;YAER,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;YAClE,YAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ISourceMapContext, ISourceMapProvider } from './ISourceMapProvider.js';
|
|
2
|
+
import { ISourcePart, ISvgPathHandleSourcePartData } from './ISourcePart.js';
|
|
3
|
+
export declare function createSvgPathHandleSourcePartKey(segmentIndex: number, handleType: ISvgPathHandleSourcePartData['handleType']): string;
|
|
4
|
+
export declare class SvgPathSourceMapProvider implements ISourceMapProvider {
|
|
5
|
+
canMap(context: ISourceMapContext): boolean;
|
|
6
|
+
map(context: ISourceMapContext): ISourcePart<ISvgPathHandleSourcePartData>[];
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { parseSvgPathDataSourceMap } from './SvgPathDataSourceMap.js';
|
|
2
|
+
export function createSvgPathHandleSourcePartKey(segmentIndex, handleType) {
|
|
3
|
+
return `attribute:d/svg-path/segment:${segmentIndex}/handle:${handleType}`;
|
|
4
|
+
}
|
|
5
|
+
export class SvgPathSourceMapProvider {
|
|
6
|
+
canMap(context) {
|
|
7
|
+
return context.sourceKind === 'attribute'
|
|
8
|
+
&& context.name === 'd'
|
|
9
|
+
&& context.designItem.element instanceof context.designItem.window.SVGPathElement;
|
|
10
|
+
}
|
|
11
|
+
map(context) {
|
|
12
|
+
return parseSvgPathDataSourceMap(context.value).map(handleRange => ({
|
|
13
|
+
designItem: context.designItem,
|
|
14
|
+
kind: 'svg-path-handle',
|
|
15
|
+
key: createSvgPathHandleSourcePartKey(handleRange.segmentIndex, handleRange.handleType),
|
|
16
|
+
name: 'd',
|
|
17
|
+
textRange: {
|
|
18
|
+
start: context.valueTextRange.start + handleRange.start,
|
|
19
|
+
length: handleRange.length
|
|
20
|
+
},
|
|
21
|
+
data: {
|
|
22
|
+
attribute: 'd',
|
|
23
|
+
segmentIndex: handleRange.segmentIndex,
|
|
24
|
+
handleType: handleRange.handleType
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=SvgPathSourceMapProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SvgPathSourceMapProvider.js","sourceRoot":"","sources":["../../../../src/elements/services/sourceMapService/SvgPathSourceMapProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,MAAM,UAAU,gCAAgC,CAAC,YAAoB,EAAE,UAAsD;IAC3H,OAAO,gCAAgC,YAAY,WAAW,UAAU,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,OAAO,wBAAwB;IACnC,MAAM,CAAC,OAA0B;QAC/B,OAAO,OAAO,CAAC,UAAU,KAAK,WAAW;eACpC,OAAO,CAAC,IAAI,KAAK,GAAG;eACpB,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC;IACtF,CAAC;IAED,GAAG,CAAC,OAA0B;QAC5B,OAAO,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAClE,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,IAAI,EAAE,iBAAiB;YACvB,GAAG,EAAE,gCAAgC,CAAC,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC;YACvF,IAAI,EAAE,GAAG;YACT,SAAS,EAAE;gBACT,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK;gBACvD,MAAM,EAAE,WAAW,CAAC,MAAM;aAC3B;YACD,IAAI,EAAE;gBACJ,SAAS,EAAE,GAAG;gBACd,YAAY,EAAE,WAAW,CAAC,YAAY;gBACtC,UAAU,EAAE,WAAW,CAAC,UAAU;aACnC;SACF,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
|
|
@@ -25,6 +25,7 @@ export declare class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
25
25
|
private _getOverlayStructureSignature;
|
|
26
26
|
private _hasOverlayStructureMismatch;
|
|
27
27
|
private _getRefreshValues;
|
|
28
|
+
private _getSelectedHandleRefreshKey;
|
|
28
29
|
/** Convert an SVG user-space coordinate to overlay (canvas) coordinates. */
|
|
29
30
|
private _toOverlay;
|
|
30
31
|
/** Convert overlay (canvas) coordinates back to SVG user-space. */
|
|
@@ -35,6 +36,9 @@ export declare class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
35
36
|
private _drawAnchorCircle;
|
|
36
37
|
private _drawControlCircle;
|
|
37
38
|
private _onPointerDown;
|
|
39
|
+
private _selectSourcePart;
|
|
40
|
+
private _getSourcePart;
|
|
41
|
+
private _isSelectedHandle;
|
|
38
42
|
private _onPointerMove;
|
|
39
43
|
private _dragSingleHandle;
|
|
40
44
|
private _dragRectCorner;
|
|
@@ -6,6 +6,7 @@ import { SegmentType } from './geometry/IGeometry.js';
|
|
|
6
6
|
import { getGeometryReader } from './geometry/GeometryReaderFactory.js';
|
|
7
7
|
import { applyGeometryWritesToDesignItem, applyGeometryWritesToElement } from './geometry/GeometryWriteHelper.js';
|
|
8
8
|
import { fromOverlayPointToSvgUserSpace, toOverlayPointFromSvgUserSpace } from '../../../../helper/SvgHelper.js';
|
|
9
|
+
import { createSvgPathHandleSourcePartKey } from '../../../../services/sourceMapService/SvgPathSourceMapProvider.js';
|
|
9
10
|
export class UnifiedGeometryExtension extends AbstractExtension {
|
|
10
11
|
_geometry = null;
|
|
11
12
|
_reader;
|
|
@@ -100,7 +101,8 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
100
101
|
const values = [
|
|
101
102
|
this.designerCanvas.zoomFactor,
|
|
102
103
|
this.designerCanvas.scaleFactor,
|
|
103
|
-
this._overlayStructureSignature ?? ''
|
|
104
|
+
this._overlayStructureSignature ?? '',
|
|
105
|
+
this._getSelectedHandleRefreshKey()
|
|
104
106
|
];
|
|
105
107
|
if (transformedBoxQuad) {
|
|
106
108
|
values.push(transformedBoxQuad.p1.x, transformedBoxQuad.p1.y, transformedBoxQuad.p2.x, transformedBoxQuad.p2.y, transformedBoxQuad.p3.x, transformedBoxQuad.p3.y, transformedBoxQuad.p4.x, transformedBoxQuad.p4.y);
|
|
@@ -122,6 +124,14 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
122
124
|
}
|
|
123
125
|
return values;
|
|
124
126
|
}
|
|
127
|
+
_getSelectedHandleRefreshKey() {
|
|
128
|
+
const selectedPart = this.extendedItem.instanceServiceContainer.selectionService.selectedPart;
|
|
129
|
+
const data = selectedPart?.data;
|
|
130
|
+
if (selectedPart?.designItem !== this.extendedItem || selectedPart.kind !== 'svg-path-handle') {
|
|
131
|
+
return 'selected:none';
|
|
132
|
+
}
|
|
133
|
+
return `selected:${data?.segmentIndex}:${data?.handleType}`;
|
|
134
|
+
}
|
|
125
135
|
/** Convert an SVG user-space coordinate to overlay (canvas) coordinates. */
|
|
126
136
|
_toOverlay(p) {
|
|
127
137
|
return toOverlayPointFromSvgUserSpace(this.extendedItem.element, this.designerCanvas, p);
|
|
@@ -179,6 +189,7 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
179
189
|
for (const [key, circle] of this._overlayCircles) {
|
|
180
190
|
circle.setAttribute('r', (key.startsWith('anchor-') ? anchorRadius : controlRadius).toString());
|
|
181
191
|
circle.style.strokeWidth = strokeWidth;
|
|
192
|
+
circle.classList.toggle('svg-path-selected-part', this._isSelectedHandle(key));
|
|
182
193
|
}
|
|
183
194
|
for (const line of this._overlayLines) {
|
|
184
195
|
line.style.strokeDasharray = dashArray;
|
|
@@ -224,6 +235,7 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
224
235
|
_onPointerDown(event, circle, segIndex, handleType) {
|
|
225
236
|
event.stopPropagation();
|
|
226
237
|
event.preventDefault();
|
|
238
|
+
this._selectSourcePart(segIndex, handleType, event);
|
|
227
239
|
event.target.setPointerCapture(event.pointerId);
|
|
228
240
|
const cursorPos = this.designerCanvas.getNormalizedEventCoordinates(event);
|
|
229
241
|
if (!this._geometry)
|
|
@@ -251,8 +263,32 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
251
263
|
originalPoint,
|
|
252
264
|
originalSegments,
|
|
253
265
|
startScrollOffset: this.designerCanvas.canvasOffset,
|
|
266
|
+
geometryChanged: false,
|
|
254
267
|
};
|
|
255
268
|
}
|
|
269
|
+
_selectSourcePart(segIndex, handleType, event) {
|
|
270
|
+
const selectionService = this.extendedItem.instanceServiceContainer.selectionService;
|
|
271
|
+
const sourcePart = this._getSourcePart(segIndex, handleType);
|
|
272
|
+
if (selectionService.primarySelection !== this.extendedItem)
|
|
273
|
+
selectionService.setSelectedElements([this.extendedItem], event, sourcePart);
|
|
274
|
+
else if (sourcePart)
|
|
275
|
+
selectionService.setSelectedPart(sourcePart, event);
|
|
276
|
+
}
|
|
277
|
+
_getSourcePart(segIndex, handleType) {
|
|
278
|
+
const key = createSvgPathHandleSourcePartKey(segIndex, handleType);
|
|
279
|
+
return this.extendedItem.instanceServiceContainer.designItemDocumentPositionService
|
|
280
|
+
?.getSourceParts(this.extendedItem)
|
|
281
|
+
.find(x => x.key === key);
|
|
282
|
+
}
|
|
283
|
+
_isSelectedHandle(circleKey) {
|
|
284
|
+
const [handleType, segmentIndexText] = circleKey.split('-');
|
|
285
|
+
const selectedPart = this.extendedItem.instanceServiceContainer.selectionService.selectedPart;
|
|
286
|
+
const data = selectedPart?.data;
|
|
287
|
+
return selectedPart?.designItem === this.extendedItem
|
|
288
|
+
&& selectedPart.kind === 'svg-path-handle'
|
|
289
|
+
&& data?.segmentIndex === Number(segmentIndexText)
|
|
290
|
+
&& data?.handleType === handleType;
|
|
291
|
+
}
|
|
256
292
|
_onPointerMove(event, circle, segIndex, handleType) {
|
|
257
293
|
event.stopPropagation();
|
|
258
294
|
event.preventDefault();
|
|
@@ -263,6 +299,8 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
263
299
|
const cursorPos = this.designerCanvas.getNormalizedEventCoordinates(event);
|
|
264
300
|
let dx = cursorPos.x - this._dragState.startCursorPos.x;
|
|
265
301
|
let dy = cursorPos.y - this._dragState.startCursorPos.y;
|
|
302
|
+
if (dx === 0 && dy === 0)
|
|
303
|
+
return;
|
|
266
304
|
// Shift key: constrain to axis
|
|
267
305
|
if (event.shiftKey) {
|
|
268
306
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
@@ -272,6 +310,8 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
272
310
|
dx = 0;
|
|
273
311
|
}
|
|
274
312
|
}
|
|
313
|
+
if (dx === 0 && dy === 0)
|
|
314
|
+
return;
|
|
275
315
|
// Alt key + anchor drag: move entire shape
|
|
276
316
|
if (event.altKey && handleType === 'anchor' && this._options.allowShapeDrag !== false) {
|
|
277
317
|
this._dragWholeShape(dx, dy);
|
|
@@ -279,6 +319,7 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
279
319
|
else {
|
|
280
320
|
this._dragSingleHandle(segIndex, handleType, dx, dy);
|
|
281
321
|
}
|
|
322
|
+
this._dragState.geometryChanged = true;
|
|
282
323
|
// Update geometry model
|
|
283
324
|
this._applyGeometryToElement();
|
|
284
325
|
// Update overlay positions in-place (no recreate to preserve pointer capture)
|
|
@@ -572,11 +613,11 @@ export class UnifiedGeometryExtension extends AbstractExtension {
|
|
|
572
613
|
_onPointerUp(event, segIndex) {
|
|
573
614
|
event.stopPropagation();
|
|
574
615
|
event.target.releasePointerCapture(event.pointerId);
|
|
575
|
-
if (this._dragState && this._geometry) {
|
|
616
|
+
if (this._dragState?.geometryChanged && this._geometry) {
|
|
576
617
|
// Commit via designItem for undo support (follows PathExtension pattern)
|
|
577
618
|
this._commitGeometryChange();
|
|
578
|
-
this._dragState = null;
|
|
579
619
|
}
|
|
620
|
+
this._dragState = null;
|
|
580
621
|
}
|
|
581
622
|
// -- Geometry manipulation --
|
|
582
623
|
/** Set attributes directly on the DOM element for live visual feedback during drag */
|