]> granicus.if.org Git - cgit/commitdiff
line-range-highlight: onclick handler and range selection
authorAndy Green <andy@warmcat.com>
Sun, 24 Jun 2018 01:08:40 +0000 (09:08 +0800)
committerAndy Green <andy@warmcat.com>
Fri, 29 Jun 2018 06:30:23 +0000 (14:30 +0800)
This allows the user to select line ranges simply by clicking on the
line number links.

 - No selected highlit line, or a range already selected, causes the
click to highlight just the clicked line as usual.

 - Clicking on a second line number link when a single line was already
highlit creates a line range highlight, between the lowest and
highest line numbers of the already-selected and newly-selected
line number links.

The order of the clicks is unimportant, you can click the higher
line number link first and then the lower to define the range of
lines equally well.

The implementation is slightly complicated by our single parent
onclick handler not being able to interrupt the already ongoing
processing of the a href #n change from the link click itself.

Rather than bloat every linenumber link with its own onclick handler
defeating this default we simply do it with a single parent
onclick event and apply any computed range url in the existing
hashchange event handler.

Signed-off-by: Andy Green <andy@warmcat.com>
cgit.js
ui-blame.c
ui-tree.c

diff --git a/cgit.js b/cgit.js
index d99c980e50e04197384fc62a6d75fbf341f538e0..015dd7683fe4e00e926317f45f754c123802b071 100644 (file)
--- a/cgit.js
+++ b/cgit.js
@@ -108,11 +108,45 @@ function line_range_highlight()
        t.scrollIntoView(true);
 }
 
+function line_range_click(e) {
+       var t, m, n = window.location.href.length - window.location.hash.length;
+
+       /* disable passthru to stop needless scrolling by default browser #URL handler */
+       e.stopPropagation();
+       e.preventDefault();
+
+       if (!window.location.hash ||
+           window.location.hash.indexOf("-") >= 0)
+               t = window.location.href.substring(0, n) +
+                   '#n' + e.target.id.substring(1);
+       else {
+               if (parseInt(window.location.hash.substring(2)) <
+                   parseInt(e.target.id.substring(1)))  /* forwards */
+                       t = window.location + '-' + e.target.id.substring(1);
+               else
+                       t = window.location.href.substring(0, n) +
+                               '#n' + e.target.id.substring(1) + '-' +
+                               window.location.href.substring(n + 2);
+       }
+
+       window.history.replaceState(null, null, t);
+
+       line_range_highlight();
+}
+
 /* we have to use load, because header images can push the layout vertically */
 window.addEventListener("load", function() {
        line_range_highlight();
 }, false);
 
+document.addEventListener("DOMContentLoaded", function() {
+       /* event listener cannot override default #URL browser processing,
+        * requires onclick */
+       var e = document.getElementById("linenumbers");
+       if (e)
+               e.onclick = line_range_click;
+}, false);
+
 window.addEventListener("hashchange", function() {
        line_range_highlight();
 }, false);
index 50d05803b4e621f4cefe4e6e67b4a88f887eafa5..c9cca18a3fb3ab156e54ca57b3e48eb37d71aa30 100644 (file)
@@ -170,7 +170,7 @@ static void print_object(const struct object_id *oid, const char *path,
 
        /* Line numbers */
        if (ctx.cfg.enable_tree_linenumbers) {
-               html("<td class='linenumbers'>");
+               html("<td id='linenumbers' class='linenumbers'>");
                for (ent = sb.ent; ent; ent = ent->next) {
                        html("<div class='alt'><pre>");
                        emit_blame_entry_linenumber(ent);
index e4cb5587154869729bb81adc67106dd0a9e05ab7..f96b8454752c177e973f6e70a3cbfa28273a52e2 100644 (file)
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -28,7 +28,7 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size)
        html("<table summary='blob content' class='blob'>\n");
 
        if (ctx.cfg.enable_tree_linenumbers) {
-               html("<tr><td class='linenumbers'><pre>");
+               html("<tr><td id='linenumbers' class='linenumbers'><pre>");
                idx = 0;
                lineno = 0;