# HG changeset patch # User Denis Laxalde # Date 1491206575 -7200 # Node ID d15c9feb43994bfad3ca2e7f5c435418d3e0dfb7 # Parent 02eb52e9d413d7944e632b2281108cf03b2fc9fe hgweb: rename linerangelog.js as followlines.js So that the file name matches both the feature name and user facing vocabulary (e.g. the revset function). diff -r 02eb52e9d413 -r d15c9feb4399 contrib/wix/templates.wxs --- a/contrib/wix/templates.wxs Mon Apr 03 09:58:36 2017 +0200 +++ b/contrib/wix/templates.wxs Mon Apr 03 10:02:55 2017 +0200 @@ -226,7 +226,7 @@ - + diff -r 02eb52e9d413 -r d15c9feb4399 mercurial/templates/paper/filerevision.tmpl --- a/mercurial/templates/paper/filerevision.tmpl Mon Apr 03 09:58:36 2017 +0200 +++ b/mercurial/templates/paper/filerevision.tmpl Mon Apr 03 10:02:55 2017 +0200 @@ -74,7 +74,7 @@
{text%fileline}
- + diff -r 02eb52e9d413 -r d15c9feb4399 mercurial/templates/static/followlines.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/templates/static/followlines.js Mon Apr 03 10:02:55 2017 +0200 @@ -0,0 +1,166 @@ +// followlines.js - JavaScript utilities for followlines UI +// +// Copyright 2017 Logilab SA +// +// This software may be used and distributed according to the terms of the +// GNU General Public License version 2 or any later version. + +//** Install event listeners for line block selection and followlines action */ +document.addEventListener('DOMContentLoaded', function() { + var sourcelines = document.getElementsByClassName('sourcelines')[0]; + if (typeof sourcelines === 'undefined') { + return; + } + // URL to complement with "linerange" query parameter + var targetUri = sourcelines.dataset.logurl; + if (typeof targetUri === 'undefined') { + return; + } + + // retrieve all direct children of
+    var spans = Array.prototype.filter.call(
+        sourcelines.children,
+        function(x) { return x.tagName === 'SPAN' });
+
+    // add a "followlines-select" class to change cursor type in CSS
+    for (var i = 0; i < spans.length; i++) {
+        spans[i].classList.add('followlines-select');
+    }
+
+    var lineSelectedCSSClass = 'followlines-selected';
+
+    //** add CSS class on  element in `from`-`to` line range */
+    function addSelectedCSSClass(from, to) {
+        for (var i = from; i <= to; i++) {
+            spans[i].classList.add(lineSelectedCSSClass);
+        }
+    }
+
+    //** remove CSS class from previously selected lines */
+    function removeSelectedCSSClass() {
+        var elements = sourcelines.getElementsByClassName(
+            lineSelectedCSSClass);
+        while (elements.length) {
+            elements[0].classList.remove(lineSelectedCSSClass);
+        }
+    }
+
+    // ** return the  element parent of `element` */
+    function findParentSpan(element) {
+        var parent = element.parentElement;
+        if (parent === null) {
+            return null;
+        }
+        if (element.tagName == 'SPAN' && parent.isSameNode(sourcelines)) {
+            return element;
+        }
+        return findParentSpan(parent);
+    }
+
+    //** event handler for "click" on the first line of a block */
+    function lineSelectStart(e) {
+        var startElement = findParentSpan(e.target);
+        if (startElement === null) {
+            // not a  (maybe ): abort, keeping event listener
+            // registered for other click with  target
+            return;
+        }
+        var startId = parseInt(startElement.id.slice(1));
+        startElement.classList.add(lineSelectedCSSClass); // CSS
+
+        // remove this event listener
+        sourcelines.removeEventListener('click', lineSelectStart);
+
+        //** event handler for "click" on the last line of the block */
+        function lineSelectEnd(e) {
+            var endElement = findParentSpan(e.target);
+            if (endElement === null) {
+                // not a  (maybe ): abort, keeping event listener
+                // registered for other click with  target
+                return;
+            }
+
+            // remove this event listener
+            sourcelines.removeEventListener('click', lineSelectEnd);
+
+            // compute line range (startId, endId)
+            var endId = parseInt(endElement.id.slice(1));
+            if (endId == startId) {
+                // clicked twice the same line, cancel and reset initial state
+                // (CSS and event listener for selection start)
+                removeSelectedCSSClass();
+                sourcelines.addEventListener('click', lineSelectStart);
+                return;
+            }
+            var inviteElement = endElement;
+            if (endId < startId) {
+                var tmp = endId;
+                endId = startId;
+                startId = tmp;
+                inviteElement = startElement;
+            }
+
+            addSelectedCSSClass(startId - 1, endId -1);  // CSS
+
+            // append the 
element to last line of the + // selection block + var divAndButton = followlinesBox(targetUri, startId, endId); + var div = divAndButton[0], + button = divAndButton[1]; + inviteElement.appendChild(div); + + //** event handler for cancelling selection */ + function cancel() { + // remove invite box + div.parentNode.removeChild(div); + // restore initial event listeners + sourcelines.addEventListener('click', lineSelectStart); + sourcelines.removeEventListener('click', cancel); + // remove styles on selected lines + removeSelectedCSSClass(); + } + + // bind cancel event to click on + var button = document.createElement('button'); + button.textContent = 'x'; + buttonDiv.appendChild(button); + div.appendChild(buttonDiv); + + // - +
@@ -1475,7 +1475,7 @@ another
- + diff -r 02eb52e9d413 -r d15c9feb4399 tests/test-highlight.t --- a/tests/test-highlight.t Mon Apr 03 09:58:36 2017 +0200 +++ b/tests/test-highlight.t Mon Apr 03 10:02:55 2017 +0200 @@ -185,7 +185,7 @@ - +