<commit_before>/**
 * this JavaScript files provites all logic for the page editor
 *
 * @author IcedReaper <Kevin.Lang@gmx.de>
 */
$(function() {
    if($('.content.editable').length === 1) {
        var editor = new irEditor($('.content.editable'));
    }
});

var irEditor = function($editor) {
    $('form#irEditor').on('submit', function() {
        try {
            cleanup();
            $('input[name="content"]').val(buildSkeleton());

            setup();

            return true;
        }
        catch (error) {
            console.log(error);

            return false;
        }
    });

    var buildSkeleton = function() {
        var buildSubSkeleton = function($selector) {
            var skeletonNode = [];

            $selector.each(function(index) {
                skeletonNode[index] = {};
                var lastElement = false;

                if($(this).hasClass('row')) {
                    skeletonNode[index].name = 'row';
                }
                if($(this).attr('class').substring(0, 3) === 'col') {
                    skeletonNode[index].name    = 'col';
                    skeletonNode[index].classes = $(this).attr('class');
                }
                if($(this).hasClass('textBlock')) {
                    skeletonNode[index].name = 'textBlock';
                    skeletonNode[index].text = $(this).html();

                    lastElement = true;
                }
                if($(this).hasClass('heroImage')) {
                    skeletonNode[index].name            = 'heroImage';
                    skeletonNode[index].backgroundImage = $(this).css('background-image').replace(/(url\("https*:\/\/(\w+\.*)+|"\))/gi, '');
                    if($('div', $(this)).length === 1) {
                        skeletonNode[index].content = $('div', $(this)).html();
                    }

                    lastElement = true;
                }
                if($(this).hasClass('carousel')) {
                    skeletonNode[index].name = 'slider';
                    skeletonNode[index].id   = $(this).attr('id');

                    if(typeof $(this).attr('interval') !== 'undefined') { skeletonNode[index].interval = $(this).attr('interval'); }
                    if(typeof $(this).attr('pause')    !== 'undefined') { skeletonNode[index].pause    = $(this).attr('pause'); }
                    if(typeof $(this).attr('wrap')     !== 'undefined') { skeletonNode[index].wrap     = $(this).attr('wrap'); }

                    skeletonNode[index].images = [];
                    $('.carousel-inner > .item', $(this)).each(function(imageIndex) {
                        skeletonNode[index].images[imageIndex] = {};
                        skeletonNode[index].images[imageIndex].source = $('img', $(this)).attr('src');

                        if(typeof $(this).attr('alt') !== 'undefined') { skeletonNode[index].images[imageIndex].alt = $(this).attr('alt'); }

                        if($('.carousel-caption > h3', $(this)).length === 1) {
                            skeletonNode[index].images[imageIndex].headline = $('.carousel-caption > h3', $(this)).text();
                        }

                        if($('.carousel-caption > span', $(this)).length === 1) {
                            skeletonNode[index].images[imageIndex].description = $('.carousel-caption > span', $(this)).text();
                        }
                    });
                    lastElement = true;
                }

                if($(this).children().length > 0 && ! lastElement) {
                    skeletonNode[index].modules = buildSubSkeleton($(this).children());
                }
            });

            return skeletonNode;
        }

        var skeleton = buildSubSkeleton($('.content.editable'));
        return JSON.stringify(skeleton[0].modules).replace(/\\n/gi, '');
    };

    var addEditHandler = function() {
        $('.module', $editor).each(function() {
            var delButton = $('<div/>').addClass('btn btn-danger')
                                       .append($('<span/>').addClass('glyphicon glyphicon-trash'))
                                       .on('click', function() {
                                           $(this).closest('.irEditor-wrapper').remove();
                                       });
            var editContainer = $('<aside/>').addClass('editButton')
                                             .append(delButton);

            $(this).wrap('<div/>')
                   .closest('div')
                   .addClass('irEditor-wrapper')
                   .append(editContainer);
        });
    };
    var removeEditHandler = function() {
        $('.content.editable aside.editButton').remove();
        $('.module', $editor).unwrap();
    };

    var initTextBlock = function() {
        $('.module.textBlock').each(function() {
            $(this).tinymce({
                theme: "modern",
                plugins: [
                    ["autolink link image lists preview hr anchor"],    //advlist pagebreak charmap
                    ["searchreplace insertdatetime media nonbreaking"], // wordcount visualblocks visualchars fullscreen code
                    ["table contextmenu directionality template paste"] // emoticons
                ],
                menu: {
                    edit:   {title: 'Edit',   items: 'undo redo | cut copy paste | selectall'},
                    view:   {title: 'View',   items: 'visualaid'},
                    format: {title: 'Format', items: 'bold italic underline strikethrough superscript subscript | formats | removeformat'},
                    table:  {title: 'Table',  items: 'inserttable tableprops deletetable cell row column'},
                },
                add_unload_trigger: false,
                schema: "html5",
                inline: true,
                toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
                statusbar: false
            });
        });
    };
    var cleanupTextBlock = function() {
        $('.module.textBlock[id^="mce_"]').each(function() {
            $(this).tinymce().remove();
        });
    };

    var initCarousel = function() {
        $('.module.carousel').each(function() {
            var $carousel = $(this);

            var createOptionControl = function(label, attrName, defaultValue) {
                return $('<div/>').addClass('form-group')
                                  .append($('<div/>').addClass('col-md-3 control-label')
                                                     .append($('<label/>').text(label))
                                         )
                                  .append($('<div/>').addClass('col-md-9')
                                                     .append($('<input/>').addClass('form-control')
                                                                          .val($carousel.attr(attrName) || defaultValue)
                                                                          .on('input', function() {
                                                                              $carousel.attr(attrName, $(this).val());
                                                                          })
                                                            )
                                         );
            }

            $carousel.before($('<aside/>').addClass('slider-options widget')
                                          .append($('<fieldset/>').append($('<legend/>').text('Optionen'))
                                                                  .append(createOptionControl('Interval', 'data-interval', ''))
                                                                  .append(createOptionControl('Pause',    'data-pause', 'hover'))
                                                                  .append(createOptionControl('Wrap',     'data-wrap', 'true'))
                                                 )
                            );

            $('.item', $carousel).each(function() {
                var $item = $(this);

                var createControl = function(label, id) {
                    var value = "";

                    switch(id) {
                        case 'src': {
                            value = $('img', $item).attr(id) || '';
                            break;
                        }
                        case 'headline': {
                            value = $('.carousel-caption > h3', $item).text();
                            break;
                        }
                        case 'description': {
                            value = $('.carousel-caption > span', $item).text();
                            break;
                        }
                    }

                    return $('<div/>').addClass('form-group')
                                      .append($('<div/>').addClass('col-md-3 control-label')
                                                         .text(label))
                                      .append($('<div/>').addClass('col-md-9')
                                                         .append($('<input/>').addClass('form-control')
                                                                              .val(value)
                                                                              .on('input', function() {
                                                                                switch(id) {
                                                                                case 'src': {
                                                                                $('img', $item).attr(id, $(this).val());
                                                                                break;
                                                                                }
                                                                                case 'headline': {
                                                                                if($(this).val() !== '') {
                                                                                if($('.carousel-caption > h3', $item).length === 0) {
                                                                                $('.carousel-caption', $item).prepend($('<h3/>'));
                                                                                }
                                                                                $('.carousel-caption > h3', $item).text($(this).val());
                                                                                }
                                                                                else {
                                                                                $('.carousel-caption > h3', $item).remove();
                                                                                }
                                                                                break;
                                                                                }
                                                                                case 'description': {
                                                                                if($(this).val() !== '') {
                                                                                if($('.carousel-caption > span', $item).length === 0) {
                                                                                $('.carousel-caption', $item).append($('<span/>'));
                                                                                }
                                                                                $('.carousel-caption > span', $item).text($(this).val());
                                                                                }
                                                                                else {
                                                                                $('.carousel-caption > span', $item).remove();
                                                                                }
                                                                                break;
                                                                                }
                                                                                }
                                                                              })
                                                                )
                                             );
                };

                $item.append($('<aside/>').addClass('editControls widget')
                                          .append($('<fieldset/>').append($('<legend/>').text('Optionen des aktuellen Slide'))
                                                                  .append(createControl('Bildpfad',     'src'))
                                                                  .append(createControl('Titel',        'alt'))
                                                                  .append(createControl('Überschrift',  'headline'))
                                                                  .append(createControl('Beschreibung', 'description'))
                                                 )
                            );
            });
        });
    };
    var cleanupCarousel = function() {
        $('.content.editable aside.slider-options').remove();
    };

    var initHeroImage = function() {
        $('.module.heroImage').each(function() {
            var $heroImage = $(this);

            var createOption = function(label, val, on, updateFunction) {
                return $('<div/>').addClass('form-group')
                                  .append($('<div/>').addClass('col-md-3 control-label')
                                                     .text(label))
                                  .append($('<div/>').addClass('col-md-9')
                                                     .append($('<input/>').addClass('form-control')
                                                                          .val(val)
                                                                          .on(on, updateFunction)
                                                            )
                                         );
            };

            var backgroundImage = createOption('Bildpfad',
                                               $heroImage.css('background-image').replace(/(url\("https*:\/\/(\w+\.*)+|"\))/gi, ''),
                                               'input',
                                               function() {
                                                   $heroImage.css('background-image', "url("+$(this).val()+")")
                                               });

            var content = createOption('Beschreibung',
                                       $('> div', $heroImage).html(),
                                       'change',
                                       null);

            $('input', content).tinymce({
                theme: "modern",
                plugins: [
                    ["autolink link image lists preview hr anchor"],    // advlist pagebreak charmap
                    ["searchreplace insertdatetime media nonbreaking"], // wordcount visualblocks visualchars fullscreen code
                    ["table contextmenu directionality template paste"] // emoticons
                ],
                menu: {
                    edit:   {title: 'Edit',   items: 'undo redo | cut copy paste | selectall'},
                    format: {title: 'Format', items: 'bold italic underline strikethrough superscript subscript | formats | removeformat'},
                },
                add_unload_trigger: false,
                schema: "html5",
                toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link ",
                statusbar: false,
                setup: function(ed) {
                    ed.on("change", function(event) {
                        if($('> div', $heroImage).length === 0) {
                            $heroImage.prepend($('<div/>'));
                        }
                        $('> div', $heroImage).html(ed.getContent());
                    });
                }
            });

            var $container = $('<aside/>').addClass('editControls widget')
                                          .append($('<fieldset/>').append($('<legend/>').text('Optionen'))
                                                                  .append(backgroundImage)
                                                                  .append(content)
                                                 );

            $heroImage.append($container);
        });
    };
    var cleanupHeroImage = function() {
    };

    var initAddHandler = function() {
        $('.irEditor-wrapper', $('.content.editable')).after($('#moduleAddHandler').html());
        $('.row', $('.content.editable')).after($('#rowAddHandler').html());

        $('.addHandler[data-type]').each(function() {
            $addHandler = $(this);
            $('a[data-module]', $addHandler).on('click', function(e) {
                var $anchor = $(this);
                var type    = $anchor.closest('.addHandler').attr('data-type');
                var module  = $anchor.attr('data-module');

                e.preventDefault();

                $addHandler.before($('.contentTemplate[data-type="'+type+'"][data-module="'+module+'"]').html());
            });
        });
    }
    var cleanupAddHandler = function() {

    }

    var setup = function() {
        addEditHandler();
        initAddHandler();
        initTextBlock();
        initCarousel();
        initHeroImage();
    }
    var cleanup = function() {
        removeEditHandler();
        cleanupAddHandler();
        cleanupTextBlock();
        $('.content.editable aside.editControls').remove();
        cleanupCarousel();
        cleanupHeroImage();
    }

    setup();
};<commit_msg>Simplified the init and clean functions as a struct to be usable by the addHandlers<commit_after>/**
 * this JavaScript files provites all logic for the page editor
 *
 * @author IcedReaper <Kevin.Lang@gmx.de>
 */
$(function() {
    if($('.content.editable').length === 1) {
        var editor = new irEditor($('.content.editable'));
    }
});

var irEditor = function($editor) {
    var isNumeric = function (n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    };

    $('form#irEditor').on('submit', function() {
        try {
            cleanup();
            $('input[name="content"]').val(buildSkeleton());

            setup();

            return true;
        }
        catch (error) {
            console.log(error);

            return false;
        }
    });

    var buildSkeleton = function() {
        var buildSubSkeleton = function($selector) {
            var skeletonNode = [];

            $selector.each(function(index) {
                skeletonNode[index] = {};
                var lastElement = false;

                if($(this).hasClass('row')) {
                    skeletonNode[index].name = 'row';
                }
                if($(this).attr('class').substring(0, 3) === 'col') {
                    skeletonNode[index].name    = 'col';
                    skeletonNode[index].classes = $(this).attr('class');
                }
                if($(this).hasClass('textBlock')) {
                    skeletonNode[index].name = 'textBlock';
                    skeletonNode[index].text = $(this).html();

                    lastElement = true;
                }
                if($(this).hasClass('heroImage')) {
                    skeletonNode[index].name            = 'heroImage';
                    skeletonNode[index].backgroundImage = $(this).css('background-image').replace(/(url\("https*:\/\/(\w+\.*)+|"\))/gi, '');
                    if($('div', $(this)).length === 1) {
                        skeletonNode[index].content = $('div', $(this)).html();
                    }

                    lastElement = true;
                }
                if($(this).hasClass('carousel')) {
                    skeletonNode[index].name = 'slider';
                    skeletonNode[index].id   = $(this).attr('id');

                    if(typeof $(this).attr('interval') !== 'undefined') { skeletonNode[index].interval = $(this).attr('interval'); }
                    if(typeof $(this).attr('pause')    !== 'undefined') { skeletonNode[index].pause    = $(this).attr('pause'); }
                    if(typeof $(this).attr('wrap')     !== 'undefined') { skeletonNode[index].wrap     = $(this).attr('wrap'); }

                    skeletonNode[index].images = [];
                    $('.carousel-inner > .item', $(this)).each(function(imageIndex) {
                        skeletonNode[index].images[imageIndex] = {};
                        skeletonNode[index].images[imageIndex].source = $('img', $(this)).attr('src');

                        if(typeof $(this).attr('alt') !== 'undefined') { skeletonNode[index].images[imageIndex].alt = $(this).attr('alt'); }

                        if($('.carousel-caption > h3', $(this)).length === 1) {
                            skeletonNode[index].images[imageIndex].headline = $('.carousel-caption > h3', $(this)).text();
                        }

                        if($('.carousel-caption > span', $(this)).length === 1) {
                            skeletonNode[index].images[imageIndex].description = $('.carousel-caption > span', $(this)).text();
                        }
                    });
                    lastElement = true;
                }

                if($(this).children().length > 0 && ! lastElement) {
                    skeletonNode[index].modules = buildSubSkeleton($(this).children());
                }
            });

            return skeletonNode;
        }

        var skeleton = buildSubSkeleton($('.content.editable'));
        return JSON.stringify(skeleton[0].modules).replace(/\\n/gi, '');
    };

    var addEditHandler = function() {
        $('.module', $editor).each(function() {
            var delButton = $('<div/>').addClass('btn btn-danger')
                                       .append($('<span/>').addClass('glyphicon glyphicon-trash'))
                                       .on('click', function() {
                                           $(this).closest('.irEditor-wrapper').remove();
                                       });
            var editContainer = $('<aside/>').addClass('editButton')
                                             .append(delButton);

            $(this).wrap('<div/>')
                   .closest('div')
                   .addClass('irEditor-wrapper')
                   .append(editContainer);
        });
    };
    var removeEditHandler = function() {
        $('.content.editable aside.editButton').remove();
        $('.module', $editor).unwrap();
    };

    var initItem = {
        'textBlock': function($textBlock) {
            var $textBlock = ! isNumeric($textBlock) ? $textBlock : $(this);

            $textBlock.tinymce({
                theme: "modern",
                plugins: [
                    ["autolink link image lists preview hr anchor"],    //advlist pagebreak charmap
                    ["searchreplace insertdatetime media nonbreaking"], // wordcount visualblocks visualchars fullscreen code
                    ["table contextmenu directionality template paste"] // emoticons
                ],
                menu: {
                    edit:   {title: 'Edit',   items: 'undo redo | cut copy paste | selectall'},
                    view:   {title: 'View',   items: 'visualaid'},
                    format: {title: 'Format', items: 'bold italic underline strikethrough superscript subscript | formats | removeformat'},
                    table:  {title: 'Table',  items: 'inserttable tableprops deletetable cell row column'},
                },
                add_unload_trigger: false,
                schema: "html5",
                inline: true,
                toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
                statusbar: false
            });
        },
        'carousel':  function($carousel) {
            var $carousel = ! isNumeric($carousel) ? $carousel : $(this);

            var createOptionControl = function(label, attrName, defaultValue) {
                return $('<div/>').addClass('form-group')
                                  .append($('<div/>').addClass('col-md-3 control-label')
                                                     .append($('<label/>').text(label))
                                         )
                                  .append($('<div/>').addClass('col-md-9')
                                                     .append($('<input/>').addClass('form-control')
                                                                          .val($carousel.attr(attrName) || defaultValue)
                                                                          .on('input', function() {
                                                                              $carousel.attr(attrName, $(this).val());
                                                                          })
                                                            )
                                         );
            }

            $carousel.before($('<aside/>').addClass('slider-options widget')
                                          .append($('<fieldset/>').append($('<legend/>').text('Optionen'))
                                                                  .append(createOptionControl('Interval', 'data-interval', ''))
                                                                  .append(createOptionControl('Pause',    'data-pause', 'hover'))
                                                                  .append(createOptionControl('Wrap',     'data-wrap', 'true'))
                                                 )
                            );

            $('.item', $carousel).each(function() {
                var $item = $(this);

                var createControl = function(label, id) {
                    var value = "";

                    switch(id) {
                        case 'src': {
                            value = $('img', $item).attr(id) || '';
                            break;
                        }
                        case 'headline': {
                            value = $('.carousel-caption > h3', $item).text();
                            break;
                        }
                        case 'description': {
                            value = $('.carousel-caption > span', $item).text();
                            break;
                        }
                    }

                    return $('<div/>').addClass('form-group')
                                      .append($('<div/>').addClass('col-md-3 control-label')
                                                         .text(label))
                                      .append($('<div/>').addClass('col-md-9')
                                                         .append($('<input/>').addClass('form-control')
                                                                              .val(value)
                                                                              .on('input', function() {
                                                                                switch(id) {
                                                                                case 'src': {
                                                                                $('img', $item).attr(id, $(this).val());
                                                                                break;
                                                                                }
                                                                                case 'headline': {
                                                                                if($(this).val() !== '') {
                                                                                if($('.carousel-caption > h3', $item).length === 0) {
                                                                                $('.carousel-caption', $item).prepend($('<h3/>'));
                                                                                }
                                                                                $('.carousel-caption > h3', $item).text($(this).val());
                                                                                }
                                                                                else {
                                                                                $('.carousel-caption > h3', $item).remove();
                                                                                }
                                                                                break;
                                                                                }
                                                                                case 'description': {
                                                                                if($(this).val() !== '') {
                                                                                if($('.carousel-caption > span', $item).length === 0) {
                                                                                $('.carousel-caption', $item).append($('<span/>'));
                                                                                }
                                                                                $('.carousel-caption > span', $item).text($(this).val());
                                                                                }
                                                                                else {
                                                                                $('.carousel-caption > span', $item).remove();
                                                                                }
                                                                                break;
                                                                                }
                                                                                }
                                                                              })
                                                                )
                                             );
                };

                $item.append($('<aside/>').addClass('editControls widget')
                                          .append($('<fieldset/>').append($('<legend/>').text('Optionen des aktuellen Slide'))
                                                                  .append(createControl('Bildpfad',     'src'))
                                                                  .append(createControl('Titel',        'alt'))
                                                                  .append(createControl('Überschrift',  'headline'))
                                                                  .append(createControl('Beschreibung', 'description'))
                                                 )
                            );
            });
        },
        'heroImage': function($heroImage) {
            var $heroImage = ! isNumeric($heroImage) ? $heroImage : $(this);

            var createOption = function(label, val, on, updateFunction) {
                return $('<div/>').addClass('form-group')
                                  .append($('<div/>').addClass('col-md-3 control-label')
                                                     .text(label))
                                  .append($('<div/>').addClass('col-md-9')
                                                     .append($('<input/>').addClass('form-control')
                                                                          .val(val)
                                                                          .on(on, updateFunction)
                                                            )
                                         );
            };

            var backgroundImage = createOption('Bildpfad',
                                               $heroImage.css('background-image').replace(/(url\("https*:\/\/(\w+\.*)+|"\))/gi, ''),
                                               'input',
                                               function() {
                                                   $heroImage.css('background-image', "url("+$(this).val()+")")
                                               });

            var content = createOption('Beschreibung',
                                       $('> div', $heroImage).html(),
                                       'change',
                                       null);

            $('input', content).tinymce({
                theme: "modern",
                plugins: [
                    ["autolink link image lists preview hr anchor"],    // advlist pagebreak charmap
                    ["searchreplace insertdatetime media nonbreaking"], // wordcount visualblocks visualchars fullscreen code
                    ["table contextmenu directionality template paste"] // emoticons
                ],
                menu: {
                    edit:   {title: 'Edit',   items: 'undo redo | cut copy paste | selectall'},
                    format: {title: 'Format', items: 'bold italic underline strikethrough superscript subscript | formats | removeformat'},
                },
                add_unload_trigger: false,
                schema: "html5",
                toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link ",
                statusbar: false,
                setup: function(ed) {
                    ed.on("change", function(event) {
                        if($('> div', $heroImage).length === 0) {
                            $heroImage.prepend($('<div/>'));
                        }
                        $('> div', $heroImage).html(ed.getContent());
                    });
                }
            });

            var $container = $('<aside/>').addClass('editControls widget')
                                          .append($('<fieldset/>').append($('<legend/>').text('Optionen'))
                                                                  .append(backgroundImage)
                                                                  .append(content)
                                                 );

            $heroImage.append($container);
        }
    };

    var cleanupItem = {
        'textBlock': function($textBlock) {
            var $textBlock = ! isNumeric($textBlock) ? $textBlock : $(this);

            $textBlock.tinymce().remove();
        },
        'carousel':  function($carousel) {
            var $carousel = ! isNumeric($carousel) ? $carousel : $(this);

            $('.content.editable aside.slider-options').remove();
        },
        'heroImage': function($heroImage) {
            var $heroImage = ! isNumeric($heroImage) ? $heroImage : $(this);

        }
    };

    var initTextBlock    = function() { $('.module.textBlock').each(initItem.textBlock); };
    var cleanupTextBlock = function() { $('.module.textBlock[id^="mce_"]').each(cleanupItem.textBlock); };

    var initCarousel = function() {
        $('.module.carousel').each(initItem.carousel);
    };
    var cleanupCarousel = function() {
        $('.module.carousel').each(cleanupItem.carousel);
    };

    var initHeroImage = function() {
        $('.module.heroImage').each(initItem.heroImage);
    };
    var cleanupHeroImage = function() {
        $('.module.heroImage').each(cleanupItem.heroImage);
    };

    var initAddHandler = function() {
        $('.irEditor-wrapper', $('.content.editable')).after($('#moduleAddHandler').html());
        $('.row', $('.content.editable')).after($('#rowAddHandler').html());

        $('.addHandler[data-type]').each(function() {
            $addHandler = $(this);
            $('a[data-module]', $addHandler).on('click', function(e) {
                var $anchor = $(this);
                var type    = $anchor.closest('.addHandler').attr('data-type');
                var module  = $anchor.attr('data-module');

                e.preventDefault();

                $addHandler.before($('.contentTemplate[data-type="'+type+'"][data-module="'+module+'"]').html());
            });
        });
    }
    var cleanupAddHandler = function() {

    }

    var setup = function() {
        addEditHandler();
        initAddHandler();
        initTextBlock();
        initCarousel();
        initHeroImage();
    }
    var cleanup = function() {
        removeEditHandler();
        cleanupAddHandler();
        cleanupTextBlock();
        $('.content.editable aside.editControls').remove();
        cleanupCarousel();
        cleanupHeroImage();
    }

    setup();
};<|endoftext|>


<commit_before>import TestModule from './test-module';
import Ember from 'ember';
import { getResolver } from './test-resolver';

export default TestModule.extend({
  init: function(componentName, description, callbacks) {
    this.componentName = componentName;

    this._super.call(this, 'component:' + componentName, description, callbacks);

    this.setupSteps.push(this.setupComponent);
  },

  setupComponent: function() {
    var _this = this;
    var resolver = getResolver();
    var container = this.container;
    var context = this.context;

    var layoutName = 'template:components/' + this.componentName;

    var layout = resolver.resolve(layoutName);

    if (layout) {
      container.register(layoutName, layout);
      container.injection(this.subjectName, 'layout', layoutName);
    }

    context.dispatcher = Ember.EventDispatcher.create();
    context.dispatcher.setup({}, '#ember-testing');

    this.callbacks.render = function() {
      var containerView = Ember.ContainerView.create({container: container});
      var view = Ember.run(function(){
        var subject = context.subject();
        containerView.pushObject(subject);
        containerView.appendTo('#ember-testing');
        return subject;
      });

      _this.teardownSteps.unshift(function() {
        Ember.run(function() {
          Ember.tryInvoke(containerView, 'destroy');
        });
      });

      return view.$();
    };

    this.callbacks.append = function() {
      Ember.deprecate('this.append() is deprecated. Please use this.render() instead.');
      return this.callbacks.render();
    };

    context.$ = function() {
      var $view = this.render();
      var subject = this.subject();

      if (arguments.length){
        return subject.$.apply(subject, arguments);
      } else {
        return $view;
      }
    };
  }
});
<commit_msg>`render` callback for component does not return view.$<commit_after>import TestModule from './test-module';
import Ember from 'ember';
import { getResolver } from './test-resolver';

export default TestModule.extend({
  init: function(componentName, description, callbacks) {
    this.componentName = componentName;

    this._super.call(this, 'component:' + componentName, description, callbacks);

    this.setupSteps.push(this.setupComponent);
  },

  setupComponent: function() {
    var _this = this;
    var resolver = getResolver();
    var container = this.container;
    var context = this.context;

    var layoutName = 'template:components/' + this.componentName;

    var layout = resolver.resolve(layoutName);

    if (layout) {
      container.register(layoutName, layout);
      container.injection(this.subjectName, 'layout', layoutName);
    }

    context.dispatcher = Ember.EventDispatcher.create();
    context.dispatcher.setup({}, '#ember-testing');

    this.callbacks.render = function() {
      var containerView = Ember.ContainerView.create({container: container});
      Ember.run(function(){
        var subject = context.subject();
        containerView.pushObject(subject);
        containerView.appendTo('#ember-testing');
      });

      _this.teardownSteps.unshift(function() {
        Ember.run(function() {
          Ember.tryInvoke(containerView, 'destroy');
        });
      });
    };

    this.callbacks.append = function() {
      Ember.deprecate('this.append() is deprecated. Please use this.render() instead.');
      return this.callbacks.render();
    };

    context.$ = function() {
      this.render();
      var subject = this.subject();

      return subject.$.apply(subject, arguments);
    };
  }
});
<|endoftext|>


<commit_before>import * as types from './mutation-types'

export default {
  [types.GET_STOP_DETAILS] (state, { stopDetails }) {
    var newStop = {
      'stop_id': stopDetails.stop.stop_id,
      'name': stopDetails.stop.name,
      'arrivals': stopDetails.arrivals,
      'route_names': stopDetails.route_names
    }
    state.stop = newStop
  },
  [types.GET_STOP_BUS_MAP] (state, { stopBusMap }) {
    state.stop.stop_id = stopBusMap.stop.stop_id
    state.stop.name = stopBusMap.stop.name
    state.stop.point.x = stopBusMap.stop.longitude
    state.stop.point.y = stopBusMap.stop.latitude
    state.route.stops = stopBusMap.stops
    state.trip = stopBusMap.trip
    state.vehicle = stopBusMap.vehicle
  },
  [types.GET_BUSES] (state, { allBuses }) {
    state.buses = allBuses
  },
  [types.GET_FAVORITES] (state, { favorites }) {
    state.favorites = favorites
  },
  [types.ADD_FAVORITE] (state, { favorite }) {
  },
  [types.REMOVE_FAVORITE] (state, { stopId }) {
  },
  [types.SET_CURRENT_LANGUAGE] (state, { locale }) {
    state.current_language = locale
  }
}
<commit_msg>Switched mutation - stop was missing the point object<commit_after>import * as types from './mutation-types'

export default {
  [types.GET_STOP_DETAILS] (state, { stopDetails }) {
    var newStop = {
      'stop_id': stopDetails.stop.stop_id,
      'name': stopDetails.stop.name,
      'arrivals': stopDetails.arrivals,
      'route_names': stopDetails.route_names
    }
    state.stop = newStop
  },
  [types.GET_STOP_BUS_MAP] (state, { stopBusMap }) {
    var newStop = {
      'stop_id': stopBusMap.stop.stop_id,
      'name': stopBusMap.stop.name,
      'point': {
        'x': stopBusMap.stop.longitude,
        'y': stopBusMap.stop.latitude
      }
    }
    state.stop = newStop
    state.route.stops = stopBusMap.stops
    state.trip = stopBusMap.trip
    state.vehicle = stopBusMap.vehicle
  },
  [types.GET_BUSES] (state, { allBuses }) {
    state.buses = allBuses
  },
  [types.GET_FAVORITES] (state, { favorites }) {
    state.favorites = favorites
  },
  [types.ADD_FAVORITE] (state, { favorite }) {
  },
  [types.REMOVE_FAVORITE] (state, { stopId }) {
  },
  [types.SET_CURRENT_LANGUAGE] (state, { locale }) {
    state.current_language = locale
  }
}
<|endoftext|>


<commit_before>var apiurl = "api.py";
var loadedtransactions = [];
var accountsearches = [ {"status": "$ne:closed" }, {"amount": "$ne:0"}, {} ];
var showing = -1;
var showtrans = {};
var editedfields = []
var limit = 25;
var skip = 0;
var query = accountsearches[0];
var sessioncheckinterval = null;
var categories = {};

function showerror(err) {
  $("#errormsg").text(err);
  $("#errormsg").dialog("open");
}

function loginsuccess() {
  $("#login").hide();
  $("#bottomlinks").show();
  $("#searchoptions").show();
  loadedtransactions = [];
  accountsearches = accountsearches.slice(0,3);
  showing = -1;
  limit = 25;
  skip = 0;
  loadaccounts();
  loadtransactions();
  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "getcategories" },
    success: function (data) {
      categories = data;
      keys = Object.keys(categories);
      keys.sort();
      $("#transactiondetail #category").autocomplete({
        source: keys,
        delay: 50,
        minLength: 0,
        select: function(event, ui) {
          $("#transactiondetail > #save").button("enable");
          if (editedfields.indexOf("category") == -1)
            editedfields.push("category");
          $("#transactiondetail #subcategory").autocomplete("option", "source", categories[ui.item.value]);
        }
      });
      $("#transactiondetail #subcategory").autocomplete({
        source: [],
        delay: 50,
        minLength: 0,
        select: function(event, ui) {
          if (editedfields.indexOf("subcategory") == -1)
            editedfields.push("subcategory");
          $("#transactiondetail > #save").button("enable");
        }
      });
    },
    error: function () {
      showerr("Error loading categories!");
    }
  });

  if (!sessioncheckinterval)
    sessioncheckinterval = setInterval(checksession, 60000);
}

function clearpage() {
  $("#login").hide();
  $("#transactions").hide();
  $("#transactiondetail").dialog("close");
  $("#accounts").hide();
  $("#bottomlinks").hide();
  $("#errormsg").hide();
  $("#searchoptions").hide();
  $("#newaccount").hide();
  $("#username").val("");
  $("#password").val("");
  if (sessioncheckinterval)
    clearInterval(sessioncheckinterval);

  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "checklogin" },
    success: function(data) {
      if (data) {
        loginsuccess();
      } else {
        $("#login").show();
      }
    },
    error: function() {
      $("#login").show();
    }
  });
}

function checksession() {
  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "checklogin" },
    success: function(data) {
      if (data) {
      } else {
        clearpage();
      }
    },
    error: function() {
      clearpage();
    }
  });
}

function decoratedollar() {
  if ($(this).text().substring(0,1) == "$")
    return;
  amount = parseInt($(this).text());
  if (amount > 0)
    $(this).addClass("posnum");
  else
    $(this).removeClass("posnum");
  $(this).text("$"+Math.abs(amount/100).toFixed(2));
}

function loadaccounts() {
  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "accounts" },
    success: function(data) {
      $("#accounts > .useraccount").remove();
      for (i in data) {
        for (j in data[i]["subaccounts"]) {
          newaccount = "
";
          newaccount += "
"+data[i]["name"]+"
";
          newaccount += "
"+data[i]["subaccounts"][j]["name"]+"
";
          newaccount += "
"+data[i]["subaccounts"][j]["amount"]+"
";
          newaccount += "
"+data[i]["subaccounts"][j]["date"]+"
";
          newaccount += "
";
          $("#accounts").append(newaccount);
          accountsearches.push({"account":data[i]["name"], "subaccount": data[i]["subaccounts"][j]["name"]});
        }
      }
      $(".dollar").each(decoratedollar);
      $(".account").click(function() {
        for (i=0; i < $(this).parent().children(".account").length; i++) {
          if ($(this).text() == $(this).parent().children(".account").eq(i).text()) {
            query = accountsearches[i];
            loadtransactions();
            return;
          }
        }
      });
      $("#accounts").show();
    },
    error: function() {
      showerror("Error loading accounts");
    }
  });
}

function savetransaction() {
  if (editedfields.length > 0) {
    updatejson = new Object();
    for (f in editedfields) {
      newval = $("#transactiondetail #"+editedfields[f]).text();
      if (newval == "")
        newval = $("#transactiondetail #"+editedfields[f]).val();
        updatejson[editedfields[f]] = newval;
    }
    if (editedfields.indexOf("amount") != -1) {
      newamount = $("#transactiondetail #amount").text().replace("$","").replace(",","");
      if (newamount.indexOf(".") == -1) {
        newamount += ".00";
      } else if (newamount.indexOf(".") != (newamount.length-3)) {
        showerror("Bad amount");
        return;
      }
      newamount = newamount.replace(".","");
      if (showtrans["amount"] > 0)
        updatejson["amount"] = parseInt(newamount);
      else
        updatejson["amount"] = -parseInt(newamount);
    }
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "updatetransaction", "id": showtrans["id"], "data" : JSON.stringify(updatejson) },
      success: function(data) {
        if (data) {
          showtransaction(showing);
          loadtransactions();
        } else {
          showerror("Error saving transaction");
        }
      },
      error: function() {
        showerror("HTTP Error saving transaction");
      }
    });
  }
}

function showtransaction(t) {
  if (typeof(t) == "number") {
    if (showing == t) {
      $("#transactiondetail").dialog("close");
      showing = -1;
      return;
    }
    showing = t;
    showtrans = loadedtransactions[t];
  } else {
    showtrans = t;
  }
  editedfields = [];
  $("#transactiondetail > #save").button("disable");
  $("#transactiondetail > #file").hide();
  $("#transactiondetail .transdata").each(function () {
    name = $(this).attr("id");
    $(this).text("");
    if (showtrans[name] != undefined)
      $(this).text(showtrans[name]);
  });
  $("#transactiondetail .transdataval").each(function () {
    name = $(this).attr("id");
    $(this).val("");
    if (showtrans[name] != undefined)
      $(this).val(showtrans[name]);
  });
  $("#transactiondetail > #attr").html("");
  for (key in showtrans) {
    if ((key.indexOf("attr_") == 0) && (showtrans[key] != "")) {
      $("#transactiondetail > #attr").append(key.substr(5) + ": " + showtrans[key] + "
");
    }
  }
  if (showtrans["file"] != undefined) {
    $("#transactiondetail > #file").attr("src",apiurl+"?image="+showtrans["id"]);
    $("#transactiondetail > #file").show();
  }
  $(".dollar").each(decoratedollar);
  if (categories[showtrans["category"]] != undefined)
    $("#transactiondetail #subcategory").autocomplete("option", "source", categories[showtrans["category"]]);
  $("#transactiondetail").dialog("open");
}

function loadtransactions() {
  $.ajax({
    type: "POST",
    url: apiurl,
    data: {
      "action": "search",
      "limit": limit,
      "skip": skip,
      "startdate": $("#startdate").val(),
      "enddate": $("#enddate").val(),
      "query": JSON.stringify(query)
    },
    success: function(data) {
      total = 0;
      loadedtransactions = data;
      for (t=0; t<data.length; t++) {
        if ($("#transtablebody > #trans"+t).length == 0) {
          $("#transtablebody").append("

");
          $("#trans"+t).click(function() {
            showtransaction(parseInt($(this).attr("id").substring(5)));
          });
        }
        $("#transtablebody > #trans"+t+" .date").text(data[t]["date"]);
        $("#transtablebody > #trans"+t+" .description").text(data[t]["desc"]);
        $("#transtablebody > #trans"+t+" .dollar").text(data[t]["amount"]);
        total += data[t]["amount"];
      }
      for (t=data.length; t<$("#transtablebody tr").length; t++)
        $("#transtablebody > #trans"+t).remove();
      $("#transactionsum").text(total);
      $(".dollar").each(decoratedollar);
      $("#transtablebody td").addClass("ui-widget-content");
      $("#transtablebody tr").hover(
        function() {
          $(this).children("td").addClass("ui-state-hover");
        },
        function() {
          $(this).children("td").removeClass("ui-state-hover");
        }
      );
      $("#transactions").show();
    },
    error: function() {
      showerror("Transaction loading error");
    }
  });
}

$(document).ready(function () {
  $('[contenteditable]').live('focus', function() {
    var $this = $(this);
    $this.data('before', $this.text());
      return $this;
  }).live('blur keyup paste', function() {
    var $this = $(this);
    if ($this.data('before') !== $this.text()) {
      $this.data('before', $this.text());
      if (editedfields.indexOf($(this).attr("id")) == -1) {
        editedfields.push($(this).attr("id"));
        $("#transactiondetail > #save").button("enable");
      }
    }
    return $this;
  });

  $("#transactiondetail > #save").button();
  $("#transactiondetail > #save").click(savetransaction);
  $("#transactiondetail > #dateselect").datepicker({
    dateFormat: "yy-mm-dd",
    altField: "#transactiondetail > #date",
    onSelect: function(dateText, inst) {
      $("#transactiondetail > #date").text(dateText);
      if (editedfields.indexOf("date") == -1) {
        editedfields.push("date");
        $("#transactiondetail > #save").button("enable");
      }
    }
  });
  $("#transactiondetail > #date").click(function() {
    $("#transactiondetail > #dateselect").datepicker("show");
  });
  $("#transactiondetail").dialog({
    modal: true,
    autoOpen: false,
    title: "Edit Transaction",
    minWidth: 600
  });

  $("#searchoptions .date").datepicker({
    dateFormat: "yy-mm-dd",
    onClose: function(dateText, inst) {
      loadtransactions();
    }
  });

  $("#errormsg").dialog({
    modal: true,
    autoOpen: false,
    title: "Error",
    minWidth: 250,
    buttons: {
      Ok: function() {
        $(this).dialog("close");
      }
    }
  });

  $(".limit").click(function(event) {
    event.preventDefault();
    if ($(this).text() == "all")
      limit = Number.MAX_VALUE;
    else
      limit = parseInt($(this).text());
    loadtransactions();
  });

  $(".page").click(function(event) {
    event.preventDefault();
    if ($(this).html() == "<<") {
      if (skip == 0)
        return;
      skip -= limit;
      if (skip < 0)
        skip = 0;
      loadtransactions();
    } else {
      if (loadedtransactions.length < limit)
        return;
      skip += limit;
      loadtransactions();
    }
  });

  $("#logout").click(function(event) {
    event.preventDefault();
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "logout" },
      success: function() {
        clearpage();
      },
      error: function() {
        clearpage();
      }
    });
  });

  $("#loginsubmit").click(function () {
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "login", "username": $("#username").val(), "password": $("#password").val() },
      success: function(data) {
        if (data) {
          loginsuccess();
        } else {
          showerror("Login Failed");
        }
      },
      error: function() {
        showerror("Login Error");
      }
    });
  });

  $("#newuser").click(function () {
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "newuser", "username": $("#username").val(), "password": $("#password").val() },
      success: function(data) {
        if (data) {
          $("#loginsubmit").click();
        } else {
          showerror("Username already exists");
        }
      },
      error: function() {
        showerror("Error making new user");
      }
    });
  });

  $("#newaccount").dialog({
    modal: true,
    autoOpen: false,
    title: "Add/Edit Account"
  });

  $("#addaccount").click(function (event) {
    event.preventDefault();
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "getbanks" },
      success: function(data) {
        newhtml = "<option value=''>Select a bank</option>";
        for (i=0; i<data.length; i++)
          newhtml += "<option value='"+data[i]+"'>"+data[i]+"</option>";
        $("#newaccount #bankname").html(newhtml);
      }
    });
    $("#newaccount > #createaccount").button("disable");
    $("#newaccount input").each(function() {
      $(this).val("");
    });
    $("#newaccount").dialog("open");
  });

  $("#newaccount .required").keyup(function () {
    ready = true;
    for (var i=0; i<$("#newaccount .required").length; i++) {
      if ($("#newaccount .required").eq(i).val() == "")
        ready = false;
    }
    if (ready)
      $("#newaccount > #createaccount").button("enable");
  });

  $("#newaccount > #createaccount").button();
  $("#newaccount > #createaccount").click(function () {
    account = new Object();
    $("#newaccount input,select").each(function() {
      account[$(this).attr("id")] = $(this).val();
    });
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "editaccount", "account": JSON.stringify(account) },
      success: function(data) {
        if (data) {
          $("#newaccount").dialog("close");
          loadaccounts();
        } else {
          showerror("Could not add/edit account");
        }
      },
      error: function() {
        showerror("HTTP Error editing account");
      }
    });
  });

  clearpage();

  $("th").addClass("ui-state-default");

});
<commit_msg>Fix cleaning up of unused table rows.<commit_after>var apiurl = "api.py";
var loadedtransactions = [];
var accountsearches = [ {"status": "$ne:closed" }, {"amount": "$ne:0"}, {} ];
var showing = -1;
var showtrans = {};
var editedfields = []
var limit = 25;
var skip = 0;
var query = accountsearches[0];
var sessioncheckinterval = null;
var categories = {};

function showerror(err) {
  $("#errormsg").text(err);
  $("#errormsg").dialog("open");
}

function loginsuccess() {
  $("#login").hide();
  $("#bottomlinks").show();
  $("#searchoptions").show();
  loadedtransactions = [];
  accountsearches = accountsearches.slice(0,3);
  showing = -1;
  limit = 25;
  skip = 0;
  loadaccounts();
  loadtransactions();
  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "getcategories" },
    success: function (data) {
      categories = data;
      keys = Object.keys(categories);
      keys.sort();
      $("#transactiondetail #category").autocomplete({
        source: keys,
        delay: 50,
        minLength: 0,
        select: function(event, ui) {
          $("#transactiondetail > #save").button("enable");
          if (editedfields.indexOf("category") == -1)
            editedfields.push("category");
          $("#transactiondetail #subcategory").autocomplete("option", "source", categories[ui.item.value]);
        }
      });
      $("#transactiondetail #subcategory").autocomplete({
        source: [],
        delay: 50,
        minLength: 0,
        select: function(event, ui) {
          if (editedfields.indexOf("subcategory") == -1)
            editedfields.push("subcategory");
          $("#transactiondetail > #save").button("enable");
        }
      });
    },
    error: function () {
      showerr("Error loading categories!");
    }
  });

  if (!sessioncheckinterval)
    sessioncheckinterval = setInterval(checksession, 60000);
}

function clearpage() {
  $("#login").hide();
  $("#transactions").hide();
  $("#transactiondetail").dialog("close");
  $("#accounts").hide();
  $("#bottomlinks").hide();
  $("#errormsg").hide();
  $("#searchoptions").hide();
  $("#newaccount").hide();
  $("#username").val("");
  $("#password").val("");
  if (sessioncheckinterval)
    clearInterval(sessioncheckinterval);

  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "checklogin" },
    success: function(data) {
      if (data) {
        loginsuccess();
      } else {
        $("#login").show();
      }
    },
    error: function() {
      $("#login").show();
    }
  });
}

function checksession() {
  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "checklogin" },
    success: function(data) {
      if (data) {
      } else {
        clearpage();
      }
    },
    error: function() {
      clearpage();
    }
  });
}

function decoratedollar() {
  if ($(this).text().substring(0,1) == "$")
    return;
  amount = parseInt($(this).text());
  if (amount > 0)
    $(this).addClass("posnum");
  else
    $(this).removeClass("posnum");
  $(this).text("$"+Math.abs(amount/100).toFixed(2));
}

function loadaccounts() {
  $.ajax({
    type: "POST",
    url: apiurl,
    data: { "action": "accounts" },
    success: function(data) {
      $("#accounts > .useraccount").remove();
      for (i in data) {
        for (j in data[i]["subaccounts"]) {
          newaccount = "
";
          newaccount += "
"+data[i]["name"]+"
";
          newaccount += "
"+data[i]["subaccounts"][j]["name"]+"
";
          newaccount += "
"+data[i]["subaccounts"][j]["amount"]+"
";
          newaccount += "
"+data[i]["subaccounts"][j]["date"]+"
";
          newaccount += "
";
          $("#accounts").append(newaccount);
          accountsearches.push({"account":data[i]["name"], "subaccount": data[i]["subaccounts"][j]["name"]});
        }
      }
      $(".dollar").each(decoratedollar);
      $(".account").click(function() {
        for (i=0; i < $(this).parent().children(".account").length; i++) {
          if ($(this).text() == $(this).parent().children(".account").eq(i).text()) {
            query = accountsearches[i];
            loadtransactions();
            return;
          }
        }
      });
      $("#accounts").show();
    },
    error: function() {
      showerror("Error loading accounts");
    }
  });
}

function savetransaction() {
  if (editedfields.length > 0) {
    updatejson = new Object();
    for (f in editedfields) {
      newval = $("#transactiondetail #"+editedfields[f]).text();
      if (newval == "")
        newval = $("#transactiondetail #"+editedfields[f]).val();
        updatejson[editedfields[f]] = newval;
    }
    if (editedfields.indexOf("amount") != -1) {
      newamount = $("#transactiondetail #amount").text().replace("$","").replace(",","");
      if (newamount.indexOf(".") == -1) {
        newamount += ".00";
      } else if (newamount.indexOf(".") != (newamount.length-3)) {
        showerror("Bad amount");
        return;
      }
      newamount = newamount.replace(".","");
      if (showtrans["amount"] > 0)
        updatejson["amount"] = parseInt(newamount);
      else
        updatejson["amount"] = -parseInt(newamount);
    }
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "updatetransaction", "id": showtrans["id"], "data" : JSON.stringify(updatejson) },
      success: function(data) {
        if (data) {
          showtransaction(showing);
          loadtransactions();
        } else {
          showerror("Error saving transaction");
        }
      },
      error: function() {
        showerror("HTTP Error saving transaction");
      }
    });
  }
}

function showtransaction(t) {
  if (typeof(t) == "number") {
    if (showing == t) {
      $("#transactiondetail").dialog("close");
      showing = -1;
      return;
    }
    showing = t;
    showtrans = loadedtransactions[t];
  } else {
    showtrans = t;
  }
  editedfields = [];
  $("#transactiondetail > #save").button("disable");
  $("#transactiondetail > #file").hide();
  $("#transactiondetail .transdata").each(function () {
    name = $(this).attr("id");
    $(this).text("");
    if (showtrans[name] != undefined)
      $(this).text(showtrans[name]);
  });
  $("#transactiondetail .transdataval").each(function () {
    name = $(this).attr("id");
    $(this).val("");
    if (showtrans[name] != undefined)
      $(this).val(showtrans[name]);
  });
  $("#transactiondetail > #attr").html("");
  for (key in showtrans) {
    if ((key.indexOf("attr_") == 0) && (showtrans[key] != "")) {
      $("#transactiondetail > #attr").append(key.substr(5) + ": " + showtrans[key] + "
");
    }
  }
  if (showtrans["file"] != undefined) {
    $("#transactiondetail > #file").attr("src",apiurl+"?image="+showtrans["id"]);
    $("#transactiondetail > #file").show();
  }
  $(".dollar").each(decoratedollar);
  if (categories[showtrans["category"]] != undefined)
    $("#transactiondetail #subcategory").autocomplete("option", "source", categories[showtrans["category"]]);
  $("#transactiondetail").dialog("open");
}

function loadtransactions() {
  $.ajax({
    type: "POST",
    url: apiurl,
    data: {
      "action": "search",
      "limit": limit,
      "skip": skip,
      "startdate": $("#startdate").val(),
      "enddate": $("#enddate").val(),
      "query": JSON.stringify(query)
    },
    success: function(data) {
      total = 0;
      loadedtransactions = data;
      for (t=0; t<data.length; t++) {
        if ($("#transtablebody > #trans"+t).length == 0) {
          $("#transtablebody").append("

");
          $("#trans"+t).click(function() {
            showtransaction(parseInt($(this).attr("id").substring(5)));
          });
        }
        $("#transtablebody > #trans"+t+" .date").text(data[t]["date"]);
        $("#transtablebody > #trans"+t+" .description").text(data[t]["desc"]);
        $("#transtablebody > #trans"+t+" .dollar").text(data[t]["amount"]);
        total += data[t]["amount"];
      }
      for (t=data.length; $("#transtablebody > #trans"+t).length > 0; t++)
        $("#transtablebody > #trans"+t).remove();
      $("#transactionsum").text(total);
      $(".dollar").each(decoratedollar);
      $("#transtablebody td").addClass("ui-widget-content");
      $("#transtablebody tr").hover(
        function() {
          $(this).children("td").addClass("ui-state-hover");
        },
        function() {
          $(this).children("td").removeClass("ui-state-hover");
        }
      );
      $("#transactions").show();
    },
    error: function() {
      showerror("Transaction loading error");
    }
  });
}

$(document).ready(function () {
  $('[contenteditable]').live('focus', function() {
    var $this = $(this);
    $this.data('before', $this.text());
      return $this;
  }).live('blur keyup paste', function() {
    var $this = $(this);
    if ($this.data('before') !== $this.text()) {
      $this.data('before', $this.text());
      if (editedfields.indexOf($(this).attr("id")) == -1) {
        editedfields.push($(this).attr("id"));
        $("#transactiondetail > #save").button("enable");
      }
    }
    return $this;
  });

  $("#transactiondetail > #save").button();
  $("#transactiondetail > #save").click(savetransaction);
  $("#transactiondetail > #dateselect").datepicker({
    dateFormat: "yy-mm-dd",
    altField: "#transactiondetail > #date",
    onSelect: function(dateText, inst) {
      $("#transactiondetail > #date").text(dateText);
      if (editedfields.indexOf("date") == -1) {
        editedfields.push("date");
        $("#transactiondetail > #save").button("enable");
      }
    }
  });
  $("#transactiondetail > #date").click(function() {
    $("#transactiondetail > #dateselect").datepicker("show");
  });
  $("#transactiondetail").dialog({
    modal: true,
    autoOpen: false,
    title: "Edit Transaction",
    minWidth: 600
  });

  $("#searchoptions .date").datepicker({
    dateFormat: "yy-mm-dd",
    onClose: function(dateText, inst) {
      loadtransactions();
    }
  });

  $("#errormsg").dialog({
    modal: true,
    autoOpen: false,
    title: "Error",
    minWidth: 250,
    buttons: {
      Ok: function() {
        $(this).dialog("close");
      }
    }
  });

  $(".limit").click(function(event) {
    event.preventDefault();
    if ($(this).text() == "all")
      limit = Number.MAX_VALUE;
    else
      limit = parseInt($(this).text());
    loadtransactions();
  });

  $(".page").click(function(event) {
    event.preventDefault();
    if ($(this).html() == "<<") {
      if (skip == 0)
        return;
      skip -= limit;
      if (skip < 0)
        skip = 0;
      loadtransactions();
    } else {
      if (loadedtransactions.length < limit)
        return;
      skip += limit;
      loadtransactions();
    }
  });

  $("#logout").click(function(event) {
    event.preventDefault();
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "logout" },
      success: function() {
        clearpage();
      },
      error: function() {
        clearpage();
      }
    });
  });

  $("#loginsubmit").click(function () {
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "login", "username": $("#username").val(), "password": $("#password").val() },
      success: function(data) {
        if (data) {
          loginsuccess();
        } else {
          showerror("Login Failed");
        }
      },
      error: function() {
        showerror("Login Error");
      }
    });
  });

  $("#newuser").click(function () {
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "newuser", "username": $("#username").val(), "password": $("#password").val() },
      success: function(data) {
        if (data) {
          $("#loginsubmit").click();
        } else {
          showerror("Username already exists");
        }
      },
      error: function() {
        showerror("Error making new user");
      }
    });
  });

  $("#newaccount").dialog({
    modal: true,
    autoOpen: false,
    title: "Add/Edit Account"
  });

  $("#addaccount").click(function (event) {
    event.preventDefault();
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "getbanks" },
      success: function(data) {
        newhtml = "<option value=''>Select a bank</option>";
        for (i=0; i<data.length; i++)
          newhtml += "<option value='"+data[i]+"'>"+data[i]+"</option>";
        $("#newaccount #bankname").html(newhtml);
      }
    });
    $("#newaccount > #createaccount").button("disable");
    $("#newaccount input").each(function() {
      $(this).val("");
    });
    $("#newaccount").dialog("open");
  });

  $("#newaccount .required").keyup(function () {
    ready = true;
    for (var i=0; i<$("#newaccount .required").length; i++) {
      if ($("#newaccount .required").eq(i).val() == "")
        ready = false;
    }
    if (ready)
      $("#newaccount > #createaccount").button("enable");
  });

  $("#newaccount > #createaccount").button();
  $("#newaccount > #createaccount").click(function () {
    account = new Object();
    $("#newaccount input,select").each(function() {
      account[$(this).attr("id")] = $(this).val();
    });
    $.ajax({
      type: "POST",
      url: apiurl,
      data: { "action": "editaccount", "account": JSON.stringify(account) },
      success: function(data) {
        if (data) {
          $("#newaccount").dialog("close");
          loadaccounts();
        } else {
          showerror("Could not add/edit account");
        }
      },
      error: function() {
        showerror("HTTP Error editing account");
      }
    });
  });

  clearpage();

  $("th").addClass("ui-state-default");

});
<|endoftext|>


<commit_before>// List of ASOIAF characters and their IDs
var asoiaf_chars = [
	["Jon Arryn", "jonarryn"],
	["Petyr Baelish", "littlefinger"],
	["Joffrey Baratheon", "joffrey"],
	["Myrcella Baratheon", "myrcella"],
	["Robert Baratheon", "robertbaratheon"],
	["Stannis Baratheon", "stannis"],
	["Renly Baratheon", "renly"],
	["Tommen Baratheon", "tommen"],
	["Bronn", "bronn"],
	["Brotherhood Without Banners", "brotherhood"],
	["Gregor Clegane", "gregor"],
	["Direwolves", "direwolves"],
	["Dragons", "dragons"],
	["Drogo", "drogo"],
	["Mirri Maz Duur", "mirri"],
	["Faith Militant", "faithmilitant"],
	["Gendry", "gendry"],
	["Gilly", "gilly"],
	["Asha Greyjoy", "asha"],
	["Theon Greyjoy", "theon"],
	["High Sparrow", "highsparrow"],
	["Iron Bank of Braavos", "ironbank"],
	["Kettleblacks", "kettleblacks"],
	["Cersei Lannister", "cersei"],
	["Jaime Lannister", "jaime"],
	["Tyrion Lannister", "tyrion"],
	["Tywin Lannister", "tywin"],
	["Quentyn Martell", "quentyn"],
	["Melisandre", "melisandre"],
	["Jorah Mormont", "jorah"],
	["Daario Naharis", "daario"],
	["Ilyn Payne", "ilyn"],
	["Mance Rayder's son", "mancesson", "Aemon_Steelsong"],
	["Barristan Selmy", "barristan"],
	["Jon Snow", "jon"],
	["Catelyn Stark", "catelyn"],
	["Eddard Stark", "eddard"],
	["Robb Stark", "robb"],
	["Sansa Stark", "sansa"],
	["Aegon I Targaryen", "aegon1"],
	["Aegon VI Targaryen", "aegon6"],
	["Baelor I Targaryen", "baelor"],
	["Daenerys Targaryen", "daenerys"],
	["Viserys Targaryen", "viserys"],
	["Samwell Tarly", "sam"],
	["Brienne of Tarth", "brienne"],
	["Loras Tyrell", "loras"],
	["Margaery Tyrell", "margaery"],
	["Margaery's cousins", "margaeryscousins"],
	["Olenna Tyrell", "olenna"],
	["Undying Ones", "undying"],
	["Varys", "varys"]
];

// List of TAK characters, their IDs, and their neighbors' IDs
var tak_chars = [
	["Allies", "allies"],
	["Brothers d'Aunay", "aunays"],
	["Beatrice d'Hirson", "beatrice"],
	["Blanche of Burgundy", "blanche"],
	["Hugues de Bouville", "bouville"],
	["Charles IV of France", "charles4"],
	["Clemence of Hungary", "clemence"],
	["Hugh Despenser the Younger", "despenser"],
	["Edward II of England", "edward2"],
	["Edward III of England", "edward3"],
	["Gaucher V de Chatillon", "gaucher"],
	["Guccio Baglioni", "guccio"],
	["Isabella of France", "isabella"],
	["Jean I of France", "jean1"],
	["Jeanne of Burgundy", "jeanneofburgundy", "Joan_II,_Countess_of_Burgundy"],
	["Pope John XXII", "john22"],
	["Knights Templar", "templars"],
	["Lormet", "lormet"],
	["Louis IX of France", "louis9"],
	["Louis X of France", "louis10"],
	["Louis X's illegitimate daughter", "louisdaughter"], // TODO: what's her name?
	["Mahaut of Artois", "mahaut"],
	["Marguerite of Burgundy", "marguerite", "Margaret_of_Burgundy,_Queen_of_France"],
	["Marie de Cressay", "marie"],
	["Marie of Hungary", "marieofhungary", "Mary_of_Hungary,_Queen_of_Naples"],
	["Roger Mortimer", "mortimer", "Roger_Mortimer,_1st_Earl_of_March"],
	["Guillaume de Nogaret", "nogaret"],
	["Enguerrand de Marigny", "marigny"],
	["Philip IV of France", "philip4"],
	["Philip IV's hounds", "hounds"],
	["Philippa of Hainaut", "philippa"],
	["Philippe V of France", "philippe5"],
	["Cola di Rienzi", "rienzi"],
	["Robert III of Artois", "robertofartois"],
	["Spinello Tolomei", "tolomei"],
	["Charles of Valois", "valois"],
	["William I of England", "william"]
];

/*
 * Define "vertex" object corresponding to each character
 *
 * Each vertex has the following fields:
 * - name: the character's full name
 * - id: character's unique ID string
 * - series: either "tak" or "asoiaf"
 * - index: the vertex's index in its respective list
 */
var vertexList = [];

/* Define "edge" object corresponding to each connection between a TAK character and an ASOIAF character
 *
 * Each edge has the following fields:
 * - l: the ID of the TAK character (left part of graph)
 * - r: the ID of the ASOIAF character (right part of graph)
 */
var edgeList = [];

var l = asoiaf_chars;
while(true) {

	for(var i = 0; i < l.length; i++) {

		var char_ID = l[i][1],
			full_name = l[i][0],
			series = (l == asoiaf_chars ? "asoiaf" : "tak");

		var vertex = {
			name: full_name,
			id: char_ID,
			series: series,
			index: i
		};

		if(l[i].length >= 3)
			vertex.wiki_handle = l[i][2];

		vertexList.push(vertex);

		// Delete everything but the character ID from the original list
		l[i] = char_ID;
	}

	// Update l to next list
	if(l == asoiaf_chars)
		l = tak_chars;
	else
		break;
}
<commit_msg>Change character order to make it more alphabetical<commit_after>// List of ASOIAF characters and their IDs
var asoiaf_chars = [
	["Jon Arryn", "jonarryn"],
	["Petyr Baelish", "littlefinger"],
	["Joffrey Baratheon", "joffrey"],
	["Myrcella Baratheon", "myrcella"],
	["Renly Baratheon", "renly"],
	["Robert Baratheon", "robertbaratheon"],
	["Stannis Baratheon", "stannis"],
	["Tommen Baratheon", "tommen"],
	["Bronn", "bronn"],
	["Brotherhood Without Banners", "brotherhood"],
	["Gregor Clegane", "gregor"],
	["Direwolves", "direwolves"],
	["Dragons", "dragons"],
	["Drogo", "drogo"],
	["Mirri Maz Duur", "mirri"],
	["Faith Militant", "faithmilitant"],
	["Gendry", "gendry"],
	["Gilly", "gilly"],
	["Asha Greyjoy", "asha"],
	["Theon Greyjoy", "theon"],
	["High Sparrow", "highsparrow"],
	["Iron Bank of Braavos", "ironbank"],
	["Kettleblacks", "kettleblacks"],
	["Cersei Lannister", "cersei"],
	["Jaime Lannister", "jaime"],
	["Tyrion Lannister", "tyrion"],
	["Tywin Lannister", "tywin"],
	["Quentyn Martell", "quentyn"],
	["Melisandre", "melisandre"],
	["Jorah Mormont", "jorah"],
	["Daario Naharis", "daario"],
	["Ilyn Payne", "ilyn"],
	["Mance Rayder's son", "mancesson", "Aemon_Steelsong"],
	["Barristan Selmy", "barristan"],
	["Jon Snow", "jon"],
	["Catelyn Stark", "catelyn"],
	["Eddard Stark", "eddard"],
	["Robb Stark", "robb"],
	["Sansa Stark", "sansa"],
	["Aegon I Targaryen", "aegon1"],
	["Aegon VI Targaryen", "aegon6"],
	["Baelor I Targaryen", "baelor"],
	["Daenerys Targaryen", "daenerys"],
	["Viserys Targaryen", "viserys"],
	["Samwell Tarly", "sam"],
	["Brienne of Tarth", "brienne"],
	["Loras Tyrell", "loras"],
	["Margaery Tyrell", "margaery"],
	["Margaery's cousins", "margaeryscousins"],
	["Olenna Tyrell", "olenna"],
	["Undying Ones", "undying"],
	["Varys", "varys"]
];

// List of TAK characters, their IDs, and their neighbors' IDs
var tak_chars = [
	["Allies", "allies"],
	["Brothers d'Aunay", "aunays"],
	["Beatrice d'Hirson", "beatrice"],
	["Blanche of Burgundy", "blanche"],
	["Hugues de Bouville", "bouville"],
	["Charles IV of France", "charles4"],
	["Clemence of Hungary", "clemence"],
	["Hugh Despenser the Younger", "despenser"],
	["Edward II of England", "edward2"],
	["Edward III of England", "edward3"],
	["Gaucher V de Chatillon", "gaucher"],
	["Guccio Baglioni", "guccio"],
	["Isabella of France", "isabella"],
	["Jean I of France", "jean1"],
	["Jeanne of Burgundy", "jeanneofburgundy", "Joan_II,_Countess_of_Burgundy"],
	["Pope John XXII", "john22"],
	["Knights Templar", "templars"],
	["Lormet", "lormet"],
	["Louis IX of France", "louis9"],
	["Louis X of France", "louis10"],
	["Louis X's illegitimate daughter", "louisdaughter"], // TODO: what's her name?
	["Mahaut of Artois", "mahaut"],
	["Marguerite of Burgundy", "marguerite", "Margaret_of_Burgundy,_Queen_of_France"],
	["Marie de Cressay", "marie"],
	["Marie of Hungary", "marieofhungary", "Mary_of_Hungary,_Queen_of_Naples"],
	["Roger Mortimer", "mortimer", "Roger_Mortimer,_1st_Earl_of_March"],
	["Guillaume de Nogaret", "nogaret"],
	["Enguerrand de Marigny", "marigny"],
	["Philip IV of France", "philip4"],
	["Philip IV's hounds", "hounds"],
	["Philippa of Hainaut", "philippa"],
	["Philippe V of France", "philippe5"],
	["Cola di Rienzi", "rienzi"],
	["Robert III of Artois", "robertofartois"],
	["Spinello Tolomei", "tolomei"],
	["Charles of Valois", "valois"],
	["William I of England", "william"]
];

/*
 * Define "vertex" object corresponding to each character
 *
 * Each vertex has the following fields:
 * - name: the character's full name
 * - id: character's unique ID string
 * - series: either "tak" or "asoiaf"
 * - index: the vertex's index in its respective list
 */
var vertexList = [];

/* Define "edge" object corresponding to each connection between a TAK character and an ASOIAF character
 *
 * Each edge has the following fields:
 * - l: the ID of the TAK character (left part of graph)
 * - r: the ID of the ASOIAF character (right part of graph)
 */
var edgeList = [];

var l = asoiaf_chars;
while(true) {

	for(var i = 0; i < l.length; i++) {

		var char_ID = l[i][1],
			full_name = l[i][0],
			series = (l == asoiaf_chars ? "asoiaf" : "tak");

		var vertex = {
			name: full_name,
			id: char_ID,
			series: series,
			index: i
		};

		if(l[i].length >= 3)
			vertex.wiki_handle = l[i][2];

		vertexList.push(vertex);

		// Delete everything but the character ID from the original list
		l[i] = char_ID;
	}

	// Update l to next list
	if(l == asoiaf_chars)
		l = tak_chars;
	else
		break;
}
<|endoftext|>


<commit_before>//
// Strider Webapp extension for Sauce Labs tests
//

/*
 * GET /api/sauce/
 *
 * Get the current Strider config for specified project. This will be a JSON-encoded
 * object with the keys: sauce_username, sauce_access_key and sauce_browsers
 *
 * @param url Github html_url of the project.
 */
function getIndex(req, res) {
  console.log("get index");
  var url = req.param("url");

  function error(err_msg) {
    console.error("Strider-Sauce: getIndex() - %s", err_msg);
    var r = {
      errors: [err_msg],
      status: "error"
    };
    res.statusCode = 400;
    return res.end(JSON.stringify(r, null, '\t'));
  };

  Step(
    function() {
        req.user.get_repo_config(url, this);
    },
    function(err, repo, access_level, owner_user_obj) {
      if (err) {
        return error("Error fetching Repo Config for url " + url + ": " + err);
      }
      this.collabs = repo.collaborators;
      this.owner_user_obj = owner_user_obj;
      // Look up emails for each collaborator
      var group = this.group();
      _.each(repo.collaborators, function(c) {
        models.User.findOne({"_id":c.user_id}, {"email":1}, group());
      });
    },
    function(err, results) {
      if (err) {
        return error("Error fetching collaborator emails: " + err);
      }
      // Build a whitelist to output directly as JSON
      var id_email_map = {};
      _.each(results, function(user) {
        id_email_map[user._id] = user.email;
      });
      var whitelist = [];
      _.each(this.collabs, function(c) {
        whitelist.push({
          type: "user",
          email: id_email_map[c.user_id],
          access_level: c.access_level,
          owner: false,
          gravatar: email_to_gravatar(id_email_map[c.user_id]),
        });
      });
      // Synthesize the owner as a collaborator
      whitelist.push({type:"user", user_id: this.owner_user_obj._id,
        access_level: 1, email: this.owner_user_obj.email, owner:true,
        gravatar: email_to_gravatar(this.owner_user_obj.email)});
      var r = {
        status: "ok",
        errors: [],
        results: whitelist
      };
      return res.end(JSON.stringify(r, null, '\t'));
    }
  )
}

function postIndex(req, res) {
  console.log("post index")
  return res.end("ok")

}

module.exports = function(ctx, cb) {

  function saucePlugin(schema, opts) {
    schema.add({
      sauce_access_key: String,
      sauce_username: String,
      sauce_browsers: [],
    })
  }

  // Extend RepoConfig model with 'Sauce' properties
  ctx.models.RepoConfig.plugin(saucePlugin)

  // Add webserver routes
  ctx.route.get("/api/sauce",
    ctx.middleware.require_auth,
    ctx.middleware.require_params(["url"]),
    getIndex)
  ctx.route.post("/api/sauce",
    ctx.middleware.require_auth,
    ctx.middleware.require_params(["url"]),
    postIndex)

  console.log("strider-sauce webapp extension loaded")

  cb(null, null)

}
<commit_msg>implement GET /api/sauce<commit_after>//
// Strider Webapp extension for Sauce Labs tests
//

module.exports = function(ctx, cb) {

  function saucePlugin(schema, opts) {
    schema.add({
      sauce_access_key: String,
      sauce_username: String,
      sauce_browsers: [],
    })
  }

  /*
   * GET /api/sauce/
   *
   * Get the current Strider config for specified project. This will be a JSON-encoded
   * object with the keys: sauce_username, sauce_access_key and sauce_browsers
   *
   * @param url Github html_url of the project.
   */
  function getIndex(req, res) {
    var url = req.param("url")

    function error(err_msg) {
      console.error("Strider-Sauce: getIndex() - %s", err_msg)
      var r = {
        errors: [err_msg],
        status: "error"
      }
      res.statusCode = 400
      return res.end(JSON.stringify(r, null, '\t'))
    };

    Step(
      function() {
          req.user.get_repo_config(url, this)
      },
      function(err, repo, access_level, owner_user_obj) {
        if (err) {
          return error("Error fetching Repo Config for url " + url + ": " + err)
        }
        repo = repo.toJSON()
        var r = {
          status: "ok",
          errors: [],
          results: {
            sauce_username: repo.sauce_username,
            sauce_access_key: repo.sauce_access_key,
            sauce_browsers: repo.sauce_browsers,
          }
        }
        return res.end(JSON.stringify(r, null, '\t'))
      }
    )
  }

  /*
   * POST /api/sauce/
   *
   * Set the current Strider config for specified project.
   *
   * @param url Github html_url of the project.
   * @param sauce_username Sauce Labs username.
   * @param sauce_access_key Sauce Labs access key.
   * @param sauce_browsers JSON-encoded list of object tuples.
   *
   */
  function postIndex(req, res) {
    console.log("post index")
    return res.end("ok")

  }

  // Extend RepoConfig model with 'Sauce' properties
  ctx.models.RepoConfig.plugin(saucePlugin)

  // Add webserver routes
  ctx.route.get("/api/sauce",
    ctx.middleware.require_auth,
    ctx.middleware.require_params(["url"]),
    getIndex)
  ctx.route.post("/api/sauce",
    ctx.middleware.require_auth,
    ctx.middleware.require_params(["url"]),
    postIndex)

  console.log("strider-sauce webapp extension loaded")

  cb(null, null)

}
<|endoftext|>