Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java	(revision 14431)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java	(revision 14432)
@@ -53,5 +53,5 @@
  * This panel displays the properties of the currently selected changeset in the
  * {@link ChangesetCacheManager}.
- *
+ * @since 2689
  */
 public class ChangesetDetailPanel extends JPanel implements PropertyChangeListener, ChangesetAware {
@@ -347,5 +347,5 @@
         public void actionPerformed(ActionEvent evt) {
             if (currentChangeset != null)
-                new OpenChangesetPopupMenu(currentChangeset.getId()).show(btnOpenChangesetPopupMenu);
+                new OpenChangesetPopupMenu(currentChangeset.getId(), null).show(btnOpenChangesetPopupMenu);
         }
 
Index: /trunk/src/org/openstreetmap/josm/gui/history/OpenChangesetPopupMenu.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/OpenChangesetPopupMenu.java	(revision 14431)
+++ /trunk/src/org/openstreetmap/josm/gui/history/OpenChangesetPopupMenu.java	(revision 14432)
@@ -10,4 +10,5 @@
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 import javax.swing.AbstractAction;
@@ -18,4 +19,5 @@
 import org.openstreetmap.josm.data.StructUtils;
 import org.openstreetmap.josm.data.StructUtils.StructEntry;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -33,9 +35,12 @@
      *
      * @param changesetId the changeset id
+     * @param primitiveId the primitive id
+     * @since 14432
      */
-    public OpenChangesetPopupMenu(final long changesetId) {
+    public OpenChangesetPopupMenu(final long changesetId, final PrimitiveId primitiveId) {
         StructUtils.getListOfStructs(Config.getPref(), "history-dialog.tools", DEFAULT_ENTRIES, ChangesetViewerEntry.class)
                 .stream()
-                .map(entry -> entry.toAction(changesetId))
+                .map(entry -> entry.toAction(changesetId, primitiveId))
+                .filter(Objects::nonNull)
                 .forEach(this::add);
     }
@@ -58,5 +63,6 @@
             new ChangesetViewerEntry(tr("Open {0}", "achavi (Augmented OSM Change Viewer)"), "https://overpass-api.de/achavi/?changeset={0}"),
             new ChangesetViewerEntry(tr("Open {0}", "OSMCha (OSM Changeset Analyzer)"), "https://osmcha.mapbox.com/changesets/{0}"),
-            new ChangesetViewerEntry(tr("Open {0}", "OSM History Viewer"), "http://osmhv.openstreetmap.de/changeset.jsp?id={0}"),
+            new ChangesetViewerEntry(tr("Open {0}", "OSM History Viewer (osmrmhv)"), "http://osmhv.openstreetmap.de/changeset.jsp?id={0}"),
+            new ChangesetViewerEntry(tr("Open {0}", "OSM History Viewer (Pewu)"), "https://pewu.github.io/osm-history/#/{1}/{2}"),
             new ChangesetViewerEntry(tr("Open {0}", "WhoDidIt (OSM Changeset Analyzer)"),
                     "http://simon04.dev.openstreetmap.org/whodidit/index.html?changeset={0}&show=1")
@@ -70,5 +76,10 @@
         @StructEntry
         public String name;
-        /** Templated service url. <code>{0}</code> will be replaced by changeset id */
+        /**
+         * Templated service url.
+         * <code>{0}</code> will be replaced by changeset id
+         * <code>{1}</code> will be replaced by object type (node, way, relation)
+         * <code>{2}</code> will be replaced by object id
+         */
         @StructEntry
         public String url;
@@ -81,10 +92,16 @@
 
         ChangesetViewerEntry(String name, String url) {
-            this.name = name;
-            this.url = url;
+            this.name = Objects.requireNonNull(name);
+            this.url = Objects.requireNonNull(url);
         }
 
-        Action toAction(final long changesetId) {
-            return new OpenBrowserAction(name, MessageFormat.format(this.url, Long.toString(changesetId)));
+        Action toAction(final long changesetId, PrimitiveId primitiveId) {
+            if (primitiveId != null) {
+                return new OpenBrowserAction(name, MessageFormat.format(url,
+                        Long.toString(changesetId), primitiveId.getType().getAPIName(), Long.toString(primitiveId.getUniqueId())));
+            } else if (url.contains("{0}")) {
+                return new OpenBrowserAction(name, MessageFormat.format(url, Long.toString(changesetId)));
+            }
+            return null;
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 14431)
+++ /trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 14432)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.data.osm.User;
 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
@@ -68,4 +69,5 @@
     private JTextArea texChangesetSource;
     private JTextArea texChangesetImageryUsed;
+    private PrimitiveId primitiveId;
 
     protected static JTextArea buildTextArea(String tooltip) {
@@ -117,5 +119,5 @@
         arrowButton.addActionListener(action -> {
             if (changesetDialogAction.id != null) { // fix #15444, #16097
-                final OpenChangesetPopupMenu popupMenu = new OpenChangesetPopupMenu(changesetDialogAction.id);
+                final OpenChangesetPopupMenu popupMenu = new OpenChangesetPopupMenu(changesetDialogAction.id, primitiveId);
                 popupMenu.insert(changesetDialogAction, 0);
                 ((AbstractButton) popupMenu.getComponent(0)).setText(tr("Open Changeset Manager"));
@@ -223,5 +225,5 @@
         if (primitive != null) {
             Changeset cs = primitive.getChangeset();
-            update(cs, model.isLatest(primitive), primitive.getTimestamp(), primitive.getVersion());
+            update(cs, model.isLatest(primitive), primitive.getTimestamp(), primitive.getVersion(), primitive.getPrimitiveId());
         }
     }
@@ -233,5 +235,5 @@
      */
     public void update(final OsmPrimitive primitive, final boolean isLatest) {
-        update(Changeset.fromPrimitive(primitive), isLatest, primitive.getTimestamp(), primitive.getVersion());
+        update(Changeset.fromPrimitive(primitive), isLatest, primitive.getTimestamp(), primitive.getVersion(), primitive.getPrimitiveId());
     }
 
@@ -242,7 +244,10 @@
      * @param timestamp the timestamp
      * @param version the version of the primitive
+     * @param id the id and type of the primitive
+     * @since 14432
      */
-    public void update(final Changeset cs, final boolean isLatest, final Date timestamp, final long version) {
+    public void update(final Changeset cs, final boolean isLatest, final Date timestamp, final long version, final PrimitiveId id) {
         lblInfo.setText(getInfoText(timestamp, version, isLatest));
+        primitiveId = id;
 
         if (!isLatest && cs != null) {
