summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt5
-rw-r--r--TODO.txt6
-rw-r--r--coverage/html.py3
-rw-r--r--coverage/htmlfiles/coverage_html.js101
-rw-r--r--coverage/htmlfiles/jquery.isonscreen.js53
-rw-r--r--coverage/htmlfiles/pyfile.html1
6 files changed, 164 insertions, 5 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index bbf42f26..cf67f1c5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,7 +9,10 @@ Version 3.5
- The HTML report now has hotkeys. Try ``n``, ``s``, ``m``, ``x``, ``b``,
``p``, and ``c`` on the overview page to change the column sorting.
On a file page, ``r``, ``m``, ``x``, and ``p`` toggle the run, missing,
- excluded, and partial line markings.
+ excluded, and partial line markings. You can navigate the highlighted
+ sections of code by using the ``j`` and ``k`` keys for next and previous.
+ The ``1`` (one) key jumps to the first highlighted section in the file,
+ and ``0`` (zero) scrolls to the top of the file.
- The ``--omit`` and ``--include`` switches now interpret their values more
usefully. If the value starts with a wildcard character, it is used as-is.
diff --git a/TODO.txt b/TODO.txt
index 347936a8..66733280 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -12,7 +12,7 @@ Coverage TODO
- while TRUE claims to be partial.
- A way to mark lines as partial branches, with a regex?
- Default to "while True:", "while 1:"
-- HTML keyboard short cuts
++ HTML keyboard short cuts
* 3.2
@@ -111,8 +111,8 @@ x Why can't you specify execute (-x) and report (-r) in the same invocation?
- Rolled-up statistics.
- Some way to focus in on red and yellow
- Show only lines near highlights?
- - Jump to next highlight?
- - Keyboard navigation: N and P
+ + Jump to next highlight?
+ + Keyboard navigation: j and k.
- Cookie for changes to pyfile.html state.
+ Clickable column headers on the index page.
+ Syntax coloring in HTML report.
diff --git a/coverage/html.py b/coverage/html.py
index 97e92be0..e4404de4 100644
--- a/coverage/html.py
+++ b/coverage/html.py
@@ -33,8 +33,9 @@ class HtmlReporter(Reporter):
STATIC_FILES = [
"style.css",
"jquery-1.4.3.min.js",
- "jquery.tablesorter.min.js",
"jquery.hotkeys.js",
+ "jquery.isonscreen.js",
+ "jquery.tablesorter.min.js",
"coverage_html.js",
]
diff --git a/coverage/htmlfiles/coverage_html.js b/coverage/htmlfiles/coverage_html.js
index 7b6db427..3e2ed71d 100644
--- a/coverage/htmlfiles/coverage_html.js
+++ b/coverage/htmlfiles/coverage_html.js
@@ -90,8 +90,15 @@ coverage.pyfile_ready = function($) {
var frag = location.hash;
if (frag.length > 2 && frag[1] === 'n') {
$(frag).addClass('highlight');
+ coverage.sel_begin = parseInt(frag.substr(2));
+ coverage.sel_end = coverage.sel_begin + 1;
}
+ $(document).bind('keydown', 'j', coverage.to_next_chunk);
+ $(document).bind('keydown', 'k', coverage.to_prev_chunk);
+ $(document).bind('keydown', '0', coverage.to_top);
+ $(document).bind('keydown', '1', coverage.to_first_chunk);
+
coverage.assign_shortkeys();
};
@@ -108,3 +115,97 @@ coverage.toggle_lines = function(btn, cls) {
}
};
+// The first line selected, and the next line not selected.
+coverage.sel_begin = 0;
+coverage.sel_end = 1;
+
+coverage.to_top = function() {
+ coverage.sel_begin = 0;
+ coverage.sel_end = 1;
+ $("html").animate({scrollTop: 0}, 200);
+}
+
+coverage.to_first_chunk = function() {
+ coverage.sel_begin = 0;
+ coverage.sel_end = 1;
+ coverage.to_next_chunk();
+}
+
+coverage.to_next_chunk = function() {
+ var c = coverage;
+
+ // Find the start of the next colored chunk.
+ var probe = c.sel_end;
+ var color = $("#t" + probe).css("background-color");
+ while (color === "transparent") {
+ probe += 1;
+ var probe_line = $("#t" + probe);
+ if (probe_line.length === 0) {
+ return;
+ }
+ color = probe_line.css("background-color");
+ }
+
+ // There's a next chunk, `probe` points to it.
+ c.sel_begin = probe;
+
+ // Find the end of this chunk.
+ var next_color = color;
+ while (next_color === color) {
+ probe += 1;
+ next_color = $("#t" + probe).css("background-color");
+ }
+ c.sel_end = probe;
+ coverage.show_selected_chunk();
+};
+
+coverage.to_prev_chunk = function() {
+ var c = coverage;
+
+ // Find the end of the prev colored chunk.
+ var probe = c.sel_begin-1;
+ var color = $("#t" + probe).css("background-color");
+ while (probe > 0 && color === "transparent") {
+ probe -= 1;
+ var probe_line = $("#t" + probe);
+ if (probe_line.length === 0) {
+ return;
+ }
+ color = probe_line.css("background-color");
+ }
+
+ // There's a prev chunk, `probe` points to its last line.
+ c.sel_end = probe+1;
+
+ // Find the beginning of this chunk.
+ var prev_color = color;
+ while (prev_color === color) {
+ probe -= 1;
+ prev_color = $("#t" + probe).css("background-color");
+ }
+ c.sel_begin = probe+1;
+ coverage.show_selected_chunk();
+};
+
+coverage.show_selected_chunk = function() {
+ var c = coverage;
+
+ // Highlight the lines in the chunk
+ $(".linenos p").removeClass("highlight");
+ var probe = c.sel_begin;
+ while (probe > 0 && probe < c.sel_end) {
+ $("#n" + probe).addClass("highlight");
+ probe += 1;
+ }
+
+ // Scroll the page if the chunk isn't fully visible.
+ var top = $("#t" + c.sel_begin);
+ var bot = $("#t" + (c.sel_end-1));
+
+ if (!top.isOnScreen() || !bot.isOnScreen()) {
+ // Need to move the page.
+ var top_pos = parseInt(top.offset().top);
+ $("html").animate({scrollTop: top_pos-30}, 300);
+ }
+};
+
diff --git a/coverage/htmlfiles/jquery.isonscreen.js b/coverage/htmlfiles/jquery.isonscreen.js
new file mode 100644
index 00000000..b147aff0
--- /dev/null
+++ b/coverage/htmlfiles/jquery.isonscreen.js
@@ -0,0 +1,53 @@
+/* Copyright (c) 2010
+ * @author Laurence Wheway
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * @version 1.2.0
+ */
+(function($) {
+ jQuery.extend({
+ isOnScreen: function(box, container) {
+ //ensure numbers come in as intgers (not strings) and remove 'px' is it's there
+ for(var i in box){box[i] = parseFloat(box[i])};
+ for(var i in container){container[i] = parseFloat(container[i])};
+
+ if(!container){
+ container = {
+ left: $(window).scrollLeft(),
+ top: $(window).scrollTop(),
+ width: $(window).width(),
+ height: $(window).height()
+ }
+ }
+
+ if( box.left+box.width-container.left > 0 &&
+ box.left < container.width+container.left &&
+ box.top+box.height-container.top > 0 &&
+ box.top < container.height+container.top
+ ) return true;
+ return false;
+ }
+ })
+
+
+ jQuery.fn.isOnScreen = function (container) {
+ for(var i in container){container[i] = parseFloat(container[i])};
+
+ if(!container){
+ container = {
+ left: $(window).scrollLeft(),
+ top: $(window).scrollTop(),
+ width: $(window).width(),
+ height: $(window).height()
+ }
+ }
+
+ if( $(this).offset().left+$(this).width()-container.left > 0 &&
+ $(this).offset().left < container.width+container.left &&
+ $(this).offset().top+$(this).height()-container.top > 0 &&
+ $(this).offset().top < container.height+container.top
+ ) return true;
+ return false;
+ }
+})(jQuery);
diff --git a/coverage/htmlfiles/pyfile.html b/coverage/htmlfiles/pyfile.html
index d9d0e4c6..6f99e6a6 100644
--- a/coverage/htmlfiles/pyfile.html
+++ b/coverage/htmlfiles/pyfile.html
@@ -9,6 +9,7 @@
<link rel='stylesheet' href='style.css' type='text/css'>
<script type='text/javascript' src='jquery-1.4.3.min.js'></script>
<script type='text/javascript' src='jquery.hotkeys.js'></script>
+ <script type='text/javascript' src='jquery.isonscreen.js'></script>
<script type='text/javascript' src='coverage_html.js'></script>
<script type='text/javascript' charset='utf-8'>
jQuery(document).ready(coverage.pyfile_ready);