Skip to content

Commit

Permalink
added gutter and error markers in the gutter
Browse files Browse the repository at this point in the history
  • Loading branch information
annekekleppe committed Oct 8, 2024
1 parent 2fe6325 commit de139f2
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 34 deletions.
3 changes: 1 addition & 2 deletions packages/core-svelte/src/lib/components/ErrorMarker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
export let element;
export let content;
let innerTop = 10;
let innerHeight = 24;
let innerHeight = 8;
async function calcPos() {
await tick();
Expand All @@ -17,7 +17,6 @@
// console.log(`ErrorMarker top ${elementRect.top} bottom ${elementRect.bottom} height ${elementRect.height} viewport.top ${$viewport.top}`)
// get the position of the element relative to the editor view
innerTop = elementRect.top - $viewport.top;
// innerHeight = elementRect.height - 5; /* minus padding */
} else {
console.log("No bounding rect")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// Because an ErrorMarker also has its 'position' set to something other than 'static'.
left = event.pageX - $viewport.left - parentLeft + 5;
top = event.pageY - $viewport.top - parentTop + 5;
console.log(`ErrorTooltip: left-top [${left}, ${top}] event [${event.pageX}, ${event.pageY}] parent [${parentLeft}, ${parentTop}] viewport [${$viewport.left}, ${$viewport.top}]`)
// console.log(`ErrorTooltip: left-top [${left}, ${top}] event [${event.pageX}, ${event.pageY}] parent [${parentLeft}, ${parentTop}] viewport [${$viewport.left}, ${$viewport.top}]`)
}
}
function mouseMove(event: MouseEvent) {
Expand Down
6 changes: 4 additions & 2 deletions packages/core-svelte/src/lib/styles/freon.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
}
.gutter {
/*border: 1px solid;*/
min-width: 4px;
width: 8px;
height: 100%;
height: 100vh;
box-sizing: border-box;
}
.editor-component {
Expand Down Expand Up @@ -182,7 +183,8 @@
/* padding seems to be the only way to make the element visible without content*/
/* padding-left is width of the image plus some extra */
padding: 2px 2px 2px 2px;
width: 8px; /* equal to the gutter width */
width: 4px; /* (padding-left + width + padding-right) is equal to the gutter width */
height: 8px;
}

.error-positioning {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/editor/FreEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export class FreEditor {
LOGGER.log(
`findBoxForNode ${node?.freLanguageConcept()} with id ${node?.freId()}, property: ${propertyName}[${propertyIndex}]`
);
if (this.checkParam(node)) {
if (this.checkParam(node) && !node.freIsModel()) {
const box: ElementBox = this.projection.getBox(node);
// check whether the box is shown in the current projection
if (isNullOrUndefined(box) || !this.isBoxInTree(box)) {
Expand Down
47 changes: 25 additions & 22 deletions packages/core/src/editor/FreErrorDecorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export class FreErrorDecorator {
*/
setErrors(errors: FreError[]) {
// todo this method of removing old errors should be changed when nodes are validated
// upon every change
// upon every AST change
// Remove all old errors
this.previousList.forEach(err => {
if (Array.isArray(err.reportedOn)) {
err.reportedOn.forEach((x, index) => {
this.setErrorForNode(false, x, '', err.propertyName, index);
this.setErrorForNode([],false, x, '', err.propertyName, index);
})
} else {
this.setErrorForNode(false, err.reportedOn, '', err.propertyName);
this.setErrorForNode([],false, err.reportedOn, '', err.propertyName);
}
});
// Remember the errors
Expand All @@ -46,28 +46,31 @@ export class FreErrorDecorator {
errors.forEach(err => {
if (Array.isArray(err.reportedOn)) {
err.reportedOn.forEach((x, index) => {
erroneousBoxes.push(...this.setErrorForNode(true, x, err.message, err.propertyName, index));
this.setErrorForNode(erroneousBoxes, true, x, err.message, err.propertyName, index);
})
} else {
erroneousBoxes.push(...this.setErrorForNode(true, err.reportedOn, err.message, err.propertyName));
this.setErrorForNode(erroneousBoxes,true, err.reportedOn, err.message, err.propertyName);
}
});
// Sort the erroneous boxes based on their y-coordinate, because we want to gather all messages on the same 'line'
erroneousBoxes.sort((a, b: Box) => (a.actualY > b.actualY) ? 1 : -1);
// Group the boxes
let lines: Box[][] = [];
let lineIndex: number = 0;
let oldIndex: number = 0;
for( let i: number = 0; i < erroneousBoxes.length; i++ ) {
if (erroneousBoxes[i].actualY + LINE_HEIGHT_MARGIN < erroneousBoxes[i+1].actualY ) {
lines[lineIndex] = erroneousBoxes.slice(oldIndex, i);
oldIndex = i;
lineIndex ++;
let prevLineEnd: number = 0;
for( let i: number = 0; i < erroneousBoxes.length - 1; i++ ) {
// console.log(`Check: ${erroneousBoxes[i].actualY} < ${erroneousBoxes[i+1].actualY} - LINE_HEIGHT_MARGIN === ${erroneousBoxes[i].actualY < erroneousBoxes[i+1].actualY - LINE_HEIGHT_MARGIN}`)
if (erroneousBoxes[i].actualY < erroneousBoxes[i+1].actualY - LINE_HEIGHT_MARGIN) { // found line end
lines[lineIndex++] = erroneousBoxes.slice(prevLineEnd, i+1);
prevLineEnd = i+1;
}
}
console.log(`Found lines:
${lines.map((line: Box[]) => `[${line.map(box => `${box.id} ${box.kind} ${box.errorMessages}`).join(', ')}]\n`
)}`)
// Make the final line
lines[lineIndex] = erroneousBoxes.slice(prevLineEnd, erroneousBoxes.length -1);

// console.log(`Found lines:
// ${lines.map((line: Box[]) => `[${line.map(box => `${box.id} ${box.kind} \t\n${box.errorMessages.map(err => `${err}`).join("\t\n")}`).join(', \n')}]\n`
// ).join('\n')}`)
// For each 'line' get the outermost box, i.e. the one of the left, and put all error messages
// on the line in that box. Remove the error messages from the other boxes, but do not remove the 'hasError' marker.
// The latter enables the styling of erroneous boxes, regardless of the presence of the error message.
Expand All @@ -81,31 +84,31 @@ export class FreErrorDecorator {
line[i].resetErrorMessages();
}
})
console.log(`Found messages:
${lines.map((line: Box[]) => `[${line.map(box => `${box.id} ${box.kind} ${box.errorMessages}`).join(', ')}]\n`
)}`)
console.log(`Found lines:
${lines.map((line: Box[]) => `[${line.map(box => `${box.id} ${box.kind} \t\n${box.errorMessages.map(err => `${err}`).join("\t\n")}`).join(', \n')}]\n`
).join('\n')}`)
}

private setErrorForNode(value: boolean, node: FreNode, errorMessage: string, propertyName?: string, propertyIndex?: number): Box[] {
private setErrorForNode(erroneousBoxes: Box[], value: boolean, node: FreNode, errorMessage: string, propertyName?: string, propertyIndex?: number) {
LOGGER.log(
`setErrorOnElement ${node?.freLanguageConcept()} with id ${node?.freId()}, property: [${propertyName}, ${propertyIndex}]`
);
let result: Box[] = [];
let box: Box = this.myEditor.findBoxForNode(node, propertyName, propertyIndex);
if (!isNullOrUndefined(box)) {
if (box instanceof ElementBox) {
// box is an elementBox, which is not shown, therefore we set the error on its one and only child
box = box.children[0];
}
console.log(`${value ? `SETTING` : `REMOVING`} error for ${box.role} ${box.kind}`)
// console.log(`${value ? `SETTING` : `REMOVING`} error for ${box.role} ${box.kind}`)
box.hasError = value;
if (value) {
box.addErrorMessage(errorMessage);
} else {
box.resetErrorMessages();
}
result.push(box);
}
return result;
if (!erroneousBoxes.includes(box)) {
erroneousBoxes.push(box);
}
}
}
15 changes: 13 additions & 2 deletions packages/core/src/editor/boxes/Box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,22 @@ export abstract class Box {
return this._errorMessages;
}

/**
* Adds the string or string array to the list of error messages, but only if
* the message is not already present.
* @param val
*/
addErrorMessage(val: string | string[]) {
if (Array.isArray(val)) {
this._errorMessages.push(...val);
val.forEach(v => {
if (!this._errorMessages.includes(v)) {
this._errorMessages.push(v);
}
})
} else {
this._errorMessages.push(val);
if (!this._errorMessages.includes(val)) {
this._errorMessages.push(val);
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/editor/projections/FreProjectionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,12 @@ export class FreProjectionHandler {

getKnownTableProjectionsFor(conceptName: string): string[] {
LOGGER.log("getKnownTableProjectionsFor: " + conceptName);
return this.conceptNameToProviderConstructor.get(conceptName)(this).knownTableProjections;
const providerConstructor = this.conceptNameToProviderConstructor.get(conceptName)(this);
if (!!providerConstructor) {
return providerConstructor.knownTableProjections;
} else {
return [];
}
}

getTableHeaderInfo(conceptName: string, projectionName: string): string[] {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/typer/AstType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export class AstType implements FreType {
if (!!this.astElement) {
if (this.astElement === AstType.ANY) {
return "ANY";
} else if (!!this.astElement["name"]) { // Note "name" must refer to the property of FreNamedNode!
return writer.writeNameOnly(this.astElement);
} else {
return writer.writeToString(this.astElement);
}
Expand Down
7 changes: 4 additions & 3 deletions packages/webapp-lib/src/lib/language/EditorState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ export class EditorState {
this.langEnv.editor.rootElement = newUnit;
});
this.currentUnit = newUnit;
this.getErrors();
// todo reinstate the following statement
// this.getErrors();
} else {
noUnitAvailable.set(true);
runInAction(() => {
Expand Down Expand Up @@ -349,10 +350,10 @@ export class EditorState {
} catch (e: unknown) {
// catch any errors regarding erroneously stored model units
if (e instanceof Error) {
LOGGER.log(e.message);
console.log(e.message + e.stack);
modelErrors.set([
new FreError(
"Problem reading model unit: '" + e.message + "'",
"Problem validating model unit: '" + e.message + "'",
this.currentUnit,
this.currentUnit.name,
FreErrorSeverity.Error,
Expand Down

0 comments on commit de139f2

Please sign in to comment.