Commands and Command Contributions
This is a work-in-progress design document for the command infrastructure (commands, handlers, menu contributions, etc.) in Orion.
The basic question is: How does an external party (plug-in) contribute behavior to an Orion page and describe where/how that behavior is presented? We envision this being accomplished through a command service which allows:
- Semantic definition of commands that are independent of implementation (commands)
- Definition of command implementation (handlers)
- Mapping of keybindings to commands and description of their scopes
- Structured way of describing where commands should be presented (contributions)
- buttons, menu text, popups
- scope - entire page vs. "view" vs. single object (represented as a link on page)
- location - relative to other items
There are some architectural issues to figure out with commands in Orion that aren't an issue on the desktop. These include:
- Where does the "command registry" reside (server vs. client) and what is its scope (user, workspace, etc.)?
- Command discovery - As new services are discovered, how are they presented to the user? How can the end user decide that some service is important enough to end up as a button on a toolbar?
- Contributions and API - the internal mechanism for specifying commands and deciding where they render on a page is not the same view of the world exposed to plug-ins through API. We expect the internal mechanism to start with a minimal approach, adding concepts as needed by our own pages, while the service extensions remain relatively simple and more stable.
Orion Concepts taken from Eclipse Platform
Where concepts are the same, we want to use the concept (and API if applicable). However if HTML/CSS, or perhaps dojo, already defines a concept that is similar, we may use the web concept in lieu of the Eclipse Desktop concept, depending on how fundamental it is. For example, a DOM node can be used to define the starting point of a menu, toolbar, or popup, and therefore an alternate declaration of the "anchor point" of a toolbar or menu may not be needed.
There are some concepts that could certainly apply to Orion but represent a more mature set of features. We will think about these concepts when designing, but won't necessarily define or implement it in the first release.
Commands are very similar to the Eclipse Platform commands. They have a name, id, description, category, context, expressions
- name, id, description, categoryId. Category may be ignored initially as it is mainly used to group commands for the user when showing binding mappings.
- context. Similar in concept to Eclipse Platform. This is mainly needed at the command level to manage keybindings. In Eclipse Platform, contexts are window, dialog, part, etc. Contributions to objects are described separately. Perhaps we can collapse object contributions and menu contributions? The context could be the DOM element id in which the command is active. This could be all Orion Pages, a single page, a "part" such as the navigator or editor DOM id, or even an object (the DOM node representing an object - dojo tree item id, table row id, etc... )
- activation expression - can we use JS reg exp for this? Need to review with PaulW the issue of activeWhen/visibleWhen, what we've done in e4, etc.
- CSS image classes - Eclipse Platform has the "commandImages" extension point, as well as images supplied in menu contributions. These concepts allow developers to override the common images, and to have style of images for toolbars vs. menus. In Orion, we can use CSS to allow this flexibility so it seems reasonable to define the image classes for commands (image, hoverimage, disabled image) directly in the command.
When a plug-in contributes a command through one of the *.command extension points, these properties are located in the service properties, so that the plug-in need not be loaded to assemble the commands.
A handler is both a function that is attached to a command, and a scope for calling that function. From a plug-in point of view, the handler is the service implementation, and will only be called (and thus the plug-in loaded) when the user chooses the command.
For now, we ignore menu contributions. These are used in the Eclipse Platform to define the starting point of a menu or toolbar, such as the global menu/toolbar, view menus, etc. Until proven otherwise, we will assume that these "locations" are defined by DOM nodes and ids.
Command contributions define where a command is made visible to the user.
- command id describes the command in question
- location describes where a command contribution appears.
- In the Eclipse Platform we have URI of the format "[Scheme]:[ID]?[Placement]" which could be something like "menu:someorg.somemenu.id?after=additions".
- Do we need to separate scheme (menu, toolbar, popup) from DOM id? Or would a unique DOM id represent the combination of those two? We need to understand if all possible locations can be declared in the HTML and thus found by DOM id. It might be that we have well-known id manipulations to represent the common command locations within an area, such as navigator-menu, navigator-toolbar, navigator-popup, etc.
- We also have cases where a command appears directly next to an item, and we know the DOM id of that particular item is not known in advance. So we may need a location that specifies "object:navigator" which means that it applies to an object in the navigator.
- For now, assume that bulk actions applying to selections would be defined in in well-known places in the DOM (menu, toolbar, popup) and they use the selection service to determine enablement. Other actions are located next to the item in question and the selection service may not come into play. (For example, a navigator view with checkmarks for selections and actions available on hover.)
- Eclipse Platform has well-defined syntax for placement relative to an id (after/before/endof). Dojo also defines a similar concept called "position" when placing DOM nodes. (after/before/first/last/replace/only). We should consider which syntax to use (last vs. endof) and also whether the more powerful concepts need to be supported (replace/only allow blowing away existing elements and this is probably not needed.)
- visibleWhen expression (see Eclipse e4 model for latest thinking on activation/enablement vs. visibility)
- style allows specification of style (particularly in a toolbar) - push, radio, toggle, pulldown
We currently define the concept of KeyBinding in the editor. For command contributions a few more concepts are needed. We could extend KeyBinding for this purpose but probably need to move it out of the editor.
- KeyBinding includes definition of an action, key, and modifiers. We should use a command id for the action.
- context defines where the binding applies. See discussion of command contexts. Is DOM node enough?
- scheme defines a grouping of bindings that are visible to the user, allowing the bindings to be changed as groups. This seems easy enough to add after the fact, and the editor is the main scenario where schemes seem useful. We may also have interoperability scenarios to address when Orion components appear inside the desktop Eclipse Platform.
Interoperability between Orion and the desktop Eclipse Platform
We need to define the relationship and potential interoperability between Eclipse Platform commands and Orion commands.
- Do we expect an Orion component to be able to contribute a command implementation to desktop Eclipse?
- Maybe. Not now. Need a use case (sharing bindings or schemes for common commands such as undo/redo, cut/copy/paste? more?)
- For now - a developer could use the same command id as in the desktop platform if there is an expected relationship. Eventually we might build infrastructure to respect each others bindings or handler implementations if it is a real requirement.
- Relationship between Eclipse Platform and Orion keybindings
- Keystrokes/bindings inside the browser should be handled first by the web implementation and should not be interpreted by Eclipse.
- Would the Eclipse Platform ever interpret key bindings that happen in the browser (what happens today?)
- Initially we don't expect desktop keybinding schemes to automatically translate to the correct binding in the web component.