Skip to content

Commit 5974bfc

Browse files
committed
minor #2406 [Map] Fix and improve TypeScript types, refactor same logic into dedicated methods (to reduce file size) (Kocal)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [Map] Fix and improve TypeScript types, refactor same logic into dedicated methods (to reduce file size) | Q | A | ------------- | --- | Bug fix? | no | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT <!-- Replace this notice by a description of your feature/bugfix. This will help reviewers and should be a good start for the documentation. Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - For new features, provide some code snippets to help understand usage. - Features and deprecations must be submitted against branch main. - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry - Never break backward compatibility (see https://symfony.com/bc). --> This PRs is purely internal, and aims to: - Making TypeScript happy by fixing types definitions and usages, but also simplify them - Refactoring methods containing the same logic (ex: `this.create*` or `this....ValueChanged`) methods) to dedicated methods: ```js createMarker(definition) { this.dispatchEvent('marker:before-create', { definition }); const marker = this.doCreateMarker(definition); this.dispatchEvent('marker:after-create', { marker }); marker['`@id`'] = definition['`@id`']; this.markers.set(definition['`@id`'], marker); return marker; } createPolygon(definition) { this.dispatchEvent('polygon:before-create', { definition }); const polygon = this.doCreatePolygon(definition); this.dispatchEvent('polygon:after-create', { polygon }); polygon['`@id`'] = definition['`@id`']; this.polygons.set(definition['`@id`'], polygon); return polygon; } createPolyline(definition) { this.dispatchEvent('polyline:before-create', { definition }); const polyline = this.doCreatePolyline(definition); this.dispatchEvent('polyline:after-create', { polyline }); polyline['`@id`'] = definition['`@id`']; this.polylines.set(definition['`@id`'], polyline); return polyline; } ``` becomes ```js this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this)); this.createPolygon = this.createDrawingFactory('polygon', this.polygons, this.doCreatePolygon.bind(this)); this.createPolyline = this.createDrawingFactory('polyline', this.polylines, this.doCreatePolyline.bind(this)); ``` and ```js markersValueChanged() { if (!this.map) { return; } this.markers.forEach((marker) => { if (!this.markersValue.find((m) => m['`@id`'] === marker['`@id`'])) { this.removeMarker(marker); this.markers.delete(marker['`@id`']); } }); this.markersValue.forEach((marker) => { if (!this.markers.has(marker['`@id`'])) { this.createMarker(marker); } }); if (this.fitBoundsToMarkersValue) { this.doFitBoundsToMarkers(); } } polygonsValueChanged() { if (!this.map) { return; } this.polygons.forEach((polygon) => { if (!this.polygonsValue.find((p) => p['`@id`'] === polygon['`@id`'])) { this.removePolygon(polygon); this.polygons.delete(polygon['`@id`']); } }); this.polygonsValue.forEach((polygon) => { if (!this.polygons.has(polygon['`@id`'])) { this.createPolygon(polygon); } }); } polylinesValueChanged() { if (!this.map) { return; } this.polylines.forEach((polyline) => { if (!this.polylinesValue.find((p) => p['`@id`'] === polyline['`@id`'])) { this.removePolyline(polyline); this.polylines.delete(polyline['`@id`']); } }); this.polylinesValue.forEach((polyline) => { if (!this.polylines.has(polyline['`@id`'])) { this.createPolyline(polyline); } }); } ``` becomes ```js markersValueChanged() { if (!this.isConnected) { return; } this.onDrawChanged(this.markers, this.markersValue, this.createMarker, this.doRemoveMarker); if (this.fitBoundsToMarkersValue) { this.doFitBoundsToMarkers(); } } polygonsValueChanged() { if (!this.isConnected) { return; } this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon); } polylinesValueChanged() { if (!this.isConnected) { return; } this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline); } ``` Commits ------- 1d33a5f [Map] Create "onDrawChanged" to refactor methods "markersValueChanged"/"polygonsValueChanged"/"polylinesValueChanged" (not identical but follow the same pattern) d9d9ff9 [Map] Create "createDrawingFactory" to refactor methods "createMarker"/"createPolyline"/"createPolygon" (not identical but follow the same pattern) a443ad8 [Map] Re-organize methods order, simplify types, don't dirty-append ``@id`` anymore
2 parents dadc81b + 1d33a5f commit 5974bfc

File tree

10 files changed

+576
-566
lines changed

10 files changed

+576
-566
lines changed

src/Map/assets/dist/abstract_map_controller.d.ts

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,31 @@ export type Point = {
33
lat: number;
44
lng: number;
55
};
6-
export type MarkerDefinition<MarkerOptions, InfoWindowOptions> = {
7-
'@id': string;
6+
export type Identifier = string;
7+
export type WithIdentifier<T extends Record<string, unknown>> = T & {
8+
'@id': Identifier;
9+
};
10+
export type MarkerDefinition<MarkerOptions, InfoWindowOptions> = WithIdentifier<{
811
position: Point;
912
title: string | null;
10-
infoWindow?: Omit<InfoWindowDefinition<InfoWindowOptions>, 'position'>;
13+
infoWindow?: InfoWindowWithoutPositionDefinition<InfoWindowOptions>;
1114
rawOptions?: MarkerOptions;
1215
extra: Record<string, unknown>;
13-
};
14-
export type PolygonDefinition<PolygonOptions, InfoWindowOptions> = {
15-
'@id': string;
16-
infoWindow?: Omit<InfoWindowDefinition<InfoWindowOptions>, 'position'>;
16+
}>;
17+
export type PolygonDefinition<PolygonOptions, InfoWindowOptions> = WithIdentifier<{
18+
infoWindow?: InfoWindowWithoutPositionDefinition<InfoWindowOptions>;
1719
points: Array<Point>;
1820
title: string | null;
1921
rawOptions?: PolygonOptions;
2022
extra: Record<string, unknown>;
21-
};
22-
export type PolylineDefinition<PolylineOptions, InfoWindowOptions> = {
23-
'@id': string;
24-
infoWindow?: Omit<InfoWindowDefinition<InfoWindowOptions>, 'position'>;
23+
}>;
24+
export type PolylineDefinition<PolylineOptions, InfoWindowOptions> = WithIdentifier<{
25+
infoWindow?: InfoWindowWithoutPositionDefinition<InfoWindowOptions>;
2526
points: Array<Point>;
2627
title: string | null;
2728
rawOptions?: PolylineOptions;
2829
extra: Record<string, unknown>;
29-
};
30+
}>;
3031
export type InfoWindowDefinition<InfoWindowOptions> = {
3132
headerContent: string | null;
3233
content: string | null;
@@ -36,6 +37,7 @@ export type InfoWindowDefinition<InfoWindowOptions> = {
3637
rawOptions?: InfoWindowOptions;
3738
extra: Record<string, unknown>;
3839
};
40+
export type InfoWindowWithoutPositionDefinition<InfoWindowOptions> = Omit<InfoWindowDefinition<InfoWindowOptions>, 'position'>;
3941
export default abstract class<MapOptions, Map, MarkerOptions, Marker, InfoWindowOptions, InfoWindow, PolygonOptions, Polygon, PolylineOptions, Polyline> extends Controller<HTMLElement> {
4042
static values: {
4143
providerOptions: ObjectConstructor;
@@ -55,50 +57,47 @@ export default abstract class<MapOptions, Map, MarkerOptions, Marker, InfoWindow
5557
polylinesValue: Array<PolylineDefinition<PolylineOptions, InfoWindowOptions>>;
5658
optionsValue: MapOptions;
5759
protected map: Map;
58-
protected markers: globalThis.Map<any, any>;
60+
protected markers: globalThis.Map<string, Marker>;
61+
protected polygons: globalThis.Map<string, Polygon>;
62+
protected polylines: globalThis.Map<string, Polyline>;
5963
protected infoWindows: Array<InfoWindow>;
60-
protected polygons: globalThis.Map<any, any>;
61-
protected polylines: globalThis.Map<any, any>;
64+
private isConnected;
65+
private createMarker;
66+
private createPolygon;
67+
private createPolyline;
68+
protected abstract dispatchEvent(name: string, payload: Record<string, unknown>): void;
6269
connect(): void;
70+
createInfoWindow({ definition, element, }: {
71+
definition: InfoWindowWithoutPositionDefinition<InfoWindowOptions>;
72+
element: Marker | Polygon | Polyline;
73+
}): InfoWindow;
74+
abstract centerValueChanged(): void;
75+
abstract zoomValueChanged(): void;
76+
markersValueChanged(): void;
77+
polygonsValueChanged(): void;
78+
polylinesValueChanged(): void;
6379
protected abstract doCreateMap({ center, zoom, options, }: {
6480
center: Point | null;
6581
zoom: number | null;
6682
options: MapOptions;
6783
}): Map;
68-
createMarker(definition: MarkerDefinition<MarkerOptions, InfoWindowOptions>): Marker;
69-
protected abstract removeMarker(marker: Marker): void;
70-
protected abstract doCreateMarker(definition: MarkerDefinition<MarkerOptions, InfoWindowOptions>): Marker;
71-
createPolygon(definition: PolygonDefinition<PolygonOptions, InfoWindowOptions>): Polygon;
72-
protected abstract removePolygon(polygon: Polygon): void;
73-
protected abstract doCreatePolygon(definition: PolygonDefinition<PolygonOptions, InfoWindowOptions>): Polygon;
74-
createPolyline(definition: PolylineDefinition<PolylineOptions, InfoWindowOptions>): Polyline;
75-
protected abstract removePolyline(polyline: Polyline): void;
76-
protected abstract doCreatePolyline(definition: PolylineDefinition<PolylineOptions, InfoWindowOptions>): Polyline;
77-
protected createInfoWindow({ definition, element, }: {
78-
definition: MarkerDefinition<MarkerOptions, InfoWindowOptions>['infoWindow'];
79-
element: Marker;
80-
} | {
81-
definition: PolygonDefinition<PolygonOptions, InfoWindowOptions>['infoWindow'];
82-
element: Polygon;
83-
} | {
84-
definition: PolylineDefinition<PolylineOptions, InfoWindowOptions>['infoWindow'];
85-
element: Polyline;
86-
}): InfoWindow;
84+
protected abstract doFitBoundsToMarkers(): void;
85+
protected abstract doCreateMarker({ definition, }: {
86+
definition: MarkerDefinition<MarkerOptions, InfoWindowOptions>;
87+
}): Marker;
88+
protected abstract doRemoveMarker(marker: Marker): void;
89+
protected abstract doCreatePolygon({ definition, }: {
90+
definition: PolygonDefinition<PolygonOptions, InfoWindowOptions>;
91+
}): Polygon;
92+
protected abstract doRemovePolygon(polygon: Polygon): void;
93+
protected abstract doCreatePolyline({ definition, }: {
94+
definition: PolylineDefinition<PolylineOptions, InfoWindowOptions>;
95+
}): Polyline;
96+
protected abstract doRemovePolyline(polyline: Polyline): void;
8797
protected abstract doCreateInfoWindow({ definition, element, }: {
88-
definition: MarkerDefinition<MarkerOptions, InfoWindowOptions>['infoWindow'];
89-
element: Marker;
90-
} | {
91-
definition: PolygonDefinition<PolygonOptions, InfoWindowOptions>['infoWindow'];
92-
element: Polygon;
93-
} | {
94-
definition: PolylineDefinition<PolylineOptions, InfoWindowOptions>['infoWindow'];
95-
element: Polyline;
98+
definition: InfoWindowWithoutPositionDefinition<InfoWindowOptions>;
99+
element: Marker | Polygon | Polyline;
96100
}): InfoWindow;
97-
protected abstract doFitBoundsToMarkers(): void;
98-
protected abstract dispatchEvent(name: string, payload: Record<string, unknown>): void;
99-
abstract centerValueChanged(): void;
100-
abstract zoomValueChanged(): void;
101-
markersValueChanged(): void;
102-
polygonsValueChanged(): void;
103-
polylinesValueChanged(): void;
101+
private createDrawingFactory;
102+
private onDrawChanged;
104103
}

src/Map/assets/dist/abstract_map_controller.js

Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ class default_1 extends Controller {
44
constructor() {
55
super(...arguments);
66
this.markers = new Map();
7-
this.infoWindows = [];
87
this.polygons = new Map();
98
this.polylines = new Map();
9+
this.infoWindows = [];
10+
this.isConnected = false;
1011
}
1112
connect() {
1213
const options = this.optionsValue;
1314
this.dispatchEvent('pre-connect', { options });
15+
this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this));
16+
this.createPolygon = this.createDrawingFactory('polygon', this.polygons, this.doCreatePolygon.bind(this));
17+
this.createPolyline = this.createDrawingFactory('polyline', this.polylines, this.doCreatePolyline.bind(this));
1418
this.map = this.doCreateMap({ center: this.centerValue, zoom: this.zoomValue, options });
15-
this.markersValue.forEach((marker) => this.createMarker(marker));
16-
this.polygonsValue.forEach((polygon) => this.createPolygon(polygon));
17-
this.polylinesValue.forEach((polyline) => this.createPolyline(polyline));
19+
this.markersValue.forEach((definition) => this.createMarker({ definition }));
20+
this.polygonsValue.forEach((definition) => this.createPolygon({ definition }));
21+
this.polylinesValue.forEach((definition) => this.createPolyline({ definition }));
1822
if (this.fitBoundsToMarkersValue) {
1923
this.doFitBoundsToMarkers();
2024
}
@@ -25,30 +29,7 @@ class default_1 extends Controller {
2529
polylines: [...this.polylines.values()],
2630
infoWindows: this.infoWindows,
2731
});
28-
}
29-
createMarker(definition) {
30-
this.dispatchEvent('marker:before-create', { definition });
31-
const marker = this.doCreateMarker(definition);
32-
this.dispatchEvent('marker:after-create', { marker });
33-
marker['@id'] = definition['@id'];
34-
this.markers.set(definition['@id'], marker);
35-
return marker;
36-
}
37-
createPolygon(definition) {
38-
this.dispatchEvent('polygon:before-create', { definition });
39-
const polygon = this.doCreatePolygon(definition);
40-
this.dispatchEvent('polygon:after-create', { polygon });
41-
polygon['@id'] = definition['@id'];
42-
this.polygons.set(definition['@id'], polygon);
43-
return polygon;
44-
}
45-
createPolyline(definition) {
46-
this.dispatchEvent('polyline:before-create', { definition });
47-
const polyline = this.doCreatePolyline(definition);
48-
this.dispatchEvent('polyline:after-create', { polyline });
49-
polyline['@id'] = definition['@id'];
50-
this.polylines.set(definition['@id'], polyline);
51-
return polyline;
32+
this.isConnected = true;
5233
}
5334
createInfoWindow({ definition, element, }) {
5435
this.dispatchEvent('info-window:before-create', { definition, element });
@@ -58,53 +39,50 @@ class default_1 extends Controller {
5839
return infoWindow;
5940
}
6041
markersValueChanged() {
61-
if (!this.map) {
42+
if (!this.isConnected) {
6243
return;
6344
}
64-
this.markers.forEach((marker) => {
65-
if (!this.markersValue.find((m) => m['@id'] === marker['@id'])) {
66-
this.removeMarker(marker);
67-
this.markers.delete(marker['@id']);
68-
}
69-
});
70-
this.markersValue.forEach((marker) => {
71-
if (!this.markers.has(marker['@id'])) {
72-
this.createMarker(marker);
73-
}
74-
});
45+
this.onDrawChanged(this.markers, this.markersValue, this.createMarker, this.doRemoveMarker);
7546
if (this.fitBoundsToMarkersValue) {
7647
this.doFitBoundsToMarkers();
7748
}
7849
}
7950
polygonsValueChanged() {
80-
if (!this.map) {
51+
if (!this.isConnected) {
8152
return;
8253
}
83-
this.polygons.forEach((polygon) => {
84-
if (!this.polygonsValue.find((p) => p['@id'] === polygon['@id'])) {
85-
this.removePolygon(polygon);
86-
this.polygons.delete(polygon['@id']);
87-
}
88-
});
89-
this.polygonsValue.forEach((polygon) => {
90-
if (!this.polygons.has(polygon['@id'])) {
91-
this.createPolygon(polygon);
92-
}
93-
});
54+
this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon);
9455
}
9556
polylinesValueChanged() {
96-
if (!this.map) {
57+
if (!this.isConnected) {
9758
return;
9859
}
99-
this.polylines.forEach((polyline) => {
100-
if (!this.polylinesValue.find((p) => p['@id'] === polyline['@id'])) {
101-
this.removePolyline(polyline);
102-
this.polylines.delete(polyline['@id']);
103-
}
60+
this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
61+
}
62+
createDrawingFactory(type, draws, factory) {
63+
const eventBefore = `${type}:before-create`;
64+
const eventAfter = `${type}:after-create`;
65+
return ({ definition }) => {
66+
this.dispatchEvent(eventBefore, { definition });
67+
const drawing = factory({ definition });
68+
this.dispatchEvent(eventAfter, { [type]: drawing });
69+
draws.set(definition['@id'], drawing);
70+
return drawing;
71+
};
72+
}
73+
onDrawChanged(draws, newDrawDefinitions, factory, remover) {
74+
const idsToRemove = new Set(draws.keys());
75+
newDrawDefinitions.forEach((definition) => {
76+
idsToRemove.delete(definition['@id']);
77+
});
78+
idsToRemove.forEach((id) => {
79+
const draw = draws.get(id);
80+
remover(draw);
81+
draws.delete(id);
10482
});
105-
this.polylinesValue.forEach((polyline) => {
106-
if (!this.polylines.has(polyline['@id'])) {
107-
this.createPolyline(polyline);
83+
newDrawDefinitions.forEach((definition) => {
84+
if (!draws.has(definition['@id'])) {
85+
factory({ definition });
10886
}
10987
});
11088
}

0 commit comments

Comments
 (0)