From: Willy Tarreau Date: Fri, 31 Jul 2026 17:54:47 +0000 (+0200) Subject: DEV: patchbot: support passing the page settings in the URL fragment X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fhaproxy.git DEV: patchbot: support passing the page settings in the URL fragment It's difficult to point a coworker to a set of patches resulting from a selection. Some browser-based tools such as slides pass information in the URL as a fragment that the code in the browser is able to retrieve. Conversely it's possible to update it without causing a page reload using history.replaceState(). This means that we can instantly update the URL bar with extra params passed as fragments as we click on the page, so it's possible to copy-paste a current state so that someone else gets the same view (without local edits). --- diff --git a/dev/patchbot/README b/dev/patchbot/README index 4b8fd6d78..69bb4e2f2 100644 --- a/dev/patchbot/README +++ b/dev/patchbot/README @@ -493,6 +493,24 @@ is being typed on it, so that a pending note never hides itself. The verdicts are not taken into account, on purpose: they are routinely adjusted on misqualified patches, which would leave far too many lines to be of any use. +The state of these checkboxes and the first line to review are also maintained +in the URL fragment, which is updated on the fly as they are clicked, without +ever reloading the page nor adding entries to the browsing history. The address +bar hence always holds a link reproducing exactly what is displayed, that can +be copy-pasted to a coworker to point them at a specific set of patches. Its +format is: + + #show=&start= + +where is the concatenation of the letters of the categories to show +(any subset of "bnuwyo", the missing ones being hidden), and is either +"all" or the number of the first line to review, as displayed in the first +column. Both elements are optional and independent, and anything that is not +understood is silently ignored, so that a link produced by an older version, a +truncated one, or one pointing to a line which does not exist anymore just +falls back to the page's defaults. Pasting such a link into a tab which +already shows the page applies it immediately, without reloading either. + In order to reduce the risk of missing a misqualified patch, those marked "BUG" or "DOC" are displayed in bold even if tagged "No". It has been shown to be sufficient to catch the eye when scrolling and encouraging to re-visit them. diff --git a/dev/patchbot/scripts/post-ai.sh b/dev/patchbot/scripts/post-ai.sh index 6bcda4f76..d78293f59 100755 --- a/dev/patchbot/scripts/post-ai.sh +++ b/dev/patchbot/scripts/post-ai.sh @@ -777,6 +777,14 @@ function updt(line,value) { updt_table(line); updt_output(); updt_save_btn(); + if (value == "r") + updt_url(); +} + +// a "Show" checkbox was clicked: redraw and republish the view in the URL +function updt_show() { + updt_table(0); + updt_url(); } // selects the categories to show; is optional and defaults to showing @@ -813,6 +821,87 @@ function init_review() { } } +// the letters of the "Show" checkboxes, in the order they appear in the URL +// fragment; each one designates the checkbox of id "sh_" plus that letter. +var show_boxes = "bnuwyo"; + +// Reflects the current view (the shown categories and the first line to +// review) into the URL fragment, so that the address bar always holds a link +// reproducing exactly what is displayed and which can be sent to a coworker +// as-is. The history entry is replaced and never pushed: nothing is reloaded +// nor scrolled, the listing does not even blink, and leaving the page still +// takes a single click on "back". +function updt_url() { + var show = ""; + var i; + + if (!window.history || !history.replaceState) + return; + + for (i = 0; i < show_boxes.length; i++) + if (document.getElementById("sh_" + show_boxes.charAt(i)).checked) + show += show_boxes.charAt(i); + + // browsers may refuse to touch the history of a page loaded from a local + // file (opaque origin). The fragment is then just not maintained, which + // affects nothing else, hence the silent catch. + try { + history.replaceState(null, "", "#show=" + show + + "&start=" + (review ? review : "all")); + } catch (e) { + } +} + +// Applies the view settings possibly passed in the URL fragment: "show" holds +// the letters of the categories to display, the missing ones being hidden, +// and "start" is the first line to review, either "all" or a line number. +// Both are optional and anything not understood is ignored, so that an old or +// hand-edited link degrades to the page's defaults instead of breaking. A +// fragment element without "=" is left alone as well, which preserves the +// ability to point at a commit id. Only the state is set here, the caller +// redraws. +function apply_url() { + var args = location.hash.substring(1).split("&"); + var i, j, eq, key, val, num, el; + + for (i = 0; i < args.length; i++) { + eq = args[i].indexOf("="); + if (eq < 0) + continue; + key = args[i].substring(0, eq); + val = args[i].substring(eq + 1); + if (key == "show") { + for (j = 0; j < show_boxes.length; j++) + document.getElementById("sh_" + show_boxes.charAt(j)).checked = + val.indexOf(show_boxes.charAt(j)) >= 0; + } + else if (key == "start") { + if (val == "all") { + document.getElementById("show_all").checked = true; + review = 0; + } + else { + num = parseInt(val, 10); + el = document.getElementById("rv_" + num); + if (el) { + el.checked = true; + review = num; + } + } + } + } +} + +// Pasting a link into a tab which already shows the page only changes the +// fragment, and the browser reloads nothing: apply it by hand or nothing +// would happen at all. replaceState() does not trigger this event, so the +// updates emitted above cannot loop back here. +window.addEventListener("hashchange", function() { + apply_url(); + updt_table(0); + updt_output(); +}); + // --> @@ -844,12 +933,12 @@ echo -n "0" echo "

" echo -n "Show:" -echo -n " B (${#bkp[*]}) " -echo -n " N (0) " -echo -n " U (0) " -echo -n " W (0) " -echo -n " Y (0) " -echo -n " O (0) " +echo -n " B (${#bkp[*]}) " +echo -n " N (0) " +echo -n " U (0) " +echo -n " W (0) " +echo -n " Y (0) " +echo -n " O (0) " echo -n "
(B=show backported, N=no/drop, U=uncertain, W=wait/next, Y=yes/pick," echo -n " O=original notes; uncheck to see only the 0 edited ones" echo ")

" @@ -999,7 +1088,7 @@ echo "

" echo "

Output:

" echo "" echo "

" -echo "" +echo "" # the shared state is fetched right away so that a page left open or reloaded # always shows the current review; forgetting to click "Get updates" is far # too easy. It is only a time-boxed attempt (see autofetch_ms), the button