Web resources allow you to include JavaScript and CSS resources into certain contexts. For example, in Bamboo, you might want to change the style of the build results. You can read more about web resource modules for Bamboo in Atlassian’s documentation.

Setup

Web resources need to be loaded either from a plugin, or from specified directories. You can provide a list of directories using the system property plugin.resource.directories. It makes sense to use the default scripts directory, which is automatically created in your application "home" directory.

If you do this you can modify your setenv.sh (or .bat) script like so:

JVM_REQUIRED_ARGS='-Dplugin.resource.directories=/app/home/scripts -Dother.properties...'

You can provide multiple, comma-delimited directories if you want, in which case the resource loader will search them in order until it finds a matching file.

Reloading

When a web resource is found, it is cached to improve performance.

That means that you cannot change your resource and have it instantly reloaded. After changing the resource, you need to edit the web-resource item in the UI, and update, then hard refresh in your browser.

This is not the case when running with the JVM argument -Datlassian.dev.mode=true, in which case reloading should "just work". Which means you should work on your web resources in a dev environment, then transfer them to your production environment when you are finished.

Basic Example

Modifying CSS

As an example, let’s modify the CSS on the build results page.

Go to Admin → Script Fragments → Install Web Resource. Fill out the form as follows:

web resource

The main thing to copy is the context, which should be bamboo.result. The key only needs to be unique.

Clicking Preview or Update will give you an error at this point, as you have not yet created the resource: myCssResource.css.

In a text editor, create this directory and file under one of the directories you have defined in plugin.resource.directories…​ if you took the advice above then this would be <app.home>/scripts. Enter the contents:

.status-ribbon-status.Successful {
    background: #E87722 !important;
}

Now return to the page and click Update. If you still get an error, double check the list of configured resource directories that the error spits out. Make sure the place you dropped myCssResource.css is one of them.

If you navigate to a successful build, it should have an orange banner now instead of the typical green.

orange build

A trivial example, but the full power of CSS is now yours to command.

Modifying JavaScript

The process for adding a JavaScript file is the same as the above; just point to a .js file that you create in the same directory. Try adding a simple file called myJsResource.js with contents like

alert("Custom javascript file loaded!");

Or, perhaps more gently,

console.log("Custom javascript file loaded!");

to a resource directory. You can even add it to the same script fragment that we used in the CSS example.

myCssResource.css
myJsResource.js

Navigate to a build results page, and you should get the alert (or console log, if you went that route).

Deep Dive: Dialog Buttons and JavaScript

A practical example would be to wire up the buttons of a custom dialog using a JavaScript resource.

Let’s say we want to add a button to our dialog box that, when clicked, inserts a cat picture into the middle of the dialog. As of this writing, there’s an inexplicable free API we can use to facilitate that.

First, create a REST Endpoint similar to the one in the Web Items documentation.

import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript

import javax.ws.rs.core.MediaType
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

showCatDialog() { MultivaluedMap queryParams ->

    def dialog =
        """<section role="dialog" id="sr-dialog" class="aui-layer aui-dialog2 aui-dialog2-medium" aria-hidden="true" data-aui-remove-on-hide="true">
            <header class="aui-dialog2-header">
                <h2 class="aui-dialog2-header-main">Some dialog</h2>
                <a class="aui-dialog2-header-close">
                    <span class="aui-icon aui-icon-small aui-iconfont-close-dialog">Close</span>
                </a>
            </header>
            <div class="aui-dialog2-content">
                <p>This is a dialog... with cats.</p>
                <button id="scriptrunnerpluscatsequalsawesome">Click here for feline</button>
            </div>
            <footer class="aui-dialog2-footer">
                <div class="aui-dialog2-footer-actions">
                    <button id="dialog-close-button" class="aui-button aui-button-link">Close</button>
                </div>
                <div class="aui-dialog2-footer-hint">Some hint here if you like</div>
            </footer>
        </section>
        """

    Response.ok().type(MediaType.TEXT_HTML).entity(dialog.toString()).build()
}

Now, create a JavaScript file in your script roots with contents like the following:

(function ($) {
    $(function () {
        AJS.dialog2.on('show', function (dialogShownEvent) {
            if (dialogShownEvent.target.id == "sr-dialog") {
                let catButton = document.getElementById('scriptrunnerpluscatsequalsawesome');
                catButton.addEventListener('click', function (event) {
                    let parentDiv = event.target.parentElement;
                    let catPicture = document.createElement('img');
                    catPicture.setAttribute('src', 'http://thecatapi.com/api/images/get?format=src&type=gif');
                    catPicture.setAttribute('alt', 'A most dapper animated feline');
                    parentDiv.appendChild(catPicture);
                }, false);
            }
        });
    });
})(AJS.$);

Then, configure that file as a Web Resource in the atl.general context (or whatever context you decided to put your dialog button into).

For how-to questions please ask on Atlassian Answers where there is a very active community. Adaptavist staff are also likely to respond there.

Ask a question about ScriptRunner for JIRA, for for Bitbucket Server, or for Confluence.