Initializing Background Loading Plugins

Plugins that specify a loading policy of "background" download in the background while EditLive! is initializing which gives faster start up times and a better user experience. The downside is that the plugin has to handle being loaded at an indeterminate time, possibly during or possibly after the editor has started up. Fortunately, handling this is actually quite straight forward.

As an example, we'll develop a simple framework for a plugin that will automatically convert links the user types in to clickable hyperlinks. We'll develop the initializing code in this article and the link conversion in part two. If you just want to get the functionality straight away, we've made available a ready-to-go plugin.

To get started, we need the standard constructor that takes an instance of ELJBean and stores it for use later. We also add ourselves as an editor event listener which is safe to do anytime and allows us to get notifications when the editor finishes loading.

public class Autolink implements EventListener {
  private ELJBean _bean;
  public Autolink(ELJBean bean) {
    _bean = bean;
    _bean.addEditorEventListener(this);
  }
}

Next, we add the raiseEvent method that looks for the TextEvent.LOADING_COMPLETE event and adds our listener.

public void raiseEvent(TextEvent e) {
  if (e.getActionCommand() == TextEvent.LOADING_COMPLETE) {
    initializePlugin();
  }
}

At this point (assuming we define initializePlugin, which we'll cover in part two), we have a plugin that works perfectly if it's loading policy is set to early. With background loading we also need to handle being loaded after the LOADING_COMPLETE event fires - with the current code, our plugin wouldn't initialize if it missed that event.

Revisiting the constructor, all we have to do is add the highlighted code below to check if the editor has loaded and immediately initialize if it has.

public Autolink(ELJBean bean) {
  _bean = bean;
  _bean.addEditorEventListener(this);
  if (_bean.isInitFinished()) {
    initializePlugin();
  }
}

That's it! Now if the editor is loaded when our plugin loads, the constructor will take care of initialization, otherwise the LOADING_COMPLETE event will trigger it. You can download the complete file and use it as a template for your own plugins.

Astute readers might be tempted to add synchronization to the class to avoid race conditions, however EditLive! actually takes care of it for us. Since plugins are so heavily oriented towards accessing Swing methods, they are always created on the Swing thread and EditLive! only ever calls the raiseEvent function on the swing thread. So our initialization code will only ever be called from the swing thread and we don't have to worry about threading issues.

The downside is that if your plugin needs to do anything complex for initializing, it needs to spawn a new thread to do the initialization off the swing thread or it may interrupt the user's work. Just make sure to use SwingUtilities.invokeLater to jump back onto the swing thread before accessing any Swing or EditLive! methods.

Adrian spends his days working out ways to make life easier for Ephox clients through initiatives like LiveWorks! Previously a senior engineer, he has now moved on to the fancier sounding title of CTO.

Leave a Reply