Edit online

Workspace Access Plugin Extension (JavaScript-Based)

This is a JavaScript-based plugin extension that allows you to contribute actions to the main menu and toolbars, create custom views, interact with the application workspace, make modifications to opened documents, and add listeners for various events.

This extension can use the same API as the Workspace Access plugin extension, but the implementation is JavaScript-based and uses the bundled Rhino library to create and work with Java API from the JavaScript code.

First, you need to create a custom plugin folder inside the plugins folder (for example, [OXYGEN_INSTALL_DIR]/plugins/myPlugin). This folder will contain your custom plugin descriptor file (plugin.xml) and all other resources for the plugin.

The plugin descriptor file (named plugin.xml) needs to reference a JavaScript file, as in the following example:
<!DOCTYPE plugin PUBLIC "-//Oxygen Plugin" "../plugin.dtd">
<plugin
 id="unique.id.value"
 name="Add Action To DITA Maps Manager popup-menu"
 description="Plugin adds action to DITA Maps Manager contextual menu."
 version="1.0"
 vendor="Syncro Soft"
 class="ro.sync.exml.plugin.Plugin"
 classLoaderType="preferReferencedResources">
 <extension type="WorkspaceAccessJS" href="wsAccess.js"/>
</plugin>
In the example above, the JavaScript file wsAccess.js (located in your custom plugin folder) will be called. This JavaScript file needs to have two JavaScript methods defined inside. Methods that will be called when the application starts and when it ends:
function applicationStarted(pluginWorkspaceAccess) {
..........
}

function applicationClosing(pluginWorkspaceAccess) {
..........
}

With regard to the applicationStarted callback, besides using the ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace API with the pluginWorkspaceAccess parameter, you can also use a globally defined field called jsDirURL that points to the folder where the JavaScript file is located.

Below is a much larger example with a JavaScript Workspace Access plugin extension implementation that adds a new action in the contextual menu of the DITA Maps Manager view. The action starts the notepad.exe application and passes the reference to the currently selected <topicref> to it.
function applicationStarted(pluginWorkspaceAccess) {
 Packages.java.lang.System.err.println("Application started "
      + pluginWorkspaceAccess);
 edChangedListener = {
  /*Called when a DITA Map is opened*/
   editorOpened: function (editorLocation) {
   Packages.java.lang.System.err.println("\nrunning " + editorLocation);
  /*Get the opened DITA Map*/
   editor = pluginWorkspaceAccess.getEditorAccess(editorLocation, 
   Packages.ro.sync.exml.workspace.api.PluginWorkspace.DITA_MAPS_EDITING_AREA);
   ditaMapPage = editor.getCurrentPage();
  /*Add listener called when right-click is done in the DITA Maps manager*/
   customizerObj = {
   customizePopUpMenu: function (popUp, ditaMapDocumentController) {
   Packages.java.lang.System.err.println("RIGHT CLICK" + popUp);
   tree = ditaMapPage.getDITAMapTreeComponent();
  /*Selected tree path*/
   sel = tree.getSelectionPath();
   if (sel != null) {
   selectedElement = sel.getLastPathComponent();
  /*Reference attribute*/
   href = selectedElement.getAttribute("href");
   if (href != null) {
     try {
  /*Create absolute reference*/
   absoluteRef = new Packages.java.net.URL(selectedElement.getXMLBaseURL(), 
           href.getValue());
   Packages.java.lang.System.err.println("Computed absolute reference "
         + absoluteRef);
   mi = new Packages.javax.swing.JMenuItem("Run notepad");
        popUp.add(mi);
        actionPerfObj = {
        actionPerformed: function (e) {
          try {
           Packages.java.lang.Runtime.getRuntime().exec("notepad.exe " 
               + pluginWorkspaceAccess.getUtilAccess().locateFile(absoluteRef));
          }
        catch (e1) {
         e1.printStackTrace();
          }
         }
        }
   mi.addActionListener(new JavaAdapter(Packages.java.awt.event.ActionListener, 
            actionPerfObj));
       }
       catch (e1) {
        Packages.java.lang.System.err.println(e1);
       }
      }
     }
    }
   }
   
   ditaMapPage.setPopUpMenuCustomizer(new Packages.ro.sync.exml.workspace.api.
editor.page.ditamap.DITAMapPopupMenuCustomizer(customizerObj));
  }
 }
   edChangedListener = new JavaAdapter(Packages.ro.sync.exml.workspace.api.
listeners.WSEditorChangeListener, edChangedListener);
   pluginWorkspaceAccess.addEditorChangeListener(
   edChangedListener,
   Packages.ro.sync.exml.workspace.api.PluginWorkspace.DITA_MAPS_EDITING_AREA);
}

 function applicationClosing(pluginWorkspaceAccess) {
   Packages.java.lang.System.err.println("Application closing "
        + pluginWorkspaceAccess);
}

Declaring Multiple Modules

JavaScript-based plugins can include multiple modules of JavaScript files in the plugin. In those files, you can declare functions that can be used in the main WorkspaceAccessJS JavaScript file. Thus, you can use those external script files as a library of functions. The modules must be declared in the plugin descriptor file (plugin.xml).

For example:
<!DOCTYPE plugin PUBLIC "-//Oxygen Plugin" "../plugin.dtd">
<plugin
 id="unique.id.value"
 name="Add Action To DITA Maps Manager popup-menu"
 description="Plugin adds action to DITA Maps Manager contextual menu."
 version="1.0"
 vendor="Syncro Soft"
 class="ro.sync.exml.plugin.Plugin"
 classLoaderType="preferReferencedResources">
 <extension type="WorkspaceAccessJS" href="wsAccess.js"/>
 <extension type="WorkspaceAccessJSModule" href="wsAccessModule1.js"/>
 <extension type="WorkspaceAccessJSModule" href="wsAccessModule2.js"/>
</plugin>

For more information and some samples, see GitHub Project with Multiple Workspace Access JavaScript-Based Plugin Samples.