diff --git a/src/main/java/htmlpublisher/HtmlPublisher.java b/src/main/java/htmlpublisher/HtmlPublisher.java index 396f7bb..3be0801 100644 --- a/src/main/java/htmlpublisher/HtmlPublisher.java +++ b/src/main/java/htmlpublisher/HtmlPublisher.java @@ -48,6 +48,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.util.DirScanner; import jenkins.util.SystemProperties; +import org.apache.commons.lang.StringUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.accmod.restrictions.suppressions.SuppressRestrictedWarnings; @@ -60,6 +61,7 @@ import hudson.FilePath; import hudson.Launcher; import hudson.Util; +import hudson.Functions; import hudson.matrix.MatrixConfiguration; import hudson.matrix.MatrixProject; import hudson.model.AbstractBuild; @@ -237,6 +239,7 @@ public static boolean publishReports(Run<?, ?> build, FilePath workspace, TaskLi for (int i=0; i < reportTargets.size(); i++) { // Create an array of lines we will eventually write out, initially the header. List<String> reportLines = new ArrayList<>(headerLines); + reportLines.add("<script type=\"text/javascript\" src=\"" + getStaticResourcesUrl() + "/plugin/htmlpublisher/js/htmlpublisher.js\"></script>"); HtmlPublisherTarget reportTarget = reportTargets.get(i); boolean keepAll = reportTarget.getKeepAll(); boolean allowMissing = reportTarget.getAllowMissing(); @@ -338,23 +341,14 @@ public static boolean publishReports(Run<?, ?> build, FilePath workspace, TaskLi } else { reportFile = report; } - String tabItem = "<li id=\"" + tabNo + "\" class=\"unselected\" onclick=\"updateBody('" + tabNo + "');\" value=\"" + htmlAttributeEscape(report) + "\">" + htmlAttributeEscape(getTitle(reportFile, titles, j)) + "</li>"; + String tabItem = "<li id=\"" + tabNo + "\" class=\"unselected\" value=\"" + htmlAttributeEscape(report) + "\">" + htmlAttributeEscape(getTitle(reportFile, titles, j)) + "</li>"; reportLines.add(tabItem); } // Add the JS to change the link as appropriate. String hudsonUrl = Jenkins.get().getRootUrl(); Job job = build.getParent(); - reportLines.add("<script type=\"text/javascript\">document.getElementById(\"hudson_link\").innerHTML=\"Back to " + htmlAttributeEscape(job.getName()) + "\";</script>"); - // If the URL isn't configured in Hudson, the best we can do is attempt to go Back. - if (hudsonUrl == null) { - reportLines.add("<script type=\"text/javascript\">document.getElementById(\"hudson_link\").onclick = function() { history.go(-1); return false; };</script>"); - } else { - String jobUrl = hudsonUrl + job.getUrl(); - reportLines.add("<script type=\"text/javascript\">document.getElementById(\"hudson_link\").href=\"" + jobUrl + "\";</script>"); - } - - reportLines.add("<script type=\"text/javascript\">document.getElementById(\"zip_link\").href=\"*zip*/" + reportTarget.getSanitizedName() + ".zip\";</script>"); - + reportLines.add("<span class='links-data-holder' data-back-to-name='" + job.getName() + "' data-root-url='" + + hudsonUrl + "' data-job-url='" + job.getUrl() + "' data-zip-link='" + reportTarget.getSanitizedName() + "'/>"); // Now add the footer. reportLines.addAll(footerLines); // And write this as the index @@ -398,6 +392,15 @@ public Collection<? extends Action> getProjectActions(AbstractProject<?, ?> proj } } + private static String getStaticResourcesUrl() { + String rootUrl = Jenkins.get().getRootUrl(); + if (rootUrl == null) { + rootUrl = ""; + } + + return StringUtils.stripEnd(rootUrl, "/") + Functions.getResourcePath(); + } + private static void adjustMatrixProject(AbstractProject<?, ?> project) { MatrixProject mp = (MatrixProject) project; if (mp.getActiveConfigurations() != null) { diff --git a/src/main/resources/htmlpublisher/HtmlPublisher/header.html b/src/main/resources/htmlpublisher/HtmlPublisher/header.html index 01e2d92..71bf735 100644 --- a/src/main/resources/htmlpublisher/HtmlPublisher/header.html +++ b/src/main/resources/htmlpublisher/HtmlPublisher/header.html @@ -86,26 +86,9 @@ } </style> - -<script type="text/javascript"> -function updateBody(tabId, page) { - document.getElementById(selectedTab).setAttribute("class", "unselected"); - tab = document.getElementById(tabId) - tab.setAttribute("class", "selected"); - selectedTab = tabId; - iframe = document.getElementById("myframe"); - iframe.src = encodeURIComponent(tab.getAttribute("value")).replace(/%2F/g, '/'); -} -function init(tabId){ - updateBody(tabId); -} - -var selectedTab = "tab1" -</script> - </head> -<body onload="init('tab1');"> +<body> <nav> <h1><a id="hudson_link" href="#"></a></h1> <h2><a id="zip_link" href="#">Zip</a></h2> diff --git a/src/main/resources/htmlpublisher/HtmlPublisherTarget/BaseHTMLAction/index.groovy b/src/main/resources/htmlpublisher/HtmlPublisherTarget/BaseHTMLAction/index.groovy index ab0b282..f9607d2 100644 --- a/src/main/resources/htmlpublisher/HtmlPublisherTarget/BaseHTMLAction/index.groovy +++ b/src/main/resources/htmlpublisher/HtmlPublisherTarget/BaseHTMLAction/index.groovy @@ -2,6 +2,7 @@ package htmlpublisher.HtmlPublisherTarget.BaseHTMLAction import htmlpublisher.HtmlPublisher import htmlpublisher.HtmlPublisherTarget +import hudson.Functions import hudson.Util import hudson.model.Descriptor @@ -10,6 +11,8 @@ import java.security.MessageDigest l = namespace(lib.LayoutTagLib) st = namespace("jelly:stapler") +Functions.initPageVariables(context) + def text = new File(my.dir(), my.getHTMLTarget().getWrapperName()).text def actual = Util.toHexString(MessageDigest.getInstance("SHA-1").digest(text.getBytes("UTF-8"))) @@ -26,9 +29,10 @@ def serveWrapper() { def footer = HtmlPublisher.class.getResourceAsStream("/htmlpublisher/HtmlPublisher/footer.html").text raw(header) + script(src: "${resURL}/plugin/htmlpublisher/js/htmlpublisher.js", type: "text/javascript") def legacyFile = new File(my.dir(), "htmlpublisher-wrapper.html") - def matcher = legacyFile.text =~ /<li id="tab\d+" class="unselected" onclick="updateBody\('tab\d+'\);" value="([^"]+)">([^<]+)<\/li>/ + def matcher = legacyFile.text =~ /<li id="tab\d+" class="unselected"(?: onclick="updateBody\('tab\d+'\);")? value="([^"]+)">([^<]+)<\/li>/ def items = [] def itemsTitle = [] @@ -39,14 +43,15 @@ def serveWrapper() { def idx = 1 items.each { file -> - li(itemsTitle[idx - 1], id: "tab${idx}", class: "unselected", onclick: "updateBody('tab${idx}')", value: file.trim()) + li(itemsTitle[idx - 1], id: "tab${idx}", class: "unselected", value: file.trim()) idx++ } - // TODO replace unnecessary JS usage by properly integrating header.html/footer.html in this groovy view - raw("<script type=\"text/javascript\">document.getElementById(\"hudson_link\").innerHTML=\"Back to ${my.backToName}\";</script>") - raw("<script type=\"text/javascript\">document.getElementById(\"hudson_link\").href=\"${rootURL}/${my.backToUrl}\";</script>") - raw("<script type=\"text/javascript\">document.getElementById(\"zip_link\").href=\"*zip*/${my.getHTMLTarget().sanitizedName}.zip\";</script>") + span(class: "links-data-holder", + "data-back-to-name": "${my.backToName}", + "data-root-url": "${rootURL}", + "data-job-url": "${my.backToUrl}", + "data-zip-link": "${my.getHTMLTarget().sanitizedName}") raw(footer) } diff --git a/src/main/webapp/js/htmlpublisher.js b/src/main/webapp/js/htmlpublisher.js new file mode 100644 index 0000000..f52ed2a --- /dev/null +++ b/src/main/webapp/js/htmlpublisher.js @@ -0,0 +1,31 @@ +function updateBody(tabId) { + document.getElementById(selectedTab).setAttribute("class", "unselected"); + tab = document.getElementById(tabId) + tab.setAttribute("class", "selected"); + selectedTab = tabId; + iframe = document.getElementById("myframe"); + iframe.src = encodeURIComponent(tab.getAttribute("value")).replace(/%2F/g, '/'); +} +function init(tabId){ + updateBody(tabId); +} + +var selectedTab = "tab1"; + +window.addEventListener("DOMContentLoaded", () => { + init("tab1"); + + const dataHolder = document.querySelector(".links-data-holder"); + const { backToName, rootUrl, jobUrl, zipLink } = dataHolder.dataset; + const backButton = document.querySelector("#hudson_link"); + backButton.innerText = `Back to ${backToName}`; + backButton.href = `${rootUrl}/${jobUrl}`; + + document.querySelector("#zip_link").href = `*zip*/${zipLink}.zip`; + + document.querySelectorAll("#tabnav li").forEach((item) => { + item.addEventListener("click", (event) => { + updateBody(event.target.id); + }); + }); +});