1 OSM.HistoryChangesetBboxLayer = L.FeatureGroup.extend({
 
   2   getLayerId: function (layer) {
 
   6   addChangesetLayer: function (changeset) {
 
   7     const style = this._getChangesetStyle(changeset);
 
   8     const rectangle = L.rectangle(changeset.bounds, {
 
  12         text: OSM.i18n.t("javascripts.context.scroll_to_changeset"),
 
  14           this.fire("requestscrolltochangeset", { id: changeset.id }, true);
 
  22     rectangle.id = changeset.id;
 
  23     rectangle.on("click", function (e) {
 
  24       OSM.router.click(e.originalEvent, $(`#changeset_${changeset.id} a.changeset_id`).attr("href"));
 
  26     return this.addLayer(rectangle);
 
  29   updateChangesetLayerBounds: function (changeset) {
 
  30     this.getLayer(changeset.id)?.setBounds(changeset.bounds);
 
  33   _getSidebarRelativeClassName: function ({ sidebarRelativePosition }) {
 
  34     if (sidebarRelativePosition > 0) {
 
  35       return "changeset-above-sidebar-viewport";
 
  36     } else if (sidebarRelativePosition < 0) {
 
  37       return "changeset-below-sidebar-viewport";
 
  39       return "changeset-in-sidebar-viewport";
 
  44 OSM.HistoryChangesetBboxAreaLayer = OSM.HistoryChangesetBboxLayer.extend({
 
  45   _getChangesetStyle: function (changeset) {
 
  49       className: this._getSidebarRelativeClassName(changeset)
 
  54 OSM.HistoryChangesetBboxOutlineLayer = OSM.HistoryChangesetBboxLayer.extend({
 
  55   _getChangesetStyle: function (changeset) {
 
  58       color: "var(--changeset-outline-color)",
 
  60       className: this._getSidebarRelativeClassName(changeset)
 
  65 OSM.HistoryChangesetBboxBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
 
  66   _getChangesetStyle: function (changeset) {
 
  69       color: "var(--changeset-border-color)",
 
  71       className: this._getSidebarRelativeClassName(changeset)
 
  76 OSM.HistoryChangesetBboxHighlightAreaLayer = OSM.HistoryChangesetBboxLayer.extend({
 
  77   _getChangesetStyle: function (changeset) {
 
  81       fillColor: "var(--changeset-fill-color)",
 
  83       className: this._getSidebarRelativeClassName(changeset)
 
  88 OSM.HistoryChangesetBboxHighlightOutlineLayer = OSM.HistoryChangesetBboxLayer.extend({
 
  89   _getChangesetStyle: function (changeset) {
 
  92       weight: changeset.sidebarRelativePosition === 0 ? 8 : 6,
 
  93       color: "var(--changeset-outline-color)",
 
  95       className: this._getSidebarRelativeClassName(changeset) + " changeset-highlight-outline"
 
 100 OSM.HistoryChangesetBboxHighlightBorderLayer = OSM.HistoryChangesetBboxLayer.extend({
 
 101   _getChangesetStyle: function (changeset) {
 
 105       color: "var(--changeset-border-color)",
 
 107       className: this._getSidebarRelativeClassName(changeset)
 
 112 OSM.HistoryChangesetsLayer = L.FeatureGroup.extend({
 
 113   updateChangesets: function (map, changesets) {
 
 114     this._changesets = new Map(changesets.map(changeset => [changeset.id, changeset]));
 
 115     this.updateChangesetsGeometry(map);
 
 118   updateChangesetsGeometry: function (map) {
 
 119     const changesetSizeLowerBound = 20, // Min width/height of changeset in pixels
 
 120           mapViewExpansion = 2; // Half of bbox border+outline width in pixels
 
 122     const mapViewCenterLng = map.getCenter().lng,
 
 123           mapViewPixelBounds = map.getPixelBounds();
 
 125     mapViewPixelBounds.min.x -= mapViewExpansion;
 
 126     mapViewPixelBounds.min.y -= mapViewExpansion;
 
 127     mapViewPixelBounds.max.x += mapViewExpansion;
 
 128     mapViewPixelBounds.max.y += mapViewExpansion;
 
 130     for (const changeset of this._changesets.values()) {
 
 131       const changesetNorthWestLatLng = L.latLng(changeset.bbox.maxlat, changeset.bbox.minlon),
 
 132             changesetSouthEastLatLng = L.latLng(changeset.bbox.minlat, changeset.bbox.maxlon),
 
 133             changesetCenterLng = (changesetNorthWestLatLng.lng + changesetSouthEastLatLng.lng) / 2,
 
 134             shiftInWorldCircumferences = Math.round((changesetCenterLng - mapViewCenterLng) / 360);
 
 136       if (shiftInWorldCircumferences) {
 
 137         changesetNorthWestLatLng.lng -= shiftInWorldCircumferences * 360;
 
 138         changesetSouthEastLatLng.lng -= shiftInWorldCircumferences * 360;
 
 141       const changesetMinCorner = map.project(changesetNorthWestLatLng),
 
 142             changesetMaxCorner = map.project(changesetSouthEastLatLng),
 
 143             changesetSizeX = changesetMaxCorner.x - changesetMinCorner.x,
 
 144             changesetSizeY = changesetMaxCorner.y - changesetMinCorner.y;
 
 146       if (changesetSizeX < changesetSizeLowerBound) {
 
 147         changesetMinCorner.x -= (changesetSizeLowerBound - changesetSizeX) / 2;
 
 148         changesetMaxCorner.x += (changesetSizeLowerBound - changesetSizeX) / 2;
 
 151       if (changesetSizeY < changesetSizeLowerBound) {
 
 152         changesetMinCorner.y -= (changesetSizeLowerBound - changesetSizeY) / 2;
 
 153         changesetMaxCorner.y += (changesetSizeLowerBound - changesetSizeY) / 2;
 
 156       changeset.bounds = L.latLngBounds(map.unproject(changesetMinCorner),
 
 157                                         map.unproject(changesetMaxCorner));
 
 159       const changesetPixelBounds = L.bounds(changesetMinCorner, changesetMaxCorner);
 
 161       changeset.hasEdgesInMapView = changesetPixelBounds.overlaps(mapViewPixelBounds) &&
 
 162                                     !changesetPixelBounds.contains(mapViewPixelBounds);
 
 165     this.updateChangesetsOrder();
 
 168   updateChangesetsOrder: function () {
 
 169     const changesetEntries = [...this._changesets];
 
 170     changesetEntries.sort(([, a], [, b]) => b.bounds.getSize() - a.bounds.getSize());
 
 171     this._changesets = new Map(changesetEntries);
 
 173     for (const layer of this._bboxLayers) {
 
 177     for (const changeset of this._changesets.values()) {
 
 178       if (changeset.sidebarRelativePosition !== 0 && changeset.hasEdgesInMapView) {
 
 179         this._areaLayer.addChangesetLayer(changeset);
 
 183     for (const changeset of this._changesets.values()) {
 
 184       if (changeset.sidebarRelativePosition === 0 && changeset.hasEdgesInMapView) {
 
 185         this._areaLayer.addChangesetLayer(changeset);
 
 189     for (const changeset of this._changesets.values()) {
 
 190       if (changeset.sidebarRelativePosition !== 0) {
 
 191         this._borderLayer.addChangesetLayer(changeset);
 
 195     for (const changeset of this._changesets.values()) {
 
 196       if (changeset.sidebarRelativePosition === 0) {
 
 197         this._outlineLayer.addChangesetLayer(changeset);
 
 201     for (const changeset of this._changesets.values()) {
 
 202       if (changeset.sidebarRelativePosition === 0) {
 
 203         this._borderLayer.addChangesetLayer(changeset);
 
 208   toggleChangesetHighlight: function (id, state) {
 
 209     const changeset = this._changesets.get(id);
 
 210     if (!changeset) return;
 
 212     this._highlightAreaLayer.clearLayers();
 
 213     this._highlightOutlineLayer.clearLayers();
 
 214     this._highlightBorderLayer.clearLayers();
 
 217       this._highlightAreaLayer.addChangesetLayer(changeset);
 
 218       this._highlightOutlineLayer.addChangesetLayer(changeset);
 
 219       this._highlightBorderLayer.addChangesetLayer(changeset);
 
 223   setChangesetSidebarRelativePosition: function (id, state) {
 
 224     const changeset = this._changesets.get(id);
 
 225     if (!changeset) return;
 
 226     changeset.sidebarRelativePosition = state;
 
 230 OSM.HistoryChangesetsLayer.addInitHook(function () {
 
 231   this._changesets = new Map;
 
 234     this._areaLayer = new OSM.HistoryChangesetBboxAreaLayer().addTo(this),
 
 235     this._outlineLayer = new OSM.HistoryChangesetBboxOutlineLayer().addTo(this),
 
 236     this._borderLayer = new OSM.HistoryChangesetBboxBorderLayer().addTo(this),
 
 237     this._highlightAreaLayer = new OSM.HistoryChangesetBboxHighlightAreaLayer().addTo(this),
 
 238     this._highlightOutlineLayer = new OSM.HistoryChangesetBboxHighlightOutlineLayer().addTo(this),
 
 239     this._highlightBorderLayer = new OSM.HistoryChangesetBboxHighlightBorderLayer().addTo(this)