Repository: ietf-tools/datatracker

Issue:
Diff any version for /doc/html
### Description

The new interface for /doc/html is great, but it inspired me to suggest a tweak.

Currently, the "Compare Versions" buttons offer options to compare in different ways (inline vs. side-by-side), but there is no easy way to choose which versions are compared.  I often find that I need to compare across multiple revisions, particularly when a document has gone through a lot of churn around IESG review time.

It might be relatively easy to add a dropdown/select form element that is populated with all of the versions of the document and have the button submit the form (using "GET") in a way that allows better access to comparisons.  This dropdown/select could be populated with all other versions (excluding the current), but default to the immediately preceding version.

### Code of Conduct

- [X] I agree to follow the [IETF's Code of Conduct](https://github.com/ietf-tools/.github/blob/main/CODE_OF_CONDUCT.md)


Discussion:

Resolving patch:
diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py
--- a/ietf/doc/views_doc.py
+++ b/ietf/doc/views_doc.py
@@ -533,6 +533,7 @@ def document_main(request, name, rev=None, document_html=False):
                                        review_assignments=review_assignments,
                                        no_review_from_teams=no_review_from_teams,
                                        due_date=due_date,
+                                       diff_revisions=get_diff_revisions(request, name, doc if isinstance(doc,Document) else doc.doc) if document_html else None
                                        ))
 
     if doc.type_id == "charter":
@@ -901,44 +902,77 @@ def document_email(request,name):
                  )
 
 
-def document_history(request, name):
-    doc = get_object_or_404(Document, docalias__name=name)
-    top = render_document_top(request, doc, "history", name)
+def get_diff_revisions(request, name, doc):
+    diffable = any(
+        [
+            name.startswith(prefix)
+            for prefix in [
+                "rfc",
+                "draft",
+                "charter",
+                "conflict-review",
+                "status-change",
+            ]
+        ]
+    )
+
+    if not diffable:
+        return []
 
     # pick up revisions from events
     diff_revisions = []
 
-    diffable = [ name.startswith(prefix) for prefix in ["rfc", "draft", "charter", "conflict-review", "status-change", ]]
-    if any(diffable):
-        diff_documents = [ doc ]
-        diff_documents.extend(Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces"))
-
-        if doc.get_state_slug() == "rfc":
-            e = doc.latest_event(type="published_rfc")
-            aliases = doc.docalias.filter(name__startswith="rfc")
-            if aliases:
-                name = aliases[0].name
-            diff_revisions.append((name, "", e.time if e else doc.time, name))
-
-        seen = set()
-        for e in NewRevisionDocEvent.objects.filter(type="new_revision", doc__in=diff_documents).select_related('doc').order_by("-time", "-id"):
-            if (e.doc.name, e.rev) in seen:
-                continue
-
-            seen.add((e.doc.name, e.rev))
-
-            url = ""
-            if name.startswith("charter"):
-                url = request.build_absolute_uri(urlreverse('ietf.doc.views_charter.charter_with_milestones_txt', kwargs=dict(name=e.doc.name, rev=e.rev)))
-            elif name.startswith("conflict-review"):
-                url = find_history_active_at(e.doc, e.time).get_href()
-            elif name.startswith("status-change"):
-                url = find_history_active_at(e.doc, e.time).get_href()
-            elif name.startswith("draft") or name.startswith("rfc"):
-                # rfcdiff tool has special support for IDs
-                url = e.doc.name + "-" + e.rev
-
-            diff_revisions.append((e.doc.name, e.rev, e.time, url))
+    diff_documents = [doc]
+    diff_documents.extend(
+        Document.objects.filter(
+            docalias__relateddocument__source=doc,
+            docalias__relateddocument__relationship="replaces",
+        )
+    )
+
+    if doc.get_state_slug() == "rfc":
+        e = doc.latest_event(type="published_rfc")
+        aliases = doc.docalias.filter(name__startswith="rfc")
+        if aliases:
+            name = aliases[0].name
+        diff_revisions.append((name, "", e.time if e else doc.time, name))
+
+    seen = set()
+    for e in (
+        NewRevisionDocEvent.objects.filter(type="new_revision", doc__in=diff_documents)
+        .select_related("doc")
+        .order_by("-time", "-id")
+    ):
+        if (e.doc.name, e.rev) in seen:
+            continue
+
+        seen.add((e.doc.name, e.rev))
+
+        url = ""
+        if name.startswith("charter"):
+            url = request.build_absolute_uri(
+                urlreverse(
+                    "ietf.doc.views_charter.charter_with_milestones_txt",
+                    kwargs=dict(name=e.doc.name, rev=e.rev),
+                )
+            )
+        elif name.startswith("conflict-review"):
+            url = find_history_active_at(e.doc, e.time).get_href()
+        elif name.startswith("status-change"):
+            url = find_history_active_at(e.doc, e.time).get_href()
+        elif name.startswith("draft") or name.startswith("rfc"):
+            # rfcdiff tool has special support for IDs
+            url = e.doc.name + "-" + e.rev
+
+        diff_revisions.append((e.doc.name, e.rev, e.time, url))
+
+    return diff_revisions
+
+
+def document_history(request, name):
+    doc = get_object_or_404(Document, docalias__name=name)
+    top = render_document_top(request, doc, "history", name)
+    diff_revisions = get_diff_revisions(request, name, doc)
 
     # grab event history
     events = doc.docevent_set.all().order_by("-time", "-id").select_related("by")


Test patch:
diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py
--- a/ietf/doc/tests.py
+++ b/ietf/doc/tests.py
@@ -744,6 +744,12 @@ def test_document_draft(self):
         q = PyQuery(r.content)
         self.assertEqual(q('title').text(), 'draft-ietf-mars-test-01')
 
+        # check that revision list has expected versions
+        self.assertEqual(len(q('#sidebar .revision-list .page-item.active a.page-link[href$="draft-ietf-mars-test-01"]')), 1)
+
+        # check that diff dropdowns have expected versions
+        self.assertEqual(len(q('#sidebar option[value="draft-ietf-mars-test-00"][selected="selected"]')), 1)
+
         rfc = WgRfcFactory()
         (Path(settings.RFC_PATH) / rfc.get_base_name()).touch()
         r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name())))