WIP
This commit is contained in:
@@ -10,7 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver;
|
||||
|
||||
import org.eclipse.lsp4j.jsonrpc.services.JsonDelegate;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.sprotty.SprottyService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService;
|
||||
|
||||
@@ -39,5 +41,9 @@ public interface Sts4LanguageServer extends LanguageServer {
|
||||
* @return
|
||||
*/
|
||||
DiagnosticService getDiagnosticService();
|
||||
|
||||
@JsonDelegate
|
||||
SprottyService getSprottyService();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.ide.vscode.commons.languageserver.sprotty;
|
||||
|
||||
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface SprottyService {
|
||||
|
||||
@JsonNotification("sts/sprotty")
|
||||
void sprottyMessage(JsonObject message);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.ide.vscode.commons.protocol;
|
||||
|
||||
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface SprottyClient {
|
||||
|
||||
@JsonNotification("sts/progress")
|
||||
void sprottyMessage(JsonObject message);
|
||||
|
||||
}
|
||||
@@ -42,6 +42,7 @@
|
||||
<module>commons-gradle</module>
|
||||
<module>commons-boot-app-cli</module>
|
||||
<module>language-server-starter</module>
|
||||
<module>commons-sprotty</module>
|
||||
</modules>
|
||||
|
||||
<repositories>
|
||||
|
||||
@@ -8,11 +8,13 @@ if command -v xvfb-run ; then
|
||||
-f ../pom.xml \
|
||||
-pl $modules \
|
||||
-am \
|
||||
clean install
|
||||
clean install \
|
||||
-DskipTests
|
||||
else
|
||||
../mvnw \
|
||||
-f ../pom.xml \
|
||||
-pl $modules \
|
||||
-am \
|
||||
clean install
|
||||
clean install \
|
||||
-DskipTests
|
||||
fi
|
||||
|
||||
@@ -18,18 +18,19 @@ public class PopupModelFactory implements IPopupModelFactory {
|
||||
@Override
|
||||
public SModelRoot createPopupModel(SModelElement element, RequestPopupModelAction request, IDiagramServer server) {
|
||||
|
||||
SGraph graph = new SGraph();
|
||||
graph.setId("popup");
|
||||
List<SModelElement> children = new ArrayList<>();
|
||||
|
||||
SLabel label = new SLabel();
|
||||
label.setType("node:label");
|
||||
label.setText("I'm a tooltip!");
|
||||
children.add(label);
|
||||
|
||||
graph.setChildren(children);
|
||||
|
||||
return graph;
|
||||
// SGraph graph = new SGraph();
|
||||
// graph.setId("popup");
|
||||
// List<SModelElement> children = new ArrayList<>();
|
||||
//
|
||||
// SLabel label = new SLabel();
|
||||
// label.setType("node:label");
|
||||
// label.setText("I'm a tooltip!");
|
||||
// children.add(label);
|
||||
//
|
||||
// graph.setChildren(children);
|
||||
//
|
||||
// return graph;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
5
nodejs-packages/sprotty-live-beans-client/copy-script.sh
Normal file
5
nodejs-packages/sprotty-live-beans-client/copy-script.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
rm -rf ../../vscode-extensions/vscode-spring-boot/media/*
|
||||
mkdir -p ../../vscode-extensions/vscode-spring-boot/media
|
||||
cp bundle.js* ../../vscode-extensions/vscode-spring-boot/media
|
||||
cp -R css ../../vscode-extensions/vscode-spring-boot/media
|
||||
cp -R lib ../../vscode-extensions/vscode-spring-boot/media
|
||||
46
nodejs-packages/sprotty-live-beans-client/css/diagram.css
Normal file
46
nodejs-packages/sprotty-live-beans-client/css/diagram.css
Normal file
@@ -0,0 +1,46 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2017-2018 TypeFox 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
|
||||
********************************************************************************/
|
||||
|
||||
.sprotty-node {
|
||||
fill: #aae;
|
||||
stroke: #66b;
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
.sprotty-text {
|
||||
font-size: 16pt;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
.sprotty-edge {
|
||||
fill: none;
|
||||
stroke: #488;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.sprotty-node.selected {
|
||||
stroke: #dd8;
|
||||
stroke-width: 6;
|
||||
}
|
||||
|
||||
.sprotty-missing {
|
||||
stroke-width: 1;
|
||||
stroke: #f00;
|
||||
fill: #f00;
|
||||
font-family: SansSerif;
|
||||
font-size: 14pt;
|
||||
text-anchor: middle;
|
||||
}
|
||||
38
nodejs-packages/sprotty-live-beans-client/css/page.css
Normal file
38
nodejs-packages/sprotty-live-beans-client/css/page.css
Normal file
@@ -0,0 +1,38 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2017-2018 TypeFox 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
|
||||
********************************************************************************/
|
||||
|
||||
.copyright {
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.help {
|
||||
margin-top: 24px;
|
||||
text-align: right;
|
||||
font-size: 16px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #bbb;
|
||||
}
|
||||
39
nodejs-packages/sprotty-live-beans-client/index.html
Normal file
39
nodejs-packages/sprotty-live-beans-client/index.html
Normal file
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>sprotty Circles Example</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="css/page.css">
|
||||
<!-- support Microsoft browsers -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dom4/3.0.0/dom4.js">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row" id="sprotty-app" data-app="circlegraph">
|
||||
<div class="col-md-10">
|
||||
<h1>sprotty Circles Example</h1>
|
||||
<p>
|
||||
<button id="refresh">Refresh</button>
|
||||
<button id="scrambleNodes">Scramble nodes</button>
|
||||
</p>
|
||||
</div>
|
||||
<div class="help col-md-2">
|
||||
<a href='https://github.com/theia-ide/sprotty/wiki/Using-sprotty'>Help</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="spring-boot" class="sprotty"/>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
© 2017 <a href="http://typefox.io">TypeFox GmbH</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="bundle.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
33
nodejs-packages/sprotty-live-beans-client/package.json
Normal file
33
nodejs-packages/sprotty-live-beans-client/package.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "sprotty-live-beans-client",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "bundle.js",
|
||||
"scripts": {
|
||||
"defunct-build": "tsc -p ./tsconfig.json",
|
||||
"build": "webpack --progress --config ./webpack.config.js && bash copy-script.sh",
|
||||
"run": "npx http-server -c-1 .",
|
||||
"watch": "tsc -w -p ./tsconfig.json",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Kris De Volder <kdevolder@pivotal.io>",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/sockjs-client": "^1.1.1",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"sprotty": "^0.6.0",
|
||||
"sockjs-client": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.7.2",
|
||||
"circular-dependency-plugin": "^2.0.0",
|
||||
"core-js": "^2.5.1",
|
||||
"css-loader": "^2.1.0",
|
||||
"http-server": "^0.11.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"ts-loader": "^4.4.2",
|
||||
"typescript": "^3.5.3",
|
||||
"webpack": "^4.15.1",
|
||||
"webpack-cli": "^3.0.8"
|
||||
}
|
||||
}
|
||||
29
nodejs-packages/sprotty-live-beans-client/src/app.ts
Normal file
29
nodejs-packages/sprotty-live-beans-client/src/app.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2017-2018 TypeFox 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
|
||||
********************************************************************************/
|
||||
|
||||
import "reflect-metadata";
|
||||
console.log("Loaded reflect-metadata");
|
||||
|
||||
import runStandalone from "./standalone";
|
||||
|
||||
const appDiv = document.getElementById('sprotty-app')
|
||||
if(appDiv) {
|
||||
const appMode = appDiv.getAttribute('data-app');
|
||||
if (appMode === 'circlegraph')
|
||||
runStandalone();
|
||||
else
|
||||
throw new Error('Dunno what to do :-(');
|
||||
}
|
||||
78
nodejs-packages/sprotty-live-beans-client/src/di.config.ts
Normal file
78
nodejs-packages/sprotty-live-beans-client/src/di.config.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2017-2018 TypeFox 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
|
||||
********************************************************************************/
|
||||
import {BeanNode, VSCodeWebViewDiagramServer} from "./model";
|
||||
|
||||
console.log("Loading di.config");
|
||||
import "reflect-metadata"
|
||||
|
||||
import { Container, ContainerModule } from "inversify";
|
||||
import {
|
||||
defaultModule,
|
||||
TYPES,
|
||||
configureViewerOptions,
|
||||
ConsoleLogger,
|
||||
LogLevel,
|
||||
boundsModule,
|
||||
hoverModule,
|
||||
moveModule,
|
||||
selectModule,
|
||||
undoRedoModule,
|
||||
viewportModule,
|
||||
LocalModelSource,
|
||||
exportModule,
|
||||
CircularNode,
|
||||
configureModelElement,
|
||||
SGraph,
|
||||
updateModule,
|
||||
graphModule,
|
||||
routingModule,
|
||||
modelSourceModule,
|
||||
SLabel,
|
||||
SLabelView,
|
||||
SCompartment,
|
||||
SCompartmentView, SEdge
|
||||
} from "sprotty";
|
||||
import {BeanNodeView, CircleNodeView, EdgeView, ExampleGraphView} from "./views";
|
||||
|
||||
export default (useWebsocket: boolean) => {
|
||||
require("sprotty/css/sprotty.css");
|
||||
require("../css/diagram.css");
|
||||
const circlegraphModule = new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
if (useWebsocket)
|
||||
bind(TYPES.ModelSource).to(VSCodeWebViewDiagramServer).inSingletonScope();
|
||||
else
|
||||
bind(TYPES.ModelSource).to(LocalModelSource).inSingletonScope();
|
||||
rebind(TYPES.ILogger).to(ConsoleLogger).inSingletonScope();
|
||||
rebind(TYPES.LogLevel).toConstantValue(LogLevel.log);
|
||||
const context = { bind, unbind, isBound, rebind };
|
||||
configureModelElement(context, 'graph', SGraph, ExampleGraphView);
|
||||
configureModelElement(context, 'node:circle', CircularNode, CircleNodeView);
|
||||
configureModelElement(context, 'node:bean', BeanNode, BeanNodeView);
|
||||
configureModelElement(context, 'node:label', SLabel, SLabelView);
|
||||
configureModelElement(context, 'compartment', SCompartment, SCompartmentView);
|
||||
configureModelElement(context, 'edge:straight', /*OrthogonalEgde*/ SEdge, EdgeView);
|
||||
configureViewerOptions(context, {
|
||||
needsClientLayout: true,
|
||||
needsServerLayout: true,
|
||||
baseDiv: 'spring-boot'
|
||||
});
|
||||
});
|
||||
|
||||
const container = new Container();
|
||||
container.load(defaultModule, selectModule, moveModule, boundsModule, undoRedoModule, viewportModule,
|
||||
exportModule, updateModule, graphModule, routingModule, modelSourceModule, circlegraphModule, hoverModule);
|
||||
return container;
|
||||
};
|
||||
67
nodejs-packages/sprotty-live-beans-client/src/model.ts
Normal file
67
nodejs-packages/sprotty-live-beans-client/src/model.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import {ManhattanEdgeRouter, RectangularNode, SEdge, WebSocketDiagramServer, ActionMessage, DiagramServer} from "sprotty";
|
||||
import {injectable} from 'inversify';
|
||||
|
||||
export class BeanNode extends RectangularNode {
|
||||
|
||||
}
|
||||
|
||||
export class OrthogonalEgde extends SEdge {
|
||||
|
||||
routerKind = ManhattanEdgeRouter.KIND;
|
||||
|
||||
}
|
||||
|
||||
const SOCKET_MESSAGE_BUFFER = 4000;
|
||||
const END_MESSAGE = '@end';
|
||||
|
||||
@injectable()
|
||||
export class ExampleWebsocketDiagramServer extends WebSocketDiagramServer {
|
||||
|
||||
protected sendMessage(message: ActionMessage): void {
|
||||
if (this.webSocket) {
|
||||
const messageStr = JSON.stringify(message);
|
||||
let offset = 0;
|
||||
while (offset < messageStr.length) {
|
||||
this.webSocket.send(messageStr.substring(offset, offset + SOCKET_MESSAGE_BUFFER));
|
||||
offset += SOCKET_MESSAGE_BUFFER;
|
||||
}
|
||||
this.webSocket.send(END_MESSAGE);
|
||||
} else {
|
||||
throw new Error('WebSocket is not connected');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class VSCodeWebViewDiagramServer extends DiagramServer {
|
||||
|
||||
protected vscode: any;
|
||||
|
||||
listen(vscode: any): void {
|
||||
|
||||
window.addEventListener('message', event => {
|
||||
const message = event.data; // The json data that the extension sent
|
||||
console.log('Message Received');
|
||||
this.messageReceived(message);
|
||||
});
|
||||
|
||||
this.vscode = vscode;
|
||||
|
||||
}
|
||||
|
||||
// disconnect() {
|
||||
// if (this.webSocket) {
|
||||
// this.webSocket.close();
|
||||
// this.webSocket = undefined;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
protected sendMessage(message: ActionMessage): void {
|
||||
console.log('Send Message');
|
||||
if (this.vscode) {
|
||||
this.vscode.postMessage(message);
|
||||
} else {
|
||||
throw new Error('No VSCode api object');
|
||||
}
|
||||
}
|
||||
}
|
||||
118
nodejs-packages/sprotty-live-beans-client/src/standalone.ts
Normal file
118
nodejs-packages/sprotty-live-beans-client/src/standalone.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2017-2018 TypeFox 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
|
||||
********************************************************************************/
|
||||
|
||||
declare const acquireVsCodeApi: any;
|
||||
|
||||
import {
|
||||
TYPES, IActionDispatcher, SModelElementSchema, SEdgeSchema, SNodeSchema, SGraphSchema,
|
||||
ModelSource, LocalModelSource, WebSocketDiagramServer, RequestModelAction
|
||||
} from "sprotty";
|
||||
import createContainer from "./di.config";
|
||||
import * as SockJS from "sockjs-client";
|
||||
import {VSCodeWebViewDiagramServer} from "./model";
|
||||
|
||||
export default function runStandalone() {
|
||||
const container = createContainer(true);
|
||||
const dispatcher = container.get<IActionDispatcher>(TYPES.IActionDispatcher);
|
||||
|
||||
// Initialize gmodel
|
||||
const node0 = {
|
||||
id: 'node0', type: 'node:bean', position: {x: 100, y: 100}, size: {width: 80, height: 80},
|
||||
layout: 'vbox',
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 'node0_header',
|
||||
type: 'compartment',
|
||||
layout: 'hbox',
|
||||
children: [
|
||||
{
|
||||
id: 'bean-name',
|
||||
type: 'node:label',
|
||||
text: 'SpringBootApplication'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// const children_for_node = [];
|
||||
|
||||
|
||||
const graph: SGraphSchema = {id: 'graph', type: 'graph', children: [node0]};
|
||||
|
||||
let count = 2;
|
||||
|
||||
function addNode(): SModelElementSchema[] {
|
||||
const newNode: SNodeSchema = {
|
||||
id: 'node' + count,
|
||||
type: 'node:bean',
|
||||
position: {
|
||||
x: Math.random() * 1024,
|
||||
y: Math.random() * 768
|
||||
},
|
||||
size: {
|
||||
width: 80,
|
||||
height: 80
|
||||
}
|
||||
};
|
||||
const newEdge: SEdgeSchema = {
|
||||
id: 'edge' + count,
|
||||
type: 'edge:straight',
|
||||
sourceId: 'node0',
|
||||
targetId: 'node' + count++
|
||||
};
|
||||
return [newNode, newEdge];
|
||||
}
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
const newElements = addNode();
|
||||
for (const e of newElements) {
|
||||
graph.children.splice(0, 0, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Run
|
||||
const modelSource = container.get<ModelSource>(TYPES.ModelSource);
|
||||
console.log('Model source: ' + modelSource);
|
||||
if (modelSource instanceof LocalModelSource) {
|
||||
(<LocalModelSource>modelSource).setModel(graph);
|
||||
}
|
||||
|
||||
if (modelSource instanceof WebSocketDiagramServer) {
|
||||
const ws = new SockJS('http://localhost:8080/websocket');
|
||||
modelSource.clientId = 'spring-boot';
|
||||
modelSource.listen(ws);
|
||||
ws.addEventListener('open', () => {
|
||||
dispatcher.dispatch(new RequestModelAction());
|
||||
});
|
||||
ws.addEventListener('error', (event) => {
|
||||
console.error(`WebSocket Error: ${event}`)
|
||||
})
|
||||
}
|
||||
|
||||
if (modelSource instanceof VSCodeWebViewDiagramServer) {
|
||||
modelSource.listen(acquireVsCodeApi());
|
||||
}
|
||||
|
||||
console.log('Before requesting model');
|
||||
|
||||
// Button features
|
||||
document.getElementById('refresh')!.addEventListener('click', () => {
|
||||
dispatcher.dispatch(new RequestModelAction());
|
||||
});
|
||||
|
||||
}
|
||||
107
nodejs-packages/sprotty-live-beans-client/src/views.tsx
Normal file
107
nodejs-packages/sprotty-live-beans-client/src/views.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2017-2018 TypeFox 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
|
||||
********************************************************************************/
|
||||
|
||||
/** @jsx svg */
|
||||
import { svg } from 'snabbdom-jsx';
|
||||
|
||||
import { VNode } from "snabbdom/vnode";
|
||||
import {
|
||||
RenderingContext,
|
||||
SNode,
|
||||
IView,
|
||||
SGraphView,
|
||||
SGraph,
|
||||
PolylineEdgeView,
|
||||
SEdge,
|
||||
Point,
|
||||
RectangularNodeView,
|
||||
Selectable,
|
||||
SPort,
|
||||
Hoverable,
|
||||
SShapeElement
|
||||
} from "sprotty";
|
||||
import { injectable } from 'inversify';
|
||||
|
||||
/**
|
||||
* A very simple example node consisting of a plain circle.
|
||||
*/
|
||||
@injectable()
|
||||
export class CircleNodeView implements IView {
|
||||
render(node: SNode, context: RenderingContext): VNode {
|
||||
const radius = this.getRadius(node);
|
||||
return <g>
|
||||
<circle class-sprotty-node={true} class-selected={node.selected} r={radius} cx={radius} cy={radius}></circle>
|
||||
<text x={radius} y={radius + 7} class-sprotty-text={true}>{node.id.substr(4)}</text>
|
||||
</g>;
|
||||
}
|
||||
|
||||
protected getRadius(node: SNode) {
|
||||
return 40;
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class ExampleGraphView extends SGraphView {
|
||||
|
||||
render(model: Readonly<SGraph>, context: RenderingContext): VNode {
|
||||
const transform = `scale(${model.zoom}) translate(${-model.scroll.x},${-model.scroll.y})`;
|
||||
return <svg class-sprotty-graph={true}>
|
||||
<defs>
|
||||
<marker id="arrow" orient="auto" overflow="visible" markerUnits="userSpaceOnUse">
|
||||
<path transform="rotate(180)" d="M 10 -5 0 0 10 5 z" />
|
||||
</marker>
|
||||
|
||||
<marker id="dot" viewBox="0 0 10 10" refX="5" refY="5"
|
||||
markerWidth="5" markerHeight="5">
|
||||
<circle cx="5" cy="5" r="5" fill="red" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g transform={transform}>
|
||||
{context.renderChildren(model)}
|
||||
</g>
|
||||
</svg>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class EdgeView extends PolylineEdgeView {
|
||||
|
||||
protected renderLine(edge: SEdge, segments: Point[], context: RenderingContext): VNode {
|
||||
const firstPoint = segments[0];
|
||||
let path = `M ${firstPoint.x},${firstPoint.y}`;
|
||||
for (let i = 1; i < segments.length; i++) {
|
||||
const p = segments[i];
|
||||
path += ` L ${p.x},${p.y}`;
|
||||
}
|
||||
const dom: any = <path d={path}/>;
|
||||
dom.data.attrs['marker-end'] = 'url(#arrow)';
|
||||
return dom;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class BeanNodeView extends RectangularNodeView {
|
||||
render(node: Readonly<SShapeElement & Hoverable & Selectable>, context: RenderingContext): VNode {
|
||||
return <g>
|
||||
<rect class-sprotty-node={node instanceof SNode} class-sprotty-port={node instanceof SPort}
|
||||
class-mouseover={node.hoverFeedback} class-selected={node.selected}
|
||||
x="0" y="0" width={Math.max(node.size.width, 0)} height={Math.max(node.size.height, 0)} rx="10" ry="10"></rect>
|
||||
{context.renderChildren(node)}
|
||||
</g>;
|
||||
}
|
||||
}
|
||||
|
||||
33
nodejs-packages/sprotty-live-beans-client/tsconfig.json
Normal file
33
nodejs-packages/sprotty-live-beans-client/tsconfig.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6", "dom"
|
||||
],
|
||||
"types": [
|
||||
"node", "reflect-metadata",
|
||||
],
|
||||
"typeRoots": [
|
||||
"node_modules/@types", "typings"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"strictNullChecks": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"outDir": "lib",
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"src", "typings"
|
||||
],
|
||||
"exclude": [
|
||||
"**/*.spec.ts", "**/*.spec.tsx"
|
||||
]
|
||||
}
|
||||
53
nodejs-packages/sprotty-live-beans-client/webpack.config.js
Normal file
53
nodejs-packages/sprotty-live-beans-client/webpack.config.js
Normal file
@@ -0,0 +1,53 @@
|
||||
var webpack = require('webpack');
|
||||
var path = require('path');
|
||||
var CircularDependencyPlugin = require('circular-dependency-plugin');
|
||||
|
||||
module.exports = {
|
||||
entry: [
|
||||
'core-js/es6/map',
|
||||
'core-js/es6/promise',
|
||||
'core-js/es6/string',
|
||||
'core-js/es6/symbol',
|
||||
'./src/app.ts'
|
||||
],
|
||||
output: {
|
||||
filename: 'bundle.js',
|
||||
path: path.resolve(__dirname, '.')
|
||||
},
|
||||
mode: 'development',
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
// Add `.ts` and `.tsx` as a resolvable extension.
|
||||
extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: [{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
configFile: path.resolve(__dirname, 'tsconfig.json')
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: /\.useable\.css$/,
|
||||
loader: 'style-loader!css-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
node : { fs: 'empty', net: 'empty' },
|
||||
plugins: [
|
||||
new CircularDependencyPlugin({
|
||||
exclude: /(node_modules|examples)\/./,
|
||||
failOnError: false
|
||||
}),
|
||||
new webpack.WatchIgnorePlugin([
|
||||
/\.js$/,
|
||||
/\.d\.ts$/
|
||||
])
|
||||
]
|
||||
};
|
||||
@@ -15,4 +15,5 @@ src/test/resources/test-projects/**/.classpath
|
||||
src/test/resources/test-projects/**/.project
|
||||
src/test/resources/test-projects/**/.factorypath
|
||||
src/test/resources/test-projects/**/.settings/**
|
||||
src/test/resources/test-projects/**/bin/**
|
||||
src/test/resources/test-projects/**/bin/**
|
||||
/media/
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
import * as VSCode from 'vscode';
|
||||
import {workspace} from 'vscode';
|
||||
import * as LiveBeansModule from './live-bean-view';
|
||||
|
||||
import * as commons from '@pivotal-tools/commons-vscode';
|
||||
|
||||
import {LanguageClient} from "vscode-languageclient";
|
||||
import {LanguageClient, NotificationType} from "vscode-languageclient";
|
||||
|
||||
const PROPERTIES_LANGUAGE_ID = "spring-boot-properties";
|
||||
const YAML_LANGUAGE_ID = "spring-boot-properties-yaml";
|
||||
@@ -18,7 +19,7 @@ export function activate(context: VSCode.ExtensionContext): Thenable<LanguageCli
|
||||
// registerPipelineGenerator(context);
|
||||
let options : commons.ActivatorOptions = {
|
||||
DEBUG: false,
|
||||
CONNECT_TO_LS: false,
|
||||
CONNECT_TO_LS: true,
|
||||
extensionId: 'vscode-spring-boot',
|
||||
preferJdk: true,
|
||||
checkjvm: (context: VSCode.ExtensionContext, jvm: commons.JVM) => {
|
||||
@@ -67,5 +68,7 @@ export function activate(context: VSCode.ExtensionContext): Thenable<LanguageCli
|
||||
highlightCodeLensSettingKey: 'boot-java.highlight-codelens.on'
|
||||
};
|
||||
|
||||
return commons.activate(options, context);
|
||||
return commons.activate(options, context).then(client => {
|
||||
return LiveBeansModule.activate(context, client).then(() => client);
|
||||
})
|
||||
}
|
||||
|
||||
255
vscode-extensions/vscode-spring-boot/lib/live-bean-view.ts
Normal file
255
vscode-extensions/vscode-spring-boot/lib/live-bean-view.ts
Normal file
@@ -0,0 +1,255 @@
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as SockJS from 'sockjs-client';
|
||||
import * as WebSocket from 'ws';
|
||||
import {LanguageClient, NotificationType} from "vscode-languageclient";
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext, client: LanguageClient) {
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('sts4.liveBeans.start', () => {
|
||||
LiveBeansView.createOrShow(context.extensionPath, client);
|
||||
})
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages cat coding webview panels
|
||||
*/
|
||||
class LiveBeansView {
|
||||
/**
|
||||
* Track the currently panel. Only allow a single panel to exist at a time.
|
||||
*/
|
||||
public static currentPanel: LiveBeansView | undefined;
|
||||
|
||||
public static readonly viewType = 'catCoding';
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public static createOrShow(extensionPath: string, client: LanguageClient) {
|
||||
const column = vscode.window.activeTextEditor
|
||||
? vscode.window.activeTextEditor.viewColumn
|
||||
: undefined;
|
||||
|
||||
// If we already have a panel, show it.
|
||||
if (LiveBeansView.currentPanel) {
|
||||
LiveBeansView.currentPanel._panel.reveal(column);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, create a new panel.
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
LiveBeansView.viewType,
|
||||
'Live Beans',
|
||||
column || vscode.ViewColumn.One,
|
||||
{
|
||||
// Enable javascript in the webview
|
||||
enableScripts: true,
|
||||
|
||||
|
||||
|
||||
// And restrict the webview to only loading content from our extension's `media` directory.
|
||||
localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))]
|
||||
}
|
||||
);
|
||||
|
||||
LiveBeansView.currentPanel = new LiveBeansView(panel, extensionPath);
|
||||
|
||||
console.log('Created webview panel!');
|
||||
const bridge: LSWebViewToLSPBridge = new LSWebViewToLSPBridge(panel.webview, client);
|
||||
panel.webview.onDidReceiveMessage(message => bridge.sendToLs(message));
|
||||
}
|
||||
|
||||
public static revive(panel: vscode.WebviewPanel, extensionPath: string) {
|
||||
LiveBeansView.currentPanel = new LiveBeansView(panel, extensionPath);
|
||||
}
|
||||
|
||||
private constructor(panel: vscode.WebviewPanel, extensionPath: string) {
|
||||
this._panel = panel;
|
||||
this._extensionPath = extensionPath;
|
||||
|
||||
// Set the webview's initial html content
|
||||
this._update();
|
||||
|
||||
// Listen for when the panel is disposed
|
||||
// This happens when the user closes the panel or when the panel is closed programatically
|
||||
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
||||
|
||||
// Update the content based on view changes
|
||||
this._panel.onDidChangeViewState(
|
||||
e => {
|
||||
if (this._panel.visible) {
|
||||
this._update();
|
||||
}
|
||||
},
|
||||
null,
|
||||
this._disposables
|
||||
);
|
||||
|
||||
// Handle messages from the webview
|
||||
this._panel.webview.onDidReceiveMessage(
|
||||
message => {
|
||||
switch (message.command) {
|
||||
case 'alert':
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
return;
|
||||
}
|
||||
},
|
||||
null,
|
||||
this._disposables
|
||||
);
|
||||
}
|
||||
|
||||
public doRefactor() {
|
||||
// Send a message to the webview webview.
|
||||
// You can send any JSON serializable data.
|
||||
this._panel.webview.postMessage({ command: 'refactor' });
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
LiveBeansView.currentPanel = undefined;
|
||||
|
||||
// Clean up our resources
|
||||
this._panel.dispose();
|
||||
|
||||
while (this._disposables.length) {
|
||||
const x = this._disposables.pop();
|
||||
if (x) {
|
||||
x.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _update() {
|
||||
this._panel.webview.html = this._getHtmlForWebview(/*cats[catName]*/);
|
||||
}
|
||||
|
||||
mediaUrl(...pathsegments: string[]) {
|
||||
const mediaPath = path.join(this._extensionPath, 'media')
|
||||
|
||||
// Local path to main script run in the webview
|
||||
const scriptPathOnDisk = vscode.Uri.file(
|
||||
path.join(mediaPath, ...pathsegments)
|
||||
);
|
||||
|
||||
// And the uri we use to load this script in the webview
|
||||
return scriptPathOnDisk.with({ scheme: 'vscode-resource' });
|
||||
}
|
||||
|
||||
private _getHtmlForWebview(/*catGif: string*/) {
|
||||
|
||||
// And the uri we use to load this script in the webview
|
||||
const scriptUri = this.mediaUrl('bundle.js');
|
||||
const cssUri = this.mediaUrl('css', 'page.css');
|
||||
|
||||
// Use a nonce to whitelist which scripts can be run
|
||||
const nonce = getNonce();
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>sprotty Circles Example</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href=${cssUri}>
|
||||
<!-- support Microsoft browsers -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dom4/3.0.0/dom4.js">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row" id="sprotty-app" data-app="circlegraph">
|
||||
<div class="col-md-10">
|
||||
<h1>sprotty Circles Example</h1>
|
||||
<p>
|
||||
<button id="refresh">Refresh</button>
|
||||
<button id="scrambleNodes">Scramble nodes</button>
|
||||
</p>
|
||||
</div>
|
||||
<div class="help col-md-2">
|
||||
<a href='https://github.com/theia-ide/sprotty/wiki/Using-sprotty'>Help</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="spring-boot" class="sprotty"/>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
© 2017 <a href="http://typefox.io">TypeFox GmbH</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="${scriptUri}"></script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
|
||||
function getNonce() {
|
||||
let text = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
const SOCKET_MESSAGE_BUFFER = 4000;
|
||||
const END_MESSAGE = '@end';
|
||||
|
||||
interface LSWebviewBridgeConstructor {
|
||||
create(webview: vscode.Webview): LSWebViewBridge;
|
||||
}
|
||||
|
||||
interface LSWebViewBridge {
|
||||
sendToLs(message: any);
|
||||
}
|
||||
|
||||
class LSWebViewToWebsocketBridge implements LSWebViewBridge {
|
||||
private ws: WebSocket;
|
||||
|
||||
constructor(webview: vscode.Webview): LSWebViewBridge {
|
||||
this.ws = new SockJS('http://localhost:8080/websocket');
|
||||
this.ws.addEventListener('message', (event) => {
|
||||
console.dir(event.data);
|
||||
const actionMessage = JSON.parse(event.data);
|
||||
webview.postMessage(actionMessage);
|
||||
});
|
||||
}
|
||||
|
||||
sendToLs(message: any) {
|
||||
console.log('Send messge Webview -> LS');
|
||||
const messageStr = JSON.stringify(message);
|
||||
for (let offset = 0; offset < messageStr.length; offset += SOCKET_MESSAGE_BUFFER) {
|
||||
this.ws.send(messageStr.substring(offset, offset + SOCKET_MESSAGE_BUFFER));
|
||||
}
|
||||
this.ws.send(END_MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const SPROTTY_LSP_NOTIFICATION = new NotificationType<any, void>("sts/sprotty");
|
||||
|
||||
class LSWebViewToLSPBridge implements LSWebViewBridge {
|
||||
|
||||
private client: LanguageClient;
|
||||
|
||||
constructor(webview: vscode.Webview, client: LanguageClient) {
|
||||
client.onReady().then(() => {
|
||||
client.onNotification(SPROTTY_LSP_NOTIFICATION, async (params: any) =>
|
||||
webview.postMessage(params)
|
||||
);
|
||||
});
|
||||
this.client = client;
|
||||
|
||||
}
|
||||
|
||||
sendToLs(message: any) {
|
||||
this.client.onReady().then(() => {
|
||||
this.client.sendNotification(SPROTTY_LSP_NOTIFICATION, message);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,8 @@
|
||||
"onLanguage:spring-boot-properties",
|
||||
"onLanguage:spring-boot-properties-yaml",
|
||||
"onLanguage:java",
|
||||
"onLanguage:xml"
|
||||
"onLanguage:xml",
|
||||
"onCommand:sts4.liveBeans.start"
|
||||
],
|
||||
"contributes": {
|
||||
"javaExtensions": [
|
||||
@@ -176,6 +177,13 @@
|
||||
"scopeName": "source.java-properties",
|
||||
"path": "./properties-support/java-properties.tmLanguage"
|
||||
}
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"command": "sts4.liveBeans.start",
|
||||
"title": "Live Beans Graph",
|
||||
"category": "Spring-Boot"
|
||||
}
|
||||
]
|
||||
},
|
||||
"main": "./out/lib/Main",
|
||||
@@ -190,12 +198,15 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@pivotal-tools/commons-vscode": "file:../commons-vscode/pivotal-tools-commons-vscode-0.2.2.tgz",
|
||||
"sockjs-client": "1.3.0",
|
||||
"vscode-languageclient": "5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vsce": "^1.36.1",
|
||||
"@types/sockjs-client": "^1.1.1",
|
||||
"@types/node": "^9.6.51",
|
||||
"@types/ws": "^6.0.2",
|
||||
"typescript": "2.7.2",
|
||||
"@types/node": "^9.4.6",
|
||||
"vsce": "^1.36.1",
|
||||
"vscode": "^1.1.33"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"declaration": true,
|
||||
"outDir": "out",
|
||||
"sourceMap": true,
|
||||
"rootDir": "."
|
||||
"rootDir": ".",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"typings/*.d.ts",
|
||||
|
||||
Reference in New Issue
Block a user