@hydranium/glsp-client 1.0.0-next → 1.0.0-next.299

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,6 +18,9 @@ VS Code webview, or a plain browser page. It builds on `@eclipse-glsp/client`.
18
18
  rather than dropped.
19
19
  - An edge whose labels keep finite bounds without bendpoints, so fit to
20
20
  screen frames the diagram instead of blanking it.
21
+ - A plain click on an unselected element that replaces a selection still
22
+ pending, so two quick clicks on different elements leave only the second
23
+ selected.
21
24
  - One binder that mounts all of it in a diagram container.
22
25
 
23
26
  ## Install
@@ -19,7 +19,8 @@ export interface GlspClientModuleOptions {
19
19
  * Binds the framework's client classes into a GLSP diagram container, whatever
20
20
  * hosts it: the instrumented action dispatcher, the failure-reporting diagram
21
21
  * loader, the route-repairing hidden-bounds updater, the status overlay that
22
- * stays on the page, and a sprotty logger that reports through the host's.
22
+ * stays on the page, the select listener whose plain click replaces a pending
23
+ * selection, and a sprotty logger that reports through the host's.
23
24
  *
24
25
  * Call it from the module a host adds AFTER GLSP's defaults, since every class
25
26
  * here replaces a token those defaults bind; `rebind` on an unbound token
@@ -1 +1 @@
1
- {"version":3,"file":"glsp-client-module.d.ts","sourceRoot":"","sources":["../src/glsp-client-module.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,cAAc,EAMrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAA4C,KAAK,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAQzG,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACrC;;mDAE+C;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,uBAA4B,GAAG,IAAI,CAwB3G"}
1
+ {"version":3,"file":"glsp-client-module.d.ts","sourceRoot":"","sources":["../src/glsp-client-module.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,cAAc,EAOrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAA4C,KAAK,MAAM,EAAe,MAAM,qBAAqB,CAAC;AASzG,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACrC;;mDAE+C;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,uBAA4B,GAAG,IAAI,CAyB3G"}
@@ -14,6 +14,7 @@ const protocol_1 = require("@hydranium/protocol");
14
14
  const action_dispatcher_1 = require("./action-dispatcher");
15
15
  const diagram_loader_1 = require("./diagram-loader");
16
16
  const hidden_bounds_updater_1 = require("./hidden-bounds-updater");
17
+ const select_mouse_listener_1 = require("./select-mouse-listener");
17
18
  const sprotty_logger_adapter_1 = require("./sprotty-logger-adapter");
18
19
  const status_overlay_1 = require("./status-overlay");
19
20
  const types_1 = require("./types");
@@ -21,7 +22,8 @@ const types_1 = require("./types");
21
22
  * Binds the framework's client classes into a GLSP diagram container, whatever
22
23
  * hosts it: the instrumented action dispatcher, the failure-reporting diagram
23
24
  * loader, the route-repairing hidden-bounds updater, the status overlay that
24
- * stays on the page, and a sprotty logger that reports through the host's.
25
+ * stays on the page, the select listener whose plain click replaces a pending
26
+ * selection, and a sprotty logger that reports through the host's.
25
27
  *
26
28
  * Call it from the module a host adds AFTER GLSP's defaults, since every class
27
29
  * here replaces a token those defaults bind; `rebind` on an unbound token
@@ -58,6 +60,7 @@ function createGlspClientModule(context, options = {}) {
58
60
  rebind(client_1.DiagramLoader).to(diagram_loader_1.HydraniumDiagramLoader).inSingletonScope();
59
61
  rebind(client_1.GLSPHiddenBoundsUpdater).to(hidden_bounds_updater_1.HydraniumHiddenBoundsUpdater).inSingletonScope();
60
62
  rebind(client_1.StatusOverlay).to(status_overlay_1.HydraniumStatusOverlay).inSingletonScope();
63
+ rebind(client_1.RankedSelectMouseListener).to(select_mouse_listener_1.HydraniumSelectMouseListener).inSingletonScope();
61
64
  rebind(client_1.TYPES.ILogger).to(sprotty_logger_adapter_1.SprottyLoggerAdapter).inSingletonScope();
62
65
  }
63
66
  //# sourceMappingURL=glsp-client-module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"glsp-client-module.js","sourceRoot":"","sources":["../src/glsp-client-module.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF,iDAO8B;AAC9B,kDAAyG;AACzG,2DAAoE;AACpE,qDAA0D;AAC1D,mEAAuE;AACvE,qEAAgE;AAChE,qDAA0D;AAC1D,mCAA+C;AAU/C;;;;;;;;;;;;;;;;GAgBG;AACH,gCAAuC,OAAuB,EAAE,OAAO,GAA4B,EAAE;IAClG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAClB,CAAC,OAAO,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvH,CAAC;SAAM,IAAI,CAAC,OAAO,CAAC,4BAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,IAAI,wBAAa,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,4BAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,4BAAoB,CAAC,MAAM,CAAC;aAC7B,cAAc,CAAC,GAAG,CAAC,EAAE;YACnB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAS,4BAAoB,CAAC,MAAM,CAAC,CAAC;YACtE,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,4BAAoB,CAAC,KAAK,CAAC;gBAC5D,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAQ,4BAAoB,CAAC,KAAK,CAAC;gBACtD,CAAC,CAAC,IAAI,sBAAW,EAAE,CAAC;YACvB,OAAO,IAAI,wBAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC;aACD,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,iDAA6B,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAChE,MAAM,CAAC,6BAAoB,CAAC,CAAC,SAAS,CAAC,iDAA6B,CAAC,CAAC;IACtE,MAAM,CAAC,sBAAa,CAAC,CAAC,EAAE,CAAC,uCAAsB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpE,MAAM,CAAC,gCAAuB,CAAC,CAAC,EAAE,CAAC,oDAA4B,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpF,MAAM,CAAC,sBAAa,CAAC,CAAC,EAAE,CAAC,uCAAsB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpE,MAAM,CAAC,cAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,6CAAoB,CAAC,CAAC,gBAAgB,EAAE,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"glsp-client-module.js","sourceRoot":"","sources":["../src/glsp-client-module.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF,iDAQ8B;AAC9B,kDAAyG;AACzG,2DAAoE;AACpE,qDAA0D;AAC1D,mEAAuE;AACvE,mEAAuE;AACvE,qEAAgE;AAChE,qDAA0D;AAC1D,mCAA+C;AAU/C;;;;;;;;;;;;;;;;;GAiBG;AACH,gCAAuC,OAAuB,EAAE,OAAO,GAA4B,EAAE;IAClG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAClB,CAAC,OAAO,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvH,CAAC;SAAM,IAAI,CAAC,OAAO,CAAC,4BAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,IAAI,wBAAa,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,4BAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,4BAAoB,CAAC,MAAM,CAAC;aAC7B,cAAc,CAAC,GAAG,CAAC,EAAE;YACnB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAS,4BAAoB,CAAC,MAAM,CAAC,CAAC;YACtE,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,4BAAoB,CAAC,KAAK,CAAC;gBAC5D,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAQ,4BAAoB,CAAC,KAAK,CAAC;gBACtD,CAAC,CAAC,IAAI,sBAAW,EAAE,CAAC;YACvB,OAAO,IAAI,wBAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC;aACD,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,iDAA6B,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAChE,MAAM,CAAC,6BAAoB,CAAC,CAAC,SAAS,CAAC,iDAA6B,CAAC,CAAC;IACtE,MAAM,CAAC,sBAAa,CAAC,CAAC,EAAE,CAAC,uCAAsB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpE,MAAM,CAAC,gCAAuB,CAAC,CAAC,EAAE,CAAC,oDAA4B,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpF,MAAM,CAAC,sBAAa,CAAC,CAAC,EAAE,CAAC,uCAAsB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpE,MAAM,CAAC,kCAAyB,CAAC,CAAC,EAAE,CAAC,oDAA4B,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACtF,MAAM,CAAC,cAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,6CAAoB,CAAC,CAAC,gBAAgB,EAAE,CAAC;AACrE,CAAC"}
package/lib/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export * from './edge';
13
13
  export * from './glsp-client';
14
14
  export * from './glsp-client-module';
15
15
  export * from './hidden-bounds-updater';
16
+ export * from './select-mouse-listener';
16
17
  export * from './sprotty-logger-adapter';
17
18
  export * from './status-overlay';
18
19
  export * from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAOlF,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAOlF,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC"}
package/lib/index.js CHANGED
@@ -34,6 +34,7 @@ __exportStar(require("./edge"), exports);
34
34
  __exportStar(require("./glsp-client"), exports);
35
35
  __exportStar(require("./glsp-client-module"), exports);
36
36
  __exportStar(require("./hidden-bounds-updater"), exports);
37
+ __exportStar(require("./select-mouse-listener"), exports);
37
38
  __exportStar(require("./sprotty-logger-adapter"), exports);
38
39
  __exportStar(require("./status-overlay"), exports);
39
40
  __exportStar(require("./types"), exports);
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,6EAA6E;AAC7E,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,SAAS;AACT,sDAAoC;AACpC,wDAAsC;AACtC,mDAAiC;AACjC,yCAAuB;AACvB,gDAA8B;AAC9B,uDAAqC;AACrC,0DAAwC;AACxC,2DAAyC;AACzC,mDAAiC;AACjC,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,6EAA6E;AAC7E,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,SAAS;AACT,sDAAoC;AACpC,wDAAsC;AACtC,mDAAiC;AACjC,yCAAuB;AACvB,gDAA8B;AAC9B,uDAAqC;AACrC,0DAAwC;AACxC,0DAAwC;AACxC,2DAAyC;AACzC,mDAAiC;AACjC,0CAAwB"}
@@ -0,0 +1,30 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { type Action, type GModelElement, RankedSelectMouseListener, type SelectableElement } from '@eclipse-glsp/client';
10
+ /**
11
+ * GLSP's select mouse listener, with a plain click on an unselected element
12
+ * replacing whatever is selected when its action executes.
13
+ *
14
+ * The listener names the elements a click deselects from each element's
15
+ * `selected` flag, which the feedback the previous click's command queues
16
+ * writes only when that feedback runs; a click landing before then names
17
+ * nothing, and both elements end up selected. A plain click sends
18
+ * `deselectAll` instead, which `SelectCommand` resolves against the selection
19
+ * service as it executes. Reading the service from the listener would still
20
+ * race the previous click's command, since dispatch is asynchronous.
21
+ * Ctrl/Cmd-click keeps GLSP's add to the selection; a routing handle keeps
22
+ * GLSP's path, since `deselectAll` cannot spare the handle's own edge.
23
+ *
24
+ * Bound by `createGlspClientModule` via `rebind(RankedSelectMouseListener)`.
25
+ */
26
+ export declare class HydraniumSelectMouseListener extends RankedSelectMouseListener {
27
+ protected handleSelectTarget(selectableTarget: SelectableElement, deselectedElements: GModelElement[], event: MouseEvent): (Action | Promise<Action>)[];
28
+ protected handleDeselectAll(): (Action | Promise<Action>)[];
29
+ }
30
+ //# sourceMappingURL=select-mouse-listener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-mouse-listener.d.ts","sourceRoot":"","sources":["../src/select-mouse-listener.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,MAAM,EAEX,KAAK,aAAa,EAGlB,yBAAyB,EAEzB,KAAK,iBAAiB,EACxB,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;;;;;;;GAeG;AACH,qBACa,4BAA6B,SAAQ,yBAAyB;IACxE,UAAmB,kBAAkB,CAClC,gBAAgB,EAAE,iBAAiB,EACnC,kBAAkB,EAAE,aAAa,EAAE,EACnC,KAAK,EAAE,UAAU,GACjB,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAK9B;IAED,UAAmB,iBAAiB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAEnE;CACH"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
11
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.HydraniumSelectMouseListener = void 0;
18
+ const client_1 = require("@eclipse-glsp/client");
19
+ const inversify_1 = require("inversify");
20
+ /**
21
+ * GLSP's select mouse listener, with a plain click on an unselected element
22
+ * replacing whatever is selected when its action executes.
23
+ *
24
+ * The listener names the elements a click deselects from each element's
25
+ * `selected` flag, which the feedback the previous click's command queues
26
+ * writes only when that feedback runs; a click landing before then names
27
+ * nothing, and both elements end up selected. A plain click sends
28
+ * `deselectAll` instead, which `SelectCommand` resolves against the selection
29
+ * service as it executes. Reading the service from the listener would still
30
+ * race the previous click's command, since dispatch is asynchronous.
31
+ * Ctrl/Cmd-click keeps GLSP's add to the selection; a routing handle keeps
32
+ * GLSP's path, since `deselectAll` cannot spare the handle's own edge.
33
+ *
34
+ * Bound by `createGlspClientModule` via `rebind(RankedSelectMouseListener)`.
35
+ */
36
+ let HydraniumSelectMouseListener = class HydraniumSelectMouseListener extends client_1.RankedSelectMouseListener {
37
+ handleSelectTarget(selectableTarget, deselectedElements, event) {
38
+ if ((0, client_1.isCtrlOrCmd)(event) || selectableTarget instanceof client_1.GRoutingHandle) {
39
+ return super.handleSelectTarget(selectableTarget, deselectedElements, event);
40
+ }
41
+ return [client_1.SelectAction.setSelection([selectableTarget.id]), client_1.BringToFrontAction.create([selectableTarget.id])];
42
+ }
43
+ handleDeselectAll() {
44
+ return [client_1.SelectAction.setSelection([])];
45
+ }
46
+ };
47
+ exports.HydraniumSelectMouseListener = HydraniumSelectMouseListener;
48
+ exports.HydraniumSelectMouseListener = HydraniumSelectMouseListener = __decorate([
49
+ (0, inversify_1.injectable)()
50
+ ], HydraniumSelectMouseListener);
51
+ //# sourceMappingURL=select-mouse-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-mouse-listener.js","sourceRoot":"","sources":["../src/select-mouse-listener.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;AAElF,iDAS8B;AAC9B,yCAAuC;AAEvC;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,kCAAyB;IACrD,kBAAkB,CAClC,gBAAmC,EACnC,kBAAmC,EACnC,KAAiB;QAEjB,IAAI,IAAA,oBAAW,EAAC,KAAK,CAAC,IAAI,gBAAgB,YAAY,uBAAc,EAAE,CAAC;YACpE,OAAO,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,CAAC,qBAAY,CAAC,YAAY,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,2BAAkB,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/G,CAAC;IAEkB,iBAAiB;QACjC,OAAO,CAAC,qBAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;CACH,CAAA;;uCAfY,4BAA4B;IADxC,IAAA,sBAAU,GAAE;GACA,4BAA4B,CAexC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/glsp-client",
3
- "version": "1.0.0-next",
3
+ "version": "1.0.0-next.299",
4
4
  "description": "Host-neutral client classes for GLSP heads built on @hydranium/glsp-server, the binder that mounts them in a Theia frontend, a VS Code webview or a plain browser page, and the edge whose labels keep finite bounds without bendpoints.",
5
5
  "keywords": [
6
6
  "diagram",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@eclipse-glsp/client": "2.7.0",
62
- "@hydranium/protocol": "1.0.0-next",
62
+ "@hydranium/protocol": "1.0.0-next.299",
63
63
  "@types/node": "^22.0.0",
64
64
  "inversify": "6.2.2",
65
65
  "reflect-metadata": "0.2.2",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "peerDependencies": {
71
71
  "@eclipse-glsp/client": "^2.6.0",
72
- "@hydranium/protocol": "^1.0.0-next",
72
+ "@hydranium/protocol": "1.0.0-next.299",
73
73
  "inversify": "^6.0.0",
74
74
  "snabbdom": "^3.5.1"
75
75
  },
@@ -12,6 +12,7 @@ import {
12
12
  DiagramLoader,
13
13
  GLSPActionDispatcher,
14
14
  GLSPHiddenBoundsUpdater,
15
+ RankedSelectMouseListener,
15
16
  StatusOverlay,
16
17
  TYPES
17
18
  } from '@eclipse-glsp/client';
@@ -19,6 +20,7 @@ import { type Clock, ConsoleLogger, DefaultTracer, type Logger, SystemClock } fr
19
20
  import { HydraniumGlspActionDispatcher } from './action-dispatcher';
20
21
  import { HydraniumDiagramLoader } from './diagram-loader';
21
22
  import { HydraniumHiddenBoundsUpdater } from './hidden-bounds-updater';
23
+ import { HydraniumSelectMouseListener } from './select-mouse-listener';
22
24
  import { SprottyLoggerAdapter } from './sprotty-logger-adapter';
23
25
  import { HydraniumStatusOverlay } from './status-overlay';
24
26
  import { HydraniumClientTypes } from './types';
@@ -35,7 +37,8 @@ export interface GlspClientModuleOptions {
35
37
  * Binds the framework's client classes into a GLSP diagram container, whatever
36
38
  * hosts it: the instrumented action dispatcher, the failure-reporting diagram
37
39
  * loader, the route-repairing hidden-bounds updater, the status overlay that
38
- * stays on the page, and a sprotty logger that reports through the host's.
40
+ * stays on the page, the select listener whose plain click replaces a pending
41
+ * selection, and a sprotty logger that reports through the host's.
39
42
  *
40
43
  * Call it from the module a host adds AFTER GLSP's defaults, since every class
41
44
  * here replaces a token those defaults bind; `rebind` on an unbound token
@@ -71,5 +74,6 @@ export function createGlspClientModule(context: BindingContext, options: GlspCli
71
74
  rebind(DiagramLoader).to(HydraniumDiagramLoader).inSingletonScope();
72
75
  rebind(GLSPHiddenBoundsUpdater).to(HydraniumHiddenBoundsUpdater).inSingletonScope();
73
76
  rebind(StatusOverlay).to(HydraniumStatusOverlay).inSingletonScope();
77
+ rebind(RankedSelectMouseListener).to(HydraniumSelectMouseListener).inSingletonScope();
74
78
  rebind(TYPES.ILogger).to(SprottyLoggerAdapter).inSingletonScope();
75
79
  }
package/src/index.ts CHANGED
@@ -19,6 +19,7 @@ export * from './edge';
19
19
  export * from './glsp-client';
20
20
  export * from './glsp-client-module';
21
21
  export * from './hidden-bounds-updater';
22
+ export * from './select-mouse-listener';
22
23
  export * from './sprotty-logger-adapter';
23
24
  export * from './status-overlay';
24
25
  export * from './types';
@@ -0,0 +1,54 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import {
11
+ type Action,
12
+ BringToFrontAction,
13
+ type GModelElement,
14
+ GRoutingHandle,
15
+ isCtrlOrCmd,
16
+ RankedSelectMouseListener,
17
+ SelectAction,
18
+ type SelectableElement
19
+ } from '@eclipse-glsp/client';
20
+ import { injectable } from 'inversify';
21
+
22
+ /**
23
+ * GLSP's select mouse listener, with a plain click on an unselected element
24
+ * replacing whatever is selected when its action executes.
25
+ *
26
+ * The listener names the elements a click deselects from each element's
27
+ * `selected` flag, which the feedback the previous click's command queues
28
+ * writes only when that feedback runs; a click landing before then names
29
+ * nothing, and both elements end up selected. A plain click sends
30
+ * `deselectAll` instead, which `SelectCommand` resolves against the selection
31
+ * service as it executes. Reading the service from the listener would still
32
+ * race the previous click's command, since dispatch is asynchronous.
33
+ * Ctrl/Cmd-click keeps GLSP's add to the selection; a routing handle keeps
34
+ * GLSP's path, since `deselectAll` cannot spare the handle's own edge.
35
+ *
36
+ * Bound by `createGlspClientModule` via `rebind(RankedSelectMouseListener)`.
37
+ */
38
+ @injectable()
39
+ export class HydraniumSelectMouseListener extends RankedSelectMouseListener {
40
+ protected override handleSelectTarget(
41
+ selectableTarget: SelectableElement,
42
+ deselectedElements: GModelElement[],
43
+ event: MouseEvent
44
+ ): (Action | Promise<Action>)[] {
45
+ if (isCtrlOrCmd(event) || selectableTarget instanceof GRoutingHandle) {
46
+ return super.handleSelectTarget(selectableTarget, deselectedElements, event);
47
+ }
48
+ return [SelectAction.setSelection([selectableTarget.id]), BringToFrontAction.create([selectableTarget.id])];
49
+ }
50
+
51
+ protected override handleDeselectAll(): (Action | Promise<Action>)[] {
52
+ return [SelectAction.setSelection([])];
53
+ }
54
+ }