about summary refs log tree commit diff
path: root/src/librustdoc/html/static/source-script.js
diff options
context:
space:
mode:
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 81df5411896..81cf437c7db 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("/");
@@ -149,3 +150,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;
+})();