Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
cb9036c4
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cb9036c4
编写于
11月 24, 2014
作者:
T
tfennelly
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Single/Multiline Build History
上级
6bf6e7f5
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
618 addition
and
70 deletion
+618
-70
core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.jelly
...resources/hudson/widgets/BuildHistoryWidget/entries.jelly
+31
-23
core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly
...c/main/resources/hudson/widgets/HistoryWidget/entry.jelly
+38
-31
core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly
...c/main/resources/hudson/widgets/HistoryWidget/index.jelly
+1
-0
war/src/main/webapp/css/style.css
war/src/main/webapp/css/style.css
+125
-7
war/src/main/webapp/scripts/hudson-behavior.js
war/src/main/webapp/scripts/hudson-behavior.js
+423
-9
未找到文件。
core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.jelly
浏览文件 @
cb9036c4
...
@@ -33,30 +33,38 @@ THE SOFTWARE.
...
@@ -33,30 +33,38 @@ THE SOFTWARE.
<j:if
test=
"${!pending.isEmpty()}"
>
<j:if
test=
"${!pending.isEmpty()}"
>
<j:forEach
var=
"item"
items=
"${queuedItems}"
indexVar=
"i"
>
<j:forEach
var=
"item"
items=
"${queuedItems}"
indexVar=
"i"
>
<j:set
var=
"id"
value=
"${h.generateId()}"
/>
<j:set
var=
"id"
value=
"${h.generateId()}"
/>
<tr
class=
"build-row transitive"
id=
"${id}"
>
<tr
class=
"build-row build-pending transitive single-line"
id=
"${id}"
>
<td
nowrap=
"nowrap"
>
<td
class=
"build-row-cell"
>
<l:icon
class=
"icon-grey icon-sm"
/>
<div
class=
"pane build-name"
>
<st:nbsp/>
<div
class=
"build-icon"
>
<!-- Don't use math unless needed, in case nextBuildNumber is not numeric -->
<l:icon
class=
"icon-grey icon-sm"
/>
#${queuedItems.size()==1 ? it.owner.nextBuildNumber
</div>
: it.owner.nextBuildNumber+queuedItems.size()-i-1}
<!-- Don't use math unless needed, in case nextBuildNumber is not numeric -->
</td>
<div
class=
"display-name"
>
<td
style=
"white-space:normal;"
colspan=
"2"
>
#${queuedItems.size()==1 ? it.owner.nextBuildNumber
<div
style=
"float:right"
>
: it.owner.nextBuildNumber+queuedItems.size()-i-1}
<j:if
test=
"${item.hasCancelPermission()}"
>
</div>
<l:stopButton
href=
"${rootURL}/queue/cancelItem?id=${item.id}"
alt=
"${%cancel this build}"
/>
</div>
</j:if>
<div
class=
"pane build-details indent-multiline"
>
<j:set
var=
"cause"
value=
"${item.getCauseOfBlockage()}"
/>
<j:choose>
<j:when
test=
"${cause!=null}"
>
(${%pending}—
<st:include
it=
"${cause}"
page=
"summary.jelly"
/>
)
</j:when>
<j:otherwise>
(${%pending})
</j:otherwise>
</j:choose>
${item.params}
</div>
<div
class=
"pane build-controls"
>
<div
class=
"build-stop"
>
<j:if
test=
"${item.hasCancelPermission()}"
>
<l:stopButton
href=
"${rootURL}/queue/cancelItem?id=${item.id}"
alt=
"${%cancel this build}"
/>
</j:if>
</div>
</div>
</div>
<j:set
var=
"cause"
value=
"${item.getCauseOfBlockage()}"
/>
<div
class=
"left-bar"
></div>
<j:choose>
<j:when
test=
"${cause!=null}"
>
(${%pending}—
<st:include
it=
"${cause}"
page=
"summary.jelly"
/>
)
</j:when>
<j:otherwise>
(${%pending})
</j:otherwise>
</j:choose>
${item.params}
</td>
</td>
</tr>
</tr>
</j:forEach>
</j:forEach>
...
...
core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly
浏览文件 @
cb9036c4
...
@@ -29,41 +29,48 @@ THE SOFTWARE.
...
@@ -29,41 +29,48 @@ THE SOFTWARE.
<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: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 var="link" value="${it.baseUrl}/${build.number}/" />
<j:set var="link" value="${it.baseUrl}/${build.number}/" />
<j:set var="transitive" value="${(it.firstTransientBuildKey!=null and (it.adapter.compare(build,it.firstTransientBuildKey) ge 0)) ? 'transitive' : null}" />
<j:set var="transitive" value="${(it.firstTransientBuildKey!=null and (it.adapter.compare(build,it.firstTransientBuildKey) ge 0)) ? 'transitive' : null}" />
<tr class="build-row ${transitive}">
<tr class="build-row ${transitive} single-line">
<td class="pane build-name">
<td class="build-row-cell">
<a class="build-status-link" href="${link}console"><l:icon alt="${build.iconColor.description} > ${%Console Output}" class="${build.buildStatusIconClassName} icon-sm" tooltip="${build.iconColor.description} > ${%Console Output}"/></a><st:nbsp/>
<div class="pane build-name">
${build.displayName}
<div class="build-icon">
</td>
<a class="build-status-link" href="${link}console"><l:icon alt="${build.iconColor.description} > ${%Console Output}" class="${build.buildStatusIconClassName} icon-sm" tooltip="${build.iconColor.description} > ${%Console Output}"/></a>
<td class="pane build-details">
</div>
<a class="tip model-link inside" href="${link}">
<a class="display-name" href="${link}">${build.displayName}</a>
<i:formatDate value="${build.timestamp.time}" type="both" dateStyle="medium" timeStyle="medium"/>
</div>
</a>
<div class="pane build-details" time="${build.timestamp.time.time}">
<j:if test="${build.building}">
<a class="tip model-link inside build-link" href="${link}">
<j:set target="${it}" property="nextBuildNumberToFetch" value="${build.number}"/>
<i:formatDate value="${build.timestamp.time}" type="both" dateStyle="medium" timeStyle="short" />
<t:buildProgressBar build="${build}"/>
</a>
</j:if>
<j:if test="${build.building}">
<j:set target="${it}" property="nextBuildNumberToFetch" value="${build.number}"/>
<t:buildProgressBar build="${build}"/>
</j:if>
</div>
<div class="pane build-controls">
<div class="middle-align build-badge">
<j:set var="badges" value="${build.badgeActions}"/>
<j:if test="${!empty(badges)}">
<st:nbsp/>
<j:forEach var="badge" items="${badges}">
<st:include it="${badge}" page="badge.jelly" />
</j:forEach>
</j:if>
</div>
<j:if test="${build.building}">
<div class="build-stop">
<!-- Check ABORT permission for Project, Admin permission otherwise -->
<j:if test="${empty(it.owner.ABORT) ? h.hasPermission(app.ADMINISTER) : it.owner.hasPermission(it.owner.ABORT)}">
<l:stopButton href="${link}stop" alt="[cancel]"/>
</j:if>
</div>
</j:if>
</div>
<j:if test="${!empty build.description}">
<j:if test="${!empty build.description}">
<div class="
desc
">
<div class="
pane desc indent-multiline
">
<j:out value="${app.markupFormatter.translate(build.truncatedDescription)}"/>
<j:out value="${app.markupFormatter.translate(build.truncatedDescription)}"/>
</div>
</div>
</j:if>
</j:if>
</td>
<div class="left-bar" />
<td class="pane build-stop">
<j:if test="${build.building}">
<!-- Check ABORT permission for Project, Admin permission otherwise -->
<j:if test="${empty(it.owner.ABORT) ? h.hasPermission(app.ADMINISTER) : it.owner.hasPermission(it.owner.ABORT)}">
<l:stopButton href="${link}stop" alt="[cancel]"/>
</j:if>
</j:if>
</td>
<td class="pane middle-align build-badge">
<j:set var="badges" value="${build.badgeActions}"/>
<j:if test="${!empty(badges)}">
<st:nbsp/>
<j:forEach var="badge" items="${badges}">
<st:include it="${badge}" page="badge.jelly" />
</j:forEach>
</j:if>
</td>
</td>
</tr>
</tr>
</j:jelly>
</j:jelly>
core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly
浏览文件 @
cb9036c4
...
@@ -88,6 +88,7 @@ THE SOFTWARE.
...
@@ -88,6 +88,7 @@ THE SOFTWARE.
newhist.headers = hist.headers
newhist.headers = hist.headers
replace(hist, newhist);
replace(hist, newhist);
fireBuildHistoryChanged();
}
}
});
});
}
}
...
...
war/src/main/webapp/css/style.css
浏览文件 @
cb9036c4
...
@@ -441,10 +441,6 @@ pre.console {
...
@@ -441,10 +441,6 @@ pre.console {
width
:
480px
;
width
:
480px
;
}
}
.build-row
{
padding
:
3px
4px
3px
4px
;
}
.build-keep
{
.build-keep
{
font-weight
:
bold
;
font-weight
:
bold
;
}
}
...
@@ -934,18 +930,140 @@ table.parameters > tbody:hover {
...
@@ -934,18 +930,140 @@ table.parameters > tbody:hover {
}
}
#buildHistory
.desc
{
#buildHistory
.desc
{
position
:
relative
;
padding
:
0
;
padding
:
0
;
margin-top
:
5px
;
margin-top
:
5px
;
white-space
:
normal
;
white-space
:
normal
;
max-width
:
200px
;
opacity
:
0.6
;
font-style
:
italic
;
}
#buildHistory
.build-row-cell
{
position
:
relative
;
}
}
#buildHistory
.build-rss-links
{
#buildHistory
.build-rss-links
{
float
:
right
;
float
:
right
;
}
}
#buildHistory
.build-name
{
.build-row
{
max-width
:
120px
;
padding
:
3px
4px
3px
4px
;
}
.build-row
:hover
{
background
:
#e8e8e8
!important
;
}
.build-row-cell
{
font-size
:
12px
;
}
.build-row-cell
.pane.build-name
{
width
:
20%
;
font-weight
:
bold
;
}
.build-row-cell
.pane.build-details
{
width
:
50%
;
}
.build-row-cell
.pane.build-controls
{
width
:
30%
;
text-align
:
right
;
}
.build-row-cell
.pane.build-details.block
{
width
:
100%
;
}
.pane.build-name
a
,
.pane.build-name
a
:visited
{
color
:
black
;
text-decoration
:
underline
;
}
.pane.build-details
a
,
.pane.build-details
a
:visited
{
color
:
black
;
opacity
:
0.6
;
text-decoration
:
none
;
}
.pane.build-details
a
:hover
{
opacity
:
1.0
;
text-decoration
:
underline
;
}
.build-row.multi-line
.build-row-cell
.pane.build-name.block
{
width
:
100%
;
}
.build-row-cell
.pane.build-controls.block
{
width
:
100%
;
}
.build-row-cell
.pane.build-name
.build-icon
,
.build-row-cell
.pane.build-name
.display-name
{
display
:
inline-block
;
}
.build-row-cell
.pane.build-name
.build-icon
{
position
:
absolute
;
}
.build-row-cell
.build-stop
{
display
:
inline-block
;
width
:
30%
;
}
.build-row-cell
.build-badge
{
display
:
inline-block
;
padding
:
2px
;
width
:
70%
;
text-align
:
right
;
}
.build-row
.build-name-controls
.pane.build-name
,
.build-row
.build-details-controls
.pane.build-details
{
width
:
70%
;
}
.build-row
.build-row-cell
.pane
{
padding
:
0px
2px
;
/* Sync changes with func expandControlsTo50Percent in hudson-behavior.js */
display
:
inline-block
;
overflow
:
hidden
;
}
.build-row.multi-line
.build-row-cell
.block
{
display
:
block
;
overflow
:
auto
;
}
.build-row.multi-line
.build-row-cell
.indent-multiline
{
margin-top
:
5px
;
}
.build-row.multi-line
.build-row-cell
.left-bar
{
position
:
absolute
;
top
:
19px
;
bottom
:
3px
;
left
:
14px
;
border-left
:
1px
solid
#cdcdcd
;
}
.build-row-cell
.pane.build-name
.display-name
,
.build-row-cell
.indent-multiline
{
padding-left
:
20px
!important
;
/* Sync changes with func expandControlsTo50Percent in hudson-behavior.js */
}
.build-row
.build-row-cell
{
visibility
:
hidden
;
}
.build-row.overflow-checked
.build-row-cell
{
visibility
:
visible
;
}
/* ================ Element overflow calculation helper styles ================ */
.force-wrap
,
.force-wrap
a
{
white-space
:
normal
!important
;
overflow
:
visible
!important
;
}
.force-nowrap
,
.force-nowrap
a
{
white-space
:
nowrap
!important
;
overflow
:
hidden
!important
;
}
}
/* ========================= editable combobox style ========================= */
/* ========================= editable combobox style ========================= */
...
...
war/src/main/webapp/scripts/hudson-behavior.js
浏览文件 @
cb9036c4
...
@@ -1552,21 +1552,324 @@ Form.findMatchingInput = function(base, name) {
...
@@ -1552,21 +1552,324 @@ Form.findMatchingInput = function(base, name) {
return
null
;
// not found
return
null
;
// not found
}
}
function
onBuildHistoryChange
(
handler
)
{
Event
.
observe
(
window
,
'
jenkins:buildHistoryChanged
'
,
handler
);
}
function
fireBuildHistoryChanged
()
{
Event
.
fire
(
window
,
'
jenkins:buildHistoryChanged
'
);
}
function
updateBuildHistory
(
ajaxUrl
,
nBuild
)
{
function
updateBuildHistory
(
ajaxUrl
,
nBuild
)
{
if
(
isRunAsTest
)
return
;
if
(
isRunAsTest
)
return
;
$
(
'
buildHistory
'
).
headers
=
[
"
n
"
,
nBuild
];
var
bh
=
$
(
'
buildHistory
'
);
bh
.
headers
=
[
"
n
"
,
nBuild
];
function
getDataTable
(
buildHistoryDiv
)
{
return
$
(
buildHistoryDiv
).
getElementsBySelector
(
'
table.pane
'
)[
0
];
}
var
leftRightPadding
=
4
;
function
checkRowCellOverflows
(
row
)
{
if
(
!
row
)
{
return
;
}
if
(
Element
.
hasClassName
(
row
,
"
overflow-checked
"
))
{
// already done.
return
;
}
function
markSingleline
()
{
Element
.
addClassName
(
row
,
"
single-line
"
);
Element
.
removeClassName
(
row
,
"
multi-line
"
);
}
function
markMultiline
()
{
Element
.
removeClassName
(
row
,
"
single-line
"
);
Element
.
addClassName
(
row
,
"
multi-line
"
);
}
function
indentMultiline
(
element
)
{
Element
.
addClassName
(
element
,
"
indent-multiline
"
);
}
function
blockWrap
(
el1
,
el2
)
{
var
div
=
document
.
createElement
(
'
div
'
);
Element
.
addClassName
(
div
,
"
block
"
);
Element
.
addClassName
(
div
,
"
wrap
"
);
Element
.
addClassName
(
el1
,
"
wrapped
"
);
Element
.
addClassName
(
el2
,
"
wrapped
"
);
el1
.
parentNode
.
insertBefore
(
div
,
el1
);
el1
.
parentNode
.
removeChild
(
el1
);
el2
.
parentNode
.
removeChild
(
el2
);
div
.
appendChild
(
el1
);
div
.
appendChild
(
el2
);
return
div
;
}
function
blockUnwrap
(
element
)
{
var
wrapped
=
$
(
element
).
getElementsBySelector
(
'
.wrapped
'
);
for
(
var
i
=
0
;
i
<
wrapped
.
length
;
i
++
)
{
var
wrappedEl
=
wrapped
[
i
];
wrappedEl
.
parentNode
.
removeChild
(
wrappedEl
);
element
.
parentNode
.
insertBefore
(
wrappedEl
,
element
);
Element
.
removeClassName
(
wrappedEl
,
"
wrapped
"
);
}
element
.
parentNode
.
removeChild
(
element
);
}
var
buildName
=
$
(
row
).
getElementsBySelector
(
'
.build-name
'
)[
0
];
var
buildDetails
=
$
(
row
).
getElementsBySelector
(
'
.build-details
'
)[
0
];
if
(
!
buildName
||
!
buildDetails
)
{
return
;
}
var
displayName
=
$
(
buildName
).
getElementsBySelector
(
'
.display-name
'
)[
0
];
var
buildControls
=
$
(
row
).
getElementsBySelector
(
'
.build-controls
'
)[
0
];
var
desc
;
var
descElements
=
$
(
row
).
getElementsBySelector
(
'
.desc
'
);
if
(
descElements
.
length
>
0
)
{
desc
=
descElements
[
0
];
}
function
resetCellOverflows
()
{
markSingleline
();
// undo block wraps
var
blockWraps
=
$
(
row
).
getElementsBySelector
(
'
.block.wrap
'
);
for
(
var
i
=
0
;
i
<
blockWraps
.
length
;
i
++
)
{
blockUnwrap
(
blockWraps
[
i
]);
}
removeZeroWidthSpaces
(
displayName
);
removeZeroWidthSpaces
(
desc
);
Element
.
removeClassName
(
buildName
,
"
block
"
);
buildName
.
removeAttribute
(
'
style
'
);
Element
.
removeClassName
(
buildDetails
,
"
block
"
);
buildDetails
.
removeAttribute
(
'
style
'
);
if
(
buildControls
)
{
Element
.
removeClassName
(
buildControls
,
"
block
"
);
buildDetails
.
removeAttribute
(
'
style
'
);
}
}
// Undo everything from the previous poll.
resetCellOverflows
();
// Insert zero-width spaces so as to allow text to wrap, allowing us to get the true clientWidth.
insertZeroWidthSpaces
(
displayName
,
2
);
if
(
desc
)
{
insertZeroWidthSpaces
(
desc
,
30
);
markMultiline
();
}
var
rowWidth
=
bh
.
clientWidth
;
var
usableRowWidth
=
rowWidth
-
(
leftRightPadding
*
2
);
var
nameOverflowParams
=
getElementOverflowParams
(
buildName
);
var
detailsOverflowParams
=
getElementOverflowParams
(
buildDetails
);
var
controlsOverflowParams
;
if
(
buildControls
)
{
controlsOverflowParams
=
getElementOverflowParams
(
buildControls
);
}
if
(
nameOverflowParams
.
isOverflowed
)
{
// If the name is overflowed, lets remove the zero-width spaces we added above and
// re-add zero-width spaces with a bigger max word sizes.
removeZeroWidthSpaces
(
displayName
);
insertZeroWidthSpaces
(
displayName
,
20
);
}
function
fitToControlsHeight
(
element
)
{
if
(
buildControls
)
{
if
(
element
.
clientHeight
<
buildControls
.
clientHeight
)
{
$
(
element
).
setStyle
({
height
:
buildControls
.
clientHeight
.
toString
()
+
'
px
'
});
}
}
}
function
setBuildControlWidths
()
{
if
(
buildControls
)
{
var
buildBadge
=
$
(
buildControls
).
getElementsBySelector
(
'
.build-badge
'
)[
0
];
if
(
buildBadge
)
{
var
buildControlsWidth
=
buildControls
.
clientWidth
;
var
buildBadgeWidth
;
var
buildStop
=
$
(
buildControls
).
getElementsBySelector
(
'
.build-stop
'
)[
0
];
if
(
buildStop
)
{
$
(
buildStop
).
setStyle
({
width
:
'
24px
'
});
// Minus 24 for the buildStop width,
// minus 4 for left+right padding in the controls container
buildBadgeWidth
=
(
buildControlsWidth
-
24
-
leftRightPadding
);
if
(
Element
.
hasClassName
(
buildControls
,
"
indent-multiline
"
))
{
buildBadgeWidth
=
buildBadgeWidth
-
20
;
}
$
(
buildBadge
).
setStyle
({
width
:
(
buildBadgeWidth
)
+
'
px
'
});
}
else
{
$
(
buildBadge
).
setStyle
({
width
:
'
100%
'
});
}
}
controlsOverflowParams
=
getElementOverflowParams
(
buildControls
);
}
}
setBuildControlWidths
();
var
controlsRepositioned
=
false
;
if
(
nameOverflowParams
.
isOverflowed
||
detailsOverflowParams
.
isOverflowed
)
{
// At least one of the cells (name or details) needs to move to a row of its own.
markMultiline
();
if
(
buildControls
)
{
// We have build controls. Lets see can we find a combination that allows the build controls
// to sit beside either the build name or the build details.
var
badgesOverflowing
=
false
;
var
nameLessThanHalf
=
true
;
var
detailsLessThanHalf
=
true
;
var
buildBadge
=
$
(
buildControls
).
getElementsBySelector
(
'
.build-badge
'
)[
0
];
if
(
buildBadge
)
{
var
badgeOverflowParams
=
getElementOverflowParams
(
buildBadge
);
if
(
badgeOverflowParams
.
isOverflowed
)
{
// The badges are also overflowing. In this case, we will only attempt to
// put the controls on the same line as the name or details (see below)
// if the name or details is using less than half the width of the build history
// widget.
badgesOverflowing
=
true
;
nameLessThanHalf
=
(
nameOverflowParams
.
scrollWidth
<
usableRowWidth
/
2
);
detailsLessThanHalf
=
(
detailsOverflowParams
.
scrollWidth
<
usableRowWidth
/
2
);
}
}
function
expandLeftWithRight
(
leftCellOverFlowParams
,
rightCellOverflowParams
)
{
// Float them left and right...
$
(
leftCellOverFlowParams
.
element
).
setStyle
({
float
:
'
left
'
});
$
(
rightCellOverflowParams
.
element
).
setStyle
({
float
:
'
right
'
});
if
(
!
leftCellOverFlowParams
.
isOverflowed
&&
!
rightCellOverflowParams
.
isOverflowed
)
{
// If neither left nor right are overflowed, just leave as is and let them float left and right.
return
;
}
if
(
leftCellOverFlowParams
.
isOverflowed
&&
!
rightCellOverflowParams
.
isOverflowed
)
{
$
(
leftCellOverFlowParams
.
element
).
setStyle
({
width
:
leftCellOverFlowParams
.
scrollWidth
+
'
px
'
});
return
;
}
if
(
!
leftCellOverFlowParams
.
isOverflowed
&&
rightCellOverflowParams
.
isOverflowed
)
{
$
(
rightCellOverflowParams
.
element
).
setStyle
({
width
:
rightCellOverflowParams
.
scrollWidth
+
'
px
'
});
return
;
}
}
if
((
!
badgesOverflowing
||
nameLessThanHalf
)
&&
(
nameOverflowParams
.
scrollWidth
+
controlsOverflowParams
.
scrollWidth
<=
usableRowWidth
))
{
// Build name and controls can go on one row (first row). Need to move build details down
// to a row of its own (second row) by making it a block element, forcing it to wrap. If there
// are controls, we move them up to position them after the build name by inserting before the
// build details.
Element
.
addClassName
(
buildDetails
,
"
block
"
);
buildControls
.
parentNode
.
removeChild
(
buildControls
);
buildDetails
.
parentNode
.
insertBefore
(
buildControls
,
buildDetails
);
var
wrap
=
blockWrap
(
buildName
,
buildControls
);
Element
.
addClassName
(
wrap
,
"
build-name-controls
"
);
indentMultiline
(
buildDetails
);
nameOverflowParams
=
getElementOverflowParams
(
buildName
);
// recalculate
expandLeftWithRight
(
nameOverflowParams
,
controlsOverflowParams
);
setBuildControlWidths
();
fitToControlsHeight
(
buildName
);
}
else
if
((
!
badgesOverflowing
||
detailsLessThanHalf
)
&&
(
detailsOverflowParams
.
scrollWidth
+
controlsOverflowParams
.
scrollWidth
<=
usableRowWidth
))
{
// Build details and controls can go on one row. Need to make the
// build name (first field) a block element, forcing the details and controls to wrap
// onto the next row (creating a second row).
Element
.
addClassName
(
buildName
,
"
block
"
);
var
wrap
=
blockWrap
(
buildDetails
,
buildControls
);
indentMultiline
(
wrap
);
Element
.
addClassName
(
wrap
,
"
build-details-controls
"
);
$
(
displayName
).
setStyle
({
width
:
'
100%
'
});
detailsOverflowParams
=
getElementOverflowParams
(
buildDetails
);
// recalculate
expandLeftWithRight
(
detailsOverflowParams
,
controlsOverflowParams
);
setBuildControlWidths
();
fitToControlsHeight
(
buildDetails
);
}
else
{
// No suitable combo fits on a row. All need to go on rows of their own.
Element
.
addClassName
(
buildName
,
"
block
"
);
Element
.
addClassName
(
buildDetails
,
"
block
"
);
Element
.
addClassName
(
buildControls
,
"
block
"
);
indentMultiline
(
buildDetails
);
indentMultiline
(
buildControls
);
nameOverflowParams
=
getElementOverflowParams
(
buildName
);
// recalculate
detailsOverflowParams
=
getElementOverflowParams
(
buildDetails
);
// recalculate
setBuildControlWidths
();
}
controlsRepositioned
=
true
;
}
else
{
Element
.
addClassName
(
buildName
,
"
block
"
);
Element
.
addClassName
(
buildDetails
,
"
block
"
);
indentMultiline
(
buildDetails
);
}
}
if
(
buildControls
&&
!
controlsRepositioned
)
{
var
buildBadge
=
$
(
buildControls
).
getElementsBySelector
(
'
.build-badge
'
)[
0
];
if
(
buildBadge
)
{
var
badgeOverflowParams
=
getElementOverflowParams
(
buildBadge
);
if
(
badgeOverflowParams
.
isOverflowed
)
{
markMultiline
();
indentMultiline
(
buildControls
);
Element
.
addClassName
(
buildControls
,
"
block
"
);
controlsRepositioned
=
true
;
setBuildControlWidths
();
}
}
}
if
(
!
nameOverflowParams
.
isOverflowed
&&
!
detailsOverflowParams
.
isOverflowed
&&
!
controlsRepositioned
)
{
fitToControlsHeight
(
buildName
);
fitToControlsHeight
(
buildDetails
);
}
Element
.
addClassName
(
row
,
"
overflow-checked
"
);
}
function
checkAllRowCellOverflows
()
{
if
(
isRunAsTest
)
{
return
;
}
var
bh
=
$
(
'
buildHistory
'
);
var
dataTable
=
getDataTable
(
bh
);
var
rows
=
dataTable
.
rows
;
// Insert zero-width spaces in text that may cause overflow distortions.
var
displayNames
=
$
(
bh
).
getElementsBySelector
(
'
.display-name
'
);
for
(
var
i
=
0
;
i
<
displayNames
.
length
;
i
++
)
{
insertZeroWidthSpaces
(
displayNames
[
i
],
2
);
}
var
descriptions
=
$
(
bh
).
getElementsBySelector
(
'
.desc
'
);
for
(
var
i
=
0
;
i
<
descriptions
.
length
;
i
++
)
{
insertZeroWidthSpaces
(
descriptions
[
i
],
30
);
}
for
(
var
i
=
0
;
i
<
rows
.
length
;
i
++
)
{
var
row
=
rows
[
i
];
checkRowCellOverflows
(
row
);
}
}
var
updateBuildsRefreshInterval
=
5000
;
function
updateBuilds
()
{
function
updateBuilds
()
{
if
(
isPageVisible
()){
if
(
isPageVisible
()){
var
bh
=
$
(
'
buildHistory
'
);
if
(
bh
.
headers
==
null
)
{
if
(
bh
.
headers
==
null
)
{
// Yahoo.log("Missing headers in buildHistory element");
// Yahoo.log("Missing headers in buildHistory element");
}
}
function
getDataTable
(
buildHistoryDiv
)
{
return
$
(
buildHistoryDiv
).
getElementsBySelector
(
'
table.pane
'
)[
0
];
}
new
Ajax
.
Request
(
ajaxUrl
,
{
new
Ajax
.
Request
(
ajaxUrl
,
{
requestHeaders
:
bh
.
headers
,
requestHeaders
:
bh
.
headers
,
onSuccess
:
function
(
rsp
)
{
onSuccess
:
function
(
rsp
)
{
...
@@ -1598,17 +1901,128 @@ function updateBuildHistory(ajaxUrl,nBuild) {
...
@@ -1598,17 +1901,128 @@ function updateBuildHistory(ajaxUrl,nBuild) {
// next update
// next update
bh
.
headers
=
[
"
n
"
,
rsp
.
getResponseHeader
(
"
n
"
)];
bh
.
headers
=
[
"
n
"
,
rsp
.
getResponseHeader
(
"
n
"
)];
window
.
setTimeout
(
updateBuilds
,
5000
);
window
.
setTimeout
(
updateBuilds
,
updateBuildsRefreshInterval
);
checkAllRowCellOverflows
();
}
}
});
});
}
else
{
}
else
{
// Reschedule again
// Reschedule again
window
.
setTimeout
(
updateBuilds
,
5000
);
window
.
setTimeout
(
updateBuilds
,
updateBuildsRefreshInterval
);
}
}
}
}
window
.
setTimeout
(
updateBuilds
,
5000
);
window
.
setTimeout
(
updateBuilds
,
updateBuildsRefreshInterval
);
onPanelResize
(
function
()
{
checkAllRowCellOverflows
();
});
onBuildHistoryChange
(
function
()
{
checkAllRowCellOverflows
();
});
}
}
function
getElementOverflowParams
(
element
)
{
// First we force it to wrap so we can get those dimension.
// Then we force it to "nowrap", so we can get those dimension.
// We can then compare the two sets, which will indicate if
// wrapping is potentially happening, or not.
// Force it to wrap.
Element
.
addClassName
(
element
,
"
force-wrap
"
);
var
wrappedClientWidth
=
element
.
clientWidth
;
var
wrappedClientHeight
=
element
.
clientHeight
;
Element
.
removeClassName
(
element
,
"
force-wrap
"
);
// Force it to nowrap. Return the comparisons.
Element
.
addClassName
(
element
,
"
force-nowrap
"
);
var
nowrapClientHeight
=
element
.
clientHeight
;
try
{
var
overflowParams
=
{
element
:
element
,
clientWidth
:
wrappedClientWidth
,
scrollWidth
:
element
.
scrollWidth
,
isOverflowed
:
wrappedClientHeight
>
nowrapClientHeight
};
return
overflowParams
;
}
finally
{
Element
.
removeClassName
(
element
,
"
force-nowrap
"
);
}
}
var
zeroWidthSpace
=
String
.
fromCharCode
(
8203
);
function
insertZeroWidthSpaces
(
element
,
maxWordSize
)
{
if
(
Element
.
hasClassName
(
element
,
'
zws-inserted
'
))
{
// already done.
return
;
}
var
words
=
element
.
textContent
.
split
(
/
\s
+/
);
var
newTextContent
=
''
;
var
splitRegex
=
new
RegExp
(
'
.{1,
'
+
maxWordSize
+
'
}
'
,
'
g
'
);
for
(
var
i
=
0
;
i
<
words
.
length
;
i
++
)
{
var
word
=
words
[
i
];
var
wordTokens
=
word
.
match
(
splitRegex
);
if
(
wordTokens
)
{
for
(
var
ii
=
0
;
ii
<
wordTokens
.
length
;
ii
++
)
{
if
(
newTextContent
.
length
===
0
)
{
newTextContent
+=
wordTokens
[
ii
];
}
else
{
newTextContent
+=
zeroWidthSpace
+
wordTokens
[
ii
];
}
}
}
else
{
newTextContent
+=
word
;
}
newTextContent
+=
'
'
;
}
element
.
textContent
=
newTextContent
;
Element
.
addClassName
(
element
,
'
zws-inserted
'
);
}
function
removeZeroWidthSpaces
(
element
)
{
if
(
element
)
{
element
.
textContent
=
element
.
textContent
.
replace
(
zeroWidthSpace
,
''
);
Element
.
removeClassName
(
element
,
'
zws-inserted
'
);
}
}
function
onPanelResize
(
handler
)
{
Event
.
observe
(
window
,
'
jenkins:panelResized
'
,
handler
);
}
function
firePanelResized
()
{
Event
.
fire
(
window
,
'
jenkins:panelResized
'
);
}
Element
.
observe
(
document
,
'
dom:loaded
'
,
function
(){
if
(
isRunAsTest
)
{
return
;
}
var
fixedSidePanelWidth
=
360
;
var
pageBody
=
$
(
'
page-body
'
);
var
sidePanel
=
$
(
pageBody
).
getElementsBySelector
(
'
#side-panel
'
)[
0
];
var
mainPanel
=
$
(
pageBody
).
getElementsBySelector
(
'
#main-panel
'
)[
0
];
function
doPanelResize
()
{
var
pageBodyWidth
=
Element
.
getWidth
(
pageBody
);
if
(
pageBodyWidth
>
768
)
{
$
(
sidePanel
).
setAttribute
(
'
style
'
,
'
width:
'
+
fixedSidePanelWidth
+
'
px;
'
);
$
(
mainPanel
).
setAttribute
(
'
style
'
,
'
width:
'
+
(
pageBodyWidth
-
fixedSidePanelWidth
-
5
)
+
'
px;
'
);
}
else
{
$
(
sidePanel
).
removeAttribute
(
'
style
'
);
$
(
mainPanel
).
removeAttribute
(
'
style
'
);
}
firePanelResized
();
}
doPanelResize
();
Event
.
observe
(
window
,
'
resize
'
,
function
()
{
doPanelResize
();
});
});
// get the cascaded computed style value. 'a' is the style name like 'backgroundColor'
// get the cascaded computed style value. 'a' is the style name like 'backgroundColor'
function
getStyle
(
e
,
a
){
function
getStyle
(
e
,
a
){
if
(
document
.
defaultView
&&
document
.
defaultView
.
getComputedStyle
)
if
(
document
.
defaultView
&&
document
.
defaultView
.
getComputedStyle
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录