From 03c029301a30aa8be95d19862f5df673dc37ff52 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Tue, 16 Sep 2025 00:05:13 +0200 Subject: [PATCH 1/2] Add ext-searchbox in workflow-editor This a preliminary patch to add the workflow editor. Some patches need to be added on top to make it cooperate better with samples pipeline select menu. Signed-off-by: Michael Trimarchi --- plugin/src/main/js/workflow-editor.js | 2 ++ .../jenkinsci/plugins/workflow/editor/workflow-editor.jelly | 1 + plugin/webpack.common.js | 3 +++ 3 files changed, 6 insertions(+) diff --git a/plugin/src/main/js/workflow-editor.js b/plugin/src/main/js/workflow-editor.js index 1952cc5ea..cbda3aa1a 100644 --- a/plugin/src/main/js/workflow-editor.js +++ b/plugin/src/main/js/workflow-editor.js @@ -8,6 +8,7 @@ import ace from "ace-builds/src-noconflict/ace"; import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-groovy"; import "ace-builds/src-noconflict/snippets/javascript"; +import "ace-builds/src-noconflict/ext-searchbox"; // Import custom snippets import "./snippets/workflow"; @@ -103,6 +104,7 @@ $(function() { // can be used to get them going. if (editor.getValue() === '') { addSamplesWidget(editor, editorId, aceContainer.attr('samplesUrl')); + editor.searchBox.hide(); } } showSamplesWidget(); diff --git a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/editor/workflow-editor.jelly b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/editor/workflow-editor.jelly index d068312ba..651375a07 100644 --- a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/editor/workflow-editor.jelly +++ b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/editor/workflow-editor.jelly @@ -17,6 +17,7 @@
+ diff --git a/plugin/webpack.common.js b/plugin/webpack.common.js index 99998763c..604ce1f6b 100644 --- a/plugin/webpack.common.js +++ b/plugin/webpack.common.js @@ -9,6 +9,9 @@ module.exports = { path.join(__dirname, 'src/main/js/workflow-editor.js'), path.join(__dirname, 'src/main/less/workflow-editor.less'), ], + "ext-searchbox": [ + path.join(__dirname, 'node_modules/ace-builds/src-noconflict/ext-searchbox.js'), + ], }, output: { path: path.join( From bc7be1b65ac8456b646231e4b103d04944cffecc Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Tue, 16 Sep 2025 22:03:24 +0200 Subject: [PATCH 2/2] workflow-editor: Align the code, no functional change Signed-off-by: Michael Trimarchi --- plugin/src/main/js/workflow-editor.js | 185 +++++++++++++------------- 1 file changed, 93 insertions(+), 92 deletions(-) diff --git a/plugin/src/main/js/workflow-editor.js b/plugin/src/main/js/workflow-editor.js index cbda3aa1a..f61ccb768 100644 --- a/plugin/src/main/js/workflow-editor.js +++ b/plugin/src/main/js/workflow-editor.js @@ -32,104 +32,105 @@ $(function() { var editorId = 'workflow-editor-' + editorIdCounter; aceContainer.attr('id', editorId); - var editor = ace.edit(editorId); - - // Attach the ACE editor instance to the element. Useful for testing. - var $wfEditor = $('#' + editorId); - $wfEditor.get(0).aceEditor = editor; - - // https://stackoverflow.com/a/66923593 - var snippetManager = ace.require('ace/snippets').snippetManager; - var snippetContent = ace.require('ace/snippets/groovy').snippetText; - var snippets = snippetManager.parseSnippetFile(snippetContent); - snippetManager.register(snippets, 'groovy'); - editor.session.setMode("ace/mode/groovy"); - editor.setAutoScrollEditorIntoView(true); - editor.setOption("minLines", 20); - // enable autocompletion and snippets - editor.setOptions({ - enableBasicAutocompletion: true, - enableSnippets: true, - enableLiveAutocompletion: false - }); - - editor.setValue(textarea.val(), 1); - // eslint-disable-next-line no-unused-vars - editor.getSession().on('change', function(delta) { - textarea.val(editor.getValue()); - showSamplesWidget(); - }); - - editor.on('blur', function() { - editor.session.clearAnnotations(); - var url = textarea.attr("checkUrl") + 'Compile'; - - - fetch(url, { - method: textarea.attr('checkMethod') || 'POST', - headers: crumb.wrap({ // eslint-disable-line no-undef - "Content-Type": "application/x-www-form-urlencoded", - }), - body: new URLSearchParams({ - value: editor.getValue(), - }), - }).then((rsp) => { - if (rsp.ok) { - rsp.json().then((json) => { - var annotations = []; - if (json.status && json.status === 'success') { - // Fire script approval check - only if the script is syntactically correct - textarea.trigger('change'); - return; - } else { - // Syntax errors - $.each(json, function(i, value) { - annotations.push({ - row: value.line - 1, - column: value.column, - text: value.message, - type: 'error' - }); - }); - } - editor.getSession().setAnnotations(annotations); + var editor = ace.edit(editorId); + + // Attach the ACE editor instance to the element. Useful for testing. + var $wfEditor = $('#' + editorId); + $wfEditor.get(0).aceEditor = editor; + + // https://stackoverflow.com/a/66923593 + var snippetManager = ace.require('ace/snippets').snippetManager; + var snippetContent = ace.require('ace/snippets/groovy').snippetText; + var snippets = snippetManager.parseSnippetFile(snippetContent); + snippetManager.register(snippets, 'groovy'); + editor.session.setMode("ace/mode/groovy"); + editor.setAutoScrollEditorIntoView(true); + editor.setOption("minLines", 20); + // enable autocompletion and snippets + editor.setOptions({ + enableBasicAutocompletion: true, + enableSnippets: true, + enableLiveAutocompletion: false + }); + + editor.setValue(textarea.val(), 1); + // eslint-disable-next-line no-unused-vars + editor.getSession().on('change', function(delta) { + textarea.val(editor.getValue); + showSamplesWidget(); + }); + + editor.on('blur', function() { + editor.session.clearAnnotations(); + var url = textarea.attr("checkUrl") + 'Compile'; + + fetch(url, { + method: textarea.attr('checkMethod') || 'POST', + headers: crumb.wrap({ // eslint-disable-line no-undef + "Content-Type": "application/x-www-form-urlencoded", + }), + body: new URLSearchParams({ + value: editor.getValue(), + }), + }).then((rsp) => { + if (rsp.ok) { + rsp.json().then((json) => { + var annotations = []; + if (json.status && json.status === 'success') { + // Fire script approval check - only if the script is syntactically correct + textarea.trigger('change'); + return; + } else { + // Syntax errors + $.each(json, function(i, value) { + annotations.push({ + row: value.line - 1, + column: value.column, + text: value.message, + type: 'error' + }); }); } + editor.getSession().setAnnotations(annotations); }); - }); - - function showSamplesWidget() { - // If there's no workflow defined (e.g. on a new workflow), then - // we add a samples widget to let the user select some samples that - // can be used to get them going. - if (editor.getValue() === '') { - addSamplesWidget(editor, editorId, aceContainer.attr('samplesUrl')); - editor.searchBox.hide(); - } } - showSamplesWidget(); - - // Make the editor resizable using jQuery UI resizable (http://api.jqueryui.com/resizable). - // ACE Editor doesn't have this as a config option. - $wfEditor.wrap('
'); - $wfEditor.resizable({ - handles: "s", // Only allow vertical resize off the bottom/south border - minHeight: 100, - resize: function () { - // Use requestAnimationFrame to throttle resizes to happen before frame render - requestAnimationFrame(() => { - editor.resize(); - // window.layoutUpdateCallback is defined in Jenkins core. - // call it to allow buttonbars that are fixed on the screen to be pushed down - // when the editor size is increased. - if (window.layoutUpdateCallback) { - window.layoutUpdateCallback.call(); - } - }) - }, }); + }); + + function showSamplesWidget() { + // If there's no workflow defined (e.g. on a new workflow), then + // we add a samples widget to let the user select some samples that + // can be used to get them going. + if (editor.getValue() === '') { + addSamplesWidget(editor, editorId, aceContainer.attr('samplesUrl')); + editor.searchBox.hide(); + } + } + + showSamplesWidget(); + + // Make the editor resizable using jQuery UI resizable (http://api.jqueryui.com/resizable). + // ACE Editor doesn't have this as a config option. + $wfEditor.wrap('
'); + $wfEditor.resizable({ + handles: "s", // Only allow vertical resize off the bottom/south border + minHeight: 100, + resize: function () { + // Use requestAnimationFrame to throttle resizes to happen before frame render + requestAnimationFrame(() => { + editor.resize(); + // window.layoutUpdateCallback is defined in Jenkins core. + // call it to allow buttonbars that are fixed on the screen to be pushed down + // when the editor size is increased. + if (window.layoutUpdateCallback) { + window.layoutUpdateCallback.call(); + } + }) + }, + }); wrapper.show(); textarea.hide(); } -}); + } +);