[PATCH 7 of 7 V4] hgweb: expose a followlines UI in filerevision view (RFC)
Denis Laxalde
denis at laxalde.org
Fri Mar 24 03:57:40 EDT 2017
# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1489594320 -3600
# Wed Mar 15 17:12:00 2017 +0100
# Node ID b633be53b40e8b2f5debb3a7aa528799072987bf
# Parent f997405d59861cf460931d519425b361b7aea0fb
# Available At http://hg.logilab.org/users/dlaxalde/hg
# hg pull http://hg.logilab.org/users/dlaxalde/hg -r b633be53b40e
# EXP-Topic linerange-log/hgweb-filelog
hgweb: expose a followlines UI in filerevision view (RFC)
In filerevision view (/file/<rev>/<fname>) we add some event listeners on
mouse selection of <span> elements in the <pre class="sourcelines"> block.
Those listeners will capture the range of mouse-selected lines and, upon mouse
release, a box inviting to follow the history of selected lines will show up.
This action is advertised by a :after pseudo-element on file lines that shows
up on hover and invite to "select a block of lines to follow its history".
All JavaScript code lives in a new "linerangelog.js" file, sourced in
filerevision template (only in "paper" style for now).
This is proposal implementation, comments welcome on any aspects.
diff --git a/contrib/wix/templates.wxs b/contrib/wix/templates.wxs
--- a/contrib/wix/templates.wxs
+++ b/contrib/wix/templates.wxs
@@ -225,6 +225,7 @@
<File Id="static.coal.file.png" Name="coal-file.png" />
<File Id="static.coal.folder.png" Name="coal-folder.png" />
<File Id="static.excanvas.js" Name="excanvas.js" />
+ <File Id="static.linerangelog.js" Name="linerangelog.js" />
<File Id="static.mercurial.js" Name="mercurial.js" />
<File Id="static.hgicon.png" Name="hgicon.png" />
<File Id="static.hglogo.png" Name="hglogo.png" />
diff --git a/mercurial/templates/paper/filerevision.tmpl b/mercurial/templates/paper/filerevision.tmpl
--- a/mercurial/templates/paper/filerevision.tmpl
+++ b/mercurial/templates/paper/filerevision.tmpl
@@ -71,8 +71,11 @@
<div class="overflow">
<div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="javascript:toggleLinewrap()">on</a></div>
<div class="sourcefirst"> line source</div>
-<pre class="sourcelines stripes4 wrap bottomline">{text%fileline}</pre>
+<pre class="sourcelines stripes4 wrap bottomline" data-logurl="{url|urlescape}log/{symrev}/{file|urlescape}">{text%fileline}</pre>
</div>
+
+<script type="text/javascript" src="{staticurl|urlescape}linerangelog.js"></script>
+
</div>
</div>
diff --git a/mercurial/templates/static/linerangelog.js b/mercurial/templates/static/linerangelog.js
new file mode 100644
--- /dev/null
+++ b/mercurial/templates/static/linerangelog.js
@@ -0,0 +1,83 @@
+// Copyright 2017 Logilab SA <contact at logilab.fr>
+//
+// This software may be used and distributed according to the terms
+// of the GNU General Public License, incorporated herein by reference.
+
+document.addEventListener('DOMContentLoaded', function() {
+ // install mouse event listeners on <pre class="sourcelines">
+ var sourcelines = document.getElementsByClassName('sourcelines')[0];
+ if (typeof sourcelines === 'undefined') {
+ return;
+ }
+ var targetUri = sourcelines.dataset.logurl;
+ if (typeof targetUri === 'undefined') {
+ return;
+ }
+ // add event listener to the whole <pre class="sourcelines"> block to have
+ // it available in all children <span>
+ sourcelines.addEventListener('mousedown', lineSelectStart);
+
+ //** event handler for "mousedown" */
+ function lineSelectStart(e) {
+ var startElement = e.target;
+ if (startElement.tagName !== 'SPAN') {
+ // we may be on a <a>
+ return;
+ }
+ // retarget "mouseup" to sourcelines element so that if this event
+ // occurs outside the <pre> we don't miss it
+ sourcelines.setCapture();
+ // drop any prior <div id="followlines">
+ var previousInvite = document.getElementById('followlines');
+ if (previousInvite !== null) {
+ previousInvite.parentNode.removeChild(previousInvite);
+ }
+
+ var startId = parseInt(startElement.id.slice(1));
+
+ //** event handler for "mouseup" */
+ function lineSelectEnd(e) {
+ // remove "mouseup" listener
+ sourcelines.removeEventListener('mouseup', lineSelectEnd);
+
+ var endElement = e.target;
+ if (endElement.tagName !== 'SPAN') {
+ // not on <span>, probably outside <pre class="sourcelines">,
+ // we cannot compute endId
+ return;
+ }
+
+ // compute line range (startId, endId) and insert the
+ // "followlines" element
+ var endId = parseInt(endElement.id.slice(1));
+ if (endId == startId) {
+ return;
+ }
+ var inviteElement = endElement;
+ if (endId < startId) {
+ var tmp = endId;
+ endId = startId;
+ startId = tmp;
+ inviteElement = startElement;
+ }
+ var div = followlinesBox(startId, endId);
+ inviteElement.appendChild(div);
+ }
+
+ sourcelines.addEventListener('mouseup', lineSelectEnd);
+
+ }
+
+ //** return a <div id="followlines"> with a link for followlines action */
+ function followlinesBox(startId, endId) {
+ var div = document.createElement('div');
+ div.id = 'followlines';
+ var a = document.createElement('a');
+ var url = targetUri + '?patch=&linerange=' + startId + ':' + endId;
+ a.setAttribute('href', url);
+ a.textContent = 'follow lines ' + startId + ':' + endId;
+ div.appendChild(a);
+ return div;
+ }
+
+}, false);
diff --git a/mercurial/templates/static/style-paper.css b/mercurial/templates/static/style-paper.css
--- a/mercurial/templates/static/style-paper.css
+++ b/mercurial/templates/static/style-paper.css
@@ -276,10 +276,28 @@ td.annotate:hover div.annotate-info { di
float: left;
}
+div.overflow pre.sourcelines > span:hover:after {
+ content: "select a block of lines to follow its history";
+ display: inline;
+ float: right;
+ line-height: 1em;
+ background-color: #FFFFFF;
+ color: #001199;
+}
+
.sourcelines > span:target, tr:target td {
background-color: #bfdfff;
}
+div#followlines {
+ display: inline;
+ position: absolute;
+ background-color: #FFFFFF;
+ border: 1px solid #999;
+ color: #000000;
+ padding: 2px;
+}
+
.sourcelines > a {
display: inline-block;
position: absolute;
diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t
--- a/tests/test-hgweb-commands.t
+++ b/tests/test-hgweb-commands.t
@@ -1343,9 +1343,12 @@ File-related
<div class="overflow">
<div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="javascript:toggleLinewrap()">on</a></div>
<div class="sourcefirst"> line source</div>
- <pre class="sourcelines stripes4 wrap bottomline">
+ <pre class="sourcelines stripes4 wrap bottomline" data-logurl="/log/1/foo">
<span id="l1">foo</span><a href="#l1"></a></pre>
</div>
+
+ <script type="text/javascript" src="/static/linerangelog.js"></script>
+
</div>
</div>
@@ -1468,9 +1471,12 @@ File-related
<div class="overflow">
<div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="javascript:toggleLinewrap()">on</a></div>
<div class="sourcefirst"> line source</div>
- <pre class="sourcelines stripes4 wrap bottomline">
+ <pre class="sourcelines stripes4 wrap bottomline" data-logurl="/log/2/foo">
<span id="l1">another</span><a href="#l1"></a></pre>
</div>
+
+ <script type="text/javascript" src="/static/linerangelog.js"></script>
+
</div>
</div>
More information about the Mercurial-devel
mailing list