WaniKani Markdown Notes

Allows you to write Markdown in the notes, which will be rendered as HTML when the page loads.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         WaniKani Markdown Notes
// @namespace    rfindley
// @description  Allows you to write Markdown in the notes, which will be rendered as HTML when the page loads.
// @version      1.4
// @require      https://cdnjs.cloudflare.com/ajax/libs/showdown/1.3.0/showdown.min.js
// @include      https://www.wanikani.com/level*
// @include      https://www.wanikani.com/radical*
// @include      https://www.wanikani.com/kanji*
// @include      https://www.wanikani.com/vocabulary*
// @include      https://www.wanikani.com/review/session*
// @copyright    2013, Jeshua
// @run-at       document-end
// @grant        none
// ==/UserScript==

wkmdnotes = {};

(function() {
    
    /**
    * Render the given markdown text.
    */
    function render(text) {
        // Do some custom replacements.
        text = text.replace(/#kan#/g, '<span class="kanji-highlight highlight-kanji" rel="tooltip" data-original-title="Kanji">');
        text = text.replace(/#\/kan#/g, '</span>');

        text = text.replace(/#rad#/g, '<span class="radical-highlight highlight-radical" rel="tooltip" data-original-title="Radical">');
        text = text.replace(/#\/rad#/g, '</span>');

        text = text.replace(/#read#/g, '<span class="reading-highlight highlight-reading" rel="tooltip" data-original-title="Reading">');
        text = text.replace(/#\/read#/g, '</span>');

        text = text.replace(/#voc#/g, '<span class="vocabulary-highlight highlight-vocabulary" rel="tooltip" data-original-title="Vocabulary">');
        text = text.replace(/#\/voc#/g, '</span>');

        // Render the rest as markdown.
        return (new showdown.Converter()).makeHtml(text);
    }

    /**
    * Find all of the tooltips in the given container and tooltipify them.
    */
    function activateTooltips(container) {
        if (container.tooltip) {
            container.find('span[rel="tooltip"]').tooltip();
        }
    }

    /**
    * Setup the given note field with the required callbacks.
    */
    function setupNoteField(note) {
        // Save the markdown and render the content.
        var html = note.html();
        if (typeof html === 'undefined') html = '';
        note.data('noteContent', html.replace(/<br>/g,'\n'));
        note.html(render(html));
        activateTooltips(note);

        note.click(function(e) {
            if (e.target.tagName.toLowerCase() === 'textarea') {
                return;
            }

            // If the target is the div, they are going from display --> edit.
            if (e.target.tagName.toLowerCase() !== 'button') {
                var interval = setInterval(function() {
                    // If we can find a textarea, they must have clicked to edit the text field.
                    // So, we want to display the markdown content.
                    if (note.find('textarea')) {
                        clearInterval(interval);
                        if (note.data('noteContent') === 'Click to add note') {
                            note.find('textarea').val('');
                        } else {
                            note.find('textarea').val(note.data('noteContent'));
                        }
                    }
                }, 50);
            } 

            // Otherwise, they are going from edit --> display.
            else {
                var textarea = note.find('textarea');
                var str = textarea.val().replace(/\n/g,'\n');
                textarea.html(str);
                var interval = setInterval(function() {
                    // Keep waiting until there is no text area. Then, save the changed markdown
                    // value to the data. Also re-render the note.
                    if (note.find('textarea').length === 0) {
                        clearInterval(interval);
                        note.data('noteContent', note.html().replace(/<br>/g,'\n'));
                        note.html(render(note.html()));
                        activateTooltips(note);
                    }
                }, 50);
            }        
        });
    }
    
    function main() {
        // Convert the text in the meaning note.
        var noteFields = ['.note-meaning', '.note-reading'];
        $.each(noteFields, function(i, noteSelector) {
            // During reviews, we have to wait for the field to be added to the dom first.
            // Then, we can add a listener to the note selector.
            $('#option-item-info').click(function() {
                var interval = setInterval(function() {
                    if ($(noteSelector).length !== 0) {
                        clearInterval(interval);
                        setupNoteField($(noteSelector));
                    }
                }, 50);
            });

            // Setup the note field if it is on the page already.
            setupNoteField($(noteSelector));
        });
    }
    
    // Run startup() after window.onload event.
    if (document.readyState === 'complete')
        main();
    else
        window.addEventListener("load", main, false);
})(wkmdnotes);