From f30858983ff4e8a6baa142984a86a8125b54f319 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Thu, 9 Jun 2016 10:45:32 -0700 Subject: [PATCH 1/7] Update blame links with selected line, fix bug 1007293 --- dxr/indexers.py | 3 ++ dxr/static_unhashed/js/code-highlighter.js | 43 +++++++++++++++++++--- dxr/vcs.py | 4 +- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/dxr/indexers.py b/dxr/indexers.py index 60b1ed8df..472c596a3 100644 --- a/dxr/indexers.py +++ b/dxr/indexers.py @@ -224,6 +224,9 @@ def links(self): (sort order, heading, [(icon, title, href), ...]) + File views will replace any {{line}} within the href with the + last-selected line number. + """ return [] diff --git a/dxr/static_unhashed/js/code-highlighter.js b/dxr/static_unhashed/js/code-highlighter.js index 07061b511..b0f02817c 100644 --- a/dxr/static_unhashed/js/code-highlighter.js +++ b/dxr/static_unhashed/js/code-highlighter.js @@ -7,13 +7,15 @@ * 1) Multi-select highlight lines with shift key and update window.location.hash * 2) Multi-select highlight lines with command/control key and update window.location.hash * 3) Highlight lines when page loads, if window.location.hash exists - * In addition, we update the permalink link to keep it synchronized with window.location. + * In addition, we update the permalink and other nav links to keep them + * synchronized with window.location. */ $(function () { 'use strict'; var container = $('#line-numbers'), - permalink = $('.permalink'), // whenever we update window.location, update this href too + navlinks = $('.panel a'), // whenever we update window.location, maybe update these too + permalink = $('.permalink'), // a subset of navlinks, but it has more specific update rules lastModifierKey = null, // use this as a sort of canary/state indicator showing the last user action singleLinesArray = [], //track single highlighted lines here rangesArray = []; // track ranges of highlighted lines here @@ -86,6 +88,7 @@ $(function () { var selectedArray = generateSelectedArrays(); // generates sorted arrays var singleLinesArray = selectedArray[0]; var rangesArray = selectedArray[1]; + var lastNumber; // eliminate duplication for (s = 0; s < singleLinesArray.length; s++) { for (r = 0; r < rangesArray.length; r++) { @@ -103,22 +106,25 @@ $(function () { // if no singleLines left or range < singleLine add range to hash if ((r == rangesArray.length) || (singleLinesArray[s] < rangesArray[r][0])) { windowHash += singleLinesArray[s] + ','; + lastNumber = singleLinesArray[s]; s++; } else if (( s == singleLinesArray.length) || (rangesArray[r][0] < singleLinesArray[s])) { windowHash += rangesArray[r][0] + '-' + rangesArray[r][1] + ','; + lastNumber = rangesArray[r][1]; r++; } } if (windowHash) { windowHash = windowHash.replace(reCleanup, ''); - updateHash(windowHash); + updateHash(windowHash, lastNumber); } } - //update places where hash location is used: window, permalink - function updateHash(hash) { + //update places where hash location is used: window, permalink, other nav links + function updateHash(hash, lastNumber) { if (permalink.length > 0) updatePermalink(hash); + updateNavLinks(lastNumber); history.replaceState(null, '', hash); } @@ -132,6 +138,27 @@ $(function () { permalink.attr('href', permalink_href + windowHash); } + //replace any occurrence of {{line}} in hrefs with the last-selected line. + //unless the last-selected line is undefined, then remove {{line}} from the + //displayed url. + function updateNavLinks(lastNumber) { + navlinks.each(function() { + console.log(lastNumber); + var jqthis = $(this); + // Copy the href to a template attr, since we will be updating it + // and don't want to lose the template. This behavior will happen + // only the first time this function is called. + if (!jqthis.data('template')) { + jqthis.data('template', jqthis.attr('href')); + } + if (lastNumber) { + jqthis.attr('href', jqthis.data('template').replace(/{{line}}/g, lastNumber)); + } else { + jqthis.attr('href', jqthis.data('template').replace(/{{line}}/g, '')); + } + }); + } + //parse window.location.hash on new requests into two arrays //one of single lines and one multilines //use with singleLinesArray and rangesArray for adding/changing new highlights @@ -327,9 +354,13 @@ $(function () { } // Highlight any lines specified by hash in either a direct page load or a history pop. - $(document).ready(processHash); + $(document).ready(function() { + updateNavLinks(); + processHash(); + }); $(window).on('popstate', function() { removeAllHighlighting(); + updateNavLinks(); processHash(); }); }); diff --git a/dxr/vcs.py b/dxr/vcs.py index 755be36dc..0bb678e0c 100644 --- a/dxr/vcs.py +++ b/dxr/vcs.py @@ -147,7 +147,7 @@ def generate_diff(self, path): return self.upstream + 'diff/' + self.previous_revisions[path] + '/' + path def generate_blame(self, path): - return self.upstream + 'annotate/' + self.revision + '/' + path + return self.upstream + 'annotate/' + self.revision + '/' + path + '#l{{line}}' def generate_log(self, path): return self.upstream + 'filelog/' + self.revision + '/' + path @@ -210,7 +210,7 @@ def generate_diff(self, path): return self.upstream + "/commit/" + self.revision def generate_blame(self, path): - return self.upstream + "/blame/" + self.revision + "/" + path + return self.upstream + "/blame/" + self.revision + "/" + path + '#L{{line}}' def generate_log(self, path): return self.upstream + "/commits/" + self.revision + "/" + path From cea267ed2875557121a4e5b54037adb1232c35c9 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Thu, 9 Jun 2016 13:48:46 -0700 Subject: [PATCH 2/7] Add blame template to tests --- tests/test_vcs_git/test_vcs_git.py | 2 +- tests/test_vcs_hg/test_vcs_hg.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_vcs_git/test_vcs_git.py b/tests/test_vcs_git/test_vcs_git.py index 1f02cfed6..5933fdcf9 100644 --- a/tests/test_vcs_git/test_vcs_git.py +++ b/tests/test_vcs_git/test_vcs_git.py @@ -16,7 +16,7 @@ def test_diff(self): def test_blame(self): """Make sure the blame link exists and goes to the right place.""" response = self.client().get('/code/source/main.c') - ok_('/blame/%s/main.c" title="Blame" class="blame icon">Blame' % LATEST_REVISION in response.data) + ok_('/blame/%s/main.c#L{{line}}" title="Blame" class="blame icon">Blame' % LATEST_REVISION in response.data) def test_raw(self): """Make sure the raw link exists and goes to the right place.""" diff --git a/tests/test_vcs_hg/test_vcs_hg.py b/tests/test_vcs_hg/test_vcs_hg.py index d8117b74b..79bb0ee39 100644 --- a/tests/test_vcs_hg/test_vcs_hg.py +++ b/tests/test_vcs_hg/test_vcs_hg.py @@ -28,7 +28,7 @@ def test_diff_file3(self): def test_blame(self): """Make sure the blame link goes to the right place.""" response = self.client().get('/code/source/ChangedInCommit1') - ok_('/annotate/84798105c9ab5897f8c7d630d133d9003b44a62f/ChangedInCommit1" title="Blame" class="blame icon">Blame' in response.data) + ok_('/annotate/84798105c9ab5897f8c7d630d133d9003b44a62f/ChangedInCommit1#l{{line}}" title="Blame" class="blame icon">Blame' in response.data) def test_raw(self): """Make sure the raw link goes to the right place.""" From dbc392bfb57b99cec73d88fa56590322038fca25 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Mon, 20 Jun 2016 10:30:56 -0700 Subject: [PATCH 3/7] Remove console.log, fix naming --- dxr/static_unhashed/js/code-highlighter.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dxr/static_unhashed/js/code-highlighter.js b/dxr/static_unhashed/js/code-highlighter.js index b0f02817c..f58f8bdb6 100644 --- a/dxr/static_unhashed/js/code-highlighter.js +++ b/dxr/static_unhashed/js/code-highlighter.js @@ -143,18 +143,17 @@ $(function () { //displayed url. function updateNavLinks(lastNumber) { navlinks.each(function() { - console.log(lastNumber); - var jqthis = $(this); + var $this = $(this); // Copy the href to a template attr, since we will be updating it // and don't want to lose the template. This behavior will happen // only the first time this function is called. - if (!jqthis.data('template')) { - jqthis.data('template', jqthis.attr('href')); + if (!$this.data('template')) { + $this.data('template', $this.attr('href')); } if (lastNumber) { - jqthis.attr('href', jqthis.data('template').replace(/{{line}}/g, lastNumber)); + $this.attr('href', $this.data('template').replace(/{{line}}/g, lastNumber)); } else { - jqthis.attr('href', jqthis.data('template').replace(/{{line}}/g, '')); + $this.attr('href', $this.data('template').replace(/{{line}}/g, '')); } }); } From f240fd65a92fd441dbe3cb5e23f732f26d54d453 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Mon, 27 Jun 2016 12:49:47 -0700 Subject: [PATCH 4/7] String formatting --- dxr/app.py | 11 ++++++++++ dxr/static_unhashed/js/code-highlighter.js | 20 ++++++----------- dxr/templates/file.html | 6 +++++- dxr/vcs.py | 25 +++++++++++----------- tests/test_vcs_git/test_vcs_git.py | 3 ++- tests/test_vcs_hg/test_vcs_hg.py | 3 ++- 6 files changed, 39 insertions(+), 29 deletions(-) diff --git a/dxr/app.py b/dxr/app.py index 5a8076ffc..89632e23a 100644 --- a/dxr/app.py +++ b/dxr/app.py @@ -419,12 +419,23 @@ def _browse_file(tree, path, line_docs, file_doc, config, is_binary, :arg image_rev: revision number of a textual or binary image, for images displayed at a certain rev """ + def process_link_templates(sections): + """Look for {{line}} in the links of given sections, and duplicate them onto + a 'template' field. + """ + for section in sections: + for link in section['items']: + if '{{line}}' in link['href']: + link['template'] = link['href'] + link['href'] = link['href'].replace('{{line}}', '') + def sidebar_links(sections): """Return data structure to build nav sidebar from. :: [('Section Name', [{'icon': ..., 'title': ..., 'href': ...}])] """ + process_link_templates(sections) # Sort by order, resolving ties by section name: return sorted(sections, key=lambda section: (section['order'], section['heading'])) diff --git a/dxr/static_unhashed/js/code-highlighter.js b/dxr/static_unhashed/js/code-highlighter.js index f58f8bdb6..70d7d08c6 100644 --- a/dxr/static_unhashed/js/code-highlighter.js +++ b/dxr/static_unhashed/js/code-highlighter.js @@ -143,17 +143,13 @@ $(function () { //displayed url. function updateNavLinks(lastNumber) { navlinks.each(function() { - var $this = $(this); - // Copy the href to a template attr, since we will be updating it - // and don't want to lose the template. This behavior will happen - // only the first time this function is called. - if (!$this.data('template')) { - $this.data('template', $this.attr('href')); - } - if (lastNumber) { - $this.attr('href', $this.data('template').replace(/{{line}}/g, lastNumber)); - } else { - $this.attr('href', $this.data('template').replace(/{{line}}/g, '')); + const $this = $(this); + if ($this.data('template')) { + if (lastNumber) { + $this.attr('href', $this.data('template').replace(/{{line}}/g, lastNumber)); + } else { + $this.attr('href', $this.data('template').replace(/{{line}}/g, '')); + } } }); } @@ -354,12 +350,10 @@ $(function () { // Highlight any lines specified by hash in either a direct page load or a history pop. $(document).ready(function() { - updateNavLinks(); processHash(); }); $(window).on('popstate', function() { removeAllHighlighting(); - updateNavLinks(); processHash(); }); }); diff --git a/dxr/templates/file.html b/dxr/templates/file.html index 0cf7a39ff..f46a238b4 100644 --- a/dxr/templates/file.html +++ b/dxr/templates/file.html @@ -37,7 +37,11 @@

{{ section.heading }}

diff --git a/dxr/vcs.py b/dxr/vcs.py index 0bb678e0c..b1d65f9b0 100644 --- a/dxr/vcs.py +++ b/dxr/vcs.py @@ -140,17 +140,17 @@ def is_tracked(self, path): return path in self.previous_revisions def generate_raw(self, path): - return self.upstream + 'raw-file/' + self.revision + '/' + path + return "{}raw-file/{}/{}".format(self.upstream, self.revision, path) def generate_diff(self, path): # We generate link to diff with the last revision in which the file changed. - return self.upstream + 'diff/' + self.previous_revisions[path] + '/' + path + return "{}diff/{}/{}".format(self.upstream, self.previous_revisions[path], path) def generate_blame(self, path): - return self.upstream + 'annotate/' + self.revision + '/' + path + '#l{{line}}' + return "{}annotate/{}/{}#l{{{{line}}}}".format(self.upstream, self.revision, path) def generate_log(self, path): - return self.upstream + 'filelog/' + self.revision + '/' + path + return "{}filelog/{}/{}".format(self.upstream, self.revision, path) @classmethod def get_contents(cls, path, revision, stderr=None): @@ -202,18 +202,18 @@ def is_tracked(self, path): return path in self.tracked_files def generate_raw(self, path): - return self.upstream + "/raw/" + self.revision + "/" + path + return "{}/raw/{}/{}".format(self.upstream, self.revision, path) def generate_diff(self, path): # I really want to make this anchor on the file in question, but github # doesn't seem to do that nicely - return self.upstream + "/commit/" + self.revision + return "{}/commit/{}".format(self.upstream, self.revision) def generate_blame(self, path): - return self.upstream + "/blame/" + self.revision + "/" + path + '#L{{line}}' + return "{}/blame/{}/{}#L{{{{line}}}}".format(self.upstream, self.revision, path) def generate_log(self, path): - return self.upstream + "/commits/" + self.revision + "/" + path + return "{}/commits/{}/{}".format(self.upstream, self.revision, path) @classmethod def get_contents(cls, path, revision, stderr=None): @@ -261,22 +261,21 @@ def is_tracked(self, path): def generate_raw(self, path): info = self.have[path] - return self.upstream + info['depotFile'] + '?ac=98&rev1=' + info['haveRev'] + return "{}{}?ac=98&rev1={}".format(self.upstream, info['depotFile'], info['haveRev']) def generate_diff(self, path): info = self.have[path] haveRev = info['haveRev'] prevRev = str(int(haveRev) - 1) - return (self.upstream + info['depotFile'] + '?ac=19&rev1=' + prevRev + - '&rev2=' + haveRev) + return "{}{}?ac=19&rev1={}&rev2={}".format(self.upstream, info['depotFile'], prevRev, haveRev) def generate_blame(self, path): info = self.have[path] - return self.upstream + info['depotFile'] + '?ac=193' + return "{}{}?ac=193".format(self.upstream, info['depotFile']) def generate_log(self, path): info = self.have[path] - return self.upstream + info['depotFile'] + '?ac=22#' + info['haveRev'] + return "{}{}?ac=22#{}".format(self.upstream, info['depotFile'], info['haveRev']) def display_rev(self, path): info = self.have[path] diff --git a/tests/test_vcs_git/test_vcs_git.py b/tests/test_vcs_git/test_vcs_git.py index 5933fdcf9..8f766f5b7 100644 --- a/tests/test_vcs_git/test_vcs_git.py +++ b/tests/test_vcs_git/test_vcs_git.py @@ -16,7 +16,8 @@ def test_diff(self): def test_blame(self): """Make sure the blame link exists and goes to the right place.""" response = self.client().get('/code/source/main.c') - ok_('/blame/%s/main.c#L{{line}}" title="Blame" class="blame icon">Blame' % LATEST_REVISION in response.data) + ok_('/blame/%s/main.c#L" title="Blame" class="blame icon"' % LATEST_REVISION in response.data) + ok_('/blame/%s/main.c#L{{line}}">Blame' % LATEST_REVISION in response.data) def test_raw(self): """Make sure the raw link exists and goes to the right place.""" diff --git a/tests/test_vcs_hg/test_vcs_hg.py b/tests/test_vcs_hg/test_vcs_hg.py index 79bb0ee39..3f2223d05 100644 --- a/tests/test_vcs_hg/test_vcs_hg.py +++ b/tests/test_vcs_hg/test_vcs_hg.py @@ -28,7 +28,8 @@ def test_diff_file3(self): def test_blame(self): """Make sure the blame link goes to the right place.""" response = self.client().get('/code/source/ChangedInCommit1') - ok_('/annotate/84798105c9ab5897f8c7d630d133d9003b44a62f/ChangedInCommit1#l{{line}}" title="Blame" class="blame icon">Blame' in response.data) + ok_('/annotate/84798105c9ab5897f8c7d630d133d9003b44a62f/ChangedInCommit1#l" title="Blame" class="blame icon"' in response.data) + ok_('/annotate/84798105c9ab5897f8c7d630d133d9003b44a62f/ChangedInCommit1#l{{line}}">Blame' in response.data) def test_raw(self): """Make sure the raw link goes to the right place.""" From b3deab40cb7e48e182ccec5fa162a466b9d51a04 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Mon, 27 Jun 2016 15:06:46 -0700 Subject: [PATCH 5/7] Simplify some js logic --- dxr/static_unhashed/js/code-highlighter.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dxr/static_unhashed/js/code-highlighter.js b/dxr/static_unhashed/js/code-highlighter.js index 70d7d08c6..4b246f21c 100644 --- a/dxr/static_unhashed/js/code-highlighter.js +++ b/dxr/static_unhashed/js/code-highlighter.js @@ -145,11 +145,7 @@ $(function () { navlinks.each(function() { const $this = $(this); if ($this.data('template')) { - if (lastNumber) { - $this.attr('href', $this.data('template').replace(/{{line}}/g, lastNumber)); - } else { - $this.attr('href', $this.data('template').replace(/{{line}}/g, '')); - } + $this.attr('href', $this.data('template').replace(/{{line}}/g, lastNumber || '')); } }); } From edf03dbef57f24d98452cc4b2b696a97d6166b6a Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Mon, 25 Jul 2016 16:10:01 -0700 Subject: [PATCH 6/7] Respond to comments: blame to first line, DRY. --- dxr/static_unhashed/js/code-highlighter.js | 24 ++++++++++++---------- dxr/templates/file.html | 6 +----- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/dxr/static_unhashed/js/code-highlighter.js b/dxr/static_unhashed/js/code-highlighter.js index 4b246f21c..dd79806f4 100644 --- a/dxr/static_unhashed/js/code-highlighter.js +++ b/dxr/static_unhashed/js/code-highlighter.js @@ -88,7 +88,7 @@ $(function () { var selectedArray = generateSelectedArrays(); // generates sorted arrays var singleLinesArray = selectedArray[0]; var rangesArray = selectedArray[1]; - var lastNumber; + var firstNumber; // eliminate duplication for (s = 0; s < singleLinesArray.length; s++) { for (r = 0; r < rangesArray.length; r++) { @@ -106,25 +106,29 @@ $(function () { // if no singleLines left or range < singleLine add range to hash if ((r == rangesArray.length) || (singleLinesArray[s] < rangesArray[r][0])) { windowHash += singleLinesArray[s] + ','; - lastNumber = singleLinesArray[s]; + if (!firstNumber) { + firstNumber = singleLinesArray[s]; + } s++; } else if (( s == singleLinesArray.length) || (rangesArray[r][0] < singleLinesArray[s])) { windowHash += rangesArray[r][0] + '-' + rangesArray[r][1] + ','; - lastNumber = rangesArray[r][1]; + if (!firstNumber) { + firstNumber = rangesArray[r][0]; + } r++; } } if (windowHash) { windowHash = windowHash.replace(reCleanup, ''); - updateHash(windowHash, lastNumber); + updateHash(windowHash, firstNumber); } } //update places where hash location is used: window, permalink, other nav links - function updateHash(hash, lastNumber) { + function updateHash(hash, lineNumber) { if (permalink.length > 0) updatePermalink(hash); - updateNavLinks(lastNumber); + updateNavLinks(lineNumber); history.replaceState(null, '', hash); } @@ -141,11 +145,11 @@ $(function () { //replace any occurrence of {{line}} in hrefs with the last-selected line. //unless the last-selected line is undefined, then remove {{line}} from the //displayed url. - function updateNavLinks(lastNumber) { + function updateNavLinks(lineNumber) { navlinks.each(function() { const $this = $(this); if ($this.data('template')) { - $this.attr('href', $this.data('template').replace(/{{line}}/g, lastNumber || '')); + $this.attr('href', $this.data('template').replace(/{{line}}/g, lineNumber || '')); } }); } @@ -345,9 +349,7 @@ $(function () { } // Highlight any lines specified by hash in either a direct page load or a history pop. - $(document).ready(function() { - processHash(); - }); + $(document).ready(processHash); $(window).on('popstate', function() { removeAllHighlighting(); processHash(); diff --git a/dxr/templates/file.html b/dxr/templates/file.html index f46a238b4..57f601e58 100644 --- a/dxr/templates/file.html +++ b/dxr/templates/file.html @@ -37,11 +37,7 @@

{{ section.heading }}

From c58293b3655650dd2306f3266233d0f5f9e444b7 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Wed, 27 Jul 2016 10:08:33 -0700 Subject: [PATCH 7/7] Repair misplaced close-quote. --- dxr/templates/file.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dxr/templates/file.html b/dxr/templates/file.html index 57f601e58..336ff9042 100644 --- a/dxr/templates/file.html +++ b/dxr/templates/file.html @@ -37,7 +37,7 @@

{{ section.heading }}