]> git.openstreetmap.org Git - rails.git/blobdiff - app/assets/javascripts/index/history.js
Put map key presence in js layer definitions
[rails.git] / app / assets / javascripts / index / history.js
index 9f883367a799393be5cc2d2b3a20dfbda48271e7..05877784035fba11cb621125ebca2e13f4a6a88b 100644 (file)
@@ -1,4 +1,5 @@
 //= require jquery-simulate/jquery.simulate
+//= require ./history-changesets-layer
 
 OSM.History = function (map) {
   const page = {};
@@ -12,7 +13,7 @@ OSM.History = function (map) {
       unHighlightChangeset($(this).data("changeset").id);
     });
 
-  const group = L.featureGroup()
+  const changesetsLayer = new OSM.HistoryChangesetsLayer()
     .on("mouseover", function (e) {
       highlightChangeset(e.layer.id);
     })
@@ -23,10 +24,6 @@ OSM.History = function (map) {
       clickChangeset(e.layer.id, e.originalEvent);
     });
 
-  group.getLayerId = function (layer) {
-    return layer.id;
-  };
-
   let changesetIntersectionObserver;
 
   function disableChangesetIntersectionObserver() {
@@ -87,14 +84,12 @@ OSM.History = function (map) {
   }
 
   function highlightChangeset(id) {
-    const layer = group.getLayer(id);
-    if (layer) layer.setStyle({ fillOpacity: 0.3, color: "#FF6600", weight: 3 });
+    changesetsLayer.highlightChangeset(id);
     $("#changeset_" + id).addClass("selected");
   }
 
   function unHighlightChangeset(id) {
-    const layer = group.getLayer(id);
-    if (layer) layer.setStyle({ fillOpacity: 0, color: "#FF9500", weight: 2 });
+    changesetsLayer.unHighlightChangeset(id);
     $("#changeset_" + id).removeClass("selected");
   }
 
@@ -104,6 +99,10 @@ OSM.History = function (map) {
 
   function displayFirstChangesets(html) {
     $("#sidebar_content .changesets").html(html);
+
+    if (location.pathname === "/history") {
+      setPaginationMapHashes();
+    }
   }
 
   function displayMoreChangesets(div, html) {
@@ -130,29 +129,34 @@ OSM.History = function (map) {
       nextNewList.children().appendTo(oldList);
       nextNewList.remove();
     }
+
+    if (location.pathname === "/history") {
+      setPaginationMapHashes();
+    }
+  }
+
+  function setPaginationMapHashes() {
+    $("#sidebar .pagination a").each(function () {
+      $(this).prop("hash", OSM.formatHash({
+        center: map.getCenter(),
+        zoom: map.getZoom()
+      }));
+    });
   }
 
   function loadFirstChangesets() {
     const data = new URLSearchParams();
-    const params = new URLSearchParams(location.search);
 
     disableChangesetIntersectionObserver();
 
     if (location.pathname === "/history") {
-      data.set("bbox", map.getBounds().wrap().toBBoxString());
+      setBboxFetchData(data);
       const feedLink = $("link[type=\"application/atom+xml\"]"),
             feedHref = feedLink.attr("href").split("?")[0];
       feedLink.attr("href", feedHref + "?" + data);
     }
 
-    data.set("list", "1");
-
-    if (params.has("before")) {
-      data.set("before", params.get("before"));
-    }
-    if (params.has("after")) {
-      data.set("after", params.get("after"));
-    }
+    setListFetchData(data, location);
 
     fetch(location.pathname + "?" + data)
       .then(response => response.text())
@@ -160,13 +164,15 @@ OSM.History = function (map) {
         displayFirstChangesets(html);
         enableChangesetIntersectionObserver();
 
-        if (params.has("before")) {
+        if (data.has("before")) {
           const [firstItem] = $("#sidebar_content .changesets ol").children().first();
           firstItem?.scrollIntoView();
-        }
-        if (params.has("after")) {
+        } else if (data.has("after")) {
           const [lastItem] = $("#sidebar_content .changesets ol").children().last();
           lastItem?.scrollIntoView(false);
+        } else {
+          const [sidebar] = $("#sidebar");
+          sidebar.scrollTop = 0;
         }
 
         updateMap();
@@ -179,70 +185,77 @@ OSM.History = function (map) {
 
     const div = $(this).parents(".changeset_more");
 
-    $(this).hide();
-    div.find(".loader").show();
-
-    $.get($(this).attr("href"), function (html) {
-      displayMoreChangesets(div, html);
-      enableChangesetIntersectionObserver();
-      updateMap();
-    });
-  }
+    div.find(".pagination").addClass("invisible");
+    div.find("[hidden]").prop("hidden", false);
 
-  function reloadChangesetsBecauseOfMapMovement() {
-    OSM.router.replace("/history" + window.location.hash);
-    loadFirstChangesets();
-  }
+    const data = new URLSearchParams();
 
-  let changesets = [];
+    if (location.pathname === "/history") {
+      setBboxFetchData(data);
+    }
 
-  function updateBounds() {
-    group.clearLayers();
+    const url = new URL($(this).attr("href"), location);
+    setListFetchData(data, url);
 
-    for (const changeset of changesets) {
-      const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
-            topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
-            width = topRight.x - bottomLeft.x,
-            height = bottomLeft.y - topRight.y,
-            minSize = 20; // Min width/height of changeset in pixels
+    fetch(url.pathname + "?" + data)
+      .then(response => response.text())
+      .then(function (html) {
+        displayMoreChangesets(div, html);
+        enableChangesetIntersectionObserver();
 
-      if (width < minSize) {
-        bottomLeft.x -= ((minSize - width) / 2);
-        topRight.x += ((minSize - width) / 2);
-      }
+        updateMap();
+      });
+  }
 
-      if (height < minSize) {
-        bottomLeft.y += ((minSize - height) / 2);
-        topRight.y -= ((minSize - height) / 2);
-      }
+  function setBboxFetchData(data) {
+    const crs = map.options.crs;
+    const sw = map.getBounds().getSouthWest();
+    const ne = map.getBounds().getNorthEast();
+    const swClamped = crs.unproject(crs.project(sw));
+    const neClamped = crs.unproject(crs.project(ne));
 
-      changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
-                                        map.unproject(topRight));
+    if (sw.lat >= swClamped.lat || ne.lat <= neClamped.lat || ne.lng - sw.lng < 360) {
+      data.set("bbox", map.getBounds().toBBoxString());
     }
+  }
 
-    changesets.sort(function (a, b) {
-      return b.bounds.getSize() - a.bounds.getSize();
-    });
+  function setListFetchData(data, url) {
+    const params = new URLSearchParams(url.search);
+
+    data.set("list", "1");
+
+    if (params.has("before")) {
+      data.set("before", params.get("before"));
+    }
+    if (params.has("after")) {
+      data.set("after", params.get("after"));
+    }
+  }
 
-    for (const changeset of changesets) {
-      const rect = L.rectangle(changeset.bounds,
-                               { weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFAF", fillOpacity: 0 });
-      rect.id = changeset.id;
-      rect.addTo(group);
+  function moveEndListener() {
+    if (location.pathname === "/history") {
+      OSM.router.replace("/history" + window.location.hash);
+      loadFirstChangesets();
+    } else {
+      changesetsLayer.updateChangesetsPositions(map);
     }
   }
 
+  function zoomEndListener() {
+    changesetsLayer.updateChangesetShapes(map);
+  }
+
   function updateMap() {
-    changesets = $("[data-changeset]").map(function (index, element) {
+    const changesets = $("[data-changeset]").map(function (index, element) {
       return $(element).data("changeset");
     }).get().filter(function (changeset) {
       return changeset.bbox;
     });
 
-    updateBounds();
+    changesetsLayer.updateChangesets(map, changesets);
 
     if (location.pathname !== "/history") {
-      const bounds = group.getBounds();
+      const bounds = changesetsLayer.getBounds();
       if (bounds.isValid()) map.fitBounds(bounds);
     }
   }
@@ -252,21 +265,16 @@ OSM.History = function (map) {
   };
 
   page.load = function () {
-    map.addLayer(group);
-
-    if (location.pathname === "/history") {
-      map.on("moveend", reloadChangesetsBecauseOfMapMovement);
-    }
-
-    map.on("zoomend", updateBounds);
-
+    map.addLayer(changesetsLayer);
+    map.on("moveend", moveEndListener);
+    map.on("zoomend", zoomEndListener);
     loadFirstChangesets();
   };
 
   page.unload = function () {
-    map.removeLayer(group);
-    map.off("moveend", reloadChangesetsBecauseOfMapMovement);
-    map.off("zoomend", updateBounds);
+    map.removeLayer(changesetsLayer);
+    map.off("moveend", moveEndListener);
+    map.off("zoomend", zoomEndListener);
     disableChangesetIntersectionObserver();
   };