@eclipse-glsp/client
Version:
A sprotty-based client for GLSP
149 lines • 7.14 kB
JavaScript
;
/********************************************************************************
* Copyright (c) 2022-2025 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GLSPHiddenBoundsUpdater = exports.BoundsDataExt = void 0;
const sprotty_1 = require("@eclipse-glsp/sprotty");
const inversify_1 = require("inversify");
const editor_context_service_1 = require("../../base/editor-context-service");
const gmodel_util_1 = require("../../utils/gmodel-util");
const layout_data_1 = require("./layout-data");
const local_bounds_1 = require("./local-bounds");
class BoundsDataExt extends sprotty_1.BoundsData {
}
exports.BoundsDataExt = BoundsDataExt;
/**
* Grabs the bounds from hidden SVG DOM elements, applies layouts, collects routes and fires {@link ComputedBoundsAction}s.
*
* The actions will contain the bound, alignment, and routing points of elements.
*/
let GLSPHiddenBoundsUpdater = class GLSPHiddenBoundsUpdater extends sprotty_1.HiddenBoundsUpdater {
constructor() {
super(...arguments);
this.element2route = [];
}
getElement2BoundsData() {
return this['element2boundsData'];
}
decorate(vnode, element) {
super.decorate(vnode, element);
if ((0, gmodel_util_1.isRoutable)(element)) {
this.element2route.push((0, gmodel_util_1.calcElementAndRoute)(element, this.edgeRouterRegistry));
}
return vnode;
}
postUpdate(cause) {
if (cause === undefined || cause.kind !== sprotty_1.RequestBoundsAction.KIND) {
return;
}
if (local_bounds_1.LocalRequestBoundsAction.is(cause) && cause.elementIDs) {
this.focusOnElements(cause.elementIDs);
}
// collect bounds and layout data in element2BoundsData
this.getBoundsFromDOM();
this.layouter.layout(this.getElement2BoundsData());
// prepare data for action
const resizes = [];
const alignments = [];
const layoutData = [];
this.getElement2BoundsData().forEach((boundsData, element) => {
if (boundsData.boundsChanged && boundsData.bounds !== undefined) {
const resize = {
elementId: element.id,
newSize: {
width: boundsData.bounds.width,
height: boundsData.bounds.height
}
};
// don't copy position if the element is layouted by the server
if (element instanceof sprotty_1.GChildElement && (0, sprotty_1.isLayoutContainer)(element.parent)) {
resize.newPosition = {
x: boundsData.bounds.x,
y: boundsData.bounds.y
};
}
resizes.push(resize);
}
if (boundsData.alignmentChanged && boundsData.alignment !== undefined) {
alignments.push({
elementId: element.id,
newAlignment: boundsData.alignment
});
}
if (layout_data_1.LayoutAware.is(boundsData)) {
layoutData.push({ elementId: element.id, layoutData: boundsData.layoutData });
}
});
const routes = this.element2route.length === 0 ? undefined : this.element2route;
// prepare and dispatch action
const responseId = cause.requestId;
const revision = this.root !== undefined ? this.root.revision : undefined;
const canvasBounds = this.editorContext.canvasBounds;
const viewport = this.editorContext.viewportData;
const computedBoundsAction = sprotty_1.ComputedBoundsAction.create(resizes, {
revision,
alignments,
layoutData,
routes,
responseId,
canvasBounds,
viewport
});
if (local_bounds_1.LocalRequestBoundsAction.is(cause)) {
local_bounds_1.LocalComputedBoundsAction.mark(computedBoundsAction);
}
this.actionDispatcher.dispatch(computedBoundsAction);
// cleanup
this.getElement2BoundsData().clear();
this.element2route = [];
}
focusOnElements(elementIDs) {
const data = this.getElement2BoundsData();
if (data.size > 0) {
// expand given IDs to their descendent element IDs as we need their bounding boxes as well
const index = [...data.keys()][0].index;
const relevantIds = new Set(elementIDs.flatMap(elementId => this.expandElementId(elementId, index, elementIDs)));
// ensure we only keep the bounds of the elements we are interested in
data.forEach((_bounds, element) => !relevantIds.has(element.id) && data.delete(element));
}
}
expandElementId(id, index, elementIDs) {
return (0, gmodel_util_1.getDescendantIds)(index.getById(id));
}
};
exports.GLSPHiddenBoundsUpdater = GLSPHiddenBoundsUpdater;
__decorate([
(0, inversify_1.inject)(sprotty_1.EdgeRouterRegistry),
(0, inversify_1.optional)(),
__metadata("design:type", sprotty_1.EdgeRouterRegistry)
], GLSPHiddenBoundsUpdater.prototype, "edgeRouterRegistry", void 0);
__decorate([
(0, inversify_1.inject)(editor_context_service_1.EditorContextService),
__metadata("design:type", editor_context_service_1.EditorContextService)
], GLSPHiddenBoundsUpdater.prototype, "editorContext", void 0);
exports.GLSPHiddenBoundsUpdater = GLSPHiddenBoundsUpdater = __decorate([
(0, inversify_1.injectable)()
], GLSPHiddenBoundsUpdater);
//# sourceMappingURL=glsp-hidden-bounds-updater.js.map