Newer
Older
// This script will be run within the webview itself
// It cannot access the main VS Code APIs directly.
(function () {
const vscode = acquireVsCodeApi();

Stekelenburg, A.V. (Alexander, Student )
committed
document.getElementById("constants").parentElement.style.height = "0";
for (const element of document.querySelectorAll(".pane-view .pane")) {
addCollapseBehaviour(element);
}
/**
* @type {function()[]}
*/
const revertButtons = [];
/**
* @type {HTMLSelectElement}
*/
const toolDropDown = document.getElementById("tools");
toolDropDown.addEventListener('change', event => {
var oldState = vscode.getState();
var currentTool = toolDropDown.options[toolDropDown.selectedIndex].value;
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: currentTool });
vscode.postMessage({ type: "toolSelected", toolName: currentTool });

Stekelenburg, A.V. (Alexander, Student )
committed
});
// Handle messages sent from the extension to the webview
window.addEventListener('message', event => {
const message = event.data; // The json data that the extension sent
console.log("Received message");
switch (message.type) {
case 'updateDocumentVars':
updateDocumentVars(message.documentVars, message.uri);
updateParameters(message.parameters, message.toolName);
case 'fillTools':
{
fillTools(message.tools);
break;
}

Stekelenburg, A.V. (Alexander, Student )
committed
for (const body of document.querySelectorAll(".pane-body")) {
if (body.style.height) {
expandHeight(body, 0);
}
}
const runButton = document.getElementById("run-button");
runButton.addEventListener("click", event => {
const state = vscode.getState();
for (const file of state.documentVars) {
if (file.uri === state.currentUri) {
for (const tool of state.parameters) {
if (tool.toolName === state.currentTool) {
vscode.postMessage({ type: "runTool", uri: state.currentUri, toolName: toolDropDown.options[toolDropDown.selectedIndex].value, constants: file.constants, distributions: file.distributions, parameters: tool.parameters });
}
}
});

Stekelenburg, A.V. (Alexander, Student )
committed
/**
* @param {HTMLElement} body
*/
function collapseHeight(body) {
const height = body.scrollHeight;

Stekelenburg, A.V. (Alexander, Student )
committed
body.style.removeProperty("height");
body.style.removeProperty("margin");
if (body.parentElement.parentElement.classList.contains("pane-body")) {
expandHeight(body.parentElement.parentElement, -height);

Stekelenburg, A.V. (Alexander, Student )
committed
}
}
/**
* @param {HTMLElement} body
* @param {number} amount
*/

Stekelenburg, A.V. (Alexander, Student )
committed
function expandHeight(body, additional) {
let amount = 0;
for (const child of body.childNodes) {

Stekelenburg, A.V. (Alexander, Student )
committed
if (child.scrollHeight) {

Stekelenburg, A.V. (Alexander, Student )
committed
amount += child.scrollHeight;
}
}
// body.style.transition = "initial";
// const previousHeight = body.style.height;
// body.style.removeProperty("height");
// const newHeight = (body.scrollHeight + amount) + "px";
// body.style.height = previousHeight;
// body.style.removeProperty("transition");

Stekelenburg, A.V. (Alexander, Student )
committed
body.style.height = (amount + additional) + "px";

Stekelenburg, A.V. (Alexander, Student )
committed

Stekelenburg, A.V. (Alexander, Student )
committed
body.style.margin = "0.2em 0 0.4em var(--container-paddding)";
if (body.parentElement.parentElement.classList.contains("pane-body")) {
expandHeight(body.parentElement.parentElement, amount + additional + parseFloat(getComputedStyle(body).fontSize) * 0.6);

Stekelenburg, A.V. (Alexander, Student )
committed
}
}
/**
*
* @param {HTMLElement} element
*/
function addCollapseBehaviour(element) {
const header = element.querySelector(".pane-header");
const headerIcon = header.querySelector(".codicon");

Stekelenburg, A.V. (Alexander, Student )
committed
/**
* @type {HTMLElement}
*/
const body = element.querySelector(".pane-body");
header.addEventListener("click", _ => {

Stekelenburg, A.V. (Alexander, Student )
committed
if (body.style.height) {
collapseHeight(body);
headerIcon.classList.remove("codicon-chevron-down");
headerIcon.classList.add("codicon-chevron-right");

Stekelenburg, A.V. (Alexander, Student )
committed
} else {
expandHeight(body, 0);
headerIcon.classList.remove("codicon-chevron-right");
headerIcon.classList.add("codicon-chevron-down");

Stekelenburg, A.V. (Alexander, Student )
committed
// if (body.classList.contains("hidden")) {
// body.classList.remove("hidden");
// body.style.height = body.scrollHeight + "px";
// headerIcon.classList.remove("codicon-chevron-right");
// headerIcon.classList.add("codicon-chevron-down");
// } else {
// body.classList.add("hidden");
// body.style.height = "0px";
// headerIcon.classList.remove("codicon-chevron-down");
// headerIcon.classList.add("codicon-chevron-right");
// }
function fillTools(tools) {
const select = document.querySelector("#tools");
for (const tool of tools) {
const option = document.createElement("option");
option.value = tool;
option.text = tool;
select.appendChild(option);
}
let index = tools.findIndex(x => x === oldState.currentTool);
if (index === -1) {
index = 0;
}
select.selectedIndex = index;
vscode.postMessage({ type: "toolSelected", toolName: oldState.currentTool });
vscode.setState({ tools: tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
* @param {Array<{ uri: string, constants: Array<{ name: string, value: string }>, distributions: Array<{ name: string, value: string }> }>} documentVars
function updateDocumentVars(documentVars, uri) {
const constantsUl = document.querySelector("#constants");
const distributionsUl = document.querySelector("#distributions");
const oldState = vscode.getState();
// combines the oldstate constants and distributions with the "new" constants and distributions.
for (const file of documentVars) {
const index = oldState.documentVars.findIndex(x => x.uri === file.uri);

Stekelenburg, A.V. (Alexander, Student )
committed
if (index !== -1) {
for (const constant of file.constants) {
const oldConstantIndex = oldState.documentVars[index].constants.findIndex(x => x.name === constant.name);
constant.value = oldState.documentVars[index].constants[oldConstantIndex].value;
for (const distribution of file.distributions) {
const oldDistributionIndex = oldState.documentVars[index].distributions.findIndex(x => x.name === distribution.name);
if (oldDistributionIndex !== -1) {
distribution.value = oldState.documentVars[index].distributions[oldDistributionIndex].value;
}
}
for (const file of oldState.documentVars) {
const index = documentVars.findIndex(x => x.uri === file.uri);

Stekelenburg, A.V. (Alexander, Student )
committed
if (index === -1) {

Stekelenburg, A.V. (Alexander, Student )
committed
}
}
constantsUl.innerHTML = "";
distributionsUl.innerHTML = "";
for (const file of documentVars) {
if (file.uri === uri) {
for (const constant of file.constants) {
addConstantItem(constantsUl, constant.name, constant.value);
}
if (oldState.currentTool === "prohver (prohver)") {
for (const distribution of file.distributions) {
addDistributionItem(distributionsUl, distribution.name, distribution.value);
}
}

Stekelenburg, A.V. (Alexander, Student )
committed
if (constantsUl.innerHTML === "") {
constantsUl.innerHTML = "There are no undefined constants.";
}
if (distributionsUl.innerHTML === "") {
distributionsUl.innerHTML = "There are no distributions.";
}
vscode.setState({ tools: oldState.tools, documentVars: documentVars, parameters: oldState.parameters, currentUri: uri, currentTool: oldState.currentTool });
* @param {Array<{ toolName: string, parameters: Array<{ id: string, name: string, value: string, type: ParameterType, category: string}> }>} parameters
function updateParameters(parameters, toolName) {
const parametersUl = document.querySelector("#parameters");
const oldState = vscode.getState();
// combines the oldstate parameters with the "new" parameters.
for (const tool of parameters) {
const index = oldState.parameters.findIndex(x => x.toolName === tool.toolName);
if (index !== -1) {
for (const parameter of tool.parameters) {
const oldParameterIndex = oldState.parameters[index].parameters.findIndex(x => x.name === parameter.name);

Stekelenburg, A.V. (Alexander, Student )
committed
parameter.defaultValue = parameter.value;
parameter.value = oldState.parameters[index].parameters[oldParameterIndex].value;
}
}
}
for (const tool of oldState.parameters) {
const index = parameters.findIndex(x => x.toolName === tool.toolName);
if (index === -1) {
parameters.push(tool);
}
}
parametersUl.innerHTML = parameters.length === 0 ? "There are no parameters." : "";
// adds the parameters to the sidebar.
for (const tool of parameters) {
if (tool.toolName === toolName) {
for (const parameter of tool.parameters) {
addParameterItem(parameter.name, parameter.value, parameter.category, parameter.type, parameter.description, parameter.possibleValues, parameter.defaultValue);

Stekelenburg, A.V. (Alexander, Student )
committed
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
// vscode.setState({ tools: [], documentVars: [], parameters: [], currentUri: "", currentTool: "" });
const oldState = vscode.getState() || { tools: [], documentVars: [], parameters: [], currentUri: "", currentTool: "" };
const documentVars = oldState.documentVars;
const currentUri = oldState.currentUri;
vscode.setState(oldState);
vscode.postMessage({ type: "init" });
} else {
fillTools(tools);
updateDocumentVars(documentVars, currentUri);

Stekelenburg, A.V. (Alexander, Student )
committed
for (const body of document.querySelectorAll(".pane-body")) {
if (body.style.height) {
expandHeight(body, 0);
}
}
//#region help functions
function addConstantItem(ul, name, value) {
const li = document.createElement("li");
const nameBox = document.createElement("label");
nameBox.id = "name-" + name;
nameBox.appendChild(document.createTextNode(name));
nameBox.classList.add("name");

Stekelenburg, A.V. (Alexander, Student )
committed
nameBox.title = name;
li.appendChild(nameBox);
const valueBox = document.createElement("input");
valueBox.id = "value-" + name;
valueBox.type = "text";
valueBox.value = value;
valueBox.classList.add("value");

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.addEventListener("input", _ => {
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
let oldState = vscode.getState();
for (const file of oldState.documentVars) {
if (file.uri === oldState.currentUri) {
for (const constant of file.constants) {
if (constant.name === name) {
constant.value = valueBox.value;
break;
}
}
break;
}
}
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
});
li.appendChild(valueBox);
ul.appendChild(li);
}
function addDistributionItem(ul, name, value) {
const li = document.createElement("li");
const nameBox = document.createElement("label");
nameBox.id = "name-" + name;
nameBox.appendChild(document.createTextNode(name));
nameBox.classList.add("name");
li.appendChild(nameBox);
const valueBox = document.createElement("input");
valueBox.id = "value-" + name;
valueBox.type = "text";
valueBox.value = value;
valueBox.classList.add("value");

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.addEventListener("input", _ => {
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
let oldState = vscode.getState();
for (const file of oldState.documentVars) {
if (file.uri === oldState.currentUri) {
for (const distribution of file.distributions) {
if (distribution.name === name) {
distribution.value = valueBox.value;
break;
}
}
break;
}
}
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
});
li.appendChild(valueBox);
ul.appendChild(li);
}
function addCategory(category) {
const outerDiv = document.createElement("div");
outerDiv.classList.add("pane", "vertical");
const firstInnerDiv = document.createElement("div");
firstInnerDiv.classList.add("pane-header");
const codiconDiv = document.createElement("div");
codiconDiv.classList.add("codicon", "codicon-chevron-right");
const h3 = document.createElement("h3");
h3.classList.add("title");

Stekelenburg, A.V. (Alexander, Student )
committed
h3.title = category;
h3.appendChild(document.createTextNode(category));
const secondInnerDiv = document.createElement("div");
secondInnerDiv.classList.add("pane-body");
const categoryUl = document.createElement("ul");
categoryUl.id = "parameter-" + category;
categoryUl.classList.add("option-list");
secondInnerDiv.appendChild(categoryUl);
const revertButton = document.createElement("i");
revertButton.classList.add("revert", "codicon", "codicon-discard", "hidden", "outer");
firstInnerDiv.appendChild(codiconDiv);
firstInnerDiv.appendChild(h3);
firstInnerDiv.appendChild(revertButton);
outerDiv.appendChild(firstInnerDiv);
outerDiv.appendChild(secondInnerDiv);
const parametersDiv = document.getElementById("parameters");
parametersDiv.appendChild(outerDiv);
addCollapseBehaviour(outerDiv);
revertButton.addEventListener("click", e => {
for (const revert of categoryUl.querySelectorAll(".revert:not(.hidden):not(.outer)")) {
revert.click();
}
revertButton.classList.add("hidden");
e.stopPropagation();
});
revertButtons.push(function(id, hidden) {
for (const button of categoryUl.querySelectorAll(".revert")){
if (button.id === id) {
if (hidden){
revertButton.classList.add("hidden");
} else {
revertButton.classList.remove("hidden");
}
} else if (!button.classList.contains("hidden")) {
revertButton.classList.remove("hidden");
return;
}
}
});
return categoryUl;
}

Stekelenburg, A.V. (Alexander, Student )
committed
function addParameterItem(name, value, category, type, description, possibleValues, defaultValue) {
if (category === "") {
category = "Other";
}
let categoryUl = document.getElementById("parameter-" + category);
if (categoryUl === null) {
categoryUl = addCategory(category);
}

Stekelenburg, A.V. (Alexander, Student )
committed
if (defaultValue === undefined) {
defaultValue = value;
}
const li = document.createElement("li");
const nameBox = document.createElement("label");
nameBox.id = "name-" + name;
nameBox.appendChild(document.createTextNode(name));
nameBox.classList.add("name");

Stekelenburg, A.V. (Alexander, Student )
committed
nameBox.title = description;
li.appendChild(nameBox);

Stekelenburg, A.V. (Alexander, Student )
committed
/**
* @type {HTMLSelectElement|HTMLInputElement}
*/
let valueBox;

Stekelenburg, A.V. (Alexander, Student )
committed
if (type === "Enum") {

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox = document.createElement("select");

Stekelenburg, A.V. (Alexander, Student )
committed
for (const value of possibleValues) {
const option = document.createElement("option");
option.value = value;
option.text = value;
valueBox.appendChild(option);
}
valueBox.value = value;
valueBox.addEventListener("input", _ => {

Stekelenburg, A.V. (Alexander, Student )
committed
if (valueBox.value === defaultValue) {
valueBox.revertButton.classList.add("hidden");
} else {
valueBox.revertButton.classList.remove("hidden");
}
revertButtons.forEach(x => x(valueBox.revertButton.id, valueBox.value === defaultValue));

Stekelenburg, A.V. (Alexander, Student )
committed

Stekelenburg, A.V. (Alexander, Student )
committed
let oldState = vscode.getState();
for (const tool of oldState.parameters) {
if (tool.toolName === oldState.currentTool) {
for (const parameter of tool.parameters) {
if (parameter.name === name) {

Stekelenburg, A.V. (Alexander, Student )
committed
parameter.value = valueBox.options[valueBox.selectedIndex].value;
break;
}

Stekelenburg, A.V. (Alexander, Student )
committed
break;

Stekelenburg, A.V. (Alexander, Student )
committed
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
});
} else {

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox = document.createElement("input");
if (type === "Boolean") {
valueBox.type = "checkbox";
valueBox.checked = value;
valueBox.addEventListener("input", _ => {
if (valueBox.checked === defaultValue) {
valueBox.revertButton.classList.add("hidden");
} else {
valueBox.revertButton.classList.remove("hidden");
}
revertButtons.forEach(x => x(valueBox.revertButton.id, valueBox.checked === defaultValue));

Stekelenburg, A.V. (Alexander, Student )
committed
let oldState = vscode.getState();
for (const tool of oldState.parameters) {
if (tool.toolName === oldState.currentTool) {
for (const parameter of tool.parameters) {
if (parameter.name === name) {

Stekelenburg, A.V. (Alexander, Student )
committed
parameter.value = valueBox.checked;
break;
}
}
break;
}
}
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
});
} else if (type === "Path") {
valueBox.type = "file";
valueBox.value = value;
valueBox.addEventListener("input", _ => {
if (String(valueBox.value) === String(defaultValue)) {
valueBox.revertButton.classList.add("hidden");
} else {
valueBox.revertButton.classList.remove("hidden");
}
revertButtons.forEach(x => x(valueBox.revertButton.id, String(valueBox.value) === String(defaultValue)));
let oldState = vscode.getState();
for (const tool of oldState.parameters) {
if (tool.toolName === oldState.currentTool) {
for (const parameter of tool.parameters) {
if (parameter.name === name) {
parameter.value = valueBox.value;
break;
}
}
break;
}
}
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
});

Stekelenburg, A.V. (Alexander, Student )
committed
} else {
valueBox.type = "text";
valueBox.value = value;
valueBox.addEventListener("input", _ => {
// TODO: Store as actual type using valueBox.value.asNumber and such?

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.value = valueBox.value.replace(",", ".");
}

Stekelenburg, A.V. (Alexander, Student )
committed

Stekelenburg, A.V. (Alexander, Student )
committed
if (String(valueBox.value) === String(defaultValue)) {
valueBox.revertButton.classList.add("hidden");
} else {
valueBox.revertButton.classList.remove("hidden");
}
revertButtons.forEach(x => x(valueBox.revertButton.id, String(valueBox.value) === String(defaultValue)));

Stekelenburg, A.V. (Alexander, Student )
committed
let oldState = vscode.getState();
for (const tool of oldState.parameters) {
if (tool.toolName === oldState.currentTool) {
for (const parameter of tool.parameters) {
if (parameter.name === name) {

Stekelenburg, A.V. (Alexander, Student )
committed
parameter.value = valueBox.value;
break;
}

Stekelenburg, A.V. (Alexander, Student )
committed
}

Stekelenburg, A.V. (Alexander, Student )
committed
break;

Stekelenburg, A.V. (Alexander, Student )
committed
}
}

Stekelenburg, A.V. (Alexander, Student )
committed
vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool });
});
}
}
nameBox.htmlFor = "value-" + name;

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.id = "value-" + name;
valueBox.classList.add("value");

Stekelenburg, A.V. (Alexander, Student )
committed
const valueDiv = document.createElement("div");
valueDiv.classList.add("value");
valueDiv.appendChild(valueBox);
const revertButton = document.createElement("button");
revertButton.id = "revert-" + name;
const codicon = document.createElement("i");
codicon.classList.add("codicon", "codicon-discard");
revertButton.appendChild(codicon);
revertButton.classList.add("revert");
if (String(value) === String(defaultValue)) {
revertButton.classList.add("hidden");
revertButtons.forEach(x => x(revertButton.id, false));

Stekelenburg, A.V. (Alexander, Student )
committed
}

Stekelenburg, A.V. (Alexander, Student )
committed
revertButton.title = "Revert to default";
valueBox.revertButton = revertButton;
revertButton.addEventListener("click", _ => {
if (type === "Boolean") {

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.checked = defaultValue;

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.value = defaultValue;
}
revertButtons.forEach(x => x(valueBox.revertButton.id, valueBox.value === defaultValue));

Stekelenburg, A.V. (Alexander, Student )
committed
valueBox.dispatchEvent(new InputEvent("input"));
});
valueDiv.appendChild(revertButton);
li.appendChild(valueDiv);
categoryUl.appendChild(li);
}
//#endregion