PageRenderTime 35ms CodeModel.GetById 10ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 1ms

/public/friendlycode/js/fc/ui/error-help.js

https://github.com/mrsonord/thimble.webmaker.org
JavaScript | 93 lines | 72 code | 9 blank | 12 comment | 5 complexity | 35016222f2b9007cfba36043c66ab469 MD5 | raw file
 1// Provides helpful Slowparse-based error suggestions for a
 2// ParsingCodeMirror.
 3define(["jquery-slowparse", "./mark-tracker"], function($, markTracker) {
 4  "use strict";
 5
 6  // Display an animated arrow pointing at a particular position in a
 7  // codeMirror instance. It disappears after a short delay.
 8  function pointAtPosition(codeMirror, pos) {
 9    var MOVE_TIME = 500;
10    var PAUSE_TIME = 1000;
11    var pointer = $('<div class="cursor-pointer"></div>');
12    codeMirror.addWidget(pos, pointer[0], true);
13    pointer.css({
14      opacity: 0,
15      paddingTop: '50px'
16    });
17    pointer.animate({
18      opacity: 1,
19      paddingTop: 0
20    }, MOVE_TIME).delay(PAUSE_TIME).fadeOut(function() {
21      pointer.remove();
22    });
23  }
24
25  return function ErrorHelp(options) {
26    var self = {};
27    var codeMirror = options.codeMirror;
28    var template = options.template;
29    var errorArea = options.errorArea;
30    var relocator = options.relocator;
31    var timeout = null;
32    var ERROR_DISPLAY_DELAY = 250;
33
34    // remove the error help from view
35    function clearError() {
36      clearTimeout(timeout);
37      errorHelpMarks.clear();
38      errorArea.hide();
39      relocator.cleanup();
40    }
41
42    // The escape key should close error help
43    $(document).keyup(function(event) {
44      if (event.keyCode == 27)
45        clearError();
46    });
47
48    // Keep track of error highlighting.
49    var errorHelpMarks = markTracker(codeMirror, relocator);
50
51    // Report the given Slowparse error.
52    function reportError(error) {
53      var startMark = null,
54          endMark = null,
55          errorHTML = $("<div></div>").fillError(error);
56      errorArea.html(template({error: errorHTML.html()})).show();
57      errorArea.eachErrorHighlight(function(start, end, i) {
58        // Point the error message's arrow at the first occurrence of
59        // the word "here" in the error message.
60        if (startMark === null)
61          startMark = start;
62        errorHelpMarks.mark(start, end, "highlight-" + (i+1), this);
63        $(this).click(function() {
64          var pos = codeMirror.posFromIndex(start);
65          codeMirror.setCursor(pos);
66          pointAtPosition(codeMirror, pos);
67        });
68        endMark = end;
69      });
70      relocator.relocate(errorArea, startMark, endMark, "error");
71
72      // clicking the dismiss link should also close error help
73      var dismiss = errorArea.find(".dismiss");
74      if(dismiss) {
75        dismiss.click(clearError);
76      }
77
78      errorArea.hide();
79    }
80
81    codeMirror.on("change", clearError);
82    codeMirror.on("reparse", function(event) {
83      clearError();
84      // same as context-sensitive-help.js, "cursor-activity" handling
85      if (event.error) {
86        timeout = setTimeout(function() {
87          reportError(event.error);
88        }, ERROR_DISPLAY_DELAY);
89      }
90    });
91    return self;
92  };
93});