Index: main/core/src/main/java/hudson/Functions.java =================================================================== --- main/core/src/main/java/hudson/Functions.java (revision 13799) +++ main/core/src/main/java/hudson/Functions.java (working copy) @@ -35,6 +35,9 @@ import hudson.util.Iterators; import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken; import org.apache.commons.jelly.JellyContext; +import org.apache.commons.jelly.JellyTagException; +import org.apache.commons.jelly.Script; +import org.apache.commons.jelly.XMLOutput; import org.apache.commons.jexl.parser.ASTSizeFunction; import org.apache.commons.jexl.util.Introspector; import org.kohsuke.stapler.Ancestor; @@ -872,6 +875,17 @@ } /** + * Evaluate a Jelly script and return output as a String. + * + * @since 1.267 + */ + public static String runScript(Script script) throws JellyTagException { + StringWriter out = new StringWriter(); + script.run(getCurrentJellyContext(), XMLOutput.createXMLOutput(out)); + return out.toString(); + } + + /** * Returns a sub-list if the given list is bigger than the specified 'maxSize' */ public static <T> List<T> subList(List<T> base, int maxSize) { Index: main/core/src/main/resources/lib/hudson/projectView.jelly =================================================================== --- main/core/src/main/resources/lib/hudson/projectView.jelly (revision 13799) +++ main/core/src/main/resources/lib/hudson/projectView.jelly (working copy) @@ -40,47 +40,9 @@ <j:forEach var="job" items="${jobs}"> <j:set var="lsBuild" value="${job.lastSuccessfulBuild}"/> <j:set var="lfBuild" value="${job.lastFailedBuild}"/> - <j:set var="buildHealth" value="${job.buildHealth}"/> <tr class="${h.ifThenElse(job.disabled,'disabledJob',null)}"> <t:ballColorTd it="${job.iconColor}"/> - <td data="${buildHealth.score}"> - <x:element name="div"> - <x:attribute name="class">healthReport</x:attribute> - <x:attribute name="onmouseover">this.className='healthReport hover';return true; - </x:attribute> - <x:attribute name="onmouseout">this.className='healthReport';return true;</x:attribute> - <a class="healthReport" href="${jobBaseUrl}${job.shortUrl}lastBuild"> - <img src="${rootURL}${buildHealth.getIconUrl(iconSize)}" - alt="${buildHealth.score}%"/> - </a> - <j:set var="healthReports" value="${job.buildHealthReports}"/> - <j:if test="${!empty(healthReports)}"> - <div class="healthReportDetails"> - <table border="0"> - <thead> - <tr> - <th align="left">W</th> - <th align="left">${%Description}</th> - <th align="right">%</th> - </tr> - </thead> - <tbody> - <j:forEach var="rpt" items="${job.buildHealthReports}"> - <tr> - <td align="left"> - <img src="${rootURL}${rpt.getIconUrl('16x16')}" alt="" - title=""/> - </td> - <td>${rpt.localizableDescription}</td> - <td align="right">${rpt.score}</td> - </tr> - </j:forEach> - </tbody> - </table> - </div> - </j:if> - </x:element> - </td> + <t:buildHealth td="true" link="${jobBaseUrl}${job.shortUrl}lastBuild"/> <td style="${indenter.getCss(job)}"> <a href="${jobBaseUrl}${job.shortUrl}"> ${job.displayName} @@ -139,4 +101,4 @@ <t:rssBar-with-iconSize/> </j:if> </div> -</j:jelly> \ No newline at end of file +</j:jelly> Index: main/core/src/main/resources/lib/hudson/buildHealth.jelly =================================================================== --- main/core/src/main/resources/lib/hudson/buildHealth.jelly (revision 0) +++ main/core/src/main/resources/lib/hudson/buildHealth.jelly (revision 0) @@ -0,0 +1,47 @@ +<!-- + <%@ attribute name="job" required="true" type="hudson.model.Job" %> + <%@ attribute name="iconSize" required="true" type="java.lang.String" %> + <%@ attribute name="td" required="false" type="java.lang.String" %> + <%@ attribute name="link" required="false" type="java.lang.String" %> +--> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> + <j:set var="buildHealth" value="${job.buildHealth}"/> + <j:if test="${td}"><j:set var="useTdElement" value="x"/></j:if> + <x:element name="${h.ifThenElse(useTdElement!=null,'td','div')}"> + <x:attribute name="data">${buildHealth.score}</x:attribute> + <x:attribute name="class">healthReport</x:attribute> + <x:attribute name="onmouseover">this.className='healthReport hover';return true; + </x:attribute> + <x:attribute name="onmouseout">this.className='healthReport';return true;</x:attribute> + <a href="${h.ifThenElse(empty(link),'#',link)}"> + <img src="${rootURL}${buildHealth.getIconUrl(iconSize)}" + alt="${buildHealth.score}%"/> + </a> + <j:set var="healthReports" value="${job.buildHealthReports}"/> + <j:if test="${!empty(healthReports)}"> + <div class="healthReportDetails"> + <table border="0"> + <thead> + <tr> + <th align="left">W</th> + <th align="left">${%Description}</th> + <th align="right">%</th> + </tr> + </thead> + <tbody> + <j:forEach var="rpt" items="${job.buildHealthReports}"> + <tr> + <td align="left"> + <img src="${rootURL}${rpt.getIconUrl('16x16')}" alt="" + title=""/> + </td> + <td>${rpt.localizableDescription}</td> + <td align="right">${rpt.score}</td> + </tr> + </j:forEach> + </tbody> + </table> + </div> + </j:if> + </x:element> +</j:jelly> Property changes on: main/core/src/main/resources/lib/hudson/buildHealth.jelly ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: main/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly =================================================================== --- main/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly (revision 13799) +++ main/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly (working copy) @@ -1,7 +1,10 @@ <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt"> <j:set target="${it}" property="trimmed" value="${all==null}"/> - <l:pane width="2" title=" - <div style='float:right'>(<a href='${it.baseUrl}/buildTimeTrend'>${%trend}</a>)</div>${it.displayName}" id="buildHistory"> + <j:parse var="paneTitle"> + <div style="float:right">(<a href="${it.baseUrl}/buildTimeTrend">${%trend}</a>)</div> + <t:buildHealth job="${it.owner}" iconSize="16x16" link="${it.baseUrl}/lastBuild"/> + </j:parse> + <l:pane width="2" title="${h.runScript(paneTitle)}${it.displayName}" id="buildHistory"> <!-- build history --> <st:include page="entries.jelly" /> @@ -58,4 +61,4 @@ <script defer="true"> updateBuildHistory("${it.baseUrl}/buildHistory/ajax",${it.nextBuildNumberToFetch}); </script> -</j:jelly> \ No newline at end of file +</j:jelly> Index: main/war/resources/css/style.css =================================================================== --- main/war/resources/css/style.css (revision 13799) +++ main/war/resources/css/style.css (working copy) @@ -459,31 +459,38 @@ /* ============================ health report hover ========================== */ -a.healthReport { +.healthReport a { text-decoration: none; } -div.healthReport div.healthReportDetails { +.healthReport div.healthReportDetails { display: none; } -div.healthReport:hover, div.healthReport.hover { /* fix IE6 bug with :hover */ +.healthReport:hover, .healthReport.hover { /* fix IE6 bug with :hover */ background: transparent; } -div.healthReport:hover div.healthReportDetails, div.healthReport.hover div.healthReportDetails { +.healthReport:hover div.healthReportDetails, .healthReport.hover div.healthReportDetails { display: block; position: absolute; background-color: #ffe; border: 1px solid #bbb; margin-left: 32px; /* move it across a bit */ + z-index: 26; } -div.healthReport div.healthReportDetails table { +.healthReport div.healthReportDetails table { border-collapse: collapse; width: 450px; /* fix IE bug with width */ } +/* ========================= build history ========================= */ +#buildHistory .healthReport { + display: inline; + margin-right: 1em; +} + /* ========================= editable combobox style ========================= */ .comboBoxList { border: 1px solid #000;