Skip to content
Victor Sosa edited this page Aug 10, 2016 · 18 revisions

Extension points

ternNatureAdapters

This will allow Tern.java to be seamlessly integrated to other products. See issue 38 and issue 99 for discussion about this extension point.

You can find the following sample in the Eclispe project ternNatureAdapters

Other products may declare a custom project nature to be treated as a Tern nature by adding the following extension into some plugin.xml with tern.eclipse.ide.core.ternNatureAdapters extension point.

Here a sample with ternAdaptToNature which adds automaticly tern nature for each project which have org.nodeclipse.ui.NodeNature nature and configure the .tern-poject with node tern module :

<extension point="tern.eclipse.ide.core.ternNatureAdapters">
    <ternAdaptToNature
        id="org.nodeclipse.ui.nature"
        name="NodeclipseTernNatureCapability" >
        <defaultModules>
            <module name="node" withDependencies="true"/>
        </defaultModules>
    </ternAdaptToNature>
</extension>

where ternAdaptToNature/@id is the nature to check to consider the project as tern project.

This extension point avoids :

  • configuring your node project with the menu item Convert to Tern project...
  • select node tern module in your project properties Tern -> Modules.

ITernNatureCapability

Note that you can do the same thing with ternAdaptToNature/@class :

<extension point="tern.eclipse.ide.core.ternNatureAdapters">
    <ternAdaptToNature
        id="org.nodeclipse"
        name="NodeclipseTernNatureCapability"
        class="org.nodeclipse.ui.nature.NodeclipseTernNatureCapability" >
        <defaultModules>
            <module name="node" withDependencies="true"/>
        </defaultModules>
    </ternAdaptToNature>
</extension>

where org.nodeclipse.ui.nature.NodeclipseTernNatureCapability looks like this : :

package org.nodeclipse.ui.nature;
	
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
	
import tern.eclipse.ide.core.ITernNatureCapability;
	
public class NodeclipseTernNatureCapability implements ITernNatureCapability {
	
	@Override
	public boolean hasTernNature(IProject project) throws CoreException {
		return project.hasNature("org.nodeclipse.ui.NodeNature");
	}	
}

IDefaultTernModulesProvider

The following sample uses static default tern modules. If you wish to add default tern modules with dynamic mean (eg : for some tern modules which supports version like AlloyUI), you can implement tern.eclipse.ide.core.IDefaultTernModulesProvider like this :

package org.nodeclipse.ui.nature;
	
import java.util.ArrayList;
import java.util.Collection;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;

import tern.eclipse.ide.core.DefaultTernModule;
import tern.eclipse.ide.core.IDefaultTernModulesProvider;
import tern.eclipse.ide.core.ITernNatureCapability;
import tern.server.TernPlugin;
	
import tern.eclipse.ide.core.ITernNatureCapability;
	
public class NodeclipseTernNatureCapability implements ITernNatureCapability {
	
	@Override
	public boolean hasTernNature(IProject project) throws CoreException {
		return project.hasNature("org.nodeclipse.ui.NodeNature");
	}

	@Override
	public Collection<DefaultTernModule> getTernModules(IProject project) {
		Collection<DefaultTernModule> modules = new ArrayList<DefaultTernModule>();
		// here you can manage your condition if node must be added or not.
		modules.add(new DefaultTernModule(TernPlugin.node.getName()));
		return modules;
	}	
}

And the extenion point not need to declare node :

<extension point="tern.eclipse.ide.core.ternNatureAdapters">
    <ternAdaptToNature
        id="org.nodeclipse"
        name="NodeclipseTernNatureCapability"
        class="org.nodeclipse.ui.nature.NodeclipseTernNatureCapability" >
    </ternAdaptToNature>
</extension>

ternFileConfigurations

Tern IDE is enable to support JavaScript inside HTML when script is declared inside script element. If you wish to support other HTML element, you can do it with tern.eclipse.ide.core.ternFileConfigurations extension point.

Here a sample which supports both Liferay AlloyUI tag aui:script and standard script elements :

<extension
      point="tern.eclipse.ide.core.ternFileConfigurations">
   <configuration
         class="com.liferay.ide.alloy.core.AlloyFileConfiguration">
   </configuration>
</extension>

AlloyFileConfiguration :

package com.liferay.ide.alloy.core;

import org.eclipse.core.resources.IFile;

import tern.eclipse.ide.core.ITernFileConfiguration;
import tern.server.protocol.html.ScriptTagRegion;

public class AlloyFileConfiguration implements ITernFileConfiguration {

	public static final ScriptTagRegion AUI_SCRIPT_TAG = new ScriptTagRegion("script",
			"aui:script");

	public static final ScriptTagRegion[] ALLOYUI_SCRIPT_TAGS = new ScriptTagRegion[] {
			ScriptTagRegion.SCRIPT_TAG, AUI_SCRIPT_TAG };

	@Override
	public ScriptTagRegion[] getScriptTags(IFile file) {
		if ("jsp".equals(file.getFileExtension())) {
			return ALLOYUI_SCRIPT_TAGS;
		}
		return null;
	}
}

Sample

See Liferay IDE https://github.com/liferay/liferay-ide/blob/master/jsdt/plugins/com.liferay.ide.alloy.core/plugin.xml#L85

ternModuleInstalls

This will allow to install tern modules with the ternModuleInstalls extension point. See issue 322 and issue 332 for discussion about this extension point.

You can find the following sample in the Eclispe project ternModuleInstalls

<extension
      point="tern.eclipse.ide.core.ternModuleInstalls">
   <moduleInstall
         id="ternModuleInstalls.mylibrary"
         name="Install Tern My Library"
         src="modules/tern-mylibrary.zip">
   </moduleInstall>	   
</extension>

nodeJSInstalls

This extension point allows developers to specify their own Node.js install location. This can be done in two ways:

  1. A developer can implement INodejsInstallProvider interface to programmatically tell Tern.java where Node.js is installed. This is useful for situations where you need to do some computations before specifying the location path.
  2. Bundle Node.js in the extending bundle and specify the location of the Node program relative to the bundle. If you ship Node.js in your bundle in the form of a ZIP archive, make sure you specify the ZIP location within the bundle using the zip attribute.

Samples

This is a sample of a location where the node program is expected to be in the PATH. You can find this example in the plugin.xml in tern.eclipse.ide.server.nodejs.core.

<extension point="tern.eclipse.ide.server.nodejs.core.nodeJSInstalls" >
	<install id="node-native" name="%nodeJSInstall.name" path="" />
</extension>

This second sample shows you how you can specify a Node.js that is bundled in your plugin. You can find this sample in the embedded tern.eclipse.ide.server.nodejs.embed.win32.win32.x86_64 plugin.

<extension point="tern.eclipse.ide.server.nodejs.core.nodeJSInstalls" >
	<install 
		id="node-v4.2.4-win32-x86_64"
		name="%nodeJSInstall_v4.2.4.name"
		path="/node-v4.2.4-win32-x86_64/node.exe" 
		zip="/node-v4.2.4-win32-x86_64.zip" />
</extension>

If you don't specify a zip value, then Tern.java will take the path as an uncompressed directory.

The last scenario is for when you need to perform some computation before specifying the Node.js location, for instance for the case where you ship Node.js in a location other than your current bundle, or maybe you ship it as a tarball hence you need to uncompress it before adding that location to the registry. For these cases you can use the following approach:

<extension
         point="tern.eclipse.ide.server.nodejs.core.nodeJSInstalls">
      <install
            class="myextension.nodejs.internal.core.NodeJSInstallProvider"
            id="myextension.nodejs.core.install.provider"
            name="My own Node.js">
      </install>
</extension>

As you can see in this scenario, you must provide a name, which is the displayed name in UI, an id and a class which must implement tern.eclipse.ide.server.nodejs.core.INodejsInstallProvider. This interface contains only one method with which you must return the location where the node program lives. Take this implementation as an example:

public class NodeJSInstallProvider implements INodejsInstallProvider {

	@Override
	public File getPath() {
		File nodeLocation = null;
		nodeLocation = new File("/home/myhome/nodejs/bin/node");
		if (nodeLocation.exists() && nodeLocation.canExecute()) {
			return nodeLocation;
		}
		
		// If doesn't exist, then uncompress it.
		File baseDir = FileLocator.getBundleFile(Platform.getBundle("myPluginId"));
		File tar = new File(baseDir, "myOwnNodeJS.tar");
		nodeLocation = MyTarUtils.uncompress(tar);
		
		return nodeLocation;
	}
}

In this scenario, we are expecting a node program in /home/myhome/nodejs/bin directory. If it doesn't exist, then its uncompressing a tarball archive that is in the current bundle.

Clone this wiki locally