diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-24 01:00:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-24 01:00:23 +0000 |
commit | 6252156da5066bd47f63f8bd40404d1f89909d32 (patch) | |
tree | 743d1b59945b071890dc19b6bf5e9d3ff0d1399b /lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | |
parent | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (diff) |
Notes
Diffstat (limited to 'lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index 9b820e81e374..ebf1487d4bfc 100644 --- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -91,6 +91,9 @@ public: // Rewrite the file specified by FID with HTML formatting. void RewriteFile(Rewriter &R, const SourceManager& SMgr, const PathPieces& path, FileID FID); + + /// \return Javascript for navigating the HTML report using j/k keys. + std::string generateKeyboardNavigationJavascript(); }; } // end anonymous namespace @@ -337,6 +340,9 @@ void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R, int LineNumber = path.back()->getLocation().asLocation().getExpansionLineNumber(); int ColumnNumber = path.back()->getLocation().asLocation().getExpansionColumnNumber(); + R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), + generateKeyboardNavigationJavascript()); + // Add the name of the file as an <h1> tag. { std::string s; @@ -378,8 +384,14 @@ void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R, os << "<tr><td></td><td>" << html::EscapeText(*I) << "</td></tr>\n"; } - os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n" - "<h3>Annotated Source Code</h3>\n"; + os << R"<<<( +</table> +<!-- REPORTSUMMARYEXTRA --> +<h3>Annotated Source Code</h3> +<p><span class='macro'>[?] + <span class='expansion'>Use j/k keys for keyboard navigation</span> +</span></p> +)<<<"; R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), os.str()); } @@ -777,3 +789,82 @@ void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID, html::HighlightRange(R, InstantiationStart, E, HighlightStart, HighlightEnd); } + +std::string HTMLDiagnostics::generateKeyboardNavigationJavascript() { + return R"<<<( +<script type='text/javascript'> +var digitMatcher = new RegExp("[0-9]+"); + +document.addEventListener("DOMContentLoaded", function() { + document.querySelectorAll(".PathNav > a").forEach( + function(currentValue, currentIndex) { + var hrefValue = currentValue.getAttribute("href"); + currentValue.onclick = function() { + scrollTo(document.querySelector(hrefValue)); + return false; + }; + }); +}); + +var findNum = function() { + var s = document.querySelector(".selected"); + if (!s || s.id == "EndPath") { + return 0; + } + var out = parseInt(digitMatcher.exec(s.id)[0]); + return out; +}; + +var scrollTo = function(el) { + document.querySelectorAll(".selected").forEach(function(s) { + s.classList.remove("selected"); + }); + el.classList.add("selected"); + window.scrollBy(0, el.getBoundingClientRect().top - + (window.innerHeight / 2)); +} + +var move = function(num, up, numItems) { + if (num == 1 && up || num == numItems - 1 && !up) { + return 0; + } else if (num == 0 && up) { + return numItems - 1; + } else if (num == 0 && !up) { + return 1 % numItems; + } + return up ? num - 1 : num + 1; +} + +var numToId = function(num) { + if (num == 0) { + return document.getElementById("EndPath") + } + return document.getElementById("Path" + num); +}; + +var navigateTo = function(up) { + var numItems = document.querySelectorAll(".line > .msg").length; + var currentSelected = findNum(); + var newSelected = move(currentSelected, up, numItems); + var newEl = numToId(newSelected, numItems); + + // Scroll element into center. + scrollTo(newEl); +}; + +window.addEventListener("keydown", function (event) { + if (event.defaultPrevented) { + return; + } + if (event.key == "j") { + navigateTo(/*up=*/false); + } else if (event.key == "k") { + navigateTo(/*up=*/true); + } else { + return; + } + event.preventDefault(); +}, true); +</script> + )<<<"; +} |