]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/history-changesets-layer.js
Remove unnecessary event.preventDefault() from "Add Social Link"
[rails.git] / app / assets / javascripts / index / history-changesets-layer.js
1 OSM.HistoryChangesetBboxLayer = L.FeatureGroup.extend({
2   getLayerId: function (layer) {
3     return layer.id;
4   },
5
6   addChangesetLayer: function (changeset) {
7     const style = this._getChangesetStyle(changeset);
8     const rectangle = L.rectangle(changeset.bounds, {
9       ...style,
10       contextmenu: true,
11       contextmenuItems: [{
12         text: OSM.i18n.t("javascripts.context.scroll_to_changeset"),
13         callback: () => {
14           this.fire("requestscrolltochangeset", { id: changeset.id }, true);
15         },
16         index: 0
17       }, {
18         separator: true,
19         index: 1
20       }]
21     });
22     rectangle.id = changeset.id;
23     return this.addLayer(rectangle);
24   },
25
26   updateChangesetLayerBounds: function (changeset) {
27     this.getLayer(changeset.id)?.setBounds(changeset.bounds);
28   },
29
30   _getSidebarRelativeClassName: function ({ sidebarRelativePosition }) {
31     if (sidebarRelativePosition > 0) {
32       return "changeset-above-sidebar-viewport";
33     } else if (sidebarRelativePosition < 0) {
34       return "changeset-below-sidebar-viewport";
35     } else {
36       return "changeset-in-sidebar-viewport";
37     }
38   }
39 });
40
41 OSM.HistoryChangesetBboxAreaLayer = OSM.HistoryChangesetBboxLayer.extend({
42   _getChangesetStyle: function (changeset) {
43     return {
44       stroke: false,
45       fillOpacity: 0,
46       className: this._getSidebarRelativeClassName(changeset)
47     };
48   }
49 });
50
51 OSM.HistoryChangesetBboxOutlineLayer = OSM.HistoryChangesetBboxLayer.extend({
52   _getChangesetStyle: function (changeset) {
53     return {
54       weight: 4,
55       color: "var(--changeset-outline-color)",
56       fill: false,
57       className: this._getSidebarRelativeClassName(changeset)
58     };
59   }
60 });
61
62 OSM.HistoryChangesetBboxBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
63   _getChangesetStyle: function (changeset) {
64     return {
65       weight: 2,
66       color: "var(--changeset-border-color)",
67       fill: false,
68       className: this._getSidebarRelativeClassName(changeset)
69     };
70   }
71 });
72
73 OSM.HistoryChangesetBboxHighlightAreaLayer = OSM.HistoryChangesetBboxLayer.extend({
74   _getChangesetStyle: function (changeset) {
75     return {
76       interactive: false,
77       stroke: false,
78       fillColor: "var(--changeset-fill-color)",
79       fillOpacity: 0.3,
80       className: this._getSidebarRelativeClassName(changeset)
81     };
82   }
83 });
84
85 OSM.HistoryChangesetBboxHighlightOutlineLayer = OSM.HistoryChangesetBboxLayer.extend({
86   _getChangesetStyle: function (changeset) {
87     return {
88       interactive: false,
89       weight: changeset.sidebarRelativePosition === 0 ? 8 : 6,
90       color: "var(--changeset-outline-color)",
91       fill: false,
92       className: this._getSidebarRelativeClassName(changeset) + " changeset-highlight-outline"
93     };
94   }
95 });
96
97 OSM.HistoryChangesetBboxHighlightBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
98   _getChangesetStyle: function (changeset) {
99     return {
100       interactive: false,
101       weight: 4,
102       color: "var(--changeset-border-color)",
103       fill: false,
104       className: this._getSidebarRelativeClassName(changeset)
105     };
106   }
107 });
108
109 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
110   updateChangesets: function (map, changesets) {
111     this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
112     this.updateChangesetsGeometry(map);
113   },
114
115   updateChangesetsGeometry: function (map) {
116     const changesetSizeLowerBound = 20, // Min width/height of changeset in pixels
117           mapViewExpansion = 2; // Half of bbox border+outline width in pixels
118
119     const mapViewCenterLng = map.getCenter().lng,
120           mapViewPixelBounds = map.getPixelBounds();
121
122     mapViewPixelBounds.min.x -= mapViewExpansion;
123     mapViewPixelBounds.min.y -= mapViewExpansion;
124     mapViewPixelBounds.max.x += mapViewExpansion;
125     mapViewPixelBounds.max.y += mapViewExpansion;
126
127     for (const changeset of this._changesets.values()) {
128       const changesetNorthWestLatLng = L.latLng(changeset.bbox.maxlat, changeset.bbox.minlon),
129             changesetSouthEastLatLng = L.latLng(changeset.bbox.minlat, changeset.bbox.maxlon),
130             changesetCenterLng = (changesetNorthWestLatLng.lng + changesetSouthEastLatLng.lng) / 2,
131             shiftInWorldCircumferences = Math.round((changesetCenterLng - mapViewCenterLng) / 360);
132
133       if (shiftInWorldCircumferences) {
134         changesetNorthWestLatLng.lng -= shiftInWorldCircumferences * 360;
135         changesetSouthEastLatLng.lng -= shiftInWorldCircumferences * 360;
136       }
137
138       const changesetMinCorner = map.project(changesetNorthWestLatLng),
139             changesetMaxCorner = map.project(changesetSouthEastLatLng),
140             changesetSizeX = changesetMaxCorner.x - changesetMinCorner.x,
141             changesetSizeY = changesetMaxCorner.y - changesetMinCorner.y;
142
143       if (changesetSizeX < changesetSizeLowerBound) {
144         changesetMinCorner.x -= (changesetSizeLowerBound - changesetSizeX) / 2;
145         changesetMaxCorner.x += (changesetSizeLowerBound - changesetSizeX) / 2;
146       }
147
148       if (changesetSizeY < changesetSizeLowerBound) {
149         changesetMinCorner.y -= (changesetSizeLowerBound - changesetSizeY) / 2;
150         changesetMaxCorner.y += (changesetSizeLowerBound - changesetSizeY) / 2;
151       }
152
153       changeset.bounds = L.latLngBounds(map.unproject(changesetMinCorner),
154                                         map.unproject(changesetMaxCorner));
155
156       const changesetPixelBounds = L.bounds(changesetMinCorner, changesetMaxCorner);
157
158       changeset.hasEdgesInMapView = changesetPixelBounds.overlaps(mapViewPixelBounds) &&
159                                     !changesetPixelBounds.contains(mapViewPixelBounds);
160     }
161
162     this.updateChangesetsOrder();
163   },
164
165   updateChangesetsOrder: function () {
166     const changesetEntries = [...this._changesets];
167     changesetEntries.sort(([, a], [, b]) => b.bounds.getSize() - a.bounds.getSize());
168     this._changesets = new Map(changesetEntries);
169
170     for (const layer of this._bboxLayers) {
171       layer.clearLayers();
172     }
173
174     for (const changeset of this._changesets.values()) {
175       if (changeset.sidebarRelativePosition !== 0 && changeset.hasEdgesInMapView) {
176         this._areaLayer.addChangesetLayer(changeset);
177       }
178     }
179
180     for (const changeset of this._changesets.values()) {
181       if (changeset.sidebarRelativePosition === 0 && changeset.hasEdgesInMapView) {
182         this._areaLayer.addChangesetLayer(changeset);
183       }
184     }
185
186     for (const changeset of this._changesets.values()) {
187       if (changeset.sidebarRelativePosition !== 0) {
188         this._borderLayer.addChangesetLayer(changeset);
189       }
190     }
191
192     for (const changeset of this._changesets.values()) {
193       if (changeset.sidebarRelativePosition === 0) {
194         this._outlineLayer.addChangesetLayer(changeset);
195       }
196     }
197
198     for (const changeset of this._changesets.values()) {
199       if (changeset.sidebarRelativePosition === 0) {
200         this._borderLayer.addChangesetLayer(changeset);
201       }
202     }
203   },
204
205   toggleChangesetHighlight: function (id, state) {
206     const changeset = this._changesets.get(id);
207     if (!changeset) return;
208
209     this._highlightAreaLayer.clearLayers();
210     this._highlightOutlineLayer.clearLayers();
211     this._highlightBorderLayer.clearLayers();
212
213     if (state) {
214       this._highlightAreaLayer.addChangesetLayer(changeset);
215       this._highlightOutlineLayer.addChangesetLayer(changeset);
216       this._highlightBorderLayer.addChangesetLayer(changeset);
217     }
218   },
219
220   setChangesetSidebarRelativePosition: function (id, state) {
221     const changeset = this._changesets.get(id);
222     if (!changeset) return;
223     changeset.sidebarRelativePosition = state;
224   }
225 });
226
227 OSM.HistoryChangesetsLayer.addInitHook(function () {
228   this._changesets = new Map;
229
230   this._bboxLayers = [
231     this._areaLayer = new OSM.HistoryChangesetBboxAreaLayer().addTo(this),
232     this._outlineLayer = new OSM.HistoryChangesetBboxOutlineLayer().addTo(this),
233     this._borderLayer = new OSM.HistoryChangesetBboxBorderLayer().addTo(this),
234     this._highlightAreaLayer = new OSM.HistoryChangesetBboxHighlightAreaLayer().addTo(this),
235     this._highlightOutlineLayer = new OSM.HistoryChangesetBboxHighlightOutlineLayer().addTo(this),
236     this._highlightBorderLayer = new OSM.HistoryChangesetBboxHighlightBorderLayer().addTo(this)
237   ];
238 });