review/static/scripts/comments.js @ 9030dc9517cf

web: add basic tests

This patch adds a new test module `test_web` to automate testing of web
requests. For now the tests are rather simple and only check for
expected status codes.

To set up the flask app within the tests, it has to be configured
properly. This is the reason why the app configuration part in `web.py`
has been moved into an own function - now it may also be used by the
test module.
author Oben Sonne <obensonne@googlemail.com>
date Mon, 02 Jul 2012 22:32:48 +0200
parents 3fe8d9b6705b
children (none)
_.templateSettings = {
  start       : '{{',
  end         : '}}',
  interpolate : /\{\{(.+?)\}\}/g
};

var comment_form = _.template(
    '<tr class="comment-form">' +
        '<td colspan="3">' +
            '<form id="id_comment-line-form_{{ currNum }}" method="POST" action="">' +
                '<span class="lastlinenumber disabled">{{ currNum }}</span>' +
                '<div class="field">' +
                    '<label class="infield" for="id_comment-line-form_{{ currNum }}_body">Comment</label>' +
                    '<textarea id="id_comment-line-form_{{ currNum }}_body" class="body"'  +
                              'name="new-comment-body">{{ body }}</textarea>' +
                '</div>' +

                '<div class="field cuddly">' +
                    '<input type="checkbox" class="checkbox markdown-select" name="comment-markdown" id="id_comment-line-form_{{ currNum }}_markdown" {{ markdown_checked }} />' +
                    '<label for="id_comment-line-form_{{ currNum }}_markdown">Use Markdown to format this comment.</label>' +
                '</div>' +

                '<a class="submit button"><span>Post Comment</span></a>' +
                '<a class="cancel-line button"><span>Cancel</span></a>' +

                '<input type="hidden" name="filename-u" value="{{ filename_u }}" />' +
                '<input type="hidden" name="filename-b64" value="{{ filename_b64 }}" />' +
                '<input type="hidden" name="current" value="{{ identifier }}" class="current" />' +
                '<input class="lines" type="hidden" name="lines" value="{{ currNum }}" />' +
            '</form>' +
        '</td>' +
    '</tr>'
);

function RenderLineCommentForm(line, currNum, body, markdown, identifier) {
    var filename_u = line.closest(".file").find(".filename .filename-u").text();
    var filename_b64 = line.closest(".file").find(".filename .filename-b64").text();
    markdown_checked = markdown ? 'checked="checked"' : '';
    return comment_form({ filename_u: filename_u, filename_b64: filename_b64,
                          currNum: currNum, body: body, identifier: identifier,
                          markdown_checked: markdown_checked });
}

$(function() {
    $(".activate a").click(function(event) {
        $(event.target).closest(".activate").hide();
        $(event.target).closest("div").children("form").fadeIn("fast");
        return false;
    });
    $(".activate-edit a").click(function(event) {
        $(event.target).closest(".activate-edit").hide();
        $(event.target).closest(".comment").find(".message").hide();
        $(event.target).closest("div").children("form").fadeIn("fast");
        return false;
    });
    $("a.cancel").click(function(event) {
        $(event.target).closest(".togglebox").children(".activate").show();
        $(event.target).parents("form").hide();
        return false;
    });
    $("a.cancel-edit").click(function(event) {
        $(event.target).closest(".toggleinline").children(".activate-edit").show();
        $(event.target).closest(".comment").find(".message").show();
        $(event.target).parents("form").hide();
        return false;
    });
    $("a.cancel-line").live('click', function(event) {
        $(event.target).closest(".diff").find(".chosen").removeClass("chosen");
        $(event.target).closest("tr.comment-form").hide();
        $(event.target).closest(".diff").find("tr.comment").fadeIn('fast');
        $(event.target).closest("tr.comment-form").remove();
        return false;
    });
    $("a.edit-line").click(function(event) {
        var diff = $(this).closest(".diff");
        var comment = $(this).closest("tr.comment");

        diff.find(".chosen").removeClass("chosen");
        diff.find(".comment-form").remove();
        comment.hide();

        _.each($(event.target).closest(".comment").find(".commentlines").html().split(","),
               function(i) { diff.find(".line-" + i).addClass("chosen") });

        var lines_chosen = diff.find(".chosen");
        var last_line = lines_chosen.last();
        var last_line_number = parseInt(lines_chosen.find(".linenumber").last().html());
        var body = comment.find(".raw").html();
        var markdown = comment.find(".message").hasClass("markdown");
        var identifier = comment.find(".identifier").html();

        var comment_form = RenderLineCommentForm(last_line, last_line_number, body, markdown, identifier);
        last_line.after(comment_form);
        diff.find("label").inFieldLabels();

        return false;
    });

    $("tr.comment").hover(function(event) {
        var diff = $(event.target).closest(".diff");

        _.each($(event.target).find(".commentlines").html().split(","),
               function (i) { diff.find(".line-" + i).addClass("viewing"); });
    }, function(event) {
        $(".viewing").removeClass("viewing");
    });

    var lastSelected = null;
    $(".commentable").click(function(event) {
        var currNum = parseInt($(this).find(".linenumber").html());
        var diff = $(this).closest(".diff");

        if ($(this).hasClass("chosen")) {
            $(this).removeClass("chosen");

            var newLines = _.reduce(diff.find(".chosen .linenumber"), "",
                                    function(memo, lne) { return memo + $(lne).html() + ','; });
            diff.find(".comment-form form .lines").val(newLines);

            lastSelected = null;
        } else {
            if (event.shiftKey && lastSelected) {
                if (lastSelected && jQuery.contains(diff.get(0), lastSelected.get(0))) {
                    var lastNum = parseInt(lastSelected.find(".linenumber").html());
                    _.each(_.range(currNum, lastNum, lastNum > currNum ? 1 : -1),
                           function(i) { diff.find(".line-" + i).addClass("chosen"); });
                }
            } else {
                $(this).addClass("chosen");
            }
        }

        var lines_chosen = diff.find(".chosen");
        var last_line_number = parseInt(lines_chosen.find(".linenumber").last().html());
        var existing_forms = diff.find(".comment-form");

        if (existing_forms.length) {
            if (_.isNaN(last_line_number)) {
                existing_forms.remove();
                diff.find("tr.comment").fadeIn('fast');
            } else {
                var existing_form = existing_forms.last();
                var existing_form_line_number = parseInt(existing_form.find(".lastlinenumber").html());
                var existing_body = existing_form.find(".body").val();
                var existing_markdown = existing_form.find('.markdown-select').is(':checked');
                var existing_current = existing_form.find('.current').val();

                if (existing_form_line_number != last_line_number) {
                    existing_forms.remove();

                    var comment_form = RenderLineCommentForm($(this), last_line_number, existing_body,
                                                             existing_markdown, existing_current);
                    lines_chosen.last().after(comment_form);
                    diff.find("label").inFieldLabels();
                }

                var newLines = _.reduce(diff.find(".chosen .linenumber"), "",
                                        function(memo, lne) { return memo + $(lne).html() + ','; });
                diff.find(".comment-form form .lines").val(newLines);
            }
        } else {
            var comment_form = RenderLineCommentForm($(this), last_line_number, '', true, '');
            $(this).after(comment_form);
            diff.find("label").inFieldLabels();
        }

        return false;
    });

    $("label.infield").inFieldLabels();
});