Implemented context menu action registry

This commit is contained in:
Andrew Henry
2018-11-22 15:53:50 -08:00
parent 74faf1bd48
commit a7948ce83e
9 changed files with 93 additions and 217 deletions

View File

@ -28,6 +28,7 @@ define([
'./telemetry/TelemetryAPI',
'./indicators/IndicatorAPI',
'./notifications/NotificationAPI',
'./contextMenu/ContextMenuRegistry',
'./Editor'
], function (
@ -38,6 +39,7 @@ define([
TelemetryAPI,
IndicatorAPI,
NotificationAPI,
ContextMenuRegistry,
EditorAPI
) {
return {
@ -48,6 +50,7 @@ define([
TelemetryAPI: TelemetryAPI,
IndicatorAPI: IndicatorAPI,
NotificationAPI: NotificationAPI.default,
EditorAPI: EditorAPI
EditorAPI: EditorAPI,
ContextMenuRegistry: ContextMenuRegistry.default
};
});

View File

@ -0,0 +1,75 @@
import ContextMenuComponent from '../../ui/components/controls/ContextMenu.vue';
import Vue from 'vue';
class ContextMenuRegistry {
constructor() {
this._allActions = [];
this._activeContextMenu = undefined;
this._hideActiveContextMenu = this._hideActiveContextMenu.bind(this);
}
registerAction(actionDefinition) {
this._allActions.push(actionDefinition);
}
attachTo(targetElement, objectPath) {
let showContextMenu = (event) => {
this._showContextMenuForObjectPath(event, objectPath);
};
targetElement.addEventListener('contextmenu', showContextMenu);
return function detach() {
targetElement.removeEventListener('contextMenu', showContextMenu);
}
}
/**
* @private
*/
_showContextMenuForObjectPath(event, objectPath) {
let applicableActions = this._allActions.filter(
(action) => action.appliesTo(objectPath));
event.preventDefault();
if (this._activeContextMenu) {
this._hideActiveContextMenu();
}
this._activeContextMenu = this._createContextMenuFromActions(applicableActions);
this._activeContextMenu.$mount();
this._activeContextMenu.$el.style.left = `${event.clientX}px`;
this._activeContextMenu.$el.style.top = `${event.clientY}px`;
document.body.appendChild(this._activeContextMenu.$el);
document.addEventListener('click', this._hideActiveContextMenu);
}
/**
* @private
*/
_hideActiveContextMenu() {
document.removeEventListener('click', this._hideActiveContextMenu);
document.body.removeChild(this._activeContextMenu.$el);
this._activeContextMenu.$destroy();
this._activeContextMenu = undefined;
}
/**
* @private
*/
_createContextMenuFromActions(actions) {
return new Vue({
components: {
ContextMenu: ContextMenuComponent
},
provide: {
actions: actions
},
template: '<ContextMenu></ContextMenu>'
});
}
}
export default ContextMenuRegistry;