Jump to: navigation, search

Orion/Plugin API Changes/R0.5

This page describes breaking changes occurring to the Plugin API overall, as well as API changes to service extensions that will break plugins.

Orion Plugin API Changes

We expect breaking changes in the Plugin API (plugin.js) in 0.5. However those changes are not yet implemented in 0.5M1.

Orion Service Extension Changes

Changes to individual service extensions introduced in 0.5 require modification of plugins to run on Orion 0.5. Some older Orion plugins will not function properly without modification on Orion 0.5.

Item validation and URI generation

The way that plugins validate metadata and compose URI's from metadata has changed. If your plugin defines validationProperties or href service properties, it must change. These changes affect the following service extensions.

  • orion.navigate.command
  • orion.edit.command
  • orion.page.link
  • orion.page.link.related
  • orion.navigate.openWith

See bug 370903 for details about the problems solved by these changes.

Using validationProperties

Prior to R0.5, orion.navigate.command and orion.edit.command extensions could specify validationProperties to determine whether item metadata was valid for a particular command implementation. Validation properties were an object whose properties were key/value pairs for validation. The key describes an item property, and the value describes the expected value. The value could be either a non-string value to match against the property value, or a string wildcard pattern to match against property. The string patterns were a combination of a file wildcard format and some regular expression support. For example, these validation properties will match an object which has a property called "Git" with any value and a property called "Directory" whose value is "true".

validationProperties: {"Git":"*", "Directory":"true"}

The new format for validationProperties drops the specialized wildcard patterns and instead uses JavaScript regular expressions to match properties. To allow further evolution of the properties, the validation properties are now expressed as an array of validation objects rather than key value pairs. The equivalent expression in the new format is:

validationProperties: [
  {source: "Git"},
  {source: "Directory", match: true}
]

Note that not specifying a "match" property simply means the property must be present.

Validating with content types

Prior to R0.5, validationProperties were used to match file name extensions. Regular expression patterns can still be used to match against file names, but the recommended way to specify validation against a file type is to use a content type rather than a validation property. The following validation properties were used previously to specify that a file should have a ".css" extension:

validationProperties: {"Name":"*.css"} 

The new format uses the contentType property as follows:

contentType: ["text/css"]

Previously there was no way to specify that a command was valid against either "css" OR "html". This can now be done as follows:

contentType: ["text/css", "text/html"]

Using content types

Plugins can define content types using an id of any format. The default content types registered by Orion now use the MIME type where possible. Plugins that previously specified content types that were intended to reference the platform default content types should change to the new format. For example, the old format for specifying a contentType describing all image formats was:

contentType: ["image.gif", "image.jpeg", "image.ico", "image.png","image.tiff"]

The new format is:

contentType: ["image/gif", "image/jpeg", "image/ico", "image/png","image/tiff"]

See bug 374991 for details.

Building URI's from metadata

Prior to Orion R0.5, commands that build URI's (hrefs) from metadata provide a service implementation that maps the metadata to an appropriate URI. The href property was used to specify that the implementation was returning a link rather than running code against the metadata. For example, the following code defined a command that created a link from a folder to its "Git Status" page:

var temp = document.createElement('a');
var provider = new eclipse.PluginProvider();
temp.href = "../git-status.html";
var gitStatusURL = temp.href;
provider.registerServiceProvider("orion.navigate.command", {
  run: function(item) {
     return gitStatusURL + "#" + item.Git.StatusLocation;
  }}, {
  name: "Git Status",
  id: "eclipse.git.status",
  tooltip: "Go to Git Status",
  validationProperties: {"Git":"*", "Directory":"true"},
  href: true,
  forceSingleItem: true
});

The new extension looks like this:

provider.registerServiceProvider("orion.navigate.command", {}, {
  name: "Git Status",
  id: "eclipse.git.status",
  tooltip: "Go to Git Status",
  validationProperties: [
     {source: "Git:StatusLocation", variableName: "GitStatusLocation"},
     {source: "Directory", match: true}
  ],
  uriTemplate: "{OrionHome}/git/git-status.html#{GitStatusLocation}",
  forceSingleItem: true
});

Note the following changes:

  • the service implementation (run method) is no longer necessary
  • the validationProperties are changed as discussed above. In addition, the first validation property introduces a variableName, "GitStatusLocation"
  • the href property is no longer supported. Instead, a uriTemplate is specified. The variables supported in the URI template include all the metadata properties, as well as variables that are named in the validation properties. Specifying a variable name of "GitStatusLocation" means that the property value for "Git.StatusLocation" can be referred to in the URI template using "GitStatusLocation".

Complex URI mapping using regular expressions and replacements

Prior to R0.5, it was not possible to map from one URL to another without writing a service implementation. Now, most complex expressions can be specified using the advanced capabilities of validationProperties. This is best shown by example. The following snippet was used to map a metadata GitURL to a github URL using javascript.

var mapToGithubCommand = new mCommands.Command({
  name : "Show in GitHub",
  tooltip: "Show this repository at GitHub",
  id : "orion.git.gotoGithub",
  hrefCallback : function(data) {
     //url format should include github.com/username/reponame.git or github.com:username/reponame.git
     var url = /github\.com.*\.git/.exec(data.items.GitUrl)[0];
     //convert : to / if needed
     url = url.replace(':', '/');
     return "https://" + url.substring(0, url.length-4);
  },
  visibleWhen : function(item) {
     //url format should include github.com/username/reponame.git or github.com:username/reponame.git
     return item.GitUrl && /github\.com.*\.git/.exec(item.GitUrl);
  }
});

This logic can now be expressed completely with validation properties and a URI template:

provider.registerServiceProvider("orion.page.link.related", null, {
  id: "orion.git.gotoGithub",
  name: "Show in GitHub",
  tooltip: "Show this repository at GitHub",
  validationProperties: [{
     source: "GitUrl", 
     match: "github\.com.*\.git", 
     variableName: "GitHubLocation", 
     variableMatchPosition: "only",
     replacements: [{pattern: ":", replacement: "/"}, {pattern: ".git$", replacement: ""}]
  }],
  uriTemplate: "https://{GitHubLocation}"
});

This example uses all of the currently implemented properties for validationProperties:

  • source specifies the name of the property in the metadata.
  • match specifies a value used to validate the property. When the match value is a string, the string is always assumed to specify a regular expression. Regular expression literals are not used since these are not serialized by JSON across the service boundaries. The string will be passed directly to the RegExp constructor.
  • variableName is the name of the matching variable as specified in a URI template.
  • variableMatchPosition specifies what part of a matching string is used in the variable value when a regular expression was used to match the property.
    • all (default) means the entire property value should be substituted in the URI template if there is a match.
    • only means only the matching part of the property value should be substituted in the URI template.
    • before means the part before the match is substituted in the URI template.
    • after means the part after the match is substituted in the URI template.
  • replacements specifies an array of additional regular expression patterns and replacements that can be used to further process the variable value before it is substituted in the URI template. The pattern is a regular expression string passed to the RegExp constructor. The replacement is the substituted string for the match. If no replacement is specified, an empty string will be substituted (the matching pattern is removed from the string).

For further examples, reference gitPlugin.html or the unit tests in js-tests/extensionParsing.

Combining properties

It was previously not possible to specify an OR relationship for property validation. If a command was valid against the property "ChildrenLocation" or "ContentLocation" then two command contributions would have to be specified, one for each property. Properties can now be combined using a piped OR expression. OR expressions are validated before the nested property expressions. The following expression defines a related page link that can arrive at the navigator from either folder metadata (ChildrenLocation) or git metadata (ContentLocation):

provider.registerServiceProvider("orion.page.link.related", null, {
  id: "orion.navigateFromMetadata",
  name: "Navigator",
  tooltip: "Go to the navigator",
  validationProperties: [{
     source: "ChildrenLocation|ContentLocation",
     variableName: "NavigatorLocation",
     /* strip off depth=1 if it is there because we always add it back */
     replacements: [{pattern: "\\?depth=1$", replacement: ""}]  
  }],
  uriTemplate: "{OrionHome}/navigate/table.html#{NavigatorLocation}?depth=1"
});

System URI template variables

In addition to the variables defined in metadata or by validationProperties variable names, some system template variables are supported.

  • OrionHome specifies the hostname for the Orion server instance. This variable can be used by a plugin that is installed in another domain to reference a page location in Orion. See bug 373450 for ongoing discussion about this variable. The old pattern used to achieve this functionality was to create a link and reference its URL.
var temp = document.createElement('a');
temp.href = "../git-status.html";
var gitStatusURL = temp.href;

However, this technique did not work when the plugin was installed in a third party location, such as github.

Primary navigation links

Primary navigation links specified in orion.page.link now use the uriTemplate property instead of href. Since primary navigation links do not apply to any particular metadata, and therefore have no validation properties, only special variables such as OrionHome can be used.

Related pages links

In Orion 0.4, related pages could only refer to a corresponding command id. Now that URI's can be parsed declaratively, related pages may be specified independently, as shown in the github example above.

Content Assist

Older plugins that contribute to the orion.edit.contentAssist service will require changes to work correctly in Orion 0.5. The changes are described below. See bug 375472 and this post to the orion-dev mailing list, for more details.

Signature

Prior to R0.5, plugins that contributed to the orion.edit.contentAssist service provided a method with the signature

 computeProposals(prefix, buffer, selection)

… where the selection object had an offset field that gave the caret offset.

In R0.5 the method signature is

 computeProposals(buffer, offset, context)

… where the prefix and selection parameters are inside the context object.

Proposal shape

Prior to R0.5, a Content Assist provider could return simple strings as proposals. In R0.5 a proposal must be an Object that contains at minimum the proposal and description fields.

Proposal handling

Prior to R0.5 the Orion Content Assist engine would remove the prefix from the beginning of an accepted proposal before inserting the proposal into the buffer. In R0.5 the proposal is not modified: it is inserted as-is at the caret offset. Thus, if your Content Assist provider relies on the pre-0.5 behavior, it must remove the prefix manually from the beginning of its proposals to work correctly in R0.5.

Restricting a contribution to particular file types

Prior to R0.5, several service extensions allowed a pattern property to be provided to limit a contributed service to acting only upon files of a particular type. The pattern property was a quasi-regular-expression matching the filenames of files that a contribution applied to.

In R0.5 the pattern property is not supported. Instead contributions should refer to one or more Content Types when registering the service.

For example, a pre-R0.5 outline provider used to be contributed as follows:

 registerServiceProvider("orion.edit.outliner",
   {  getOutline: function(contents, title) {
        // ...
      }
   }, 
   { name: "JavaScript hierarchical outliner",
     id: "my.great.outliner",
     pattern: "*.js"
   }

The same outline provider in R0.5 would use the contentType property instead:

 registerServiceProvider("orion.edit.outliner",
   {  getOutline: function(contents, title) {
        // ...
      }
   }, 
   { name: "JavaScript hierarchical outliner",
     id: "my.great.outliner",
     contentType: ["application/javascript"]
   }

If your plugin contributes a pattern to any of the following service extensions, it must be changed to an appropriate contentType to work in R0.5: