Documentation

JavaScript API

Table of contents

Sandboxing

An iframe instance whose parent and child reside on different domains or hostnames constitutes a sandboxed environment. The contained page has no access to its parent. These restrictions are imposed by the browser's same origin policy.

There are a few limitations applicable to iframes:

  • Stylesheet properties from the parent do not cascade to the child page
  • Child pages have no access to its parent's DOM and JavaScript properties
  • Likewise, the parent has no access to its child's DOM or JavaScript properties

However, Atlassian Connect makes use of a technique called cross-domain messaging. This technique uses postMessage to pass data between the iframe and its parent.

Atlassian Connect transparently enables cross-domain messaging in its page modules. One benefit you'll see from this is that your add-on's page modules are automatically resized based on its content when loaded on the page.

Only content within an element with the class ac-content will be resized automatically. Content without this identifier is sized according to the body element, and is not dynamically resized. The recommended DOM layout for your addon is:

<div class="ac-content">
    <div id="your-id-here">
        <p>Addon content goes here</p>
    </div>

    ...this area reserved for our resize sensor divs
</div>

Sharing data between iframes

A single add-on can generate multiple iframes in a particular page in the target application. Depending on the use case for the add-on, the iframes may need to share information between each other.

The Atlassian Connect JavaScript client library, all.js, provides a publish/subscribe mechanism that you can use to exchange data between iframes.

A common scenario in which a single add-on presents multiple iframes in a page is where a web panel or other page element spawns a dialog box.

The only restriction on the data shared in this manner is that it must be serializable using the structured clone algorithm.

For more information on the event API visit the events documentation.

JavaScript client library

Atlassian Connect provides a JavaScript client library called all.js. The Atlassian application hosts this file, making it available at the following location relative to the Atlassian application URL:

https://{HOSTNAME}/{CONTEXT}/atlassian-connect/all.js

For example:

https://acme-corp.atlassian.net/atlassian-connect/all.js

This library establishes the cross-domain messaging bridge with its parent. It also provides several methods and objects that you can use in your pages without making a trip back to your add-on server.

You must add the all.js script to your pages in order to establish the cross-domain messaging bridge. Make sure your pages include the following script:

<script src="https://{HOSTNAME}/{CONTEXT}/atlassian-connect/all.js"></script>

If you're using the atlassian-connect-express client library to build your add-on, this will automatically be inserted into your pages at run time.

Note:

Don't download the all.js file and serve it up from your add-on server directly. The all.js file must be served up by the product host in order for the cross-domain messaging bridge to be established. For determining the host's url in a static add-on, see this recipe from the Connect cookbook.

Options

The JavaScript client library has some configuration options for customizing its behavior. The options are passed using the data-options attribute.

<script src="https://{HOSTNAME}/{CONTEXT}/atlassian-connect/all.js" data-options="option1:value;option2:value"></script>

If you are using requirejs or other dynamic script loader, use an element with an id of ac-iframe-options in place of a script tag.

<div id="ac-iframe-options" data-options="option1:value;option2:value"></div>

The following options are currently supported:

Option Values Default Description
resize true or false true You can deactivate the automatic resizing by setting resize=false.
sizeToParent true or false false With sizeToParent:true, the iframe will take up its parent's space (instead of being sized to its internal content).
margin true or false true If true, the margin option sets the body element's top, right and left margin to 10px for dialogs, and to 0 for non-dialog pages.
base true or false false With base:true, a base tag pointing to the host page is injected: <base href="{host}" target="_parent" />. This can be useful for embedded links to product pages.

Debugging all.js

A non-compressed version of the all.js javascript can be viewed by replacing all.js with all-debug.js for example:

<script src="https://{HOSTNAME}/{CONTEXT}/atlassian-connect/all.js"></script>
<!-- replace with -->
<script src="https://{HOSTNAME}/{CONTEXT}/atlassian-connect/all-debug.js"></script>

This can be helpful when trying to trace errors or debug the add-on javascript.

Note on URL Encoding

URL query parameters are encoded as application/x-www-form-urlencoded. This converts spaces to + which can cause issues when using JavaScript functions such as decodeURIComponent. A simple way to handle this is to convert + to %20 before decoding. A utility function decodeQueryComponent is provided for this purpose. For example:

AP.require("_util", function(util){
  alert(util.decodeQueryComponent(window.location.href));
});

Cookbook

The cookbook is filled with snippets of client side JavaScript code, providing examples for making simple client side add-ons, and gathering data from the products JavaScript API methods.

Loading all.js from the host application for static add-ons

Loading all.js is necessary to use the AP object and access Connect APIs. This sample only applies to static add-ons. Add-ons with server components should validate JWT signatures on the server, and then generate the URL for all.js. Accepting <script> tag locations from untrusted query string sources could open your application up to XSS attacks.

If you want to set data-options for all.js, define them in the <script> tag as seen in the sample.

<script id="connect-loader" data-options="sizeToParent:true;">
(function() {
  var getUrlParam = function (param) {
    var codedParam = (new RegExp(param + '=([^&]*)')).exec(window.location.search)[1];
    return decodeURIComponent(codedParam);
  };

  var baseUrl = getUrlParam('xdm_e') + getUrlParam('cp');
  var options = document.getElementById('connect-loader').getAttribute('data-options');

  var script = document.createElement("script");
  script.src = baseUrl + '/atlassian-connect/all.js';

  if(options) {
    script.setAttribute('data-options', options);
  }

  document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>

Creating modules for AP.require

AP.require and AP.define are deprecated and will be removed after August 2017.

The available modules can now be called directly from AP, such as AP.request or AP.jira. No alternative will be provided for AP.define. See Migrate to Atlassian Connect JavaScript V5 for more information.

You can create your own modules to be included when required. A simple example creating an object myObject with a single function bonusFunction which returns a string of +1. We can take myObject as a dependency then print the results of bonusFunction to the console.

AP.define('myObject', function() {
  return {
    bonusFunction: function() {
      return "+1";
    }
  }
});
AP.require('myObject', function(myObject) {
  console.log(myObject.bonusFunction());
});

Product cookbooks

For product specific examples of what you can do through the front end JavaScript API that Connect provides, check out: