Search code examples
jqueryraphaeljquery-svg

How is Khan Academy's Hint functionality coded


I am curious to know how the hints mechanism is coded in the following URL,

http://www.khanacademy.org/math/arithmetic/multiplication-division/e/multiplication_3

when the user clicks "I'd like a hint" button on the right.

From what I have found so far, MathJax, Raphael JavaScript Library and jQuery are used.

Is my understanding correct? If so I am eager to find out how it all fits together to produce the beautiful interactivity as it does in the website.

Any pointers/clues/hints or sample code is highly appreciated.


Solution

  • Method

    The code is pretty large and complex but using the developer tool built-in to the browser we can focus on what's happening when the hint button is clicked.

    You could either put a breakpoint on click events, then click the hint button and see where in the JavaScript you end up. In this case, though, I looked at the id for the hint button (it's just hint) and, because we know the site is using jQuery, searched for occurrences of $("#hint").click or $('#hint').click. There are three, but the one we want is this:

    ... $("#hint").click(function() {
        var a = z.shift();
        if (a) {
            $(X).trigger("hintUsed"), E += 1;
            var c = z.length + " step" + (z.length === 1 ? "" : "s") + " left";
            $(this).val($(this).data("buttonText") || "I'd like another hint (" + c + ")");
            var d = $(a).parent();
            $(a).appendTo("#hintsarea").runModules(d), X.scratchpad.resize(), z.length === 0 && ($(a).addClass("final_answer"), $(X).trigger("allHintsUsed"), $(this).attr("disabled", !0));
        }
        var g = !f && e.readOnly,
            h = $("#next-question-button").is(":visible");
        !g && !h && tb("problems/" + r + "/hint", b(!1, G, "hint", (new Date).getTime()), function() {}, function() {}, "attempt_hint_queue");
    }), ...
    

    We can then check the value of these variables, step into functions, etc.

    Result

    The flow is this:

    1. z is an array of hints, or rather divs containing calls to a function called showHint(). The number of items in the array is the same as the number of hints remaining.
    2. The code gets the first div in this array and assigns it to variable a.
    3. How many hints have been used/are left are calculated.
    4. The div a is appended to an empty div with id hintsarea, within the workarea.
    5. The JavaScript within div a is executed: showHint().
    6. showHint() does the additional calculations that make up the hint and adds colour to the numbers and symbols.

    MathJax is used for this formatting. If you inspect the DOM with the developer tool, you can see that each number and symbol is enclosed by several spans, created dynamically, to control position and style.

    Regarding Raphael, it's only used to draw the horizontal line in the sum in this case. For other questions, though, I think it's used to draw images and objects that can be dragged.

    Incidentally, there's also an XHR request that's sent to the server when the hint button is clicked but this doesn't seem to affect functionality for the user. It just sends statistics back to Khan Academy which I assume they use for monitoring and improving the feature.