WaniKani Markdown Notes

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==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);