Commit b623f61d authored by Klaus Ramm's avatar Klaus Ramm

Reformat and style the code view, add hover highlight event

parent 702ca7cf
$code-highlight: rgb(128,212,255);
.highlight {
background-color: rgba(145, 138, 229, 0.4);
}
.form-select {
outline: 0;
box-shadow: none;
background: white;
position: relative;
width: 90%;
overflow: hidden;
border-radius: .2em;
border: 0.1em solid rgb(38, 64, 64);
padding: 0 .5em;
color: rgb(38, 64, 64);
cursor: pointer;
option {
color: rgb(38, 64, 64);
cursor: pointer;
}
}
.text-code {
color: $code-highlight;
/* Remove IE arrow */
select::-ms-expand {
display: none;
}
.bg-primary {
background-color: $main-background-color;
.code {
color: rgb(38, 64, 64);
position: relative;
padding-left: 0.3em;
display: flex;
&::before {
color: rgb(38, 64, 64);
content: attr(data-lang);
font-size: 100%;
position: absolute;
right: 0.5em;
top: 0.5em;
}
code {
//background: rgb(238, 238, 238);
border-radius: 0.2em;
border: 0.1em solid rgb(38, 64, 64);
color: inherit;
line-height: 1.5;
overflow-x: auto;
flex: 1;
padding: 1rem;
.keyword {
color: rgb(127, 0, 85);
}
span {
font-weight: bold;
}
}
}
......@@ -165,6 +165,10 @@ $main-background-color: rgba(128,212,255, 0.5);
flex: 1;
}
.columnAuto-2 {
flex: 2;
}
.moveText {
flex: auto;
margin: auto;
......
......@@ -114,6 +114,11 @@ strong {
cursor: pointer;
}
.center {
flex: auto;
margin: auto;
}
.columnEditorFull {
margin-top: 0.5em;
flex-basis: 100%;
......@@ -125,7 +130,16 @@ strong {
}
.columnEditorCode {
flex-basis: 50%;
margin: 0.2em;
padding-top: 1em;
flex-grow: 0;
width: 100%;
}
@media screen and (min-width: 480px) {
.columnEditorCode {
width: 50%;
}
}
@media screen and (min-width: 1200px) {
......@@ -134,7 +148,9 @@ strong {
}
.columnEditorCode {
flex-basis: 24%;
padding-top: 0;
margin: 0 1em;
width: calc(25% - 4.5em);
}
}
......@@ -158,6 +174,12 @@ strong {
overflow: hidden;
}
.fixFullWidth {
flex-basis: 100%;
flex-grow: 0;
flex-shrink: 0;
}
.tooltip {
position: relative;
&:after {
......@@ -231,7 +253,7 @@ strong {
}
.borderWidth {
flex: 0 0 2px;
flex: 0 0 3px;
}
.borderHeight {
height: 2px;
......
......@@ -51,7 +51,7 @@ export class CodeView {
'pre': "while (",
'post': ");\n"
},
'CaseNode': {'pre': "switch(",
'CaseNode': {'pre': "switch (",
'post': ")\n",
},
'InsertCase': {'preNormal': "case ",
......@@ -86,7 +86,7 @@ export class CodeView {
'pre': "while (",
'post': ");\n"
},
'CaseNode': {'pre': "switch(",
'CaseNode': {'pre': "switch (",
'post': ")\n",
},
'InsertCase': {'preNormal': "case ",
......@@ -105,20 +105,20 @@ export class CodeView {
preRender() {
let sourcecode = document.createElement('div');
//sourcecode.style.float = 'right';
sourcecode.id = 'SourcecodeDisplay';
sourcecode.classList.add('columnEditorCode');
sourcecode.classList.add('columnEditorCode', 'vcontainer');
sourcecode.style.display = 'none';
let sourcecodeDisplay = document.createElement('div');
//sourcecodeDisplay.classList.add('columns', 'd-hide');
sourcecodeDisplay.classList.add('fixFullWidth');
let sourcecodeHeader = document.createElement('div');
//sourcecodeHeader.classList.add('column', 'col-10', 'col-mx-auto');
let sourcecodeTitle = document.createElement('span');
sourcecodeHeader.classList.add('columnAuto', 'container');
let sourcecodeTitle = document.createElement('strong');
sourcecodeTitle.classList.add('center');
sourcecodeTitle.appendChild(document.createTextNode('Übersetzen in:'));
let sourcecodeForm = document.createElement('div');
//sourcecodeForm.classList.add('form-group');
sourcecodeForm.classList.add('center');
let sourcecodeSelect = document.createElement('select');
//sourcecodeSelect.classList.add('form-select');
sourcecodeSelect.classList.add('form-select');
sourcecodeSelect.id = 'SourcecodeSelect';
sourcecodeSelect.addEventListener('change', (event) => this.presenter.startTransforming(event));
let sourcecodeOption = document.createElement('option');
......@@ -137,7 +137,7 @@ export class CodeView {
sourcecodeHeader.appendChild(sourcecodeForm);
let sourcecodeWorkingArea = document.createElement('div');
//sourcecodeWorkingArea.classList.add('column', 'col-12', 'lowerPadding');
sourcecodeWorkingArea.classList.add('columnAuto');
sourcecodeWorkingArea.id = 'Sourcecode';
sourcecodeDisplay.appendChild(sourcecodeHeader);
......@@ -184,7 +184,7 @@ export class CodeView {
// create container for the spans
let preBlock = document.createElement('pre');
//preBlock.classList.add('code');
preBlock.classList.add('code');
// set the language attribute
preBlock.setAttribute('data-lang', this.lang);
......@@ -197,7 +197,7 @@ export class CodeView {
codeBlock.appendChild(i);
});
} else {
codeBlock.appendChild(document.createTextNode("Das Struktogramm enthält Elemente, \nwelche in der Programmiersprache nicht \nzur Verfügung stehen."));
codeBlock.appendChild(document.createTextNode("Das Struktogramm enthält Elemente, \nwelche in der Programmiersprache \nnicht zur Verfügung stehen."));
}
preBlock.appendChild(codeBlock);
......@@ -298,15 +298,16 @@ export class CodeView {
} else {
// create the span
let elemSpan = document.createElement('span');
elemSpan.id = subTree.id + '-codeLine';
// add eventlisteners for mouseover and click events
// highlight equivalent element in struktogramm on mouseover
elemSpan.addEventListener('mouseover', function() {
let node = document.getElementById(subTree.id);
node.firstChild.classList.add('bg-primary');
const node = document.getElementById(subTree.id);
node.firstChild.classList.add('highlight');
});
elemSpan.addEventListener('mouseout', function() {
let node = document.getElementById(subTree.id);
node.firstChild.classList.remove('bg-primary');
const node = document.getElementById(subTree.id);
node.firstChild.classList.remove('highlight');
});
// switch to edit mode of equivalent element in the struktogramm
let text = this.createHighlightedSpan(subTree.text);
......@@ -318,29 +319,52 @@ export class CodeView {
return this.transformToCode(subTree.followElement, indentLevel, lang)
break;
case 'InputNode':
elemSpan.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].InputNode.pre));
const inputPre = document.createElement('span');
inputPre.classList.add('keyword');
inputPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].InputNode.pre));
elemSpan.appendChild(inputPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].InputNode.post));
const inputPost = document.createElement('span');
inputPost.classList.add('keyword');
inputPost.appendChild(document.createTextNode(this.translationMap[lang].InputNode.post));
elemSpan.appendChild(inputPost);
return [elemSpan].concat(this.transformToCode(subTree.followElement, indentLevel, lang));
break;
case 'OutputNode':
elemSpan.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].OutputNode.pre));
const outputPre = document.createElement('span');
outputPre.classList.add('keyword');
outputPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].OutputNode.pre));
elemSpan.appendChild(outputPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].OutputNode.post));
const outputPost = document.createElement('span');
outputPost.classList.add('keyword');
outputPost.appendChild(document.createTextNode(this.translationMap[lang].OutputNode.post));
elemSpan.appendChild(outputPost);
return [elemSpan].concat(this.transformToCode(subTree.followElement, indentLevel, lang));
break;
case 'TaskNode':
elemSpan.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].TaskNode.pre));
const taskPre = document.createElement('span');
taskPre.classList.add('keyword');
taskPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].TaskNode.pre));
elemSpan.appendChild(taskPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].TaskNode.post));
const taskPost = document.createElement('span');
taskPost.classList.add('keyword');
taskPost.appendChild(document.createTextNode(this.translationMap[lang].TaskNode.post));
elemSpan.appendChild(taskPost);
return [elemSpan].concat(this.transformToCode(subTree.followElement, indentLevel, lang));
break;
case 'BranchNode':
{
let branchHeaderPre = this.addIndentations(indentLevel) + this.translationMap[lang].BranchNode.pre;
elemSpan.appendChild(document.createTextNode(branchHeaderPre));
const branchHeaderPre = document.createElement('span');
branchHeaderPre.classList.add('keyword');
branchHeaderPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].BranchNode.pre));
elemSpan.appendChild(branchHeaderPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].BranchNode.post));
const branchHeaderPost = document.createElement('span');
branchHeaderPost.classList.add('keyword');
branchHeaderPost.appendChild(document.createTextNode(this.translationMap[lang].BranchNode.post));
elemSpan.appendChild(branchHeaderPost);
let branch = [elemSpan];
if (this.translationMap[lang].leftBracket != '') {
let leftBracket = document.createElement('span');
......@@ -366,10 +390,15 @@ export class CodeView {
break;
case 'CountLoopNode':
{
let loopHeaderPre = this.addIndentations(indentLevel) + this.translationMap[lang].CountLoopNode.pre;
elemSpan.appendChild(document.createTextNode(loopHeaderPre));
const loopHeaderPre = document.createElement('span');
loopHeaderPre.classList.add('keyword');
loopHeaderPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].CountLoopNode.pre));
elemSpan.appendChild(loopHeaderPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].CountLoopNode.post));
const loopHeaderPost = document.createElement('span');
loopHeaderPost.classList.add('keyword');
loopHeaderPost.appendChild(document.createTextNode(this.translationMap[lang].CountLoopNode.post));
elemSpan.appendChild(loopHeaderPost);
let loop = [elemSpan];
if (this.translationMap[lang].leftBracket != '') {
let leftBracket = document.createElement('span');
......@@ -387,10 +416,15 @@ export class CodeView {
break;
case 'HeadLoopNode':
{
let loopHeaderPre = this.addIndentations(indentLevel) + this.translationMap[lang].HeadLoopNode.pre;
elemSpan.appendChild(document.createTextNode(loopHeaderPre));
const loopHeaderPre = document.createElement('span');
loopHeaderPre.classList.add('keyword');
loopHeaderPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].HeadLoopNode.pre));
elemSpan.appendChild(loopHeaderPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].HeadLoopNode.post));
const loopHeaderPost = document.createElement('span');
loopHeaderPost.classList.add('keyword');
loopHeaderPost.appendChild(document.createTextNode(this.translationMap[lang].HeadLoopNode.post));
elemSpan.appendChild(loopHeaderPost);
let loop = [elemSpan];
if (this.translationMap[lang].leftBracket != '') {
let leftBracket = document.createElement('span');
......@@ -408,8 +442,10 @@ export class CodeView {
break;
case 'FootLoopNode':
{
let loopContent = this.addIndentations(indentLevel) + this.translationMap[lang].FootLoopNode.prepre;
elemSpan.appendChild(document.createTextNode(loopContent));
const loopContent = document.createElement('span');
loopContent.classList.add('keyword');
loopContent.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].FootLoopNode.prepre));
elemSpan.appendChild(loopContent);
let loop = [elemSpan];
if (this.translationMap[lang].leftBracket != '') {
let leftBracket = document.createElement('span');
......@@ -424,16 +460,24 @@ export class CodeView {
loop.push(rightBracket);
}
let subContent = document.createElement('span');
subContent.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].FootLoopNode.pre));
subContent.id = subTree.id + '-codeLine';
elemSpan.id = '';
const subContentPre = document.createElement('span');
subContentPre.classList.add('keyword');
subContentPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].FootLoopNode.pre));
subContent.appendChild(subContentPre);
subContent.appendChild(text);
subContent.appendChild(document.createTextNode(this.translationMap[lang].FootLoopNode.post));
const subContentPost = document.createElement('span');
subContentPost.classList.add('keyword');
subContentPost.appendChild(document.createTextNode(this.translationMap[lang].FootLoopNode.post));
subContent.appendChild(subContentPost);
subContent.addEventListener('mouseover', function() {
let node = document.getElementById(subTree.id);
node.parentElement.parentElement.classList.add('bg-primary');
const node = document.getElementById(subTree.id);
node.firstChild.classList.add('highlight');
});
subContent.addEventListener('mouseout', function() {
let node = document.getElementById(subTree.id);
node.parentElement.parentElement.classList.remove('bg-primary');
const node = document.getElementById(subTree.id);
node.firstChild.classList.remove('highlight');
});
loop.push(subContent);
......@@ -442,22 +486,37 @@ export class CodeView {
break;
case 'CaseNode':
{
elemSpan.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].CaseNode.pre));
const caseHeadPre = document.createElement('span');
caseHeadPre.classList.add('keyword');
caseHeadPre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].CaseNode.pre));
elemSpan.appendChild(caseHeadPre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].CaseNode.post));
const caseHeadPost = document.createElement('span');
caseHeadPost.classList.add('keyword');
caseHeadPost.appendChild(document.createTextNode(this.translationMap[lang].CaseNode.post));
elemSpan.appendChild(caseHeadPost);
let cases = [elemSpan];
if (this.translationMap[lang].leftBracket != '') {
let leftBracket = document.createElement('span');
leftBracket.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].leftBracket + "\n"));
cases.push(leftBracket);
}
//subTree.cases.forEach(function(element) {
for (const element of subTree.cases) {
cases = cases.concat(this.transformToCode(element, indentLevel + 1, lang));
}
if (subTree.defaultOn) {
let defaultCase = document.createElement('span');
defaultCase.classList.add('keyword');
defaultCase.id = subTree.defaultNode.id + '-codeLine';
defaultCase.appendChild(document.createTextNode(this.addIndentations(indentLevel + 1) + this.translationMap[lang].InsertCase.preDefault + this.translationMap[lang].InsertCase.post));
defaultCase.addEventListener('mouseover', function() {
const node = document.getElementById(subTree.defaultNode.id);
node.firstChild.classList.add('highlight');
});
defaultCase.addEventListener('mouseout', function() {
const node = document.getElementById(subTree.defaultNode.id);
node.firstChild.classList.remove('highlight');
});
cases.push(defaultCase);
cases = cases.concat(this.transformToCode(subTree.defaultNode.followElement, indentLevel + 2, lang));
}
......@@ -471,13 +530,20 @@ export class CodeView {
break;
case 'InsertCase':
{
elemSpan.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].InsertCase.preNormal));
const casePre = document.createElement('span');
casePre.classList.add('keyword');
casePre.appendChild(document.createTextNode(this.addIndentations(indentLevel) + this.translationMap[lang].InsertCase.preNormal));
elemSpan.appendChild(casePre);
elemSpan.appendChild(text);
elemSpan.appendChild(document.createTextNode(this.translationMap[lang].InsertCase.post));
const casePost = document.createElement('span');
casePost.classList.add('keyword');
casePost.appendChild(document.createTextNode(this.translationMap[lang].InsertCase.post));
elemSpan.appendChild(casePost);
let content = [elemSpan];
content = content.concat(this.transformToCode(subTree.followElement, indentLevel + 1, lang));
let endContent = document.createElement('span');
endContent.classList.add('keyword');
endContent.appendChild(document.createTextNode(this.addIndentations(indentLevel + 1) + this.translationMap[lang].InsertCase.postpost));
content.push(endContent);
return content;
......
......@@ -54,7 +54,7 @@ export class Structogram {
divEditorContentSplitTop.classList.add('columnAuto', 'container');
const divEditorContentSplitBottom = document.createElement('div');
divEditorContentSplitBottom.classList.add('columnAuto');
divEditorContentSplitBottom.classList.add('columnAuto-2');
const divFixRightBorder = document.createElement('div');
divFixRightBorder.classList.add('borderWidth', 'frameLeft');
......@@ -101,6 +101,7 @@ export class Structogram {
}
//this.domRoot.appendChild(this.prepareRenderTree(tree, false, false));
for (const elem of this.renderElement(tree, false, false)) {
this.applyCodeEventListeners(elem);
this.domRoot.appendChild(elem);
}
const lastLine = document.createElement('div');
......@@ -251,12 +252,14 @@ export class Structogram {
const divTrue = document.createElement('div');
divTrue.classList.add('columnAuto', 'vcontainer', 'ov-hidden');
for (const elem of this.renderElement(subTree.trueChild, false, noInsert)) {
this.applyCodeEventListeners(elem);
divTrue.appendChild(elem);
}
const divFalse = document.createElement('div');
divFalse.classList.add('columnAuto', 'vcontainer', 'ov-hidden');
for (const elem of this.renderElement(subTree.falseChild, false, noInsert)) {
this.applyCodeEventListeners(elem);
divFalse.appendChild(elem);
}
......@@ -290,6 +293,7 @@ export class Structogram {
divLoop.classList.add('loopWidth', 'frameLeft', 'vcontainer');
for (const elem of this.renderElement(subTree.child, false, noInsert)) {
this.applyCodeEventListeners(elem);
divLoop.appendChild(elem);
}
......@@ -312,6 +316,7 @@ export class Structogram {
divLoop.classList.add('loopWidth', 'frameLeftBottom', 'vcontainer');
for (const elem of this.renderElement(subTree.child, false, noInsert)) {
this.applyCodeEventListeners(elem);
divLoop.appendChild(elem);
}
// Fix for overlapped bottom line
......@@ -373,6 +378,7 @@ export class Structogram {
divCase.classList.add('columnAuto', 'vcontainer', 'ov-hidden');
for (const elem of this.renderElement(caseElem, false, noInsert)) {
this.applyCodeEventListeners(elem);
divCase.appendChild(elem);
}
divChildren.appendChild(divCase);
......@@ -382,6 +388,7 @@ export class Structogram {
let divCase = document.createElement('div');
divCase.classList.add('columnAuto', 'vcontainer', 'ov-hidden');
for (const elem of this.renderElement(subTree.defaultNode, false, noInsert)) {
this.applyCodeEventListeners(elem);
divCase.appendChild(elem);
}
divChildren.appendChild(divCase);
......@@ -652,6 +659,36 @@ export class Structogram {
return textDiv
}
applyCodeEventListeners(obj) {
if (obj.firstChild.firstChild.classList.contains('loopShift')) {
obj.firstChild.lastChild.addEventListener('mouseover', function() {
const elemSpan = document.getElementById(obj.id + '-codeLine');
if (elemSpan) {
elemSpan.classList.add('highlight');
}
});
obj.firstChild.lastChild.addEventListener('mouseout', function() {
const elemSpan = document.getElementById(obj.id + '-codeLine');
if (elemSpan) {
elemSpan.classList.remove('highlight');
}
});
} else {
obj.firstChild.firstChild.addEventListener('mouseover', function() {
const elemSpan = document.getElementById(obj.id + '-codeLine');
if (elemSpan) {
elemSpan.classList.add('highlight');
}
});
obj.firstChild.firstChild.addEventListener('mouseout', function() {
const elemSpan = document.getElementById(obj.id + '-codeLine');
if (elemSpan) {
elemSpan.classList.remove('highlight');
}
});
}
}
/**
* Create an outer HTML structure before adding another element
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment