diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/job/console/NewNodeConsoleNote/script.js b/src/main/resources/org/jenkinsci/plugins/workflow/job/console/NewNodeConsoleNote/script.js index 3b588541..7c7e82ca 100644 --- a/src/main/resources/org/jenkinsci/plugins/workflow/job/console/NewNodeConsoleNote/script.js +++ b/src/main/resources/org/jenkinsci/plugins/workflow/job/console/NewNodeConsoleNote/script.js @@ -1,41 +1,62 @@ -Behaviour.specify("span.pipeline-new-node", 'NewNodeConsoleNote', 0, function(e) { - if (e.processedNewNodeConsoleNote) { - return - } - e.processedNewNodeConsoleNote = true - var label = e.getAttribute('label') +/** + * Fix label attributes + */ +function fixLabels(pipelineElement) { + var label = pipelineElement.getAttribute('label') if (label != null) { - var html = e.innerHTML + var html = pipelineElement.innerHTML var suffix = ' (' + label.escapeHTML() + ')'; if (html.indexOf(suffix)<0) { - e.innerHTML = e.innerHTML.replace(/.+/, '$&' + suffix) // insert before EOL - } - } - var nodeId = e.getAttribute('nodeId') - var startId = e.getAttribute('startId') - if (startId == null || startId == nodeId) { - e.innerHTML = e.innerHTML.replace(/.+/, '$& (hide)') - // TODO automatically hide second and subsequent branches: namely, in case a node has the same parent as an earlier one - } - // The CSS rule for branch names only needs to be added once per node, so we - // check in case we are viewing the truncated log and have already processed - // a duplicate synthetic span element for this node. - var maybeDupeNodes = $$('[nodeid=\"'+nodeId+'\"].pipeline-new-node'); - for (var i = 0; i < maybeDupeNodes.length; i++) { - var node = maybeDupeNodes[i]; - if (node !== e && node.processedNewNodeConsoleNote) { - return; + pipelineElement.innerHTML = pipelineElement.innerHTML.replace(/.+/, '$&' + suffix) // insert before EOL } - } - var nodes = $$('.pipeline-new-node') + } +} + +/** + * Generate hide/show links for all of the pipeline elements + */ +function addLinks (pipelineElement) { + var nodeId = pipelineElement.getAttribute('nodeId') + var startId = pipelineElement.getAttribute('startId') + if (startId == null || startId == nodeId) { + pipelineElement.innerHTML = pipelineElement.innerHTML.replace(/.+/, '$& (hide)') + } +} + +/** + * Generate enclosings for a element + */ +function generateEnclosing (node) { + var enclosings = new Map() + var labels = new Map() + var oid = node.getAttribute('nodeId') + + enclosings.set(oid, node.getAttribute('enclosingId')) + labels.set(oid, node.getAttribute('label')) +} + +/** + * Generate enclosings and labels for all of the pipeline elements + */ +function generateEnclosings () { var enclosings = new Map() // id → enclosingId var labels = new Map() // id → label + var nodes = $$(".pipeline-new-node") + for (var i = 0; i < nodes.length; i++) { var node = nodes[i] var oid = node.getAttribute('nodeId') + enclosings.set(oid, node.getAttribute('enclosingId')) labels.set(oid, node.getAttribute('label')) + appendBranchNames(oid, enclosings, labels) } +} + +/** + * Inject the branch name in the pipeline label + */ +function appendBranchNames(nodeId, enclosings, labels) { var id = nodeId while (true) { id = enclosings.get(id) @@ -51,12 +72,25 @@ Behaviour.specify("span.pipeline-new-node", 'NewNodeConsoleNote', 0, function(e) break } } -}); +} + +/** + * Determine if the pipeline contains parallel steps + */ +function isParallelBuild(node) { + return node.innerHTML.includes('parallel') +} +/** + * Functionality to show/hide a pipeline step (label) + * + * @param link - hyperlink element + **/ function showHidePipelineSection(link) { var span = link.parentNode.parentNode var id = span.getAttribute('nodeId') var display + if (link.textContent === 'hide') { display = 'none' link.textContent = 'show' @@ -66,7 +100,8 @@ function showHidePipelineSection(link) { link.textContent = 'hide' link.parentNode.className = 'pipeline-show-hide' } - var showHide = function(id, display) { + + var showHide = function (id, display) { var sect = '.pipeline-node-' + id var ss = document.styleSheets[0] for (var i = 0; i < ss.cssRules.length; i++) { @@ -84,6 +119,7 @@ function showHidePipelineSection(link) { var ids = [] var starts = new Map() var enclosings = new Map() // id → enclosingId + for (var i = 0; i < nodes.length; i++) { var node = nodes[i] var oid = node.getAttribute('nodeId') @@ -91,7 +127,8 @@ function showHidePipelineSection(link) { starts.set(oid, node.getAttribute('startId')) enclosings.set(oid, node.getAttribute('enclosingId')) } - var encloses = function(enclosing, enclosed, starts, enclosings) { + + var encloses = function (enclosing, enclosed, starts, enclosings) { var id = enclosed var start = starts.get(id) if (start != null && start != id) { @@ -107,6 +144,7 @@ function showHidePipelineSection(link) { } } } + for (var i = 0; i < ids.length; i++) { var oid = ids[i] if (oid != id && encloses(id, oid, starts, enclosings)) { @@ -127,3 +165,22 @@ function showHidePipelineSection(link) { } } } + +Behaviour.specify("span.pipeline-new-node", 'NewNodeConsoleNote', 0, function(e) { + // check if the current element has already been processed + if (e.processedNewNodeConsoleNote) { + return + } + e.processedNewNodeConsoleNote = true + + // fix labels, generate hide/show links and generate enclosings for each element + fixLabels(e) + addLinks(e) + generateEnclosing(e); + + // if a parallel build is underway, append branch names to the elements + // Note: we need to traverse all of the elements in parallel builds + if (isParallelBuild(e)) { + generateEnclosings() + } +});