Skip to content

Commit aeae000

Browse files
committed
Visualizer: Make error reporting a little less aggressive.
1 parent fe04620 commit aeae000

File tree

2 files changed

+64
-30
lines changed

2 files changed

+64
-30
lines changed

visualizer/index.html

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@
167167
border-top: 1px solid #ddd;
168168
flex: 1;
169169
overflow: auto;
170+
position: relative;
171+
}
172+
173+
#bottomSection .overlay {
174+
background-color: white;
175+
height: 100%;
176+
left: 0;
177+
opacity: 0.4;
178+
position: absolute;
179+
top: 0;
180+
width: 0;
170181
}
171182

172183
#grammarContainer,
@@ -187,9 +198,8 @@
187198
border-right: 1px solid #ddd;
188199
}
189200

190-
.errorItem {
191-
text-align: center;
192-
background-color: #FCF68B;
201+
.CodeMirror .error-interval {
202+
border-bottom: 1px dashed #C7254E;
193203
}
194204

195205
.CodeMirror.highlighting {
@@ -201,8 +211,11 @@
201211
}
202212

203213
.CodeMirror .error {
204-
background-color: #C7254E;
205-
color: #F9F2F4;
214+
background-color: #FBE3EA;
215+
border-radius: 2px;
216+
color: #C7254E;
217+
margin: 2px 4px;
218+
padding: 12px;
206219
}
207220

208221
.CodeMirror .active-definition {
@@ -252,6 +265,7 @@ <h2>Grammar</h2>
252265
<div id="bottomSection">
253266
<div id="expandedInput"></div>
254267
<div id="parseResults"></div>
268+
<div class="overlay"></div>
255269
</div>
256270
<div id="options">
257271
<!-- <label><input type="checkbox" name="showFailures"> Show failures</label> -->

visualizer/index.js

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,13 @@ function markInterval(cm, interval, className, canHighlightBlocks) {
6868
if (canHighlightBlocks && isBlockSelectable(cm, startPos, endPos)) {
6969
return markBlock(cm, startPos.line, endPos.line, className);
7070
}
71-
cm.getWrapperElement().classList.add('highlighting');
7271
return cm.markText(startPos, endPos, {className: className});
7372
}
7473

75-
function clearMark(cm, mark) {
74+
function clearMark(mark) {
7675
if (mark) {
7776
mark.clear();
7877
}
79-
cm.getWrapperElement().classList.remove('highlighting');
8078
}
8179

8280
function indexToHeight(cm, index) {
@@ -266,9 +264,11 @@ function createTraceElement(traceNode, parent, input) {
266264
}
267265
if (traceNode.interval) {
268266
inputMark = markInterval(inputEditor, traceNode.interval, 'highlight', false);
267+
inputEditor.getWrapperElement().classList.add('highlighting');
269268
}
270269
if (traceNode.expr.interval) {
271270
grammarMark = markInterval(grammarEditor, traceNode.expr.interval, 'active-appl', false);
271+
grammarEditor.getWrapperElement().classList.add('highlighting');
272272
scrollToInterval(grammarEditor, traceNode.expr.interval);
273273
}
274274
var ruleName = traceNode.expr.ruleName;
@@ -285,9 +285,11 @@ function createTraceElement(traceNode, parent, input) {
285285
if (input) {
286286
input.classList.remove('highlight');
287287
}
288-
clearMark(inputEditor, inputMark);
289-
clearMark(grammarEditor, grammarMark);
290-
clearMark(grammarEditor, defMark);
288+
inputMark = clearMark(inputMark);
289+
grammarMark = clearMark(grammarMark);
290+
defMark = clearMark(defMark);
291+
grammarEditor.getWrapperElement().classList.remove('highlighting');
292+
inputEditor.getWrapperElement().classList.remove('highlighting');
291293
});
292294
wrapper._input = input;
293295

@@ -358,30 +360,39 @@ function isPrimitive(expr) {
358360
}
359361
}
360362

361-
// Hides or shows the grammar error.
362363
var errorMarks = {
363364
grammar: null,
364365
input: null
365366
};
366367

367368
function hideError(category, editor) {
368-
if (errorMarks[category]) {
369-
clearMark(editor, errorMarks[category].interval);
370-
errorMarks[category].widget.clear();
369+
var errInfo = errorMarks[category];
370+
if (errInfo) {
371+
errInfo.mark.clear();
372+
clearTimeout(errInfo.timeout);
373+
if (errInfo.widget) {
374+
errInfo.widget.clear();
375+
}
371376
errorMarks[category] = null;
372377
}
373378
}
374379

375-
function showError(category, editor, message, interval) {
376-
var el = createElement('.errorItem');
377-
el.textContent = message;
378-
var pos = editor.posFromIndex(interval.endIdx);
380+
function setError(category, editor, interval, message) {
381+
hideError(category, editor);
382+
379383
errorMarks[category] = {
380-
interval: markInterval(editor, interval, 'error', false),
381-
widget: editor.addLineWidget(pos.line, el)
384+
mark: markInterval(editor, interval, 'error-interval', false),
385+
timeout: setTimeout(function() { showError(category, editor, interval, message); }, 1500),
386+
widget: null
382387
};
383388
}
384389

390+
function showError(category, editor, interval, message) {
391+
var errorEl = createElement('.error', message);
392+
var line = editor.posFromIndex(interval.endIdx).line;
393+
errorMarks[category].widget = editor.addLineWidget(line, errorEl);
394+
}
395+
385396
function useLocalStorage() {
386397
return typeof localStorage !== 'undefined' &&
387398
typeof Storage === 'function' &&
@@ -397,6 +408,14 @@ function setEditorValueFromLocalStorage(editor, key) {
397408
}
398409
}
399410

411+
function hideBottomOverlay() {
412+
$('#bottomSection .overlay').style.width = 0;
413+
}
414+
415+
function showBottomOverlay() {
416+
$('#bottomSection .overlay').style.width = '100%';
417+
}
418+
400419
// Main
401420
// ----
402421

@@ -406,6 +425,7 @@ function setEditorValueFromLocalStorage(editor, key) {
406425
var grammarChanged = true;
407426

408427
function triggerRefresh(delay) {
428+
showBottomOverlay();
409429
if (refreshTimeout) {
410430
clearTimeout(refreshTimeout);
411431
}
@@ -418,16 +438,14 @@ function setEditorValueFromLocalStorage(editor, key) {
418438
setEditorValueFromLocalStorage(inputEditor, 'input');
419439
setEditorValueFromLocalStorage(grammarEditor, 'grammar');
420440

421-
inputEditor.on('change', function() { triggerRefresh(150); });
441+
inputEditor.on('change', function() { triggerRefresh(250); });
422442
grammarEditor.on('change', function() {
423443
grammarChanged = true;
424-
triggerRefresh(150);
444+
hideError('grammar', grammarEditor);
445+
triggerRefresh(250);
425446
});
426447

427448
function refresh() {
428-
$('#expandedInput').innerHTML = '';
429-
$('#parseResults').innerHTML = '';
430-
431449
hideError('input', inputEditor);
432450
if (useLocalStorage()) {
433451
localStorage.setItem('input', inputEditor.getValue());
@@ -436,7 +454,6 @@ function setEditorValueFromLocalStorage(editor, key) {
436454
if (grammarChanged) {
437455
grammarChanged = false;
438456

439-
hideError('grammar', grammarEditor);
440457
var grammarSrc = grammarEditor.getValue();
441458
if (useLocalStorage()) {
442459
localStorage.setItem('grammar', grammarSrc);
@@ -447,8 +464,8 @@ function setEditorValueFromLocalStorage(editor, key) {
447464
console.log(e); // eslint-disable-line no-console
448465

449466
var message = e.shortMessage ? e.shortMessage : e.message;
450-
showError('grammar', grammarEditor, message, e.interval);
451-
// If the grammar is unusable, prevent the input to be parsed.
467+
setError('grammar', grammarEditor, e.interval, message);
468+
// If the grammar is unusable, prevent the input from being parsed.
452469
grammar = null;
453470
return;
454471
}
@@ -457,13 +474,16 @@ function setEditorValueFromLocalStorage(editor, key) {
457474
if (!grammar) {
458475
return;
459476
}
477+
hideBottomOverlay();
478+
$('#expandedInput').innerHTML = '';
479+
$('#parseResults').innerHTML = '';
460480

461481
var trace = grammar.trace(inputEditor.getValue());
462482
if (trace.result.failed()) {
463483
// Intervals with start == end won't show up in CodeMirror.
464484
var interval = trace.result.getInterval();
465485
interval.endIdx += 1;
466-
showError('input', inputEditor, 'Expected: ' + trace.result.getExpectedText(), interval);
486+
setError('input', inputEditor, interval, 'Expected ' + trace.result.getExpectedText());
467487
}
468488

469489
// Refresh the option values.

0 commit comments

Comments
 (0)