1 //= require jquery-simulate/jquery.simulate
 
   3 OSM.History = function (map) {
 
   7     .on("click", ".changeset_more a", loadMore)
 
   8     .on("mouseover", "[data-changeset]", function () {
 
   9       highlightChangeset($(this).data("changeset").id);
 
  11     .on("mouseout", "[data-changeset]", function () {
 
  12       unHighlightChangeset($(this).data("changeset").id);
 
  15   const group = L.featureGroup()
 
  16     .on("mouseover", function (e) {
 
  17       highlightChangeset(e.layer.id);
 
  19     .on("mouseout", function (e) {
 
  20       unHighlightChangeset(e.layer.id);
 
  22     .on("click", function (e) {
 
  23       clickChangeset(e.layer.id, e.originalEvent);
 
  26   group.getLayerId = function (layer) {
 
  30   function highlightChangeset(id) {
 
  31     const layer = group.getLayer(id);
 
  32     if (layer) layer.setStyle({ fillOpacity: 0.3, color: "#FF6600", weight: 3 });
 
  33     $("#changeset_" + id).addClass("selected");
 
  36   function unHighlightChangeset(id) {
 
  37     const layer = group.getLayer(id);
 
  38     if (layer) layer.setStyle({ fillOpacity: 0, color: "#FF9500", weight: 2 });
 
  39     $("#changeset_" + id).removeClass("selected");
 
  42   function clickChangeset(id, e) {
 
  43     $("#changeset_" + id).find("a.changeset_id").simulate("click", e);
 
  46   function displayFirstChangesets(html) {
 
  47     $("#sidebar_content .changesets").html(html);
 
  50   function displayMoreChangesets(div, html) {
 
  51     const sidebar = $("#sidebar")[0];
 
  52     const previousScrollHeightMinusTop = sidebar.scrollHeight - sidebar.scrollTop;
 
  54     const oldList = $("#sidebar_content .changesets ol");
 
  56     div.replaceWith(html);
 
  58     const prevNewList = oldList.prevAll("ol");
 
  59     if (prevNewList.length) {
 
  60       prevNewList.next(".changeset_more").remove();
 
  61       prevNewList.children().prependTo(oldList);
 
  64       // restore scroll position only if prepending
 
  65       sidebar.scrollTop = sidebar.scrollHeight - previousScrollHeightMinusTop;
 
  68     const nextNewList = oldList.nextAll("ol");
 
  69     if (nextNewList.length) {
 
  70       nextNewList.prev(".changeset_more").remove();
 
  71       nextNewList.children().appendTo(oldList);
 
  77     const data = new URLSearchParams();
 
  78     const params = new URLSearchParams(location.search);
 
  80     if (location.pathname === "/history") {
 
  81       data.set("bbox", map.getBounds().wrap().toBBoxString());
 
  82       const feedLink = $("link[type=\"application/atom+xml\"]"),
 
  83             feedHref = feedLink.attr("href").split("?")[0];
 
  84       feedLink.attr("href", feedHref + "?" + data);
 
  87     data.set("list", "1");
 
  89     if (params.has("before")) {
 
  90       data.set("before", params.get("before"));
 
  92     if (params.has("after")) {
 
  93       data.set("after", params.get("after"));
 
  96     fetch(location.pathname + "?" + data)
 
  97       .then(response => response.text())
 
  98       .then(function (html) {
 
  99         displayFirstChangesets(html);
 
 104   function loadMore(e) {
 
 108     const div = $(this).parents(".changeset_more");
 
 111     div.find(".loader").show();
 
 113     $.get($(this).attr("href"), function (html) {
 
 114       displayMoreChangesets(div, html);
 
 121   function updateBounds() {
 
 124     for (const changeset of changesets) {
 
 125       const bottomLeft = map.project(L.latLng(changeset.bbox.minlat, changeset.bbox.minlon)),
 
 126             topRight = map.project(L.latLng(changeset.bbox.maxlat, changeset.bbox.maxlon)),
 
 127             width = topRight.x - bottomLeft.x,
 
 128             height = bottomLeft.y - topRight.y,
 
 129             minSize = 20; // Min width/height of changeset in pixels
 
 131       if (width < minSize) {
 
 132         bottomLeft.x -= ((minSize - width) / 2);
 
 133         topRight.x += ((minSize - width) / 2);
 
 136       if (height < minSize) {
 
 137         bottomLeft.y += ((minSize - height) / 2);
 
 138         topRight.y -= ((minSize - height) / 2);
 
 141       changeset.bounds = L.latLngBounds(map.unproject(bottomLeft),
 
 142                                         map.unproject(topRight));
 
 145     changesets.sort(function (a, b) {
 
 146       return b.bounds.getSize() - a.bounds.getSize();
 
 149     for (const changeset of changesets) {
 
 150       const rect = L.rectangle(changeset.bounds,
 
 151                                { weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFAF", fillOpacity: 0 });
 
 152       rect.id = changeset.id;
 
 157   function updateMap() {
 
 158     changesets = $("[data-changeset]").map(function (index, element) {
 
 159       return $(element).data("changeset");
 
 160     }).get().filter(function (changeset) {
 
 161       return changeset.bbox;
 
 166     if (location.pathname !== "/history") {
 
 167       const bounds = group.getBounds();
 
 168       if (bounds.isValid()) map.fitBounds(bounds);
 
 172   page.pushstate = page.popstate = function (path) {
 
 173     OSM.loadSidebarContent(path, page.load);
 
 176   page.load = function () {
 
 179     if (location.pathname === "/history") {
 
 180       map.on("moveend", update);
 
 183     map.on("zoomend", updateBounds);
 
 188   page.unload = function () {
 
 189     map.removeLayer(group);
 
 190     map.off("moveend", update);
 
 191     map.off("zoomend", updateBounds);