diff --git a/frontend/src/base.html b/frontend/src/base.html
index 134ee2695..b13255f0e 100644
--- a/frontend/src/base.html
+++ b/frontend/src/base.html
@@ -135,6 +135,13 @@
{{#filters}}
{{ message }}
+ {{#needs_explanation}}
+
+ ?
+ For JavaScript , files with at least one function where all functions are uncovered.
+ For C/C++/other languages , files which have no covered lines.
+
+ {{/needs_explanation}}
{{/filters}}
diff --git a/frontend/src/style.scss b/frontend/src/style.scss
index 2f5449ad4..038dcf25f 100644
--- a/frontend/src/style.scss
+++ b/frontend/src/style.scss
@@ -394,3 +394,56 @@ $samp_size: 20px;
float: right;
}
}
+
+// Tooltip container for explanation (issue #97 enhancement)
+#menu .tooltip {
+ position: relative;
+ display: inline-block;
+
+ // Question mark container
+ .questionbox {
+ text-align: center;
+ border-bottom: 1px dotted black;
+ cursor: default;
+ }
+
+ // Show the tooltip text when you mouse over the tooltip container
+ &:hover .tooltiptext {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ .tooltiptext {
+ visibility: hidden;
+ line-height: 120%;
+ background-color: $default_color;
+ color: white;
+ text-align: left;
+ padding: 1vh 1vw;
+ border-radius: 6px;
+ box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2);
+
+ // Position the tooltip
+ position: absolute;
+ z-index: 1;
+ width: 30vw;
+ top: 100%;
+ left: 50%;
+ margin-left: -16vw; // Use half of the width including left horizontal padding size i.e 30vw/2 + 1vw
+
+ &::after {
+ content: " ";
+ position: absolute;
+ bottom: 100%; /* At the top of the tooltip */
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px;
+ border-style: solid;
+ border-color: transparent transparent $default_color transparent;
+ }
+
+ // Transition animation
+ opacity: 0;
+ transition: opacity 1s;
+ }
+}
diff --git a/frontend/src/zero_coverage_report.js b/frontend/src/zero_coverage_report.js
index 82fe1d2dc..ea356854d 100644
--- a/frontend/src/zero_coverage_report.js
+++ b/frontend/src/zero_coverage_report.js
@@ -55,7 +55,8 @@ export function zeroCoverageMenu(route) {
return {
key,
message: filter.name,
- checked: isEnabled(key)
+ checked: isEnabled(key),
+ needs_explanation: key === "completely_uncovered"
};
}),
last_pushes: Object.entries(ZERO_COVERAGE_PUSHES).map(