about summary refs log tree commit diff
path: root/src/librustdoc/html/static/source-script.js
diff options
context:
space:
mode:
authorJacob Hoffman-Andrews <github@hoffman-andrews.com>2021-05-09 11:21:38 -0700
committerJacob Hoffman-Andrews <github@hoffman-andrews.com>2021-05-11 13:45:08 -0700
commit09454513d196613e3e60ab52b7479f9d65d6270a (patch)
treedaa9b5d6c5432b0fd8bd1b3a57bb91042c948736 /src/librustdoc/html/static/source-script.js
parent6fd7a6dc0f5c4c8fd51d57c0f4f795d52481f904 (diff)
downloadrust-09454513d196613e3e60ab52b7479f9d65d6270a.tar.gz
rust-09454513d196613e3e60ab52b7479f9d65d6270a.zip
Move global click handlers to per-element ones.
In rustdoc's main.js, we had an onclick handler for the whole document
that would dispatch to handlers for various elements. This change
attaches the handlers to the elements that trigger them, instead.
This simplfies the code and avoids reimplementing the browser's bubbling
functionality.

As part of this change, change from a class to an id for help button.

Move the handlers and associated code for highlighting source lines into
source-script.js (and factor out a shared regex).
Diffstat (limited to 'src/librustdoc/html/static/source-script.js')
-rw-r--r--src/librustdoc/html/static/source-script.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js
index 42b54e4cc1e..a5aa2c5f678 100644
--- a/src/librustdoc/html/static/source-script.js
+++ b/src/librustdoc/html/static/source-script.js
@@ -3,6 +3,7 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */
+(function() {
 
 function getCurrentFilePath() {
     var parts = window.location.pathname.split("/");
@@ -150,3 +151,99 @@ function createSourceSidebar() {
         selected_elem.focus();
     }
 }
+
+var lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/;
+
+function highlightSourceLines(match, ev) {
+    if (typeof match === "undefined") {
+        match = window.location.hash.match(lineNumbersRegex);
+    }
+    if (!match) {
+        return;
+    }
+    var from = parseInt(match[1], 10);
+    var to = from;
+    if (typeof match[2] !== "undefined") {
+        to = parseInt(match[2], 10);
+    }
+    if (to < from) {
+        var tmp = to;
+        to = from;
+        from = tmp;
+    }
+    var elem = document.getElementById(from);
+    if (!elem) {
+        return;
+    }
+    if (!ev) {
+        var x = document.getElementById(from);
+        if (x) {
+            x.scrollIntoView();
+        }
+    }
+    onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
+        onEachLazy(e.getElementsByTagName("span"), function(i_e) {
+            removeClass(i_e, "line-highlighted");
+        });
+    });
+    for (var i = from; i <= to; ++i) {
+        elem = document.getElementById(i);
+        if (!elem) {
+            break;
+        }
+        addClass(elem, "line-highlighted");
+    }
+}
+
+var handleSourceHighlight = (function() {
+    var prev_line_id = 0;
+
+    var set_fragment = function(name) {
+        var x = window.scrollX,
+            y = window.scrollY;
+        if (searchState.browserSupportsHistoryApi()) {
+            history.replaceState(null, null, "#" + name);
+            highlightSourceLines();
+        } else {
+            location.replace("#" + name);
+        }
+        // Prevent jumps when selecting one or many lines
+        window.scrollTo(x, y);
+    };
+
+    return function(ev) {
+        var cur_line_id = parseInt(ev.target.id, 10);
+        ev.preventDefault();
+
+        if (ev.shiftKey && prev_line_id) {
+            // Swap selection if needed
+            if (prev_line_id > cur_line_id) {
+                var tmp = prev_line_id;
+                prev_line_id = cur_line_id;
+                cur_line_id = tmp;
+            }
+
+            set_fragment(prev_line_id + "-" + cur_line_id);
+        } else {
+            prev_line_id = cur_line_id;
+
+            set_fragment(cur_line_id);
+        }
+    };
+}());
+
+window.addEventListener("hashchange", function() {
+    var match = window.location.hash.match(lineNumbersRegex);
+    if (match) {
+        return highlightSourceLines(match, ev);
+    }
+});
+
+onEachLazy(document.getElementsByClassName("line-numbers"), function(el) {
+    el.addEventListener("click", handleSourceHighlight);
+});
+
+highlightSourceLines();
+
+window.createSourceSidebar = createSourceSidebar;
+})();