[PATCH v3 2/6] ui-shared: line range highlight: introduce javascript

Andy Green andy at warmcat.com
Sun Jun 24 04:44:34 CEST 2018


This adds a small css class, and a clientside js function plus
event registrations in cgit.js, to interpret the # part of the
URL on the client, and apply a highlight to filtered source.

Unlike blame highlight boxes which use generated divs, this
applies a computed absolutely-positioned, transparent div highlight
over the affected line(s) on the client side.

The # part of the URL is defined to not be passed to the server,
so the highlight can't be rendered on the server side.
However this has the advantage that the line range highlight
can operate on /blame/ urls trivially, since it doesn't
conflict with blame's generated div scheme.

pointer-events: none is used on the highlight overlay div to
allow the user to cut-and-paste in the highlit region and
click on links underneath normally.

The JS supports highlighting single lines as before like #n123
and also ranges of lines like #n123-135.

Because the browser can no longer automatically scroll to the
element in the second case, the JS also takes care of extracting
the range start element and scrolling to it dynamically.

Tested on Linux Firefox 60 + Linux Chrome 67

Signed-off-by: Andy Green <andy at warmcat.com>
---
 cgit.css |    7 +++++++
 cgit.js  |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/cgit.css b/cgit.css
index 61bbd49..443e04c 100644
--- a/cgit.css
+++ b/cgit.css
@@ -368,6 +368,13 @@ div#cgit table.blame td.lines > div > pre {
 	top: 0;
 }
 
+div#cgit div.selected-lines {
+	position: absolute;
+	pointer-events: none;
+	z-index: 1;
+	background-color: rgba(255, 255, 0, 0.2);
+}
+
 div#cgit table.bin-blob {
 	margin-top: 0.5em;
 	border: solid 1px black;
diff --git a/cgit.js b/cgit.js
index e69de29..501c98f 100644
--- a/cgit.js
+++ b/cgit.js
@@ -0,0 +1,53 @@
+function cgit_line_range_highlight()
+{
+	var h = window.location.hash, l1 = 0, l2 = 0, e, t;
+
+	l1 = parseInt(h.substring(2));
+	t = h.indexOf("-");
+	if (t >= 1)
+		l2 = parseInt(h.substring(t + 1));
+	else
+		l2 = l1;
+
+	if (!l1)
+		return;
+
+	var lh, t = 0, e1, e2, de;
+
+	e1 = e = document.getElementById('n' + l1);
+	if (!e)
+		return;
+
+	while (e1) { if (e1.offsetTop) t += e1.offsetTop; e1 = e1.offsetParent; }
+
+	de = document.createElement("DIV");
+
+	de.className = "selected-lines";
+	de.style.bottom = e.style.bottom;
+	de.style.top = t + 'px';
+
+	/* DOM structure is different by one level for /blame/ */
+	e1 = e.parentElement.parentElement.parentNode;
+	if (e1.offsetWidth < e1.parentNode.offsetWidth) /* blame */
+		e1 = e1.parentNode;
+
+	de.style.width = e1.offsetWidth + 'px';
+	de.style.left = e1.parentNode.parentNode.offsetLeft + 'px';
+
+	de.style.height = ((l2 - l1 + 1) * e.offsetHeight) + 'px';
+
+	e.parentElement.parentElement.insertBefore(de, e.parentElement.parentElement.firstChild);
+
+	while (l1 <= l2) {
+		e1 = document.getElementById('n' + l1++);
+		e1.style.backgroundColor = "yellow";
+	}
+
+	e.scrollIntoView(true);
+}
+
+/* line range highlight */
+
+document.addEventListener("DOMContentLoaded", function() {
+	cgit_line_range_highlight();
+}, false);



More information about the CGit mailing list