Skip to content

Instantly share code, notes, and snippets.

@ThomasRohde
Last active July 23, 2023 10:41
Show Gist options
  • Save ThomasRohde/8daf0a5c5814b597953983d0a549b04c to your computer and use it in GitHub Desktop.
Save ThomasRohde/8daf0a5c5814b597953983d0a549b04c to your computer and use it in GitHub Desktop.
Proof-of-concept for bi-directional integration of a browser editor/window #JArchi #Archimatetool #Archi
// *** WARNING ***
// On the surface, this seems to work OK, but it does not work with the Archi undo/redo mechanism,
// and there is a risk of corrupting the model Also, changes might disappear if you run another script while the browser is open
/*
Author: Thomas Klok Rohde
Description:
Proof-of-concept for interacting with a browser. Enter a regular expression in the search bar,
and edit any of listed documentation fields. Press 'Refresh' to update the model.
History:
November 29, 2022 : Created
*/
console.show();
console.clear();
const BrowserEditorInput = Java.type('com.archimatetool.editor.browser.BrowserEditorInput');
const IBrowserEditor = Java.type('com.archimatetool.editor.browser.IBrowserEditor');
const EditorManager = Java.type('com.archimatetool.editor.ui.services.EditorManager');
const CustomFunction = Java.extend(Java.type('org.eclipse.swt.browser.BrowserFunction'));
let html = /* html */
`<!DOCTYPE HTML>
<html>
<head>
<title>Interacting with the browser</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style type="text/css">
html, body {
margin: 1em;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<div class="row g-3">
<div class="col-sm-7">
<div class="input-group mb-3">
<button class="btn btn-outline-primary" type="button" id="submit" onclick='submit()'>Search</button>
<input type="text" class="form-control" onchange='submit()' id="content" placeholder="Insert a regular expression as search term" aria-label="Search in the current model" aria-describedby="button-addon1">
</div>
</div>
<div class="col">
<button class="btn btn-outline-primary" type="button" id="refresh" onclick='refresh()'>Refresh</button>
</div>
<div>
<table class="table table-striped" id="table">
</table>
<div id='editor_holder'></div>
<script type="text/javascript">
function submit() {
let content = document.querySelector("#content").value;
let table = document.querySelector("#table");
let result = submitEvent(content);
let outputArea = document.querySelector("#output");
table.innerHTML = result;
}
function refresh() {
let docAreas = document.querySelectorAll("[data='documentation']");
let result = {};
for (const docArea of docAreas) {
result[docArea.id] = docArea.value;
}
refreshEvent(JSON.stringify(result));
}
</script>
</body>
</html>`;
// Write the HTML to a temporary file, so we are allowed to execute a local script
let System = Java.type('java.lang.System');
let tmpfile = System.getProperty("java.io.tmpdir") + "testbrowser.html";
$.fs.writeFile(tmpfile, html);
let input = new BrowserEditorInput("file:///" + tmpfile, "Test browser");
let browser = EditorManager.openEditor(input, IBrowserEditor.ID).getBrowser();
let display = shell.getDisplay();
// Custom browser function to fetch matching elements
let fncSubmit = new CustomFunction(browser, "submitEvent", {
function: function (args) {
let search = new RegExp(args[0].toLowerCase().trim());
let rows = "";
$("*").each(e => {
let name = e.name.toLowerCase();
if (name.match(search)) {
rows += `<tr><th scope="row">${e.name}</th><td>${e.type}</td><td><textarea data="documentation" class="form-control" id="${e.id}" rows="1">${e.documentation}</textarea></td></tr>`
}
})
let result = `<thead><tr><th scope="col">Name</th><th scope="col">Type</th><th style="width: 60%" scope="col">Documentation</th></tr></thead><tbody>${rows}</tbody>`
return result;
}
});
// Custom browser function to update the model
let fncRefresh = new CustomFunction(browser, "refreshEvent", {
function: function (args) {
let updates = JSON.parse(args[0]);
for (const id in updates)
$("#" + id).first().documentation = updates[id];
}
});
// Keep the wheels spinning so we can update the model
while (true) {
if (!display.readAndDispatch()) display.sleep();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment