<commit_before>function SupportPage($context) {
    var $options = $context.find('section#act .option');
    var $anchors = $options.find('.adjust');
    var $infos = $options.find('.info');

    this._detectSelected($anchors, $options, $infos)
    this._initContentNav($anchors);

    $('.msg.hidden').css('display', 'none').removeClass('hidden')
    this._join($options)
    this._finance($options)
    this._media($options)
    this._fellowship($options)
    this._physical($options)
    this._donation($options)

    this._initAccordion($options)

    $('select').each(function () {
        var $this = $(this);
        var options = {'containerCssClass': $this.attr('id') + ' select2'}
        if (!$this.is('[multiple]')) {
//            options.formatResult = function(state) {
//                if (!state.id) return state.text; // optgroup
//                return state.text + 'asdasd ' ;
//            }
        }
        $this.select2(options).change(function () {
            $(this).valid();
        });
    })

    var sidebar = new Sidebar($('#sidebar'), {
        $waypoint: app.$content,
        offsets: {
            screenReduce: 120
        }
    });

}

SupportPage.prototype = {
    _join: function ($options) {
        var $form = $options.filter('.time').find('form');
        new AjaxForm($form)
    },
    _finance: function ($options) {
        var $form = $options.filter('.finance').find('form');
        new AjaxForm($form)
    },
    _media: function ($options) {
        var $form = $options.filter('.media').find('form');
        new AjaxForm($form)
    },
    _fellowship: function ($options) {
        var $form = $options.filter('.fellowship').find('form');
        new AjaxForm($form)
    },
    _physical: function ($options) {
        var $form = $options.filter('.physical').find('form');
        new AjaxForm($form)
    },
    _donation: function ($options) {
        var $section = $options.filter('.donation');
        var $form = $section.find('form.donate');
        $form.submit(function (e) {
            return e.preventDefault()
        })
        var $paypalForm = $section.find('form.paypal')
        var $epayForm = $section.find('form.epay')
        var $project = $form.find('[name="project"]')
        var $type = $form.find('[name="type"]')
        var pay = {
            paypal: function (amount, topic) {
                $paypalForm.find('[name="item_name"]').val(topic)
                $paypalForm.find('[name="amount"]').val(amount / 2)
                $paypalForm.find('[name="submit"]').click()
            },
            epay: function (amount, topic) {
                $epayForm.find('[name="DESCR"]').val(topic)
                $epayForm.find('[name="TOTAL"]').val(amount)
                $epayForm.find('[type="submit"]').click()
            }
        }
        $form.find('button').click(function (e) {
            var topic = $project.data('raw');
            var amount = $(this).data('amount')
            e.preventDefault()
            if (amount > 1000) {
                e.preventDefault()
                e.stopPropagation()
                document.location.hash = 'sponsorship';
                $options.filter('.finance').find('header').click()
                return;
            }
            if ($project.val() != 'any') topic = topic + " за " + $project.find("option:selected").text();
            $form.block({
                message: null,
                overlayCSS: {
                    backgroundColor: 'rgba(245, 245, 245, 0.6)',
                    opacity: 1
                }
            });
            var $veil = $form.find('.blockOverlay');
            AjaxForm._genSpinner().spin($veil.get(0))
            pay[$type.filter(':checked').val()](amount, topic);
        })
    },
    _detectSelected: function ($anchors, $options, $infos) {
        var $target = $anchors.filter(window.location.hash);
        console.log(!$target.length)
        if (!$target.length) {
            $target = $anchors.filter('#time');
            document.location.hash = 'time';
        }
        $options.removeClass('basic-transition-2x')
        $options.find('header p, header h2').removeClass('basic-transition-2x')
        $options.removeClass('active')
        $infos.find('.info-content').addClass('hidden')
        var $targetOption = $target.parent();
        $targetOption.find('.info-content').removeClass('hidden')
        $targetOption.addClass('active')
        $options.addClass('basic-transition-2x')
        $options.find('header p, header h2').addClass('basic-transition-2x')
    },

    _initContentNav: function ($anchors) {
        $('.toc a').click(function (e) {
            e.preventDefault()
            var $target = $anchors.filter($(this).attr('href'));
            var $targetOption = $target.parent();
            $targetOption.find('header').click()
        })
    },

    _initAccordion: function ($options) {
        $options.find('header').each(function () {
            var $header = $(this);
            var $this = $header.parent();
            var $infoNone = $this.find('.info-holder');
            var $infoContent = $this.find('.info-content');
            if ($infoContent.hasClass('hidden')) $infoContent.css('display', 'none').removeClass('hidden')
            var $info = $this.find('.info');
            var hash = $this.find('.adjust').attr('id')
            var $otherOptions = $options.not($this)

            $header.click(function () {
                changeHashWithoutScrolling(hash)
                if ($this.hasClass('active')) return;
                var $activeOption = $otherOptions.filter('.active');
                var $activeInfo = $activeOption.find('.info');
                toggleFixedHeight($activeInfo, true)
                toggleFixedHeight($info, true)
                $activeInfo.animateContentSwitch($activeInfo.find('.info-content'), $activeInfo.find('.info-holder'), {
                    speed: 300,
                    width: false,
                    parallel: true,
                    final: function () {
                        toggleFixedHeight($activeInfo, false)
                        $("html, body").animate({ scrollTop: $this.find('.adjust').offset().top }, {duration: 200});
                    }
                });
                $info.animateContentSwitch($infoNone, $infoContent, {
                    speed: 300,
                    width: false,
                    parallel: true,
                    final: function () {
                        toggleFixedHeight($info, false)
                    }
                });
                $activeOption.removeClass('active');
                $this.addClass('active')
            })
        })
    }
}<commit_msg>Added ajax form for partnership support<commit_after>function SupportPage($context) {
    var $options = $context.find('section#act .option');
    var $anchors = $options.find('.adjust');
    var $infos = $options.find('.info');

    this._detectSelected($anchors, $options, $infos)
    this._initContentNav($anchors);

    $('.msg.hidden').css('display', 'none').removeClass('hidden')
    this._join($options)
    this._finance($options)
    this._media($options)
    this._fellowship($options)
    this._partnership($options)
    this._physical($options)
    this._donation($options)

    this._initAccordion($options)

    $('select').each(function () {
        var $this = $(this);
        var options = {'containerCssClass': $this.attr('id') + ' select2'}
        if (!$this.is('[multiple]')) {
//            options.formatResult = function(state) {
//                if (!state.id) return state.text; // optgroup
//                return state.text + 'asdasd ' ;
//            }
        }
        $this.select2(options).change(function () {
            $(this).valid();
        });
    })

    var sidebar = new Sidebar($('#sidebar'), {
        $waypoint: app.$content,
        offsets: {
            screenReduce: 120
        }
    });

}

SupportPage.prototype = {
    _join: function ($options) {
        var $form = $options.filter('.time').find('form');
        new AjaxForm($form)
    },
    _finance: function ($options) {
        var $form = $options.filter('.finance').find('form');
        new AjaxForm($form)
    },
    _media: function ($options) {
        var $form = $options.filter('.media').find('form');
        new AjaxForm($form)
    },
    _fellowship: function ($options) {
        var $form = $options.filter('.fellowship').find('form');
        new AjaxForm($form)
    },
    _partnership: function ($options) {
        var $form = $options.filter('.partners').find('form');
        new AjaxForm($form)
    },
    _physical: function ($options) {
        var $form = $options.filter('.physical').find('form');
        new AjaxForm($form)
    },
    _donation: function ($options) {
        var $section = $options.filter('.donation');
        var $form = $section.find('form.donate');
        $form.submit(function (e) {
            return e.preventDefault()
        })
        var $paypalForm = $section.find('form.paypal')
        var $epayForm = $section.find('form.epay')
        var $project = $form.find('[name="project"]')
        var $type = $form.find('[name="type"]')
        var pay = {
            paypal: function (amount, topic) {
                $paypalForm.find('[name="item_name"]').val(topic)
                $paypalForm.find('[name="amount"]').val(amount / 2)
                $paypalForm.find('[name="submit"]').click()
            },
            epay: function (amount, topic) {
                $epayForm.find('[name="DESCR"]').val(topic)
                $epayForm.find('[name="TOTAL"]').val(amount)
                $epayForm.find('[type="submit"]').click()
            }
        }
        $form.find('button').click(function (e) {
            var topic = $project.data('raw');
            var amount = $(this).data('amount')
            e.preventDefault()
            if (amount > 1000) {
                e.preventDefault()
                e.stopPropagation()
                document.location.hash = 'sponsorship';
                $options.filter('.finance').find('header').click()
                return;
            }
            if ($project.val() != 'any') topic = topic + " за " + $project.find("option:selected").text();
            $form.block({
                message: null,
                overlayCSS: {
                    backgroundColor: 'rgba(245, 245, 245, 0.6)',
                    opacity: 1
                }
            });
            var $veil = $form.find('.blockOverlay');
            AjaxForm._genSpinner().spin($veil.get(0))
            pay[$type.filter(':checked').val()](amount, topic);
        })
    },
    _detectSelected: function ($anchors, $options, $infos) {
        var $target = $anchors.filter(window.location.hash);
        console.log(!$target.length)
        if (!$target.length) {
            $target = $anchors.filter('#time');
            document.location.hash = 'time';
        }
        $options.removeClass('basic-transition-2x')
        $options.find('header p, header h2').removeClass('basic-transition-2x')
        $options.removeClass('active')
        $infos.find('.info-content').addClass('hidden')
        var $targetOption = $target.parent();
        $targetOption.find('.info-content').removeClass('hidden')
        $targetOption.addClass('active')
        $options.addClass('basic-transition-2x')
        $options.find('header p, header h2').addClass('basic-transition-2x')
    },

    _initContentNav: function ($anchors) {
        $('.toc a').click(function (e) {
            e.preventDefault()
            var $target = $anchors.filter($(this).attr('href'));
            var $targetOption = $target.parent();
            $targetOption.find('header').click()
        })
    },

    _initAccordion: function ($options) {
        $options.find('header').each(function () {
            var $header = $(this);
            var $this = $header.parent();
            var $infoNone = $this.find('.info-holder');
            var $infoContent = $this.find('.info-content');
            if ($infoContent.hasClass('hidden')) $infoContent.css('display', 'none').removeClass('hidden')
            var $info = $this.find('.info');
            var hash = $this.find('.adjust').attr('id')
            var $otherOptions = $options.not($this)

            $header.click(function () {
                changeHashWithoutScrolling(hash)
                if ($this.hasClass('active')) return;
                var $activeOption = $otherOptions.filter('.active');
                var $activeInfo = $activeOption.find('.info');
                toggleFixedHeight($activeInfo, true)
                toggleFixedHeight($info, true)
                $activeInfo.animateContentSwitch($activeInfo.find('.info-content'), $activeInfo.find('.info-holder'), {
                    speed: 300,
                    width: false,
                    parallel: true,
                    final: function () {
                        toggleFixedHeight($activeInfo, false)
                        $("html, body").animate({ scrollTop: $this.find('.adjust').offset().top }, {duration: 200});
                    }
                });
                $info.animateContentSwitch($infoNone, $infoContent, {
                    speed: 300,
                    width: false,
                    parallel: true,
                    final: function () {
                        toggleFixedHeight($info, false)
                    }
                });
                $activeOption.removeClass('active');
                $this.addClass('active')
            })
        })
    }
}<|endoftext|>


<commit_before>(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as anonymous module.
        define(['jquery', 'jquery.cookie'], factory);
    } else {
        // Browser globals.
        window.djdt = factory(jQuery);
    }
}(function (jQuery) {
    var $ = jQuery;
    var djdt = {
        handleDragged: false,
        events: {
            ready: []
        },
        isReady: false,
        init: function() {
            $('#djDebug').show();
            var current = null;
            $('#djDebugPanelList li a').live('click', function() {
                if (!this.className) {
                    return false;
                }
                current = $('#djDebug #' + this.className);
                if (current.is(':visible')) {
                    $(document).trigger('close.djDebug');
                    $(this).parent().removeClass('active');
                } else {
                    $('.panelContent').hide(); // Hide any that are already open
                    var inner = current.find('.djDebugPanelContent .scroll').first();
                    if ($(inner).empty()) {
                        var ajax_data = {
                            data: {
                                toolbar_id: $('#djDebug').data('toolbar-id'),
                                panel_id: this.className
                            },
                            type: 'GET',
                            url: $('#djDebug').data('render-panel-url')
                        };
                        $.ajax(ajax_data).done(function(data){
                            inner.html(data);
                        }).fail(function(xhr){
                            var message = '
Back
'+xhr.status+': '+xhr.statusText+'

';
                            $('#djDebugWindow').html(message).show();
                        });
                    }
                    current.show();
                    $('#djDebugToolbar li').removeClass('active');
                    $(this).parent().addClass('active');
                }
                return false;
            });
            $('#djDebug a.djDebugClose').live('click', function() {
                $(document).trigger('close.djDebug');
                $('#djDebugToolbar li').removeClass('active');
                return false;
            });
            $('#djDebug .djDebugPanelButton input[type=checkbox]').live('click', function() {
                $.cookie($(this).attr('data-cookie'), 'off', {
                    path: '/',
                    expires: $(this).prop('checked') ? -1 : 10
                });
            });

            $('#djDebug .remoteCall').live('click', function() {
                var self = $(this);
                var name = self[0].tagName.toLowerCase();
                var ajax_data = {};

                if (name == 'button') {
                    var form = self.parents('form:eq(0)');
                    ajax_data['url'] = self.attr('formaction');

                    if (form.length) {
                        ajax_data['data'] = form.serialize();
                        ajax_data['type'] = form.attr('method') || 'POST';
                    }
                }

                if (name == 'a') {
                    ajax_data['url'] = self.attr('href');
                }

                $.ajax(ajax_data).done(function(data){
                    $('#djDebugWindow').html(data).show();
                }).fail(function(xhr){
                        var message = '
Back
'+xhr.status+': '+xhr.statusText+'

';
                        $('#djDebugWindow').html(message).show();
                });

                $('#djDebugWindow a.djDebugBack').live('click', function() {
                    $(this).parent().parent().hide();
                    return false;
                });

                return false;
            });

            $('#djDebugTemplatePanel a.djTemplateShowContext').live('click', function() {
                djdt.toggle_arrow($(this).children('.toggleArrow'));
                djdt.toggle_content($(this).parent().next());
                return false;
            });
            $('#djDebug a.djDebugToggle').live('click', function(e) {
                e.preventDefault();
                $(this).parent().find('.djDebugCollapsed').toggle();
                $(this).parent().find('.djDebugUncollapsed').toggle();
            });
            $('#djDebug a.djToggleSwitch').live('click', function(e) {
                e.preventDefault();
                var btn = $(this);
                var id = btn.attr('data-toggle-id');
                var open_me = btn.text() == btn.attr('data-toggle-open');
                if (id === '' || !id) {
                    return;
                }
                var name = btn.attr('data-toggle-name');
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugCollapsed').toggle(open_me);
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugUncollapsed').toggle(!open_me);
                $(this).parents('.djDebugPanelContent').find('.djToggleDetails_' + id).each(function(){
                    var $this = $(this);
                    if (open_me) {
                        $this.addClass('djSelected');
                        $this.removeClass('djUnselected');
                        btn.text(btn.attr('data-toggle-close'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    } else {
                        $this.removeClass('djSelected');
                        $this.addClass('djUnselected');
                        btn.text(btn.attr('data-toggle-open'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    }
                });
                return;
            });
            function getSubcalls(row) {
                var id = row.attr('id');
                return $('.djDebugProfileRow[id^="'+id+'_"]');
            }
            function getDirectSubcalls(row) {
                var subcalls = getSubcalls(row);
                var depth = parseInt(row.attr('depth'), 10) + 1;
                return subcalls.filter('[depth='+depth+']');
            }
            $('.djDebugProfileRow .djDebugProfileToggle').live('click', function(){
                var row = $(this).closest('.djDebugProfileRow');
                var subcalls = getSubcalls(row);
                if (subcalls.css('display') == 'none') {
                    getDirectSubcalls(row).show();
                } else {
                    subcalls.hide();
                }
            });
            $('#djHideToolBarButton').click(function() {
                djdt.hide_toolbar(true);
                return false;
            });
            $('#djShowToolBarButton').click(function() {
                if (djdt.handleDragged) {
                    djdt.handleDragged = false;
                } else {
                    djdt.show_toolbar();
                }
                return false;
            });
            var handle = $('#djDebugToolbarHandle');
            $('#djShowToolBarButton').on('mousedown', function (event) {
                var baseY = handle.offset().top - event.pageY;
                $(document).on('mousemove', function (event) {
                    var offset = handle.offset();
                    offset.top = baseY + event.pageY;
                    handle.offset(offset);
                    djdt.handleDragged = true;
                });
                return false;
            });
            $(document).on('mouseup', function () {
                $(document).off('mousemove');
                var top = handle.offset().top;
                $.cookie('djdttop', top, {
                    path: '/',
                    expires: 10
                });
                return false;
            });
            $(document).bind('close.djDebug', function() {
                // If a sub-panel is open, close that
                if ($('#djDebugWindow').is(':visible')) {
                    $('#djDebugWindow').hide();
                    return;
                }
                // If a panel is open, close that
                if ($('.panelContent').is(':visible')) {
                    $('.panelContent').hide();
                    $('#djDebugToolbar li').removeClass('active');
                    return;
                }
                // Otherwise, just minimize the toolbar
                if ($('#djDebugToolbar').is(':visible')) {
                    djdt.hide_toolbar(true);
                    return;
                }
            });
            var handleTop = $.cookie('djdttop');
            if (handleTop) {
                handle.css({top: handleTop + 'px'});
            }
            if ($.cookie('djdt')) {
                djdt.hide_toolbar(false);
            } else {
                djdt.show_toolbar(false);
            }
            $('#djDebug .djDebugHoverable').hover(function(){
                $(this).addClass('djDebugHover');
            }, function(){
                $(this).removeClass('djDebugHover');
            });
            djdt.isReady = true;
            $.each(djdt.events.ready, function(_, callback){
                callback(djdt);
            });
        },
        toggle_content: function(elem) {
            if (elem.is(':visible')) {
                elem.hide();
            } else {
                elem.show();
            }
        },
        close: function() {
            $(document).trigger('close.djDebug');
            return false;
        },
        hide_toolbar: function(setCookie) {
            // close any sub panels
            $('#djDebugWindow').hide();
            // close all panels
            $('.panelContent').hide();
            $('#djDebugToolbar li').removeClass('active');
            // finally close toolbar
            $('#djDebugToolbar').hide('fast');
            $('#djDebugToolbarHandle').show();
            // Unbind keydown
            $(document).unbind('keydown.djDebug');
            if (setCookie) {
                $.cookie('djdt', 'hide', {
                    path: '/',
                    expires: 10
                });
            }
        },
        show_toolbar: function(animate) {
            // Set up keybindings
            $(document).bind('keydown.djDebug', function(e) {
                if (e.keyCode == 27) {
                    djdt.close();
                }
            });
            $('#djDebugToolbarHandle').hide();
            if (animate) {
                $('#djDebugToolbar').show('fast');
            } else {
                $('#djDebugToolbar').show();
            }
            $.cookie('djdt', null, {
                path: '/',
                expires: -1
            });
        },
        toggle_arrow: function(elem) {
            var uarr = String.fromCharCode(0x25b6);
            var darr = String.fromCharCode(0x25bc);
            elem.html(elem.html() == uarr ? darr : uarr);
        },
        ready: function(callback){
            if (djdt.isReady) {
                callback(djdt);
            } else {
                djdt.events.ready.push(callback);
            }
        }
    };

    function renderPerf() {
        // Browser timing remains hidden unless we can successfully access the performance object
        var perf = window.performance || window.msPerformance ||
                   window.webkitPerformance || window.mozPerformance;
        if (perf) {
            var rowCount = 0,
                timingOffset = perf.timing.navigationStart,
                timingEnd = perf.timing.loadEventEnd,
                totalTime = timingEnd - timingOffset;
            function getLeft(stat) {
                return ((perf.timing[stat] - timingOffset) / (totalTime)) * 100.0;
            }
            function getCSSWidth(stat, endStat) {
                var width = ((perf.timing[endStat] - perf.timing[stat]) / (totalTime)) * 100.0;
                // Calculate relative percent (same as sql panel logic)
                width = 100.0 * width / (100.0 - getLeft(stat));
                return (width < 1) ? "2px" : width + "%";
            }
            function addRow(stat, endStat) {
                rowCount++;
                var $row = $('

');
                if (endStat) {
                    // Render a start through end bar
                    $row.html('' + stat.replace('Start', '') + '	' +
                              '

	' +
                              '' + (perf.timing[stat] - timingOffset) + ' (+' + (perf.timing[endStat] - perf.timing[stat]) + ')	');
                } else {
                    // Render a point in time
                     $row.html('' + stat + '	' +
                               '

	' +
                               '' + (perf.timing[stat] - timingOffset) + '	');
                }
                $('#djDebugBrowserTimingTableBody').append($row);
            }

            // This is a reasonably complete and ordered set of timing periods (2 params) and events (1 param)
            addRow('domainLookupStart', 'domainLookupEnd');
            addRow('connectStart', 'connectEnd');
            addRow('requestStart', 'responseEnd'); // There is no requestEnd
            addRow('responseStart', 'responseEnd');
            addRow('domLoading', 'domComplete'); // Spans the events below
            addRow('domInteractive');
            addRow('domContentLoadedEventStart', 'domContentLoadedEventEnd');
            addRow('loadEventStart', 'loadEventEnd');
            $('#djDebugBrowserTiming').css("display", "block");
        }
    }

    $(window).bind('load', function() {
        setTimeout(renderPerf, 0);
    });
    $(document).ready(function() {
        djdt.init();
    });

    return djdt;
}));
<commit_msg>Preserve handle position when the toolbar is shown.<commit_after>(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as anonymous module.
        define(['jquery', 'jquery.cookie'], factory);
    } else {
        // Browser globals.
        window.djdt = factory(jQuery);
    }
}(function (jQuery) {
    var $ = jQuery;
    var djdt = {
        handleDragged: false,
        events: {
            ready: []
        },
        isReady: false,
        init: function() {
            $('#djDebug').show();
            var current = null;
            $('#djDebugPanelList li a').live('click', function() {
                if (!this.className) {
                    return false;
                }
                current = $('#djDebug #' + this.className);
                if (current.is(':visible')) {
                    $(document).trigger('close.djDebug');
                    $(this).parent().removeClass('active');
                } else {
                    $('.panelContent').hide(); // Hide any that are already open
                    var inner = current.find('.djDebugPanelContent .scroll').first();
                    if ($(inner).empty()) {
                        var ajax_data = {
                            data: {
                                toolbar_id: $('#djDebug').data('toolbar-id'),
                                panel_id: this.className
                            },
                            type: 'GET',
                            url: $('#djDebug').data('render-panel-url')
                        };
                        $.ajax(ajax_data).done(function(data){
                            inner.html(data);
                        }).fail(function(xhr){
                            var message = '
Back
'+xhr.status+': '+xhr.statusText+'

';
                            $('#djDebugWindow').html(message).show();
                        });
                    }
                    current.show();
                    $('#djDebugToolbar li').removeClass('active');
                    $(this).parent().addClass('active');
                }
                return false;
            });
            $('#djDebug a.djDebugClose').live('click', function() {
                $(document).trigger('close.djDebug');
                $('#djDebugToolbar li').removeClass('active');
                return false;
            });
            $('#djDebug .djDebugPanelButton input[type=checkbox]').live('click', function() {
                $.cookie($(this).attr('data-cookie'), 'off', {
                    path: '/',
                    expires: $(this).prop('checked') ? -1 : 10
                });
            });

            $('#djDebug .remoteCall').live('click', function() {
                var self = $(this);
                var name = self[0].tagName.toLowerCase();
                var ajax_data = {};

                if (name == 'button') {
                    var form = self.parents('form:eq(0)');
                    ajax_data['url'] = self.attr('formaction');

                    if (form.length) {
                        ajax_data['data'] = form.serialize();
                        ajax_data['type'] = form.attr('method') || 'POST';
                    }
                }

                if (name == 'a') {
                    ajax_data['url'] = self.attr('href');
                }

                $.ajax(ajax_data).done(function(data){
                    $('#djDebugWindow').html(data).show();
                }).fail(function(xhr){
                        var message = '
Back
'+xhr.status+': '+xhr.statusText+'

';
                        $('#djDebugWindow').html(message).show();
                });

                $('#djDebugWindow a.djDebugBack').live('click', function() {
                    $(this).parent().parent().hide();
                    return false;
                });

                return false;
            });

            $('#djDebugTemplatePanel a.djTemplateShowContext').live('click', function() {
                djdt.toggle_arrow($(this).children('.toggleArrow'));
                djdt.toggle_content($(this).parent().next());
                return false;
            });
            $('#djDebug a.djDebugToggle').live('click', function(e) {
                e.preventDefault();
                $(this).parent().find('.djDebugCollapsed').toggle();
                $(this).parent().find('.djDebugUncollapsed').toggle();
            });
            $('#djDebug a.djToggleSwitch').live('click', function(e) {
                e.preventDefault();
                var btn = $(this);
                var id = btn.attr('data-toggle-id');
                var open_me = btn.text() == btn.attr('data-toggle-open');
                if (id === '' || !id) {
                    return;
                }
                var name = btn.attr('data-toggle-name');
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugCollapsed').toggle(open_me);
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugUncollapsed').toggle(!open_me);
                $(this).parents('.djDebugPanelContent').find('.djToggleDetails_' + id).each(function(){
                    var $this = $(this);
                    if (open_me) {
                        $this.addClass('djSelected');
                        $this.removeClass('djUnselected');
                        btn.text(btn.attr('data-toggle-close'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    } else {
                        $this.removeClass('djSelected');
                        $this.addClass('djUnselected');
                        btn.text(btn.attr('data-toggle-open'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    }
                });
                return;
            });
            function getSubcalls(row) {
                var id = row.attr('id');
                return $('.djDebugProfileRow[id^="'+id+'_"]');
            }
            function getDirectSubcalls(row) {
                var subcalls = getSubcalls(row);
                var depth = parseInt(row.attr('depth'), 10) + 1;
                return subcalls.filter('[depth='+depth+']');
            }
            $('.djDebugProfileRow .djDebugProfileToggle').live('click', function(){
                var row = $(this).closest('.djDebugProfileRow');
                var subcalls = getSubcalls(row);
                if (subcalls.css('display') == 'none') {
                    getDirectSubcalls(row).show();
                } else {
                    subcalls.hide();
                }
            });
            $('#djHideToolBarButton').click(function() {
                djdt.hide_toolbar(true);
                return false;
            });
            $('#djShowToolBarButton').click(function() {
                if (!djdt.handleDragged) {
                    djdt.show_toolbar();
                }
                return false;
            });
            var handle = $('#djDebugToolbarHandle');
            $('#djShowToolBarButton').on('mousedown', function (event) {
                var baseY = handle.offset().top - event.pageY;
                $(document).on('mousemove', function (event) {
                    var offset = handle.offset();
                    offset.top = baseY + event.pageY;
                    handle.offset(offset);
                    djdt.handleDragged = true;
                });
                return false;
            });
            $(document).on('mouseup', function () {
                $(document).off('mousemove');
                if (djdt.handleDragged) {
                    var top = handle.offset().top;
                    $.cookie('djdttop', top, {
                        path: '/',
                        expires: 10
                    });
                    setTimeout(function () {
                        djdt.handleDragged = false;
                    }, 10);
                }
                return false;
            });
            $(document).bind('close.djDebug', function() {
                // If a sub-panel is open, close that
                if ($('#djDebugWindow').is(':visible')) {
                    $('#djDebugWindow').hide();
                    return;
                }
                // If a panel is open, close that
                if ($('.panelContent').is(':visible')) {
                    $('.panelContent').hide();
                    $('#djDebugToolbar li').removeClass('active');
                    return;
                }
                // Otherwise, just minimize the toolbar
                if ($('#djDebugToolbar').is(':visible')) {
                    djdt.hide_toolbar(true);
                    return;
                }
            });
            if ($.cookie('djdt')) {
                djdt.hide_toolbar(false);
            } else {
                djdt.show_toolbar(false);
            }
            $('#djDebug .djDebugHoverable').hover(function(){
                $(this).addClass('djDebugHover');
            }, function(){
                $(this).removeClass('djDebugHover');
            });
            djdt.isReady = true;
            $.each(djdt.events.ready, function(_, callback){
                callback(djdt);
            });
        },
        toggle_content: function(elem) {
            if (elem.is(':visible')) {
                elem.hide();
            } else {
                elem.show();
            }
        },
        close: function() {
            $(document).trigger('close.djDebug');
            return false;
        },
        hide_toolbar: function(setCookie) {
            // close any sub panels
            $('#djDebugWindow').hide();
            // close all panels
            $('.panelContent').hide();
            $('#djDebugToolbar li').removeClass('active');
            // finally close toolbar
            $('#djDebugToolbar').hide('fast');
            $('#djDebugToolbarHandle').show();
            // set handle position
            var handleTop = $.cookie('djdttop');
            if (handleTop) {
                $('#djDebugToolbarHandle').css({top: handleTop + 'px'});
            }
            // Unbind keydown
            $(document).unbind('keydown.djDebug');
            if (setCookie) {
                $.cookie('djdt', 'hide', {
                    path: '/',
                    expires: 10
                });
            }
        },
        show_toolbar: function(animate) {
            // Set up keybindings
            $(document).bind('keydown.djDebug', function(e) {
                if (e.keyCode == 27) {
                    djdt.close();
                }
            });
            $('#djDebugToolbarHandle').hide();
            if (animate) {
                $('#djDebugToolbar').show('fast');
            } else {
                $('#djDebugToolbar').show();
            }
            $.cookie('djdt', null, {
                path: '/',
                expires: -1
            });
        },
        toggle_arrow: function(elem) {
            var uarr = String.fromCharCode(0x25b6);
            var darr = String.fromCharCode(0x25bc);
            elem.html(elem.html() == uarr ? darr : uarr);
        },
        ready: function(callback){
            if (djdt.isReady) {
                callback(djdt);
            } else {
                djdt.events.ready.push(callback);
            }
        }
    };

    function renderPerf() {
        // Browser timing remains hidden unless we can successfully access the performance object
        var perf = window.performance || window.msPerformance ||
                   window.webkitPerformance || window.mozPerformance;
        if (perf) {
            var rowCount = 0,
                timingOffset = perf.timing.navigationStart,
                timingEnd = perf.timing.loadEventEnd,
                totalTime = timingEnd - timingOffset;
            function getLeft(stat) {
                return ((perf.timing[stat] - timingOffset) / (totalTime)) * 100.0;
            }
            function getCSSWidth(stat, endStat) {
                var width = ((perf.timing[endStat] - perf.timing[stat]) / (totalTime)) * 100.0;
                // Calculate relative percent (same as sql panel logic)
                width = 100.0 * width / (100.0 - getLeft(stat));
                return (width < 1) ? "2px" : width + "%";
            }
            function addRow(stat, endStat) {
                rowCount++;
                var $row = $('

');
                if (endStat) {
                    // Render a start through end bar
                    $row.html('' + stat.replace('Start', '') + '	' +
                              '

	' +
                              '' + (perf.timing[stat] - timingOffset) + ' (+' + (perf.timing[endStat] - perf.timing[stat]) + ')	');
                } else {
                    // Render a point in time
                     $row.html('' + stat + '	' +
                               '

	' +
                               '' + (perf.timing[stat] - timingOffset) + '	');
                }
                $('#djDebugBrowserTimingTableBody').append($row);
            }

            // This is a reasonably complete and ordered set of timing periods (2 params) and events (1 param)
            addRow('domainLookupStart', 'domainLookupEnd');
            addRow('connectStart', 'connectEnd');
            addRow('requestStart', 'responseEnd'); // There is no requestEnd
            addRow('responseStart', 'responseEnd');
            addRow('domLoading', 'domComplete'); // Spans the events below
            addRow('domInteractive');
            addRow('domContentLoadedEventStart', 'domContentLoadedEventEnd');
            addRow('loadEventStart', 'loadEventEnd');
            $('#djDebugBrowserTiming').css("display", "block");
        }
    }

    $(window).bind('load', function() {
        setTimeout(renderPerf, 0);
    });
    $(document).ready(function() {
        djdt.init();
    });

    return djdt;
}));
<|endoftext|>


<commit_before>(function ($, publicAPI) {
    var onKeyDown = function(event) {
        if (event.keyCode == 27) {
            djdt.hide_one_level();
        }
    };

    var djdt = {
        handleDragged: false,
        events: {
            ready: []
        },
        isReady: false,
        init: function() {
            $('#djDebug').show();
            $('#djDebugPanelList').on('click', 'li a', function(event) {
                event.preventDefault();
                if (!this.className) {
                    return;
                }
                var current = $('#djDebug #' + this.className);
                if (current.is(':visible')) {
                    djdt.hide_panels();
                } else {
                    djdt.hide_panels();

                    current.show();
                    $(this).parent().addClass('djdt-active');

                    var inner = current.find('.djDebugPanelContent .djdt-scroll'),
                        store_id = $('#djDebug').data('store-id');
                    if (store_id && inner.children().length === 0) {
                        var ajax_data = {
                            data: {
                                store_id: store_id,
                                panel_id: this.className
                            },
                            type: 'GET',
                            url: $('#djDebug').data('render-panel-url')
                        };
                        $.ajax(ajax_data).done(function(data){
                            inner.prev().remove();  // Remove AJAX loader
                            inner.html(data);
                        }).fail(function(xhr){
                            var message = '

'+xhr.status+': '+xhr.statusText+'

';
                            $('#djDebugWindow').html(message).show();
                        });
                    }
                }
            });
            $('#djDebug').on('click', 'a.djDebugClose', function(event) {
                event.preventDefault();
                djdt.hide_one_level();
            });
            $('#djDebug').on('click', '.djDebugPanelButton input[type=checkbox]', function() {
                djdt.cookie.set($(this).attr('data-cookie'), $(this).prop('checked') ? 'on' : 'off', {
                    path: '/',
                    expires: 10
                });
            });

            // Used by the SQL and template panels
            $('#djDebug').on('click', '.remoteCall', function(event) {
                event.preventDefault();

                var self = $(this);
                var name = self[0].tagName.toLowerCase();
                var ajax_data = {};

                if (name == 'button') {
                    var form = self.parents('form:eq(0)');
                    ajax_data.url = self.attr('formaction');

                    if (form.length) {
                        ajax_data.data = form.serialize();
                        ajax_data.type = form.attr('method') || 'POST';
                    }
                }

                if (name == 'a') {
                    ajax_data.url = self.attr('href');
                }

                $.ajax(ajax_data).done(function(data){
                    $('#djDebugWindow').html(data).show();
                }).fail(function(xhr){
                        var message = '

'+xhr.status+': '+xhr.statusText+'

';
                        $('#djDebugWindow').html(message).show();
                });
            });

            // Used by the cache, profiling and SQL panels
            $('#djDebug').on('click', 'a.djToggleSwitch', function(event) {
                event.preventDefault();
                var btn = $(this);
                var id = btn.attr('data-toggle-id');
                var open_me = btn.text() == btn.attr('data-toggle-open');
                if (id === '' || !id) {
                    return;
                }
                var name = btn.attr('data-toggle-name');
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugCollapsed').toggle(open_me);
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugUncollapsed').toggle(!open_me);
                $(this).parents('.djDebugPanelContent').find('.djToggleDetails_' + id).each(function(){
                    var $this = $(this);
                    if (open_me) {
                        $this.addClass('djSelected');
                        $this.removeClass('djUnselected');
                        btn.text(btn.attr('data-toggle-close'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    } else {
                        $this.removeClass('djSelected');
                        $this.addClass('djUnselected');
                        btn.text(btn.attr('data-toggle-open'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    }
                });
            });

            $('#djHideToolBarButton').on('click', function(event) {
                event.preventDefault();
                djdt.hide_toolbar(true);
            });
            $('#djShowToolBarButton').on('click', function(event) {
                event.preventDefault();
                if (!djdt.handleDragged) {
                    djdt.show_toolbar();
                }
            });
            var startPageY, baseY, windowHeight;
            var handle = $('#djDebugToolbarHandle');
            var onMouseMove = function(event) {
                // Chrome can send spurious mousemove events, so don't do anything unless the
                // cursor really moved.  Otherwise, it will be impossible to expand the toolbar
                // due to djdt.handleDragged being set to true.
                if (djdt.handleDragged || event.pageY != startPageY) {
                    var top = baseY + event.clientY;

                    if (top < 0) {
                        top = 0;
                    } else if (top + handle.height() > windowHeight) {
                        top = windowHeight - handle.height();
                    }

                    handle.css({top: top});
                    djdt.handleDragged = true;
                }
            };
            $('#djShowToolBarButton').on('mousedown', function (event) {
                event.preventDefault();
                startPageY = event.pageY;
                baseY = handle.offset().top - startPageY;
                windowHeight = $(window).height();
                $(document).on('mousemove.djDebug', onMouseMove);
            });
            $(document).on('mouseup', function (event) {
                $(document).off('mousemove.djDebug');
                if (djdt.handleDragged) {
                    event.preventDefault();
                    var top = handle.offset().top - window.pageYOffset;
                    djdt.cookie.set('djdttop', top, {
                        path: '/',
                        expires: 10
                    });
                    setTimeout(function () {
                        djdt.handleDragged = false;
                    }, 10);
                }
            });
            $(document).on('close.djDebug', function() {
                djdt.hide_one_level();
            });
            if (djdt.cookie.get('djdt') == 'hide') {
                djdt.hide_toolbar(false);
            } else {
                djdt.show_toolbar(false);
            }
            djdt.isReady = true;
            $.each(djdt.events.ready, function(_, callback){
                callback(djdt);
            });
        },
        hide_panels: function() {
            $('#djDebugWindow').hide();
            $('.djdt-panelContent').hide();
            $('#djDebugToolbar li').removeClass('djdt-active');
        },
        hide_toolbar: function(setCookie) {
            djdt.hide_panels();
            $('#djDebugToolbar').hide('fast');

            var handle = $('#djDebugToolbarHandle');
            handle.show();
            // set handle position
            var handleTop = djdt.cookie.get('djdttop');
            if (handleTop) {
                handleTop = Math.min(handleTop, window.innerHeight - handle.outerHeight() - 10);
                handle.css({top: handleTop + 'px'});
            }

            // Unbind keydown
            $(document).off('keydown.djDebug');

            if (setCookie) {
                djdt.cookie.set('djdt', 'hide', {
                    path: '/',
                    expires: 10
                });
            }
        },
        hide_one_level: function() {
            if ($('#djDebugWindow').is(':visible')) {
                $('#djDebugWindow').hide();
            } else if ($('.djdt-panelContent').is(':visible')) {
                djdt.hide_panels();
            } else {
                djdt.hide_toolbar(true);
            }
        },
        show_toolbar: function(animate) {
            // Set up keybindings
            $(document).on('keydown.djDebug', onKeyDown);
            $('#djDebugToolbarHandle').hide();
            if (animate) {
                $('#djDebugToolbar').show('fast');
            } else {
                $('#djDebugToolbar').show();
            }
            djdt.cookie.set('djdt', 'show', {
                path: '/',
                expires: 10
            });
        },
        ready: function(callback){
            if (djdt.isReady) {
                callback(djdt);
            } else {
                djdt.events.ready.push(callback);
            }
        },
        cookie: {
            get: function(key){
                if (document.cookie.indexOf(key) === -1) return null;

                var cookieArray = document.cookie.split('; '),
                    cookies = {};

                cookieArray.forEach(function(e){
                    var parts = e.split('=');
                    cookies[ parts[0] ] = parts[1];
                });

                return cookies[ key ];
            },
            set: function(key, value, options){
                options = options || {};

                if (typeof options.expires === 'number') {
                    var days = options.expires, t = options.expires = new Date();
                    t.setDate(t.getDate() + days);
                }

                document.cookie = [
                    encodeURIComponent(key) + '=' + String(value),
                    options.expires ? '; expires=' + options.expires.toUTCString() : '',
                    options.path    ? '; path=' + options.path : '',
                    options.domain  ? '; domain=' + options.domain : '',
                    options.secure  ? '; secure' : ''
                ].join('');

                return value;
            }
        },
        applyStyle: function(name) {
            $('#djDebug [data-' + name + ']').each(function() {
                var css = {};
                css[name] = $(this).data(name);
                $(this).css(css);
            });
        }
    };
    $.extend(publicAPI, {
        show_toolbar: djdt.show_toolbar,
        hide_toolbar: djdt.hide_toolbar,
        close: djdt.hide_one_level,
        cookie: djdt.cookie,
        applyStyle: djdt.applyStyle
    });
    $(document).ready(djdt.init);
})(djdt.jQuery, djdt);
<commit_msg>port event handling<commit_after>(function ($, publicAPI) {
    var $$ = {
        on: function(root, eventName, selector, fn) {
            root.addEventListener(eventName, function(event) {
                var target = event.target.closest(selector);
                if (root.contains(target)) {
                    fn.call(target, event);
                }
            });
        },
    };

    var onKeyDown = function(event) {
        if (event.keyCode == 27) {
            djdt.hide_one_level();
        }
    };

    var djdt = {
        handleDragged: false,
        events: {
            ready: []
        },
        isReady: false,
        init: function() {
            var djDebug = document.querySelector('#djDebug');
            djDebug.classList.remove('djdt-hidden');
            $$.on(djDebug.querySelector('#djDebugPanelList'), 'click', 'li a', function(event) {
                event.preventDefault();
                if (!this.className) {
                    return;
                }
                var current = $('#djDebug #' + this.className);
                if (current.is(':visible')) {
                    djdt.hide_panels();
                } else {
                    djdt.hide_panels();

                    current.show();
                    $(this).parent().addClass('djdt-active');

                    var inner = current.find('.djDebugPanelContent .djdt-scroll'),
                        store_id = $('#djDebug').data('store-id');
                    if (store_id && inner.children().length === 0) {
                        var ajax_data = {
                            data: {
                                store_id: store_id,
                                panel_id: this.className
                            },
                            type: 'GET',
                            url: $('#djDebug').data('render-panel-url')
                        };
                        $.ajax(ajax_data).done(function(data){
                            inner.prev().remove();  // Remove AJAX loader
                            inner.html(data);
                        }).fail(function(xhr){
                            var message = '

'+xhr.status+': '+xhr.statusText+'

';
                            $('#djDebugWindow').html(message).show();
                        });
                    }
                }
            });
            $$.on(djDebug, 'click', 'a.djDebugClose', function(event) {
                event.preventDefault();
                djdt.hide_one_level();
            });
            $$.on(djDebug, 'click', '.djDebugPanelButton input[type=checkbox]', function() {
                djdt.cookie.set($(this).attr('data-cookie'), $(this).prop('checked') ? 'on' : 'off', {
                    path: '/',
                    expires: 10
                });
            });

            // Used by the SQL and template panels
            $$.on(djDebug, 'click', '.remoteCall', function(event) {
                event.preventDefault();

                var self = $(this);
                var name = self[0].tagName.toLowerCase();
                var ajax_data = {};

                if (name == 'button') {
                    var form = self.parents('form:eq(0)');
                    ajax_data.url = self.attr('formaction');

                    if (form.length) {
                        ajax_data.data = form.serialize();
                        ajax_data.type = form.attr('method') || 'POST';
                    }
                }

                if (name == 'a') {
                    ajax_data.url = self.attr('href');
                }

                $.ajax(ajax_data).done(function(data){
                    $('#djDebugWindow').html(data).show();
                }).fail(function(xhr){
                        var message = '

'+xhr.status+': '+xhr.statusText+'

';
                        $('#djDebugWindow').html(message).show();
                });
            });

            // Used by the cache, profiling and SQL panels
            $$.on(djDebug, 'click', 'a.djToggleSwitch', function(event) {
                event.preventDefault();
                var btn = $(this);
                var id = btn.attr('data-toggle-id');
                var open_me = btn.text() == btn.attr('data-toggle-open');
                if (id === '' || !id) {
                    return;
                }
                var name = btn.attr('data-toggle-name');
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugCollapsed').toggle(open_me);
                btn.parents('.djDebugPanelContent').find('#' + name + '_' + id).find('.djDebugUncollapsed').toggle(!open_me);
                $(this).parents('.djDebugPanelContent').find('.djToggleDetails_' + id).each(function(){
                    var $this = $(this);
                    if (open_me) {
                        $this.addClass('djSelected');
                        $this.removeClass('djUnselected');
                        btn.text(btn.attr('data-toggle-close'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    } else {
                        $this.removeClass('djSelected');
                        $this.addClass('djUnselected');
                        btn.text(btn.attr('data-toggle-open'));
                        $this.find('.djToggleSwitch').text(btn.text());
                    }
                });
            });

            djDebug.querySelector('#djHideToolBarButton').addEventListener('click', function(event) {
                event.preventDefault();
                djdt.hide_toolbar(true);
            });
            djDebug.querySelector('#djShowToolBarButton').addEventListener('click', function(event) {
                event.preventDefault();
                if (!djdt.handleDragged) {
                    djdt.show_toolbar();
                }
            });
            var startPageY, baseY, windowHeight;
            var handle = $('#djDebugToolbarHandle');
            var onMouseMove = function(event) {
                // Chrome can send spurious mousemove events, so don't do anything unless the
                // cursor really moved.  Otherwise, it will be impossible to expand the toolbar
                // due to djdt.handleDragged being set to true.
                if (djdt.handleDragged || event.pageY != startPageY) {
                    var top = baseY + event.clientY;

                    if (top < 0) {
                        top = 0;
                    } else if (top + handle.height() > windowHeight) {
                        top = windowHeight - handle.height();
                    }

                    handle.css({top: top});
                    djdt.handleDragged = true;
                }
            };
            djDebug.querySelector('#djShowToolBarButton').addEventListener('mousedown', function(event) {
                event.preventDefault();
                startPageY = event.pageY;
                baseY = handle.offset().top - startPageY;
                windowHeight = $(window).height();
                document.addEventListener('mousemove', onMouseMove);
            });
            document.addEventListener('mouseup', function(event) {
                document.removeEventListener('mousemove', onMouseMove);
                if (djdt.handleDragged) {
                    event.preventDefault();
                    var top = handle.offset().top - window.pageYOffset;
                    djdt.cookie.set('djdttop', top, {
                        path: '/',
                        expires: 10
                    });
                    setTimeout(function () {
                        djdt.handleDragged = false;
                    }, 10);
                }
            });
            if (djdt.cookie.get('djdt') == 'hide') {
                djdt.hide_toolbar(false);
            } else {
                djdt.show_toolbar(false);
            }
            djdt.isReady = true;
            $.each(djdt.events.ready, function(_, callback){
                callback(djdt);
            });
        },
        hide_panels: function() {
            $('#djDebugWindow').hide();
            $('.djdt-panelContent').hide();
            $('#djDebugToolbar li').removeClass('djdt-active');
        },
        hide_toolbar: function(setCookie) {
            djdt.hide_panels();
            $('#djDebugToolbar').hide('fast');

            var handle = $('#djDebugToolbarHandle');
            handle.show();
            // set handle position
            var handleTop = djdt.cookie.get('djdttop');
            if (handleTop) {
                handleTop = Math.min(handleTop, window.innerHeight - handle.outerHeight() - 10);
                handle.css({top: handleTop + 'px'});
            }

            // Unbind keydown
            document.removeEventListener('keydown', onKeyDown);

            if (setCookie) {
                djdt.cookie.set('djdt', 'hide', {
                    path: '/',
                    expires: 10
                });
            }
        },
        hide_one_level: function() {
            if ($('#djDebugWindow').is(':visible')) {
                $('#djDebugWindow').hide();
            } else if ($('.djdt-panelContent').is(':visible')) {
                djdt.hide_panels();
            } else {
                djdt.hide_toolbar(true);
            }
        },
        show_toolbar: function(animate) {
            // Set up keybindings
            document.addEventListener('keydown', onKeyDown);
            $('#djDebugToolbarHandle').hide();
            if (animate) {
                $('#djDebugToolbar').show('fast');
            } else {
                $('#djDebugToolbar').show();
            }
            djdt.cookie.set('djdt', 'show', {
                path: '/',
                expires: 10
            });
        },
        ready: function(callback){
            if (djdt.isReady) {
                callback(djdt);
            } else {
                djdt.events.ready.push(callback);
            }
        },
        cookie: {
            get: function(key){
                if (document.cookie.indexOf(key) === -1) return null;

                var cookieArray = document.cookie.split('; '),
                    cookies = {};

                cookieArray.forEach(function(e){
                    var parts = e.split('=');
                    cookies[ parts[0] ] = parts[1];
                });

                return cookies[ key ];
            },
            set: function(key, value, options){
                options = options || {};

                if (typeof options.expires === 'number') {
                    var days = options.expires, t = options.expires = new Date();
                    t.setDate(t.getDate() + days);
                }

                document.cookie = [
                    encodeURIComponent(key) + '=' + String(value),
                    options.expires ? '; expires=' + options.expires.toUTCString() : '',
                    options.path    ? '; path=' + options.path : '',
                    options.domain  ? '; domain=' + options.domain : '',
                    options.secure  ? '; secure' : ''
                ].join('');

                return value;
            }
        },
        applyStyle: function(name) {
            $('#djDebug [data-' + name + ']').each(function() {
                var css = {};
                css[name] = $(this).data(name);
                $(this).css(css);
            });
        }
    };
    $.extend(publicAPI, {
        show_toolbar: djdt.show_toolbar,
        hide_toolbar: djdt.hide_toolbar,
        close: djdt.hide_one_level,
        cookie: djdt.cookie,
        applyStyle: djdt.applyStyle
    });
    $(document).ready(djdt.init);
})(djdt.jQuery, djdt);
<|endoftext|>


<commit_before>/*
eslint no-shadow: ["error", { "allow": ["$scope"] }]
*/
/*
eslint no-underscore-dangle: ["error", { "allow": ["_id",] }]
*/

const ideaControl = function ideaControl($scope, $mdDialog, $mdToast, db) {
  $scope.isShown = true;
  $scope.current = undefined;

  $scope.remove = (idea) => {
    db.removeIdea(idea, (err) => {
      if (!err) {
        $mdToast.show(
          $mdToast.simple()
          .textContent('Idea deleted.')
          .position('bottom start')
          .hideDelay(1000)
        );
      }
    });
  };

  function EditDialogController($scope, idea) {
    $scope.idea = idea;
    $scope.cancel = function cancel() {
      $mdDialog.cancel();
    };
    $scope.update = function update(newIdea) {
      if (newIdea) {
        $mdDialog.hide(newIdea);
      }
    };
  }
  $scope.edit = (ev, cur) => {
    $mdDialog.show({
      controller: EditDialogController,
      locals: {
        idea: cur.idea,
      },
      templateUrl: 'app/components/ideas/templates/editIdeaDialog.html',
      parent: angular.element(document.body),
      targetEvent: ev,
      clickOutsideToClose: true,
    })
    .then((idea) => {
      db.editIdea(cur._id, idea, (err) => {
        if (!err) {
          db.findIdeas((ideas) => {
            $scope.ideas = ideas;
            $scope.$apply();
          });
          $mdToast.show(
            $mdToast.simple()
            .textContent('Idea edited.')
            .position('bottom start')
            .hideDelay(1000)
          );
        }
      });
    });
  };

  function SplitDialogController($scope) {
    $scope.tasks = [];
    $scope.numOfTasks = 1;
    $scope.cancel = function cancel() {
      $mdDialog.cancel();
    };
    $scope.split = function update(splittedTasks, numOfTasks) {
      if (splittedTasks.length === numOfTasks) {
        $mdDialog.hide(splittedTasks);
      }
    };
  }
  $scope.split = (ev) => {
    $mdDialog.show({
      controller: SplitDialogController,
      templateUrl: 'app/components/ideas/templates/splitIdeaDialog.html',
      parent: angular.element(document.body),
      targetEvent: ev,
      clickOutsideToClose: true,
    })
    .then((tasks) => {
      // db.editIdea(cur._id, idea, (err) => {
      //   if (!err) {
      //     db.findIdeas((ideas) => {
      //       $scope.ideas = ideas;
      //       $scope.$apply();
      //     });
      //     $mdToast.show(
      //       $mdToast.simple()
      //       .textContent('Idea edited.')
      //       .position('bottom start')
      //       .hideDelay(1000)
      //     );
      //   }
      // });
    });
  };
  $scope.$on('Update ideas', () => {
    db.findIdeas((ideas) => {
      $scope.ideas = ideas;
    });
  });
  db.findIdeas((ideas) => {
    $scope.ideas = ideas;
    $scope.$apply();
  });
};

angular.module('MainApp')
  .controller('IdeaControl', ideaControl);
<commit_msg>Add splitted tasks into database<commit_after>/*
eslint no-shadow: ["error", { "allow": ["$scope"] }]
*/
/*
eslint no-underscore-dangle: ["error", { "allow": ["_id",] }]
*/

const ideaControl = function ideaControl($scope, $rootScope, $mdDialog, $mdToast, db) {
  $scope.isShown = true;
  $scope.current = undefined;

  $scope.remove = (idea) => {
    db.removeIdea(idea, (err) => {
      if (!err) {
        $mdToast.show(
          $mdToast.simple()
          .textContent('Idea deleted.')
          .position('bottom start')
          .hideDelay(1000)
        );
      }
    });
  };

  function EditDialogController($scope, idea) {
    $scope.idea = idea;
    $scope.cancel = function cancel() {
      $mdDialog.cancel();
    };
    $scope.update = function update(newIdea) {
      if (newIdea) {
        $mdDialog.hide(newIdea);
      }
    };
  }
  $scope.edit = (ev, cur) => {
    $mdDialog.show({
      controller: EditDialogController,
      locals: {
        idea: cur.idea,
      },
      templateUrl: 'app/components/ideas/templates/editIdeaDialog.html',
      parent: angular.element(document.body),
      targetEvent: ev,
      clickOutsideToClose: true,
    })
    .then((idea) => {
      db.editIdea(cur._id, idea, (err) => {
        if (!err) {
          db.findIdeas((ideas) => {
            $scope.ideas = ideas;
            $scope.$apply();
          });
          $mdToast.show(
            $mdToast.simple()
            .textContent('Idea edited.')
            .position('bottom start')
            .hideDelay(1000)
          );
        }
      });
    });
  };

  function SplitDialogController($scope) {
    $scope.tasks = [];
    $scope.numOfTasks = 1;
    $scope.cancel = function cancel() {
      $mdDialog.cancel();
    };
    $scope.split = function update(splittedTasks, numOfTasks) {
      if (splittedTasks.length === numOfTasks) {
        $mdDialog.hide(splittedTasks);
      }
    };
  }
  $scope.split = (ev) => {
    $mdDialog.show({
      controller: SplitDialogController,
      templateUrl: 'app/components/ideas/templates/splitIdeaDialog.html',
      parent: angular.element(document.body),
      targetEvent: ev,
      clickOutsideToClose: true,
    })
    .then((tasks) => {
      let hasErr = false;
      tasks.forEach((task) => {
        db.insert(task, (err) => {
          if (err) {
            hasErr = true;
          }
        });
      });
      if (!hasErr) {
        $rootScope.$broadcast('Update tasks');
        $mdToast.show(
          $mdToast.simple()
          .textContent('Idea splitted into tasks.')
          .position('bottom start')
        );
      }
    });
  };
  $scope.$on('Update ideas', () => {
    db.findIdeas((ideas) => {
      $scope.ideas = ideas;
    });
  });
  db.findIdeas((ideas) => {
    $scope.ideas = ideas;
    $scope.$apply();
  });
};

angular.module('MainApp')
  .controller('IdeaControl', ideaControl);
<|endoftext|>


<commit_before>/**
 * dist-min.conf.js
 * Author: H.Alper Tuna <halpertuna@gmail.com>
 * Date: 18.08.2016
 */

/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
const webpack = require('webpack');
let config = require('./dist.conf');

// Webpack Production Settings - Minified
config = Object.assign(config, {
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
    }),
  ],
});
config.output.filename = 'react-metismenu.min.js';

module.exports = config;
<commit_msg>Updated webpack configuration.<commit_after>/**
 * dist-min.conf.js
 * Author: H.Alper Tuna <halpertuna@gmail.com>
 * Date: 18.08.2016
 */

/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */

const webpack = require('webpack');
const config = require('./dist.conf');

// Webpack Production Settings - Minified
module.exports = Object.assign(config, {
  output: Object.assign(config.output, {
    filename: 'react-metismenu.min.js',
  }),
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
    }),
  ],
});
<|endoftext|>


<commit_before>import cheerio from 'cheerio';

export default function create(DOM) {
  class ParseTable {
    $ = undefined
    length = 0
    trips = 0
    station = 'unknown'
    serverTime = '00:00'
    subways = []

    constructor() {
      this.$ = cheerio.load(DOM);
      // let tramLines = ['20','17','12','18','16','19','15','25','21','22','28','27'];

      this.length = this.$('tr').length;
      this.trips = this.$('.rowOdd, .rowEven').length;
      this.station = this.$('.headerStationColumn').text();
      this.serverTime = this.$('.serverTimeColumn').text();
      this.subways = this.findByType('ubahn');
    }

    findByType(type) {
      let lines = [];
      const availableTypes = ['ubahn', 'bus', 'sbahn', 'tram'];
      if(availableTypes.indexOf(type) < 0) throw `error: ${type} is not available as mvg type`;

      const that = this;

      this.$('.rowOdd, .rowEven').each(function() {
        lines.push({
          route: that.$(this).find('.lineColumn').text(),
          station: that.cleanStationTitle(that.$(this).find('.stationColumn').text()),
          arrivingIn: that.$(this).find('.inMinColumn').text()
        });
      });

      return [{
        route: 'U6',
        station: 'Garching-Forschungszentrum',
        arrivingIn: 0
      }];
    }

    cleanStationTitle(title) {
      return title.replace(/^\s+|\s+$/g, '');
    }
  }

  return new ParseTable();
}
<commit_msg>update namings and replace dummy-code with live-data<commit_after>import cheerio from 'cheerio';

export default function create(DOM) {
  class ParseTable {
    $ = undefined
    length = 0
    trips = 0
    station = 'unknown'
    serverTime = '00:00'
    departures = []

    constructor() {
      this.$ = cheerio.load(DOM);
      // let tramLines = ['20','17','12','18','16','19','15','25','21','22','28','27'];

      this.length = this.$('tr').length;
      this.trips = this.$('.rowOdd, .rowEven').length;
      this.station = this.$('.headerStationColumn').text();
      this.serverTime = this.$('.serverTimeColumn').text();
      this.departures = this.findByType('ubahn');
    }

    findByType(type) {
      let lines = [];
      const availableTypes = ['ubahn', 'bus', 'sbahn', 'tram'];
      if(availableTypes.indexOf(type) < 0) throw `error: ${type} is not available as mvg type`;

      const that = this;

      this.$('.rowOdd, .rowEven').each(function() {
        lines.push({
          route: that.$(this).find('.lineColumn').text(),
          station: that.cleanStationTitle(that.$(this).find('.stationColumn').text()),
          arrivingIn: that.$(this).find('.inMinColumn').text()
        });
      });

      return lines;
    }

    cleanStationTitle(title) {
      return title.replace(/^\s+|\s+$/g, '');
    }
  }

  return new ParseTable();
}
<|endoftext|>


<commit_before>var dns = require("dns");
const options = {
  family: 6,
  hints: dns.ADDRCONNFIG | dns.V4Mapped
  };

var nsLookup = function(domain, timeout, callback) {
    var Called = false;
    var doCallback = function(err, domains) {
        if (Called) {
            return;
        }
        Called = true;
        callback(err, domains);
    };

    /*setTimeout(function() {
        doCallback(new Error, null);
    }, timeout);*/ //It is unsafe

    dns.resolveNs(domain, doCallback);
};

nsLookup("rocket.chat", 1000, function(err, addresses) {
    //console.log("Reults for rocket.chat, timeout 1000:");
    if (err) {
        //console.log("Err: " + err);
        return;
    }

});

dns.lookupService("127.0.0.1", 22, function(err, hostname, service)  {
  //console.log(hostname, service);
  // Prints: localhost ssh
});
dns.resolve4("localhost", function(err, rec) {
  if (err) {
    //console.log(chalk.red('* dns.resolve4(\'%s\'): err: %j'), HOSTNAME, err);
    return;
  }
  //console.log('* dns.resolve4(\'%s\')', rec);
});

dns.lookup("rocket.chat",options,function(err,address,family) {
  console.log("address: %j family: IPv%s", address, family);
  });

options.all = true;
dns.lookup("rocket.chat",options,function(err,address){
  console.log("addresses: %j", address);
  });

//more upgrades and improvements will come in the code
//to implement mapping
//DNS module for nodejs is used here...
//127.0.0.1 will be replaced by valid ip<commit_msg>removed console.log<commit_after>var dns = require("dns");
const options = {
  family: 6,
  hints: dns.ADDRCONNFIG | dns.V4Mapped
  };

var nsLookup = function(domain, timeout, callback) {
    var Called = false;
    var doCallback = function(err, domains) {
        if (Called) {
            return;
        }
        Called = true;
        callback(err, domains);
    };

    /*setTimeout(function() {
        doCallback(new Error, null);
    }, timeout);*/ //It is unsafe

    dns.resolveNs(domain, doCallback);
};

nsLookup("rocket.chat", 1000, function(err, addresses) {
    //console.log("Reults for rocket.chat, timeout 1000:");
    if (err) {
        //console.log("Err: " + err);
        return;
    }

});

dns.lookupService("127.0.0.1", 22, function(err, hostname, service)  {
  //console.log(hostname, service);
  // Prints: localhost ssh
});
dns.resolve4("localhost", function(err, rec) {
  if (err) {
    //console.log(chalk.red('* dns.resolve4(\'%s\'): err: %j'), HOSTNAME, err);
    return;
  }
  //console.log('* dns.resolve4(\'%s\')', rec);
});

dns.lookup("rocket.chat",options,function(err,address,family) {
  //console.log("address: %j family: IPv%s", address, family);
  });

options.all = true;
dns.lookup("rocket.chat",options,function(err,address){
  //console.log("addresses: %j", address);
  });

//more upgrades and improvements will come in the code
//to implement mapping
//DNS module for nodejs is used here...
//127.0.0.1 will be replaced by valid ip<|endoftext|>


<commit_before>const plugin = require("tailwindcss/plugin");

module.exports = {
  purge: {
    content: ["./src/main/webapp/**/*.jsp", "./src/main/webapp/**/*.tag", "./src/main/javascript/**/*.js"],
  },
  // use a prefix to not conflict with bootstrap
  prefix: "tw-",
  // use important keyword for tailwind utility classes to override bootstrap selectors
  important: true,
  corePlugins: {
    // disable tailwind base/reset styles. we're still using bootstrap
    preflight: false,
  },
  theme: {
    extend: {
      screens: {
        print: { raw: "print" },
      },
      lineHeight: {
        normal: "normal",
      },
      fontSize: {
        "10rem": "10rem",
      },
    },
  },
  variants: {
    boxShadow: ["responsive", "hover", "focus", "focus-within"],
  },
  plugins: [
    plugin(function ({ addUtilities }) {
      const printStyles = {
        ".no-break-inside": {
          "break-inside": "avoid",
        },
        ".no-page-break-inside": {
          "break-inside": "avoid-page",
        },
        ".no-col-break-inside": {
          "break-inside": "avoid-column",
        },
      };
      addUtilities(printStyles, ["responsive"]);
    }),
  ],
};
<commit_msg>add tailwind screen xs configuration<commit_after>const defaultConfig = require("tailwindcss/defaultConfig.js");
const plugin = require("tailwindcss/plugin");

module.exports = {
  purge: {
    content: ["./src/main/webapp/**/*.jsp", "./src/main/webapp/**/*.tag", "./src/main/javascript/**/*.js"],
  },
  // use a prefix to not conflict with bootstrap
  prefix: "tw-",
  // use important keyword for tailwind utility classes to override bootstrap selectors
  important: true,
  corePlugins: {
    // disable tailwind base/reset styles. we're still using bootstrap
    preflight: false,
  },
  theme: {
    extend: {
      screens: {
        print: { raw: "print" },
      },
      lineHeight: {
        normal: "normal",
      },
      fontSize: {
        "10rem": "10rem",
      },
    },
    screens: {
      // cannot use 'extend' as `xs` would override other screens
      // since it's added to the bottom of the css file
      xs: "480px",
      ...defaultConfig.theme.screens,
    },
  },
  variants: {
    boxShadow: ["responsive", "hover", "focus", "focus-within"],
  },
  plugins: [
    plugin(function ({ addUtilities }) {
      const printStyles = {
        ".no-break-inside": {
          "break-inside": "avoid",
        },
        ".no-page-break-inside": {
          "break-inside": "avoid-page",
        },
        ".no-col-break-inside": {
          "break-inside": "avoid-column",
        },
      };
      addUtilities(printStyles, ["responsive"]);
    }),
  ],
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @format
 */

// The versions here are used across the documentation
// To use it in normal mdx, you can import this file and use a variable e.g. {site.lithoVersion}
// To use it in codeblocks, use the component in /docs/component/versionedCodeBlock.js,
// and refer to the version as: e.g. {{site.lithoVersion}}

export const site = {
  lithoVersion: '0.42.0',
  lithoSnapshotVersion: '0.43.0-SNAPSHOT',
  soloaderVersion: '0.10.4',
  flipperVersion: '0.46.0',
};
<commit_msg>Updates version code for flipper<commit_after>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @format
 */

// The versions here are used across the documentation
// To use it in normal mdx, you can import this file and use a variable e.g. {site.lithoVersion}
// To use it in codeblocks, use the component in /docs/component/versionedCodeBlock.js,
// and refer to the version as: e.g. {{site.lithoVersion}}

export const site = {
  lithoVersion: '0.42.0',
  lithoSnapshotVersion: '0.43.0-SNAPSHOT',
  soloaderVersion: '0.10.4',
  flipperVersion: '0.142.0',
};
<|endoftext|>


<commit_before>include('../../uki-core/const.js');

uki.view.Label = uki.newClass(uki.view.Base, new function() {
    var Base = uki.view.Base[PROTOTYPE],
        proto = this;

    proto._setup = function() {
        Base._setup.call(this);
        uki.extend(this, {
            _scrollable: false,
            _textSelectable: false,
            _inset: new Inset()
        });
    };

    proto.typeName = function() {
        return 'uki.view.Label';
    };

    proto._style = function(name, value) {
        var target = "fontSize textDecoration".indexOf(name) > -1 ? this._label : this._dom;
        if (value === undefined) return target.style[name];
        target.style[name] = value;
        return this;
    };

    proto.textSelectable = function(state) {
        if (state !== undefined && !this._textSelectProp) {
            this._label.unselectable = state ? '' : 'on';
        }
        return Base.textSelectable.call(this, state);
    };

    /**
     * Warning! this operation is expensive
     */
    proto.contentsSize = function(autosize) {
        var clone = this._createLabelClone(autosize), inset = this.inset(), size;

        uki.dom.probe(clone, function() {
            size = new Size(clone.offsetWidth + inset.width(), clone.offsetHeight + inset.height());
        });

        return size;
    };

    proto.text = function(text) {
        return text === undefined ? this.html() : this.html(uki.escapeHTML(text));
    };

    proto.html = function(html) {
        if (html === undefined) return this._label.innerHTML;
        this._label.innerHTML = html;
        return this;
    };

    proto.inset = uki.newProp('_inset', function(inset) {
        this._inset = Inset.create(inset);
    });

    proto.scrollable = uki.newProp('_scrollable', function(state) {
        this._scrollable = state;
        this._label.style.overflow = state ? 'auto' : 'hidden';
    });

    proto.multiline = uki.newProp('_multiline', function(state) {
        this._multiline = state;
        this._label.style.whiteSpace = state ? '' : 'nowrap';
    });

    proto._createLabelClone = function(autosize) {
        var clone = this._label.cloneNode(true),
            inset = this.inset(), rect = this.rect();

        if (autosize & ANCHOR_WIDTH) {
            clone.style.width = clone.style.right = '';
        } else if (uki.supportNativeLayout) {
            clone.style.right = '';
            clone.style.width = rect.width - inset.width() + 'px';
        }
        if (autosize & ANCHOR_HEIGHT) {
            clone.style.height = clone.style.bottom = '';
        } else if (uki.supportNativeLayout) {
            clone.style.bottom = '';
            clone.style.height = rect.height - inset.height() + 'px';
        }
        clone.style.paddingTop = 0;
        clone.style.visibility = 'hidden';
        return clone;
    };

    proto._createDom = function() {
        Base._createDom.call(this);
        this._label = uki.createElement('div', Base.defaultCss +
            "font-size:12px;white-space:nowrap;"); // text-shadow:0 1px 0px rgba(255,255,255,0.8);
        this._dom.appendChild(this._label);
        this.textSelectable(this.textSelectable());
    };

    proto._layoutDom = function() {
        Base._layoutDom.apply(this, arguments);

        var inset = this._inset;
        if (!this.multiline()) {
            var fz = parseInt(this.style('fontSize'), 10) || 12;
            this._label.style.lineHeight = (this._rect.height - inset.top - inset.bottom) + 'px';
            // this._label.style.paddingTop = MAX(0, this._rect.height/2 - fz/2) + 'px';
        }
        var l;

        if (uki.supportNativeLayout) {
            l = {
                left: inset.left,
                top: inset.top,
                right: inset.right,
                bottom: inset.bottom
            };
        } else {
            l = {
                left: inset.left,
                top: inset.top,
                width: this._rect.width - inset.width(),
                height: this._rect.height - inset.height()
            };
        }
        this._lastLabelLayout = uki.dom.layout(this._label.style, l, this._lastLabelLayout);
    };
});
<commit_msg>button color bugfix<commit_after>include('../../uki-core/const.js');

uki.view.Label = uki.newClass(uki.view.Base, new function() {
    var Base = uki.view.Base[PROTOTYPE],
        proto = this;

    proto._setup = function() {
        Base._setup.call(this);
        uki.extend(this, {
            _scrollable: false,
            _textSelectable: false,
            _inset: new Inset()
        });
    };

    proto.typeName = function() {
        return 'uki.view.Label';
    };

    proto._style = function(name, value) {
        var target = "fontSize textDecoration color".indexOf(name) > -1 ? this._label : this._dom;
        if (value === undefined) return target.style[name];
        target.style[name] = value;
        return this;
    };

    proto.textSelectable = function(state) {
        if (state !== undefined && !this._textSelectProp) {
            this._label.unselectable = state ? '' : 'on';
        }
        return Base.textSelectable.call(this, state);
    };

    /**
     * Warning! this operation is expensive
     */
    proto.contentsSize = function(autosize) {
        var clone = this._createLabelClone(autosize), inset = this.inset(), size;

        uki.dom.probe(clone, function() {
            size = new Size(clone.offsetWidth + inset.width(), clone.offsetHeight + inset.height());
        });

        return size;
    };

    proto.text = function(text) {
        return text === undefined ? this.html() : this.html(uki.escapeHTML(text));
    };

    proto.html = function(html) {
        if (html === undefined) return this._label.innerHTML;
        this._label.innerHTML = html;
        return this;
    };

    proto.inset = uki.newProp('_inset', function(inset) {
        this._inset = Inset.create(inset);
    });

    proto.scrollable = uki.newProp('_scrollable', function(state) {
        this._scrollable = state;
        this._label.style.overflow = state ? 'auto' : 'hidden';
    });

    proto.multiline = uki.newProp('_multiline', function(state) {
        this._multiline = state;
        this._label.style.whiteSpace = state ? '' : 'nowrap';
    });

    proto._createLabelClone = function(autosize) {
        var clone = this._label.cloneNode(true),
            inset = this.inset(), rect = this.rect();

        if (autosize & ANCHOR_WIDTH) {
            clone.style.width = clone.style.right = '';
        } else if (uki.supportNativeLayout) {
            clone.style.right = '';
            clone.style.width = rect.width - inset.width() + 'px';
        }
        if (autosize & ANCHOR_HEIGHT) {
            clone.style.height = clone.style.bottom = '';
        } else if (uki.supportNativeLayout) {
            clone.style.bottom = '';
            clone.style.height = rect.height - inset.height() + 'px';
        }
        clone.style.paddingTop = 0;
        clone.style.visibility = 'hidden';
        return clone;
    };

    proto._createDom = function() {
        Base._createDom.call(this);
        this._label = uki.createElement('div', Base.defaultCss +
            "font-size:12px;white-space:nowrap;"); // text-shadow:0 1px 0px rgba(255,255,255,0.8);
        this._dom.appendChild(this._label);
        this.textSelectable(this.textSelectable());
    };

    proto._layoutDom = function() {
        Base._layoutDom.apply(this, arguments);

        var inset = this._inset;
        if (!this.multiline()) {
            var fz = parseInt(this.style('fontSize'), 10) || 12;
            this._label.style.lineHeight = (this._rect.height - inset.top - inset.bottom) + 'px';
            // this._label.style.paddingTop = MAX(0, this._rect.height/2 - fz/2) + 'px';
        }
        var l;

        if (uki.supportNativeLayout) {
            l = {
                left: inset.left,
                top: inset.top,
                right: inset.right,
                bottom: inset.bottom
            };
        } else {
            l = {
                left: inset.left,
                top: inset.top,
                width: this._rect.width - inset.width(),
                height: this._rect.height - inset.height()
            };
        }
        this._lastLabelLayout = uki.dom.layout(this._label.style, l, this._lastLabelLayout);
    };
});
<|endoftext|>


<commit_before>import React from 'react'
import { getKeyCode, keyMap } from '../util/textInput'
import {
  exitNode,
  insertJSX,
  removeCurrentNode,
  replaceNodeWithJSX,
  selectCurrentNode
} from '../util/tinymce'
import { includes, some } from 'lodash'

export const hashtagAttribute = 'data-autocompleting'

const triggerKeyCodes = [keyMap.HASH, keyMap.AT_SIGN]
const triggers = ['#', '@']
const template = keyCode =>

    {String.fromCharCode(keyCode)}

const Mention = ({ person }) =>

    {person.name}

export class RichTextTagger {
  constructor (editor, autocomplete) {
    this.editor = editor
    this.autocomplete = autocomplete
  }

  domNode () {
    return this.editor.selection.getNode()
  }

  search (term) {
    this.lastSearch = term
    this.autocomplete(term, this.domNode())
  }

  isInTag () {
    return !!this.domNode().getAttribute(hashtagAttribute)
  }

  isInReplacedTag () {
    return !!this.domNode().getAttribute('data-user-id')
  }

  tagValue () {
    return this.editor.selection.getNode().innerHTML
  }

  tagValueIsEmpty () {
    return some(triggers, t => t === this.tagValue())
  }

  finishTag (choice, event) {
    const keyCode = getKeyCode(event)
    if (keyCode === keyMap.ENTER) {
      // this is a workaround for the fact that we can't suppress the insertion
      // of a new linebreak due to Enter in TinyMCE. (well, it's alleged that
      // you can, but only by defining a callback when first initializing it.)
      //
      // so we assume a new paragraph has been inserted, backtrack to the node
      // we were trying to replace, and remove the new paragraph.
      const extraP = window.tinymce.$(this.domNode())
      const origP = extraP.prev()
      const node = origP.find(`[${hashtagAttribute}]`).last()[0]
      origP.append(extraP.contents())
      this.editor.dom.remove(extraP)
      this.editor.selection.select(node)
    }

    // sort of a dumb heuristic: users have avatar_urls and tags don't
    if (choice.avatar_url) {
      replaceNodeWithJSX(<Mention person={choice}/>, this.editor)
    } else {
      // for hashtags, we just update the text in the tag instead of replacing
      // anything, so it can always be edited, autocompleted, or saved as a new
      // hashtag as-is
      this.domNode().textContent = '#' + choice.name
      this.search(null)
      exitNode(this.editor, keyMap.SPACE)
    }
  }

  handleKeyUp = event => {
    const keyCode = getKeyCode(event)

    // select the whole tag when backspacing up to it so it's easy to delete all
    // at once
    if (keyCode === keyMap.BACKSPACE && this.isInReplacedTag()) {
      selectCurrentNode(this.editor)
      return
    }

    this.updateSearch(event)
  }

  handleKeyDown = event => {
    const keyCode = getKeyCode(event)
    switch (keyCode) {
      case keyMap.SPACE:
        if (this.isInTag()) {
          exitNode(this.editor, keyCode)
          event.preventDefault()
        }
        break
      case keyMap.BACKSPACE:
        // remove the tag entirely if backspacing over its first character
        if (this.tagValueIsEmpty()) {
          removeCurrentNode(this.editor)
          event.preventDefault()
        }
    }
  }

  // you can prevent the appearance of the character you typed by calling
  // event.preventDefault()
  handleKeyPress = event => {
    const keyCode = getKeyCode(event)
    // create an empty tag when a trigger character is typed
    if (includes(triggerKeyCodes, keyCode)) {
      insertJSX(template(keyCode), this.editor)
      event.preventDefault()
    }
  }

  updateSearch = event => {
    const keyCode = getKeyCode(event)
    if (this.isInTag()) {
      // trigger or reset typeahead
      const value = keyCode === keyMap.ESC ? null : this.tagValue()
      this.search(value)
    } else {
      // always reset typeahead if not inside a tag
      if (this.lastSearch) this.search(null)
    }
  }
}

export default RichTextTagger
<commit_msg>fix tag completion in RichTextEditor on Firefox<commit_after>import React from 'react'
import { getKeyCode, keyMap } from '../util/textInput'
import {
  exitNode,
  insertJSX,
  removeCurrentNode,
  replaceNodeWithJSX,
  selectCurrentNode
} from '../util/tinymce'
import { includes, some } from 'lodash'

export const hashtagAttribute = 'data-autocompleting'
export const justCreatedAttribute = 'data-just-created'

const triggerKeyCodes = [keyMap.HASH, keyMap.AT_SIGN]
const triggers = ['#', '@']
const template = keyCode =>

    {String.fromCharCode(keyCode)}

const Mention = ({ person }) =>

    {person.name}

export class RichTextTagger {
  constructor (editor, autocomplete) {
    this.editor = editor
    this.autocomplete = autocomplete
  }

  domNode () {
    return this.editor.selection.getNode()
  }

  search (term) {
    this.lastSearch = term
    this.autocomplete(term, this.domNode())
  }

  isInTag () {
    return !!this.domNode().getAttribute(hashtagAttribute)
  }

  isInReplacedTag () {
    return !!this.domNode().getAttribute('data-user-id')
  }

  tagValue () {
    return this.editor.selection.getNode().innerHTML
  }

  tagValueIsEmpty () {
    return some(triggers, t => t === this.tagValue())
  }

  finishTag (choice, event) {
    const keyCode = getKeyCode(event)
    if (keyCode === keyMap.ENTER) {
      // this is a workaround for the fact that we can't suppress the insertion
      // of a new linebreak due to Enter in TinyMCE. (well, it's alleged that
      // you can, but only by defining a callback when first initializing
      // TinyMCE.)
      //
      // so we assume a new paragraph has been inserted, backtrack to the node
      // we were trying to replace, and remove the new paragraph.
      const extraP = window.tinymce.$(this.domNode())
      const origP = extraP.prev()
      const node = origP.find(`[${hashtagAttribute}]`).last()[0]
      origP.append(extraP.contents())
      this.editor.dom.remove(extraP)
      this.editor.selection.select(node)
    }

    // sort of a dumb heuristic: users have avatar_urls and tags don't
    if (choice.avatar_url) {
      replaceNodeWithJSX(<Mention person={choice}/>, this.editor)
    } else {
      // for hashtags, we just update the text in the tag instead of replacing
      // anything, so it can always be edited, autocompleted, or saved as a new
      // hashtag as-is
      this.domNode().textContent = '#' + choice.name
      this.search(null)
      exitNode(this.editor, keyMap.SPACE)
    }
  }

  handleKeyUp = event => {
    const keyCode = getKeyCode(event)

    // select the whole tag when backspacing up to it so it's easy to delete all
    // at once
    if (keyCode === keyMap.BACKSPACE && this.isInReplacedTag()) {
      selectCurrentNode(this.editor)
      return
    }

    this.updateSearch(event)
  }

  handleKeyDown = event => {
    const keyCode = getKeyCode(event)
    switch (keyCode) {
      case keyMap.SPACE:
        if (this.isInTag()) {
          exitNode(this.editor, keyCode)
          event.preventDefault()
        }
        break
      case keyMap.BACKSPACE:
        // remove the tag entirely if backspacing over its first character
        if (this.tagValueIsEmpty()) {
          removeCurrentNode(this.editor)
          event.preventDefault()
        }
    }
  }

  // you can prevent the appearance of the character you typed by calling
  // event.preventDefault()
  handleKeyPress = event => {
    const keyCode = getKeyCode(event)
    // create an empty tag when a trigger character is typed
    if (includes(triggerKeyCodes, keyCode)) {
      event.preventDefault()
      insertJSX(template(keyCode), this.editor)

      // if the cursor is not in the tag that was just created (this happens on
      // Firefox), we have to move it there
      const node = this.domNode()
      if (node.tagName === 'P') {
        // there's probably a simpler way to find the tag than this...
        const tag = window.tinymce.$(node).find(`[${justCreatedAttribute}]`)[0]
        this.editor.selection.setCursorLocation(tag, 1)
        tag.removeAttribute(justCreatedAttribute)
      } else {
        node.removeAttribute(justCreatedAttribute)
      }
    }
  }

  updateSearch = event => {
    const keyCode = getKeyCode(event)
    if (this.isInTag()) {
      // trigger or reset typeahead
      const value = keyCode === keyMap.ESC ? null : this.tagValue()
      this.search(value)
    } else {
      // always reset typeahead if not inside a tag
      if (this.lastSearch) this.search(null)
    }
  }
}

export default RichTextTagger
<|endoftext|>