<commit_before>function select_state(state) {
    function insert_new_form(record_type, record_pk, pre_callback, post_callback){
        console.log(record_type + " " + record_pk);
        $.get('/en-US/mozdns/record/record_ajax/',

            {
                'record_type': record_type,
                'record_pk': record_pk
            },
            function (data) {
                $('#current-form-area').empty();
                console.log("[DEBUG] Redrawing form");
                $('#current-form-area').append(data);
                $('#add-comment').attr('checked', true);
                bind_submit($('#current-form'), post_callback);
                pre_callback();
            }).error(function(e) {
                var newDoc = document.open("text/html", "replace");
                newDoc.write(e.responseText);
                newDoc.close();
            });
    }
    var data = $('#dns-data');
    switch (state) {
    /*
     *      create
     *          * clear pk
     *          * get rdtype
     *          * get form for rdtype
     *          * insert new form
     *          * hide search div
     *          * unhide form div
     */
        case 'create':
            console.log("[STATE] create");
            data.attr('record_pk', '');
            insert_new_form(data.attr('record_type'), data.attr('record_pk'),
                function (){
                    bind_smart_names();
                    bind_view_ip_type_detection();
                },
                function (){
                    if ($('#object_redirect_url').attr('record-url')) {
                        alert("Creation Successful!");
                        window.location = $('#object_redirect_url').attr('record-url');
                    }
                }
            );
            break;
    /*
     *      edit
     *          * if no pk -> do create. log a warning
     *          * get pk and rdtype
     *          * get form for rdtype
     *          * insert form
     *          * hide search div
     *          * unhide form div
     */
        case 'update':
            console.log("[STATE] update");
            console.log("[DEBUG] pk in update state: "+data.attr('record_pk'));
            if (!data.attr('record_pk')) {
                console.log("Tried to update without a record_pk. Going to create view.");
                insert_new_form(data.record_type, '',
                    function (){
                        bind_smart_names();
                        bind_view_ip_type_detection();
                    },
                    function (){
                        if ($('#object_redirect_url').attr('record-url')) {
                            alert("Creation Successful!");
                            window.location = $('#object_redirect_url').attr('record-url');
                        }
                    }
                );
                break;
            } else {
                insert_new_form(data.attr('record_type'), data.attr('record_pk'),
                    function (){
                        fix_css();
                        bind_view_ip_type_detection();
                    },
                    function (){
                    }
                );
                setup_delete();
            }
            break;
    }
}

function bind_submit(form, post_callback) {
    console.log("[DEBUG] Binding submit");
    form.submit(function (){
        console.log("[DEBUG] Submit pressed");
        if ($('#add-comment').is(':checked')) {
            console.log("[DEBUG] Submit pressed");
            var c_dialog = $( "#commit-dialog" ).dialog({
                title: 'Comment on this commit? (A bug number would be nice)',
                autoShow: false,
                minWidth: 520,
                buttons: {
                    "Commit": function() {
                        if(/^\s*$/.test($('#commit-message').val())){
                            alert("Aborting commit due to empty commit message.");
                        } else {
                            $('#id_comment').val($('#commit-message').val());
                            submit_handler(post_callback);
                        }
                        $(this).dialog("close");
                    },
                    Cancel: function() {
                        // pass
                        $(this).dialog("close");
                    }
                }
            });
        } else {
            console.log("[DEBUG] No commit message");
            submit_handler(post_callback);
        }
        return false;
    }); // end submit()
}

function submit_handler(post_callback){
    $('#form-message').html("
Sending data...
");
    var start = new Date().getTime();
    $.post('/en-US/mozdns/record/record_ajax/',
        $('#current-form').serialize(),
        function (data) {
            $('#current-form-area').empty();
            $('#current-form-area').append(data);
            var end = new Date().getTime();
            var time = end - start;
            $('#action-time').html('('+time/1000+' seconds)');
            fix_css();  // Make names the correct length
            post_callback(); // Do work if needed
            bind_submit($('#current-form'), post_callback);  // It's a new form.
        }
        ).error(function(e) {
            var newDoc = document.open("text/html", "replace");
            newDoc.write(e.responseText);
            newDoc.close();
            $('#form-message').html("
Error
");
        });
}

function fix_css(){
    // Look for inputs that have id = 'id_fqdn' | 'id_server' | 'id_name'
    // 'id_target' | server . Make these smart names.
    var inputs = $('input');
    for (var x = 0; x < inputs.length; x++){
        if(inputs[x].id === 'id_name' || inputs[x].id === 'id_fqdn'
                || inputs[x].id === 'id_target' || inputs[x].id === 'id_server'){
            $(inputs[x]).css('width', '400px');
        }
    }
}

function bind_smart_names(){
    // Look for inputs that have id = 'id_fqdn' | 'id_server' | 'id_name'
    // 'id_target' | server . Make these smart names.
    var inputs = $('input');
    for (var x = 0; x < inputs.length; x++){
        if(inputs[x].id === 'id_name' || inputs[x].id === 'id_fqdn'
                || inputs[x].id === 'id_target' || inputs[x].id === 'id_server'){
            make_smart_name_get_domains(inputs[x], true)
            $(inputs[x]).css('width', '400px');
        }
    }
}

function make_smart_name_get_domains(element, append){
    $.get('/mozdns/domain/get_all_domains/', function(domains) {
        console.log(domains.sort);
        make_smart_name(element, $.parseJSON(domains), append);
    });
}

function make_smart_name(element, domains, append){
    $(element).autocomplete({
        select: function(event, ui) {
            // We saved the matching part to ui.item.value
            var name = $(element).val(); // The name the user entered
            if(!append) {
                $(element).attr('value', ui.item.label);
            } else if (ui.item.value !== ''){
                var foo =  name.substring(0,name.lastIndexOf(ui.item.value));
                $(element).attr('value', foo + ui.item.label);
            } else {
                if (name.lastIndexOf('.') == name.length - 1) {
                    $(element).attr('value',  name + ui.item.label);
                } else {
                    $(element).attr('value',  name + '.' + ui.item.label);
                }
            }
            return false;
        },
        focus: function(event, ui) {
            return false;
        },
        autoFocus: false,
        source: function (li, callback) {
            labels = li.term.split('.')

            var suggested_domains = [];
            var domain_name = '';
            var search_name = '';
            while (labels) {
                search_name = labels.join('.');
                for (var domain in domains.sort(function(a,b) {return (a.length < b.length) ? 0 : 1; })){
                    domain_name = domains[domain];
                    if (domain_name.startsWith(search_name)){
                        suggested_domains.push({label: domain_name, value: search_name});
                    }
                }
                if (suggested_domains.length === 0){
                    labels.shift();
                } else {
                    return callback(suggested_domains.slice(0, 20)); // The list is too long sometimes
                }
            }
            return callback([]);
        }
    });
}

function setup_search_table(){
    var data = $('#dns-data');
    var record_type = data.attr('record_type');
    switch (record_type) {
        case 'AAAA':
        case 'A': table_config = {
                sortList: [[0,1]],
                headers: {
                    0: { sorter:'hostname' },
                    1: { sorter:'ipAddress' },
                }
            };
            break;
        case 'PTR': table_config = {
                sortList: [[0,1],[2,1]],
                headers: {
                    0: { sorter:'ipAddress' },
                    1: { sorter:false },
                    2: { sorter:'hostname' },
                }
            };
            break
        case 'TXT':
        case 'SSHFP':
        case 'MX':
        case 'NS':
        case 'SRV':
        case 'CNAME': table_config = {
                sortList: [[0,1]],
                headers: {
                    0: { sorter:'hostname' },
                    1: { sorter:false },
                    2: { sorter:'hostname' },
                }
            };
            break
        case 'DOMAIN': table_config = {
                sortList: [[0,1]],
                headers: {
                    0: { sorter:'hostname' },
                    1: { sorter:'hostname' },
                }
            };
            break
    }
    $("#record-table").tablesorter(table_config);
    $("#record-table th:last-child").css('width', '30px');

    $("#record-table").on('sortEnd', function(e) {
        tableSorting = e.target.config.sortList;
        data.data('tableSorting', tableSorting); // Save how the table is sorted
    });
}

function do_search(){
    //console.log("searching" + $('#search-query').val());
    var data = $('#dns-data');
    var record_type = data.attr('record_type');

    $.get('/mozdns/record/search_ajax/',
        {
            'record_type': record_type,
            'query': $('#search-query').val(),
        },
        function (table) {
            $("#record-table").remove();
            $("#search-results").append(table);
            setup_search_table();
            // let the plugin know that we made a update

            $("#record-table").trigger("update");
            if (data.data('tableSorting')) {
                // http://stackoverflow.com/questions/2288655/jquery-tablesorter-sort-same-column-after-update
                $("#record-table").trigger("sorton", [data.data('tableSorting'),0]);
            }
        }).error(function(e) {
            var newDoc = document.open("text/html", "replace");
            newDoc.write(e.responseText);
            newDoc.close();
        });
    return false;
}
function setup_delete(){
    var data = $('#dns-data');
    var record_type = data.attr('record_type');
    var record_pk = data.attr('record_pk');
    function delete_handler(){
        $.post('/en-US/mozdns/record/delete/' + record_type + '/' + record_pk + '/',
            function (data) {
                data = $.parseJSON(data)
                if (data['success']) {
                    console.log('Error: ' + data['error']);
                    alert("Delete successful");
                    window.location = "/";
                } else {
                    alert("Error during delete: " + data['error']);
                }
            }
        ).error(function(e) {
            var newDoc = document.open("text/html", "replace");
            newDoc.write(e.responseText);
            newDoc.close();
            $('#form-message').html("
Error
");
        });
    }
    $("#delete-dialog").dialog({
        title: 'Why this record is being deleted? (A bug number would be nice)',
        // Click the selected record
        autoOpen: false,
        minWidth: 520,
        minHeight: 20,
        buttons: {
            "Confirm Delete": function() {
                if (/^\s*$/.test($('#delete-message').val())) {
                    alert("Aborting commit due to empty commit message.");
                } else {
                    $('#id_comment').val($('#delete-message').val());
                    delete_handler();
                }
                $(this).dialog("close");
            },
            Cancel: function() {
                $(this).dialog("close");
            }
        }
    });
    $('#delete-button').click(function(){
        var data = $('#dns-data');
        var record_type = data.attr('record_type');
        var record_pk = data.attr('record_pk');
        $('#commit-message').val('')
        $('#delete-message').val('')
        if ($('#add-comment').is(':checked')) {
            $("#delete-dialog").dialog('open');
        } else {
            delete_handler();
        }
        return false;
    });
}

function make_free_ip_search(target_ip_str, start, end, dialog_div, message_area) {
    dialog_div.dialog({
        title: 'Specify a range in which an unallocated ip address should be found.',
        autoShow: false,
        minWidth: 520,
        buttons: {
            "Find A Free IP": function() {
                $.get("/core/range/usage_text/",
                    {
                        start: start.val(),
                        end: end.val(),
                        format: 'human_readable'
                    }, function(data) {
                        var data = $.parseJSON(data);
                        message_area.empty()
                        if (!data['success']) {
                            message_area.append(data['error_messages']);
                        } else if (data['unused'] == 0) {
                            message_area.append("No ip addresses are free.");
                        } else {
                            var p_unused = data['unused'] / (data['unused'] + data['used']);
                            p_unused = "" + p_unused; // Cast it
                            message = "%" + p_unused.substring(2, 4) + " of address are unallocated"
                                      + " in this range. The first unused address is "
                                      + data['free_ranges'][0][0];
                            message_area.append(message);
                        }
                    }).error(function (data) {
                        var data = $.parseJSON(data);
                    });
            },
            Cancel: function() {
                // pass
                $(this).dialog("close");
            }
        }
    });
}

function set_ip_type(ip){
    if(ip.indexOf('.') > 0) {
        $("#id_ip_type option[value='4']").attr("selected", "selected");
        $("#id_ip_type option[value='6']").removeAttr("selected");
    } else if(ip.indexOf(':') > 0) {
        $("#id_ip_type option[value='4']").removeAttr("selected");
        $("#id_ip_type option[value='6']").attr("selected", "selected");
    }
}

function bind_view_ip_type_detection() {
    // If an ip starts with '10' automatically set the private view
    // If an ip starts with '63.245' automatically set the public view
    var public_prefixs = ['63.245', '2620:0101', '2620:101'];
    var private_prefixs = ['10'].concat(public_prefixs);
    var found = false; // Help us only do view detect once

    var i; // loop var

    $('#id_ip_str').keyup(function(){
        set_ip_type($('#id_ip_str').val());
        function do_detect(prefixs, view_el){
            var ip_str = $('#id_ip_str').val();
            for(i = 0; i < prefixs.length; i++) {
                if (ip_str.substring(0, prefixs[i].length) === prefixs[i]) {
                    $(view_el).attr('checked', 'checked');
                    found = true;
                    break;
                }
            }
        }
        if (!found) {  // Only do view detect if we havne't done it before
            do_detect(private_prefixs, '#id_views_0');
            do_detect(public_prefixs, '#id_views_1');
        }
    });
}
<commit_msg>this must have broken when jquery was updated.<commit_after>function select_state(state) {
    function insert_new_form(record_type, record_pk, pre_callback, post_callback){
        console.log(record_type + " " + record_pk);
        $.get('/en-US/mozdns/record/record_ajax/',

            {
                'record_type': record_type,
                'record_pk': record_pk
            },
            function (data) {
                $('#current-form-area').empty();
                console.log("[DEBUG] Redrawing form");
                $('#current-form-area').append(data);
                $('#add-comment').attr('checked', true);
                bind_submit($('#current-form'), post_callback);
                pre_callback();
            }).error(function(e) {
                var newDoc = document.open("text/html", "replace");
                newDoc.write(e.responseText);
                newDoc.close();
            });
    }
    var data = $('#dns-data');
    switch (state) {
    /*
     *      create
     *          * clear pk
     *          * get rdtype
     *          * get form for rdtype
     *          * insert new form
     *          * hide search div
     *          * unhide form div
     */
        case 'create':
            console.log("[STATE] create");
            data.attr('record_pk', '');
            insert_new_form(data.attr('record_type'), data.attr('record_pk'),
                function (){
                    bind_smart_names();
                    bind_view_ip_type_detection();
                },
                function (){
                    if ($('#object_redirect_url').attr('record-url')) {
                        alert("Creation Successful!");
                        window.location = $('#object_redirect_url').attr('record-url');
                    }
                }
            );
            break;
    /*
     *      edit
     *          * if no pk -> do create. log a warning
     *          * get pk and rdtype
     *          * get form for rdtype
     *          * insert form
     *          * hide search div
     *          * unhide form div
     */
        case 'update':
            console.log("[STATE] update");
            console.log("[DEBUG] pk in update state: "+data.attr('record_pk'));
            if (!data.attr('record_pk')) {
                console.log("Tried to update without a record_pk. Going to create view.");
                insert_new_form(data.record_type, '',
                    function (){
                        bind_smart_names();
                        bind_view_ip_type_detection();
                    },
                    function (){
                        if ($('#object_redirect_url').attr('record-url')) {
                            alert("Creation Successful!");
                            window.location = $('#object_redirect_url').attr('record-url');
                        }
                    }
                );
                break;
            } else {
                insert_new_form(data.attr('record_type'), data.attr('record_pk'),
                    function (){
                        fix_css();
                        bind_view_ip_type_detection();
                    },
                    function (){
                    }
                );
                setup_delete();
            }
            break;
    }
}

function bind_submit(form, post_callback) {
    console.log("[DEBUG] Binding submit");
    form.submit(function (){
        console.log("[DEBUG] Submit pressed");
        if ($('#add-comment').is(':checked')) {
            console.log("[DEBUG] Submit pressed");
            var c_dialog = $( "#commit-dialog" ).dialog({
                title: 'Comment on this commit? (A bug number would be nice)',
                autoShow: false,
                minWidth: 520,
                buttons: {
                    "Commit": function() {
                        if(/^\s*$/.test($('#commit-message').val())){
                            alert("Aborting commit due to empty commit message.");
                        } else {
                            $('#id_comment').val($('#commit-message').val());
                            submit_handler(post_callback);
                        }
                        $(this).dialog("close");
                    },
                    Cancel: function() {
                        // pass
                        $(this).dialog("close");
                    }
                }
            });
        } else {
            console.log("[DEBUG] No commit message");
            submit_handler(post_callback);
        }
        return false;
    }); // end submit()
}

function submit_handler(post_callback){
    $('#form-message').html("
Sending data...
");
    var start = new Date().getTime();
    $.post('/en-US/mozdns/record/record_ajax/',
        $('#current-form').serialize(),
        function (data) {
            $('#current-form-area').empty();
            $('#current-form-area').append(data);
            var end = new Date().getTime();
            var time = end - start;
            $('#action-time').html('('+time/1000+' seconds)');
            fix_css();  // Make names the correct length
            post_callback(); // Do work if needed
            bind_submit($('#current-form'), post_callback);  // It's a new form.
        }
        ).error(function(e) {
            var newDoc = document.open("text/html", "replace");
            newDoc.write(e.responseText);
            newDoc.close();
            $('#form-message').html("
Error
");
        });
}

function fix_css(){
    // Look for inputs that have id = 'id_fqdn' | 'id_server' | 'id_name'
    // 'id_target' | server . Make these smart names.
    var inputs = $('input');
    for (var x = 0; x < inputs.length; x++){
        if(inputs[x].id === 'id_name' || inputs[x].id === 'id_fqdn'
                || inputs[x].id === 'id_target' || inputs[x].id === 'id_server'){
            $(inputs[x]).css('width', '400px');
        }
    }
}

function bind_smart_names(){
    // Look for inputs that have id = 'id_fqdn' | 'id_server' | 'id_name'
    // 'id_target' | server . Make these smart names.
    var inputs = $('input');
    for (var x = 0; x < inputs.length; x++){
        if(inputs[x].id === 'id_name' || inputs[x].id === 'id_fqdn'
                || inputs[x].id === 'id_target' || inputs[x].id === 'id_server'){
            make_smart_name_get_domains(inputs[x], true);
            $(inputs[x]).css('width', '400px');
        }
    }
}

function make_smart_name_get_domains(element, append){
    $.get('/mozdns/domain/get_all_domains/', function(domains) {
        make_smart_name(element, $.parseJSON(domains), append);
    });
}

function make_smart_name(element, domains, append){
    $(element).autocomplete({
        select: function(event, ui) {
            // We saved the matching part to ui.item.value
            var name = $(element).val(); // The name the user entered
            if(!append) {
                $(element).val(ui.item.label);
            } else if (ui.item.value !== ''){
                var foo =  name.substring(0,name.lastIndexOf(ui.item.value));
                $(element).val(foo + ui.item.label);
            } else {
                if (name.lastIndexOf('.') == name.length - 1) {
                    $(element).val(name + ui.item.label);
                } else {
                    $(element).val(name + '.' + ui.item.label);
                }
            }
            return false;
        },
        focus: function(event, ui) {
            return false;
        },
        autoFocus: false,
        source: function (li, callback) {
            labels = li.term.split('.')

            var suggested_domains = [];
            var domain_name = '';
            var search_name = '';
            while (labels) {
                search_name = labels.join('.');
                for (var domain in domains.sort(function(a,b) {return (a.length < b.length) ? 0 : 1; })){
                    domain_name = domains[domain];
                    if (domain_name.startsWith(search_name)){
                        suggested_domains.push({label: domain_name, value: search_name});
                    }
                }
                if (suggested_domains.length === 0){
                    labels.shift();
                } else {
                    return callback(suggested_domains.slice(0, 20)); // The list is too long sometimes
                }
            }
            return callback([]);
        }
    });
}

function setup_search_table(){
    var data = $('#dns-data');
    var record_type = data.attr('record_type');
    switch (record_type) {
        case 'AAAA':
        case 'A': table_config = {
                sortList: [[0,1]],
                headers: {
                    0: { sorter:'hostname' },
                    1: { sorter:'ipAddress' },
                }
            };
            break;
        case 'PTR': table_config = {
                sortList: [[0,1],[2,1]],
                headers: {
                    0: { sorter:'ipAddress' },
                    1: { sorter:false },
                    2: { sorter:'hostname' },
                }
            };
            break
        case 'TXT':
        case 'SSHFP':
        case 'MX':
        case 'NS':
        case 'SRV':
        case 'CNAME': table_config = {
                sortList: [[0,1]],
                headers: {
                    0: { sorter:'hostname' },
                    1: { sorter:false },
                    2: { sorter:'hostname' },
                }
            };
            break
        case 'DOMAIN': table_config = {
                sortList: [[0,1]],
                headers: {
                    0: { sorter:'hostname' },
                    1: { sorter:'hostname' },
                }
            };
            break
    }
    $("#record-table").tablesorter(table_config);
    $("#record-table th:last-child").css('width', '30px');

    $("#record-table").on('sortEnd', function(e) {
        tableSorting = e.target.config.sortList;
        data.data('tableSorting', tableSorting); // Save how the table is sorted
    });
}

function do_search(){
    //console.log("searching" + $('#search-query').val());
    var data = $('#dns-data');
    var record_type = data.attr('record_type');

    $.get('/mozdns/record/search_ajax/',
        {
            'record_type': record_type,
            'query': $('#search-query').val(),
        },
        function (table) {
            $("#record-table").remove();
            $("#search-results").append(table);
            setup_search_table();
            // let the plugin know that we made a update

            $("#record-table").trigger("update");
            if (data.data('tableSorting')) {
                // http://stackoverflow.com/questions/2288655/jquery-tablesorter-sort-same-column-after-update
                $("#record-table").trigger("sorton", [data.data('tableSorting'),0]);
            }
        }).error(function(e) {
            var newDoc = document.open("text/html", "replace");
            newDoc.write(e.responseText);
            newDoc.close();
        });
    return false;
}
function setup_delete(){
    var data = $('#dns-data');
    var record_type = data.attr('record_type');
    var record_pk = data.attr('record_pk');
    function delete_handler(){
        $.post('/en-US/mozdns/record/delete/' + record_type + '/' + record_pk + '/',
            function (data) {
                data = $.parseJSON(data)
                if (data['success']) {
                    console.log('Error: ' + data['error']);
                    alert("Delete successful");
                    window.location = "/";
                } else {
                    alert("Error during delete: " + data['error']);
                }
            }
        ).error(function(e) {
            var newDoc = document.open("text/html", "replace");
            newDoc.write(e.responseText);
            newDoc.close();
            $('#form-message').html("
Error
");
        });
    }
    $("#delete-dialog").dialog({
        title: 'Why this record is being deleted? (A bug number would be nice)',
        // Click the selected record
        autoOpen: false,
        minWidth: 520,
        minHeight: 20,
        buttons: {
            "Confirm Delete": function() {
                if (/^\s*$/.test($('#delete-message').val())) {
                    alert("Aborting commit due to empty commit message.");
                } else {
                    $('#id_comment').val($('#delete-message').val());
                    delete_handler();
                }
                $(this).dialog("close");
            },
            Cancel: function() {
                $(this).dialog("close");
            }
        }
    });
    $('#delete-button').click(function(){
        var data = $('#dns-data');
        var record_type = data.attr('record_type');
        var record_pk = data.attr('record_pk');
        $('#commit-message').val('')
        $('#delete-message').val('')
        if ($('#add-comment').is(':checked')) {
            $("#delete-dialog").dialog('open');
        } else {
            delete_handler();
        }
        return false;
    });
}

function make_free_ip_search(target_ip_str, start, end, dialog_div, message_area) {
    dialog_div.dialog({
        title: 'Specify a range in which an unallocated ip address should be found.',
        autoShow: false,
        minWidth: 520,
        buttons: {
            "Find A Free IP": function() {
                $.get("/core/range/usage_text/",
                    {
                        start: start.val(),
                        end: end.val(),
                        format: 'human_readable'
                    }, function(data) {
                        var data = $.parseJSON(data);
                        message_area.empty()
                        if (!data['success']) {
                            message_area.append(data['error_messages']);
                        } else if (data['unused'] == 0) {
                            message_area.append("No ip addresses are free.");
                        } else {
                            var p_unused = data['unused'] / (data['unused'] + data['used']);
                            p_unused = "" + p_unused; // Cast it
                            message = "%" + p_unused.substring(2, 4) + " of address are unallocated"
                                      + " in this range. The first unused address is "
                                      + data['free_ranges'][0][0];
                            message_area.append(message);
                        }
                    }).error(function (data) {
                        var data = $.parseJSON(data);
                    });
            },
            Cancel: function() {
                // pass
                $(this).dialog("close");
            }
        }
    });
}

function set_ip_type(ip){
    if(ip.indexOf('.') > 0) {
        $("#id_ip_type option[value='4']").attr("selected", "selected");
        $("#id_ip_type option[value='6']").removeAttr("selected");
    } else if(ip.indexOf(':') > 0) {
        $("#id_ip_type option[value='4']").removeAttr("selected");
        $("#id_ip_type option[value='6']").attr("selected", "selected");
    }
}

function bind_view_ip_type_detection() {
    // If an ip starts with '10' automatically set the private view
    // If an ip starts with '63.245' automatically set the public view
    var public_prefixs = ['63.245', '2620:0101', '2620:101'];
    var private_prefixs = ['10'].concat(public_prefixs);
    var found = false; // Help us only do view detect once

    var i; // loop var

    $('#id_ip_str').keyup(function(){
        set_ip_type($('#id_ip_str').val());
        function do_detect(prefixs, view_el){
            var ip_str = $('#id_ip_str').val();
            for(i = 0; i < prefixs.length; i++) {
                if (ip_str.substring(0, prefixs[i].length) === prefixs[i]) {
                    $(view_el).attr('checked', 'checked');
                    found = true;
                    break;
                }
            }
        }
        if (!found) {  // Only do view detect if we havne't done it before
            do_detect(private_prefixs, '#id_views_0');
            do_detect(public_prefixs, '#id_views_1');
        }
    });
}
<|endoftext|>


<commit_before>
var mouseState = false;
document.onmousedown = function(e){
    mouseState = true;
}
document.onmouseup = function(e){
    mouseState = false;

    // In IE obviously we use a different function
    //
    // this will deselect the text after dragging
    // has finished.
    if (document.selection) {
        document.selection.empty()
    } else {
        window.getSelection().removeAllRanges()
    }

}

function applyClass(klass) {

    /*
       Checks all the table elements,
       if they are selected, it removes the
       selected class (and all other classes)
       and applies the passed in class
    */

    $("#holiday-table")
        .find("td")
        .each(function () {
            if ($(this).hasClass("selected")) {
                $(this).removeClass();
                $(this).addClass(klass);

            }
        });
}

function submit_all() {

    /*
       Submits all entries on the form

       Takes no parameters and returns true/false
       depending on success.
    */

    var successfully_completed = false;
    $("#holiday-table")
        .find(":button")
        .not("#submit_all")
        .each(function () {
            var call = submit_holidays($(this).attr("user_id"), true)
            if (call === true) {
                successfully_completed = true;
                console.log("completed");
            } else {
                successfully_completed = false;
                console.log("Error adding holidays");
            }
        });
    if (successfully_completed) {
        alert("Holidays change successfully!");
    } else {
        alert("There was an error adding holidays");
    }
    return successfully_completed;
}

function submit_holidays(user_id, mass) {
    /*
       En masse changes a set of holidays and
       takes a user_id as a parameter.

       Mass is true/false, if true it

       Returns true for success, false for error
    */

    // create a map to hold the holidays
    var holiday_map = JSON;

    // iterate through the table and check if it's
    // selected or not, if it's selected, ignore it.
    // else, add the number and the class to the map.
    $("#holiday-table")
        .find("td[usrid='"+user_id+"']")
        .each(function () {
            // get the bg colour of the td
            var current_class = $(this).attr('class');
            if (current_class !== "selected") {
                holiday_map[$(this).text()] = current_class;
            }
        });

    // setup our ajax properties
    $.ajaxSetup({
        type: 'POST',
        dataType: 'json'
    });

    $.ajax({
        url: '/ajax/',
        data: {
            'form_type': 'mass_holidays',
            'year': $("#holiday-table").attr("year"), // from the table header
            'month': $("#holiday-table").attr("month"),
            'holiday_data': JSON.stringify(holiday_map),
            'user_id': user_id
        },
        success: function(data) {
            if (data.success === true) {
                if (!mass) {
                    alert("Holidays updated successfully");
                }
            } else {
                alert(data.error);
            }
        },
        error: function(ajaxObj, textStatus, error) {
            console.log(error);
        }
    });

    // return true so programmatic callers can
    // see we've completed
    return true;
}

function addFunctions () {

    "use strict";

    // all the daytype classes
    // are assigned a click handler which
    // swaps the colour depending on what
    // it currently is.
    $("#holiday-table")
        .find('.empty, .DAYOD, .TRAIN, .WKDAY, .SICKD, .HOLIS, .SPECI, .MEDIC, .PUABS, .PUWRK, .SATUR, .RETRN, .WKHOM, .OTHER')
        .not(":button")
        .mouseover(function (e) {
            if (mouseState) {

                if ($(this).hasClass("selected")) {
                    $(this).removeClass("selected");
                } else {
                    $(this).removeClass();
                    $(this).addClass("selected");
                    $(this).addClass("empty");
                }
                e.preventDefault();
                e.stopPropagation();
            }
        })
        .mousedown(function (e) {
            if ($(this).hasClass("selected")) {
                $(this).removeClass("selected");
                $(this).addClass("empty");
            } else {
                $(this).removeClass();
                $(this).addClass("selected");
            }
        });

    $("#holiday-table")
        .find(".user-td")
        .attr("width", "200")

}

$(function () {
    addFunctions();
});<commit_msg>Logical separation of some attr changes<commit_after>
var mouseState = false;
document.onmousedown = function(e){
    mouseState = true;
}
document.onmouseup = function(e){
    mouseState = false;

    // In IE obviously we use a different function
    //
    // this will deselect the text after dragging
    // has finished.
    if (document.selection) {
        document.selection.empty()
    } else {
        window.getSelection().removeAllRanges()
    }

}

function applyClass(klass) {

    /*
       Checks all the table elements,
       if they are selected, it removes the
       selected class (and all other classes)
       and applies the passed in class
    */

    $("#holiday-table")
        .find("td")
        .each(function () {
            if ($(this).hasClass("selected")) {
                $(this).removeClass();
                $(this).addClass(klass);

            }
        });
}

function submit_all() {

    /*
       Submits all entries on the form

       Takes no parameters and returns true/false
       depending on success.
    */

    var successfully_completed = false;
    $("#holiday-table")
        .find(":button")
        .not("#submit_all")
        .each(function () {
            var call = submit_holidays($(this).attr("user_id"), true)
            if (call === true) {
                successfully_completed = true;
                console.log("completed");
            } else {
                successfully_completed = false;
                console.log("Error adding holidays");
            }
        });
    if (successfully_completed) {
        alert("Holidays change successfully!");
    } else {
        alert("There was an error adding holidays");
    }
    return successfully_completed;
}

function submit_holidays(user_id, mass) {
    /*
       En masse changes a set of holidays and
       takes a user_id as a parameter.

       Mass is true/false, if true it

       Returns true for success, false for error
    */

    // create a map to hold the holidays
    var holiday_map = JSON;

    // iterate through the table and check if it's
    // selected or not, if it's selected, ignore it.
    // else, add the number and the class to the map.
    $("#holiday-table")
        .find("td[usrid='"+user_id+"']")
        .each(function () {
            // get the bg colour of the td
            var current_class = $(this).attr('class');
            if (current_class !== "selected") {
                holiday_map[$(this).text()] = current_class;
            }
        });

    // setup our ajax properties
    $.ajaxSetup({
        type: 'POST',
        dataType: 'json'
    });

    $.ajax({
        url: '/ajax/',
        data: {
            'form_type': 'mass_holidays',
            'year': $("#holiday-table").attr("year"), // from the table header
            'month': $("#holiday-table").attr("month"),
            'holiday_data': JSON.stringify(holiday_map),
            'user_id': user_id
        },
        success: function(data) {
            if (data.success === true) {
                if (!mass) {
                    alert("Holidays updated successfully");
                }
            } else {
                alert(data.error);
            }
        },
        error: function(ajaxObj, textStatus, error) {
            console.log(error);
        }
    });

    // return true so programmatic callers can
    // see we've completed
    return true;
}

function addFunctions () {

    "use strict";

    // all the daytype classes
    // are assigned a click handler which
    // swaps the colour depending on what
    // it currently is.
    $("#holiday-table")
        .find('.empty, .DAYOD, .TRAIN, .WKDAY, .SICKD, .HOLIS, .SPECI, .MEDIC, .PUABS, .PUWRK, .SATUR, .RETRN, .WKHOM, .OTHER')
        .not(":button")
        .mouseover(function (e) {
            if (mouseState) {

                if ($(this).hasClass("selected")) {
                    $(this).removeClass("selected");
                } else {
                    $(this).removeClass();
                    $(this).addClass("selected");
                    $(this).addClass("empty");
                }
                e.preventDefault();
                e.stopPropagation();
            }
        })
        .mousedown(function (e) {
            if ($(this).hasClass("selected")) {
                $(this).removeClass("selected");
                $(this).addClass("empty");
            } else {
                $(this).removeClass();
                $(this).addClass("selected");
            }
        });

}

$(function () {
    addFunctions();
    $("#holiday-table")
        .find(".user-td")
        .attr("width", "200")
});<|endoftext|>


<commit_before>'use strict';

/**
 * This module projects the project's primary functionality.
 */

var deasync = require('deasync');
var svn = require('svn-interface');
var _ = require('lodash');

var status = deasync(svn.status);
var svnAdd = deasync(svn.add);
var svnDelete = deasync(svn.delete);
var svnCommit = deasync(svn.commit);

function normalizeEntry(entry) {
  var normalized = entry;

  if (_.isUndefined(normalized)) {
    normalized = [];
  }

  if (! _.isArray(normalized)) {
    normalized = [normalized];
  }

  return normalized;
}

function getNormalizedFileStatusData(wcPath) {
  var result = status(wcPath, {});
  return normalizeEntry(result.status.target.entry);
}

function filterEntriesByStatus(entries, status) {
  return _.filter(entries, function(entry) {
    return entry['wc-status']._attribute.item === status;
  });
}

module.exports = {
  getFilesByStatus: function getFilesByStatus(wcPath, status) {
    var entries = getNormalizedFileStatusData(wcPath);
    return filterEntriesByStatus(entries, status);
  },

  getMissingFiles: function getMissingFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'missing');
  },

  getModifiedFiles: function getModifiedFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'modified');
  },

  getNewFiles: function getNewFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'unversioned');
  },

  hasMissingFiles: function hasMissingFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'missing').length > 0;
  },

  hasModifiedFiles: function hasModifiedFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'modified').length > 0;
  },

  hasNewFiles: function hasNewFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'unversioned').length > 0;
  },

  isWcDirty: function isWcDirty(wcPath) {
    return getNormalizedFileStatusData(wcPath).length > 0;
  },

  pushChanges: function pushChanges(wcPath, commitMessage) {
    _.forEach(module.exports.getNewFiles(wcPath), function(newFileEntry) {
      var newFilePath = newFileEntry._attribute.path;
      svnAdd(newFilePath);
    });

    _.forEach(module.exports.getMissingFiles(wcPath), function(missingFileEntry) {
      var missingFilePath = missingFileEntry._attribute.path;
      svnDelete(missingFilePath);
    });

    svnCommit(wcPath, {
      message: commitMessage
    });
  }
}
<commit_msg>Added docblocks for module functions<commit_after>'use strict';

/**
 * This module projects the project's primary functionality.
 */

var deasync = require('deasync');
var svn = require('svn-interface');
var _ = require('lodash');

var status = deasync(svn.status);
var svnAdd = deasync(svn.add);
var svnDelete = deasync(svn.delete);
var svnCommit = deasync(svn.commit);

function normalizeEntry(entry) {
  var normalized = entry;

  if (_.isUndefined(normalized)) {
    normalized = [];
  }

  if (! _.isArray(normalized)) {
    normalized = [normalized];
  }

  return normalized;
}

function getNormalizedFileStatusData(wcPath) {
  var result = status(wcPath, {});
  return normalizeEntry(result.status.target.entry);
}

function filterEntriesByStatus(entries, status) {
  return _.filter(entries, function(entry) {
    return entry['wc-status']._attribute.item === status;
  });
}

module.exports = {
  /**
   * Retrieves the svn status output for files in whe wc whose status
   * matches the specified value.
   *
   * @param {string} wcPath
   * @param {string} status
   *
   * @return {array}  filtered `svn status` output.
   */
  getFilesByStatus: function getFilesByStatus(wcPath, status) {
    var entries = getNormalizedFileStatusData(wcPath);
    return filterEntriesByStatus(entries, status);
  },

  /**
   * Compiles a list of files in the wc whose status is `missing`.
   *
   * @param {string} wcPath
   *
   * @return {array}
   */
  getMissingFiles: function getMissingFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'missing');
  },

  /**
   * Compiles a list of files in the wc whose status is `modified`.
   *
   * @param {string} wcPath
   *
   * @return {array}
   */
  getModifiedFiles: function getModifiedFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'modified');
  },

  /**
   * Compiles a list of files in the wc whose status is `unversioned`.
   *
   * @param {string} wcPath
   *
   * @return {array}
   */
  getNewFiles: function getNewFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'unversioned');
  },

  /**
   * Answers whether any files are found missing in the wc.
   *
   * @param {string} wcPath
   *
   * @return {Boolean}
   */
  hasMissingFiles: function hasMissingFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'missing').length > 0;
  },

  /**
   * Answers whether any files are found to be modified in the wc.
   *
   * @param {string} wcPath
   *
   * @return {Boolean}
   */
  hasModifiedFiles: function hasModifiedFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'modified').length > 0;
  },

  /**
   * Answers whether any new files are found in the wc.
   *
   * @param {string} wcPath
   *
   * @return {Boolean}
   */
  hasNewFiles: function hasNewFiles(wcPath) {
    return module.exports.getFilesByStatus(wcPath, 'unversioned').length > 0;
  },

  /**
   * Answers whether any modifications are found in the wc dir.
   *
   * @param {string} wcPath
   *
   * @return {Boolean}
   */
  isWcDirty: function isWcDirty(wcPath) {
    return getNormalizedFileStatusData(wcPath).length > 0;
  },

  /**
   * Pushes all changes found in the wc directory to the repository.
   *
   * @param {string} wcPath
   * @param {string} commitMessage
   */
  pushChanges: function pushChanges(wcPath, commitMessage) {
    _.forEach(module.exports.getNewFiles(wcPath), function(newFileEntry) {
      var newFilePath = newFileEntry._attribute.path;
      svnAdd(newFilePath);
    });

    _.forEach(module.exports.getMissingFiles(wcPath), function(missingFileEntry) {
      var missingFilePath = missingFileEntry._attribute.path;
      svnDelete(missingFilePath);
    });

    svnCommit(wcPath, {
      message: commitMessage
    });
  }
}
<|endoftext|>


<commit_before>'use babel';

import path from 'path';
import CSON from 'season';

export default {
  activate() {
    this.pkgName = 'levels-language-ruby';
    const pkgDirPath = atom.packages.resolvePackagePath(this.pkgName);
    this.pkgLanguageDirPath = path.join(pkgDirPath, 'language');

    var pkgSubscription = atom.packages.onDidActivatePackage(pkg => {
      if (pkg.name == this.pkgName) {
        if (this.consumedLevels) {
          this.startUsingLevels();
        }

        pkgSubscription.dispose();
        this.activated = true;
      }
    });
  },

  deactivate() {
    this.stopUsingLevels();
    this.consumedLevels = false;
    this.activated = false;
  },

  consumeLevels({languageRegistry}) {
    this.languageRegistry = languageRegistry;
    if (this.activated) {
      this.startUsingLevels();
    }
    this.consumedLevels = true;
  },

  startUsingLevels() {
    if (!this.usingLevels) {
      try {
        if (!this.language) {
          const configFilePath = CSON.resolve(path.join(this.pkgLanguageDirPath, 'config'));
          const executable = process.platform == 'win32' ? 'run.exe' : 'run';
          const executablePath = path.join(this.pkgLanguageDirPath, 'executables', process.platform, executable);
          const dummyGrammarPath = CSON.resolve(path.join(this.pkgLanguageDirPath, 'grammars', 'dummy'));
          this.dummyGrammar = atom.grammars.readGrammarSync(dummyGrammarPath);
          this.language = this.languageRegistry.readLanguageSync(configFilePath, executablePath);
          this.dummyGrammar.name = this.language.getGrammarName();
          this.dummyGrammar.scopeName = this.language.getScopeName();
          this.dummyGrammar.fileTypes = this.language.getLevelCodeFileTypes();
          this.language.setDummyGrammar(this.dummyGrammar);
        }

        atom.grammars.addGrammar(this.dummyGrammar);
        this.languageRegistry.addLanguage(this.language);

        this.usingLevels = true;
        this.setUpConfigManagement();
        process.env.LRB_WHITELIST_PATH = path.join(this.pkgLanguageDirPath, 'whitelist');
      } catch (error) {
        atom.notifications.addFatalError(`Failed to load the language from the ${this.pkgName} package`, {
          detail: error.message,
          stack: error.stack,
          dismissable: true
        });
      }
    }
  },

  stopUsingLevels() {
    if (this.usingLevels) {
      atom.grammars.removeGrammar(this.dummyGrammar);
      this.languageRegistry.removeLanguage(this.language);
      this.usingLevels = false;
      this.configSubscription.dispose();
      delete process.env.LRB_WHITELIST_PATH;
    }
  },

  config: {
    rubyInterpreterDirectoryPath: {
      title: 'Ruby Interpreter Directory Path',
      description: `The path to the directory that contains the Ruby interpreter
        (a file named \`ruby\` on macOS or Linux and \`ruby.exe\` on Windows, respectively).
        If no path is given, the \`PATH\` environment variable will be checked automatically.`,
      type: 'string',
      default: ''
    }
  },

  setExecutionCommandPatterns(directory) {
    const rubyInterpreterPath = path.join(directory.trim(), 'ruby');
    this.language.setExecutionCommandPatterns([`${rubyInterpreterPath} <filePath>`]);
  },

  setUpConfigManagement() {
    const configKeyPath = `${this.pkgName}.rubyInterpreterDirectoryPath`;
    this.setExecutionCommandPatterns(atom.config.get(configKeyPath));
    this.configSubscription = atom.config.onDidChange(configKeyPath, ({newValue}) => {
      return this.setExecutionCommandPatterns(newValue);
    });
  }
};<commit_msg>Use strict equality in the main module<commit_after>'use babel';

import path from 'path';
import CSON from 'season';

export default {
  activate() {
    this.pkgName = 'levels-language-ruby';
    const pkgDirPath = atom.packages.resolvePackagePath(this.pkgName);
    this.pkgLanguageDirPath = path.join(pkgDirPath, 'language');

    var pkgSubscription = atom.packages.onDidActivatePackage(pkg => {
      if (pkg.name === this.pkgName) {
        if (this.consumedLevels) {
          this.startUsingLevels();
        }

        pkgSubscription.dispose();
        this.activated = true;
      }
    });
  },

  deactivate() {
    this.stopUsingLevels();
    this.consumedLevels = false;
    this.activated = false;
  },

  consumeLevels({languageRegistry}) {
    this.languageRegistry = languageRegistry;
    if (this.activated) {
      this.startUsingLevels();
    }
    this.consumedLevels = true;
  },

  startUsingLevels() {
    if (!this.usingLevels) {
      try {
        if (!this.language) {
          const configFilePath = CSON.resolve(path.join(this.pkgLanguageDirPath, 'config'));
          const executable = process.platform === 'win32' ? 'run.exe' : 'run';
          const executablePath = path.join(this.pkgLanguageDirPath, 'executables', process.platform, executable);
          const dummyGrammarPath = CSON.resolve(path.join(this.pkgLanguageDirPath, 'grammars', 'dummy'));
          this.dummyGrammar = atom.grammars.readGrammarSync(dummyGrammarPath);
          this.language = this.languageRegistry.readLanguageSync(configFilePath, executablePath);
          this.dummyGrammar.name = this.language.getGrammarName();
          this.dummyGrammar.scopeName = this.language.getScopeName();
          this.dummyGrammar.fileTypes = this.language.getLevelCodeFileTypes();
          this.language.setDummyGrammar(this.dummyGrammar);
        }

        atom.grammars.addGrammar(this.dummyGrammar);
        this.languageRegistry.addLanguage(this.language);

        this.usingLevels = true;
        this.setUpConfigManagement();
        process.env.LRB_WHITELIST_PATH = path.join(this.pkgLanguageDirPath, 'whitelist');
      } catch (error) {
        atom.notifications.addFatalError(`Failed to load the language from the ${this.pkgName} package`, {
          detail: error.message,
          stack: error.stack,
          dismissable: true
        });
      }
    }
  },

  stopUsingLevels() {
    if (this.usingLevels) {
      atom.grammars.removeGrammar(this.dummyGrammar);
      this.languageRegistry.removeLanguage(this.language);
      this.usingLevels = false;
      this.configSubscription.dispose();
      delete process.env.LRB_WHITELIST_PATH;
    }
  },

  config: {
    rubyInterpreterDirectoryPath: {
      title: 'Ruby Interpreter Directory Path',
      description: `The path to the directory that contains the Ruby interpreter
        (a file named \`ruby\` on macOS or Linux and \`ruby.exe\` on Windows, respectively).
        If no path is given, the \`PATH\` environment variable will be checked automatically.`,
      type: 'string',
      default: ''
    }
  },

  setExecutionCommandPatterns(directory) {
    const rubyInterpreterPath = path.join(directory.trim(), 'ruby');
    this.language.setExecutionCommandPatterns([`${rubyInterpreterPath} <filePath>`]);
  },

  setUpConfigManagement() {
    const configKeyPath = `${this.pkgName}.rubyInterpreterDirectoryPath`;
    this.setExecutionCommandPatterns(atom.config.get(configKeyPath));
    this.configSubscription = atom.config.onDidChange(configKeyPath, ({newValue}) => {
      return this.setExecutionCommandPatterns(newValue);
    });
  }
};<|endoftext|>


<commit_before>const {CompositeDisposable, Disposable} = require('atom')
const settings = require('./settings')
const Ui = require('./ui')
const globalSubscriptions = require('./global-subscriptions')
const Provider = require('./provider/provider')

const {isNarrowEditor, getVisibleEditors, isTextEditor, suppressEvent} = require('./utils')
module.exports = {
  config: settings.config,
  lastFocusedNarrowEditor: null,

  serialize () {
    return {
      queryHistory: Ui.queryHistory.serialize()
    }
  },

  activate (restoredState) {
    Ui.queryHistory.deserialize(restoredState.queryHistory)
    const onMouseDown = this.onMouseDown.bind(this)
    this.subscriptions = new CompositeDisposable()
    this.subscriptions.add(
      this.observeStopChangingActivePaneItem(),
      this.registerCommands(),
      atom.workspace.observeTextEditors(editor => {
        let sub
        editor.element.addEventListener('mousedown', onMouseDown, true)
        const removeListener = () => editor.element.removeEventListener('mousedown', onMouseDown, true)
        this.subscriptions.add((sub = new Disposable(removeListener)))
        editor.onDidDestroy(() => this.subscriptions.remove(sub))
      })
    )
  },

  isControlBarElementClick (event) {
    const ui = Ui.get(event.currentTarget.getModel())
    return ui ? ui.controlBar.containsElement(event.target) : false
  },

  onMouseDown (event) {
    if (event.detail !== 2) return // handle double click only

    if (!Ui.getSize()) {
      if (settings.get('Search.startByDoubleClick')) {
        suppressEvent(event)
        this.narrow('search', {queryCurrentWord: true, focus: false})
      }
    } else {
      if (settings.get('queryCurrentWordByDoubleClick') && !this.isControlBarElementClick(event)) {
        suppressEvent(event)
        this.getUi().setQueryFromCurrentWord()
      }
    }
  },

  deactivate () {
    globalSubscriptions.dispose()
    if (this.subscriptions) this.subscriptions.dispose()
  },

  registerCommands () {
    const getUi = fn => {
      const ui = this.getUi()
      if (ui) fn(ui)
    }

    // prettier-ignore
    return atom.commands.add('atom-text-editor', {
      // Shared commands
      'narrow:activate-package': () => {}, // HACK activate via atom.command.dispatch with the mechanism of activationCommands
      'narrow:focus': () => getUi(ui => ui.toggleFocus()),
      'narrow:focus-prompt': () => getUi(ui => ui.focusPrompt()),
      'narrow:refresh': () => getUi(ui => ui.refreshManually()),
      'narrow:close': () => {
        const ui = this.getUi({skipProtected: true})
        if (ui) ui.close()
      },
      'narrow:next-item': () => getUi(ui => ui.confirmItemForDirection('next')),
      'narrow:previous-item': () => getUi(ui => ui.confirmItemForDirection('previous')),
      'narrow:next-query-history': () => getUi(ui => ui.setQueryFromHistroy('next')),
      'narrow:previous-query-history': () => getUi(ui => ui.setQueryFromHistroy('previous')),
      'narrow:reopen': () => this.reopen(),
      'narrow:query-current-word': () => getUi(ui => ui.setQueryFromCurrentWord()),

      // Providers
      // -------------------------
      'narrow:symbols': () => this.narrow('symbols'),
      'narrow:symbols-by-current-word': () => this.narrow('symbols', {queryCurrentWord: true}),

      'narrow:project-symbols': () => this.narrow('project-symbols'),
      'narrow:project-symbols-by-current-word': () => this.narrow('project-symbols', {queryCurrentWord: true}),

      'narrow:git-diff-all': () => this.narrow('git-diff-all'),

      'narrow:fold': () => this.narrow('fold'),
      'narrow:fold-by-current-word': () => this.narrow('fold', {queryCurrentWord: true}),

      'narrow:scan': () => this.narrow('scan'),
      'narrow:scan-by-current-word': () => this.narrow('scan', {queryCurrentWord: true}),

      // search family
      'narrow:search': () => this.narrow('search'),
      'narrow:search-by-current-word': () => this.narrow('search', {queryCurrentWord: true}),
      'narrow:search-by-current-word-without-focus': () => this.narrow('search', {queryCurrentWord: true, focus: false}),
      'narrow:search-current-project': () => this.narrow('search', {currentProject: true}),
      'narrow:search-current-project-by-current-word': () => this.narrow('search', {currentProject: true, queryCurrentWord: true}),

      'narrow:atom-scan': () => this.narrow('atom-scan'),
      'narrow:atom-scan-by-current-word': () => this.narrow('atom-scan', {queryCurrentWord: true}),

      'narrow:toggle-search-start-by-double-click': () => settings.toggle('Search.startByDoubleClick')
    })
  },

  observeStopChangingActivePaneItem () {
    return atom.workspace.onDidStopChangingActivePaneItem(item => {
      if (!isTextEditor(item)) return

      if (isNarrowEditor(item)) {
        this.lastFocusedNarrowEditor = item
        return
      }

      Ui.forEach(ui => {
        // When non-narrow-editor editor was activated
        // no longer restore editor's state at cancel.
        ui.provider.needRestoreEditorState = false
        if (!ui.isSamePaneItem(item)) ui.startSyncToEditor(item)

        ui.highlighter.clearCurrentAndLineMarker()
        ui.highlighter.highlightEditor(item)
      })
    })
  },

  getUi ({skipProtected} = {}) {
    const ui = Ui.get(this.lastFocusedNarrowEditor)
    if (ui) {
      if (skipProtected) {
        if (!ui.protected) return ui
      } else {
        return ui
      }
    }

    const visibleEditors = getVisibleEditors()
    let invisibleNarrowEditor = null
    let narrowEditors = atom.workspace.getTextEditors().filter(isNarrowEditor)
    if (skipProtected) {
      const isNotProtected = editor => !Ui.get(editor).protected
      narrowEditors = narrowEditors.filter(isNotProtected)
    }

    for (const editor of narrowEditors) {
      if (visibleEditors.includes(editor)) {
        return Ui.get(editor)
      } else {
        if (!invisibleNarrowEditor) invisibleNarrowEditor = editor
      }
    }
    if (invisibleNarrowEditor) return Ui.get(invisibleNarrowEditor)
  },

  reopen () {
    Provider.reopen()
  },

  // Return promise
  narrow (name, options) {
    return Provider.start(name, options)
  },

  consumeVim ({getEditorState, observeVimStates}) {
    this.subscriptions.add(
      observeVimStates(vimState => {
        if (!isNarrowEditor(vimState.editor)) return

        vimState.onDidActivateMode(({mode, submode}) => {
          if (mode === 'insert') {
            const ui = Ui.get(vimState.editor)
            if (ui) ui.narrowEditor.setReadOnly(false)
          } else if (mode === 'normal') {
            const ui = Ui.get(vimState.editor)
            if (ui) ui.narrowEditor.setReadOnly(true)
          }
        })
      })
    )

    // return search text
    function confirmSearch () {
      const editor = atom.workspace.getActiveTextEditor()
      const vimState = getEditorState(editor)
      const text = vimState.searchInput.editor.getText()
      vimState.searchInput.confirm()
      atom.commands.dispatch(vimState.editorElement, 'vim-mode-plus:clear-highlight-search')
      return text
    }

    this.subscriptions.add(
      atom.commands.add('atom-text-editor.vim-mode-plus-search', {
        'vim-mode-plus-user:narrow:scan': () => this.narrow('scan', {query: confirmSearch()}),
        'vim-mode-plus-user:narrow:search': () => this.narrow('search', {query: confirmSearch()}),
        'vim-mode-plus-user:narrow:atom-scan': () => this.narrow('atom-scan', {query: confirmSearch()}),
        'vim-mode-plus-user:narrow:search-current-project': () =>
          this.narrow('search', {query: confirmSearch(), currentProject: true})
      })
    )
  },

  consumeInlineGitDiff (service) {
    Provider.setService({inlineGitDiff: service})
  },

  registerProvider (name, klass) {
    Provider.registerProvider(name, klass)
  },

  provideNarrow () {
    return {
      Provider: Provider,
      registerProvider: this.registerProvider.bind(this),
      narrow: this.narrow.bind(this)
    }
  }
}
<commit_msg>:bug: now correctly fire auto-preview on first click of narrow-editor<commit_after>const {CompositeDisposable, Disposable} = require('atom')
const settings = require('./settings')
const Ui = require('./ui')
const globalSubscriptions = require('./global-subscriptions')
const Provider = require('./provider/provider')

const {isNarrowEditor, getVisibleEditors, isTextEditor, suppressEvent} = require('./utils')
module.exports = {
  config: settings.config,
  lastFocusedNarrowEditor: null,

  serialize () {
    return {
      queryHistory: Ui.queryHistory.serialize()
    }
  },

  activate (restoredState) {
    Ui.queryHistory.deserialize(restoredState.queryHistory)
    const onMouseDown = this.onMouseDown.bind(this)
    this.subscriptions = new CompositeDisposable()
    this.subscriptions.add(
      this.observeStopChangingActivePaneItem(),
      this.registerCommands(),
      atom.workspace.observeTextEditors(editor => {
        let sub
        editor.element.addEventListener('mousedown', onMouseDown, true)
        const removeListener = () => editor.element.removeEventListener('mousedown', onMouseDown, true)
        this.subscriptions.add((sub = new Disposable(removeListener)))
        editor.onDidDestroy(() => this.subscriptions.remove(sub))
      })
    )
  },

  isControlBarElementClick (event) {
    const ui = Ui.get(event.currentTarget.getModel())
    return ui ? ui.controlBar.containsElement(event.target) : false
  },

  onMouseDown (event) {
    if (event.detail !== 2) return // handle double click only

    if (!Ui.getSize()) {
      if (settings.get('Search.startByDoubleClick')) {
        suppressEvent(event)
        this.narrow('search', {queryCurrentWord: true, focus: false})
      }
    } else {
      if (settings.get('queryCurrentWordByDoubleClick') && !this.isControlBarElementClick(event)) {
        suppressEvent(event)
        this.getUi().setQueryFromCurrentWord()
      }
    }
  },

  deactivate () {
    globalSubscriptions.dispose()
    if (this.subscriptions) this.subscriptions.dispose()
  },

  registerCommands () {
    const getUi = fn => {
      const ui = this.getUi()
      if (ui) fn(ui)
    }

    // prettier-ignore
    return atom.commands.add('atom-text-editor', {
      // Shared commands
      'narrow:activate-package': () => {}, // HACK activate via atom.command.dispatch with the mechanism of activationCommands
      'narrow:focus': () => getUi(ui => ui.toggleFocus()),
      'narrow:focus-prompt': () => getUi(ui => ui.focusPrompt()),
      'narrow:refresh': () => getUi(ui => ui.refreshManually()),
      'narrow:close': () => {
        const ui = this.getUi({skipProtected: true})
        if (ui) ui.close()
      },
      'narrow:next-item': () => getUi(ui => ui.confirmItemForDirection('next')),
      'narrow:previous-item': () => getUi(ui => ui.confirmItemForDirection('previous')),
      'narrow:next-query-history': () => getUi(ui => ui.setQueryFromHistroy('next')),
      'narrow:previous-query-history': () => getUi(ui => ui.setQueryFromHistroy('previous')),
      'narrow:reopen': () => this.reopen(),
      'narrow:query-current-word': () => getUi(ui => ui.setQueryFromCurrentWord()),

      // Providers
      // -------------------------
      'narrow:symbols': () => this.narrow('symbols'),
      'narrow:symbols-by-current-word': () => this.narrow('symbols', {queryCurrentWord: true}),

      'narrow:project-symbols': () => this.narrow('project-symbols'),
      'narrow:project-symbols-by-current-word': () => this.narrow('project-symbols', {queryCurrentWord: true}),

      'narrow:git-diff-all': () => this.narrow('git-diff-all'),

      'narrow:fold': () => this.narrow('fold'),
      'narrow:fold-by-current-word': () => this.narrow('fold', {queryCurrentWord: true}),

      'narrow:scan': () => this.narrow('scan'),
      'narrow:scan-by-current-word': () => this.narrow('scan', {queryCurrentWord: true}),

      // search family
      'narrow:search': () => this.narrow('search'),
      'narrow:search-by-current-word': () => this.narrow('search', {queryCurrentWord: true}),
      'narrow:search-by-current-word-without-focus': () => this.narrow('search', {queryCurrentWord: true, focus: false}),
      'narrow:search-current-project': () => this.narrow('search', {currentProject: true}),
      'narrow:search-current-project-by-current-word': () => this.narrow('search', {currentProject: true, queryCurrentWord: true}),

      'narrow:atom-scan': () => this.narrow('atom-scan'),
      'narrow:atom-scan-by-current-word': () => this.narrow('atom-scan', {queryCurrentWord: true}),

      'narrow:toggle-search-start-by-double-click': () => settings.toggle('Search.startByDoubleClick')
    })
  },

  observeStopChangingActivePaneItem () {
    return atom.workspace.onDidStopChangingActivePaneItem(item => {
      if (!isTextEditor(item)) return

      if (isNarrowEditor(item)) {
        this.lastFocusedNarrowEditor = item
        const ui = Ui.get(item)
        if (ui.autoPreview) {
          ui.previewWithDelay()
        }
        return
      }

      Ui.forEach(ui => {
        // When non-narrow-editor editor was activated
        // no longer restore editor's state at cancel.
        ui.provider.needRestoreEditorState = false
        if (!ui.isSamePaneItem(item)) ui.startSyncToEditor(item)

        ui.highlighter.clearCurrentAndLineMarker()
        ui.highlighter.highlightEditor(item)
      })
    })
  },

  getUi ({skipProtected} = {}) {
    const ui = Ui.get(this.lastFocusedNarrowEditor)
    if (ui) {
      if (skipProtected) {
        if (!ui.protected) return ui
      } else {
        return ui
      }
    }

    const visibleEditors = getVisibleEditors()
    let invisibleNarrowEditor = null
    let narrowEditors = atom.workspace.getTextEditors().filter(isNarrowEditor)
    if (skipProtected) {
      const isNotProtected = editor => !Ui.get(editor).protected
      narrowEditors = narrowEditors.filter(isNotProtected)
    }

    for (const editor of narrowEditors) {
      if (visibleEditors.includes(editor)) {
        return Ui.get(editor)
      } else {
        if (!invisibleNarrowEditor) invisibleNarrowEditor = editor
      }
    }
    if (invisibleNarrowEditor) return Ui.get(invisibleNarrowEditor)
  },

  reopen () {
    Provider.reopen()
  },

  // Return promise
  narrow (name, options) {
    return Provider.start(name, options)
  },

  consumeVim ({getEditorState, observeVimStates}) {
    this.subscriptions.add(
      observeVimStates(vimState => {
        if (!isNarrowEditor(vimState.editor)) return

        vimState.onDidActivateMode(({mode, submode}) => {
          if (mode === 'insert') {
            const ui = Ui.get(vimState.editor)
            if (ui) ui.narrowEditor.setReadOnly(false)
          } else if (mode === 'normal') {
            const ui = Ui.get(vimState.editor)
            if (ui) ui.narrowEditor.setReadOnly(true)
          }
        })
      })
    )

    // return search text
    function confirmSearch () {
      const editor = atom.workspace.getActiveTextEditor()
      const vimState = getEditorState(editor)
      const text = vimState.searchInput.editor.getText()
      vimState.searchInput.confirm()
      atom.commands.dispatch(vimState.editorElement, 'vim-mode-plus:clear-highlight-search')
      return text
    }

    this.subscriptions.add(
      atom.commands.add('atom-text-editor.vim-mode-plus-search', {
        'vim-mode-plus-user:narrow:scan': () => this.narrow('scan', {query: confirmSearch()}),
        'vim-mode-plus-user:narrow:search': () => this.narrow('search', {query: confirmSearch()}),
        'vim-mode-plus-user:narrow:atom-scan': () => this.narrow('atom-scan', {query: confirmSearch()}),
        'vim-mode-plus-user:narrow:search-current-project': () =>
          this.narrow('search', {query: confirmSearch(), currentProject: true})
      })
    )
  },

  consumeInlineGitDiff (service) {
    Provider.setService({inlineGitDiff: service})
  },

  registerProvider (name, klass) {
    Provider.registerProvider(name, klass)
  },

  provideNarrow () {
    return {
      Provider: Provider,
      registerProvider: this.registerProvider.bind(this),
      narrow: this.narrow.bind(this)
    }
  }
}
<|endoftext|>


<commit_before>const data = require("sdk/self").data;
const tabs = require("sdk/tabs");
const localize = require("sdk/l10n").get;
const prefs = require("sdk/simple-prefs").prefs;
const testList = require("../data/tests/testlist").testList;
const editURL= /https:\/\/developer\.mozilla\.org\/.+(?:\$(?:edit|translate)|\/docs\/new(?:\?|$))/;
const templateURL= /https:\/\/developer\.mozilla\.org\/.+?\/docs\/(?:templates|Template(?::|%3A))/;

let tabWorkers = new WeakMap();
let sidebarWorker = null;

let sidebar = require("sdk/ui/sidebar").Sidebar({
  id: "mdn-doc-tests",
  title: "MDN documentation tester",
  url: data.url("sidebar.html"),
  onReady: function (sbWorker) {
    sidebarWorker = sbWorker;
    sbWorker.port.on("runTests", function() {
      let tabWorker = tabWorkers.get(tabs.activeTab);
      tabWorker.port.emit("runTests");
      tabWorker.port.on("finishedTests", () => sidebarWorker.port.emit("hideProgressBar"));
    });
  }
});

function initializeTestingEnvironment(tab, overwriteWorker) {
  if (editURL.test(tab.url) && !templateURL.test(tab.url)) {
    if (!tabWorkers.has(tab) || overwriteWorker) {
      let tabWorker = tab.attach({
        contentScriptFile: [
          "./doctests.js",
          ...testList.map(test => "./tests/" + test),
          "./runtests.js"
        ],
        contentScriptOptions: {
          LONG_ARTICLE_WORD_COUNT_THRESHOLD: prefs.longArticleWordCountThreshold
        }
      });
      tabWorker.port.on("processTestResult", function(testObj, id){
        testObj.name = localize(testObj.name);
        testObj.desc = localize(testObj.desc);
        testObj.errors.forEach((error, i, errors) => {
          errors[i] = {
            msg: localize.apply(this, [error.msg].concat(error.msgParams)),
            type: error.type
          };
        });

        if (sidebarWorker) {
          sidebarWorker.port.emit("showTestResult", testObj, id, prefs);
          sidebarWorker.port.emit("updateProgress", Math.round(100 / testList.length));
        }
      });

      tabWorkers.set(tab, tabWorker);
    }
  }
  toggleSidebar();
};

function destroyTestingEnvironment(tab) {
  tabWorkers.remove(tab);
};

function toggleSidebar() {
  if (editURL.test(tabs.activeTab.url) && !templateURL.test(tabs.activeTab.url)) {
    sidebar.show();
  } else {
    sidebar.hide();
  }
};

tabs.on("activate", toggleSidebar);
tabs.on("ready", initializeTestingEnvironment);
tabs.on("pagehide", destroyTestingEnvironment);
tabs.on("pageshow", initializeTestingEnvironment);
<commit_msg>Avoid showing the sidebar when viewing the source of a page (fixes #189)<commit_after>const data = require("sdk/self").data;
const tabs = require("sdk/tabs");
const localize = require("sdk/l10n").get;
const prefs = require("sdk/simple-prefs").prefs;
const testList = require("../data/tests/testlist").testList;
const editURL= /^https:\/\/developer\.mozilla\.org\/.+(?:\$(?:edit|translate)|\/docs\/new(?:\?|$))/;
const templateURL= /^https:\/\/developer\.mozilla\.org\/.+?\/docs\/(?:templates|Template(?::|%3A))/;

let tabWorkers = new WeakMap();
let sidebarWorker = null;

let sidebar = require("sdk/ui/sidebar").Sidebar({
  id: "mdn-doc-tests",
  title: "MDN documentation tester",
  url: data.url("sidebar.html"),
  onReady: function (sbWorker) {
    sidebarWorker = sbWorker;
    sbWorker.port.on("runTests", function() {
      let tabWorker = tabWorkers.get(tabs.activeTab);
      tabWorker.port.emit("runTests");
      tabWorker.port.on("finishedTests", () => sidebarWorker.port.emit("hideProgressBar"));
    });
  }
});

function initializeTestingEnvironment(tab, overwriteWorker) {
  if (editURL.test(tab.url) && !templateURL.test(tab.url)) {
    if (!tabWorkers.has(tab) || overwriteWorker) {
      let tabWorker = tab.attach({
        contentScriptFile: [
          "./doctests.js",
          ...testList.map(test => "./tests/" + test),
          "./runtests.js"
        ],
        contentScriptOptions: {
          LONG_ARTICLE_WORD_COUNT_THRESHOLD: prefs.longArticleWordCountThreshold
        }
      });
      tabWorker.port.on("processTestResult", function(testObj, id){
        testObj.name = localize(testObj.name);
        testObj.desc = localize(testObj.desc);
        testObj.errors.forEach((error, i, errors) => {
          errors[i] = {
            msg: localize.apply(this, [error.msg].concat(error.msgParams)),
            type: error.type
          };
        });

        if (sidebarWorker) {
          sidebarWorker.port.emit("showTestResult", testObj, id, prefs);
          sidebarWorker.port.emit("updateProgress", Math.round(100 / testList.length));
        }
      });

      tabWorkers.set(tab, tabWorker);
    }
  }
  toggleSidebar();
};

function destroyTestingEnvironment(tab) {
  tabWorkers.remove(tab);
};

function toggleSidebar() {
  if (editURL.test(tabs.activeTab.url) && !templateURL.test(tabs.activeTab.url)) {
    sidebar.show();
  } else {
    sidebar.hide();
  }
};

tabs.on("activate", toggleSidebar);
tabs.on("ready", initializeTestingEnvironment);
tabs.on("pagehide", destroyTestingEnvironment);
tabs.on("pageshow", initializeTestingEnvironment);
<|endoftext|>


<commit_before>/* SDK Modules */
const global_prefs = require('sdk/preferences/service');
const simple_prefs = require('sdk/simple-prefs');
const prefs = simple_prefs.prefs;
const self = require("sdk/self");
/* Modules */
const logger = require('./logger.js');

/* Constants */
const ENABLED_PREF = 'enabled';
const NEWTAB_PREF = 'browser.newtab.url';
const NEWTAB_FILE = 'newtab.html';

//run on addon load
exports.main = function(options, callbacks) {
    setNewTabUrl();
};

//listen to preference changes
simple_prefs.on(ENABLED_PREF, setNewTabUrl);

/**
 * Sets new tab URL if addon is enablaed.
 * Resets new tab URL if addon is disabled.
 */
function setNewTabUrl() {
    if(prefs.enabled) {
        global_prefs.set(NEWTAB_PREF, self.data.url(NEWTAB_FILE));
    } else {
        global_prefs.reset(NEWTAB_PREF);
    }
}
<commit_msg>Refactoring<commit_after>/* SDK Modules */
const globalPrefs = require('sdk/preferences/service');
const simplePrefs = require('sdk/simple-prefs');
const self = require("sdk/self");
/* Modules */
const logger = require('./logger.js');

/* Constants */
const ENABLED_PREF = 'enabled';
const NEWTAB_PREF = 'browser.newtab.url';
const NEWTAB_FILE = 'newtab.html';

//run on addon load
exports.main = function(options, callbacks) {
    setNewTabUrl();
};

//listen to preference changes
simplePrefs.on(ENABLED_PREF, setNewTabUrl);

/**
 * Sets new tab URL if addon is enabled.
 * Resets new tab URL if addon is disabled.
 */
function setNewTabUrl() {
    if(simplePrefs.prefs[ENABLED_PREF]) {
        globalPrefs.set(NEWTAB_PREF, self.data.url(NEWTAB_FILE));
    } else {
        globalPrefs.reset(NEWTAB_PREF);
    }
}
<|endoftext|>


<commit_before>// Bootstrap the extension
let { Cc, Ci, Cu } = require('chrome');
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm");

const { Panel } = require("dev/panel");
const { Disposable, setup } = require("sdk/core/disposable");
const { Class } = require("sdk/core/heritage");
const pageMod = require("sdk/page-mod");
const self = require("sdk/self");
const { MessageChannel } = require("sdk/messaging");
const tabs = require("sdk/tabs");
const { each, pairs, values } = require("sdk/util/sequence");

const workers = []; // for communicating with the Web pages under test

function detachWorker(worker, workerArray) {
	for (var index = 0; index < workerArray.length; index++) {
		if (workerArray[index].worker === worker) {
			break;
		}
	}
	if (index < workerArray.length) {
		// TODO: memory leak?
		workerArray[index].worker = undefined;
		workerArray[index].addonSide = undefined;
		workerArray[index].panelSide = undefined;

	}
}

function matchWorker(worker, workerArray) {
	for (var index = 0; index < workerArray.length; index++) {
		if (workerArray[index].worker === worker) {
			break;
		}
	}
	if (index < workerArray.length) {
		return workerArray[index];
	}
	return undefined;
}

function matchTabId(tabId, workerArray) {
	for (var index = 0; index < workerArray.length; index++) {
		if (workerArray[index].tabId === tabId) {
			break;
		}
	}
	if (index < workerArray.length) {
		return workerArray[index];
	}
	return undefined;

}

// Inject aXe into every frame
pageMod.PageMod({
	include: "*",
	contentScriptFile: self.data.url("axe.js"),
	attachTo: ['existing', 'frame']
});

// Inject aXe and the Web page communicator into the top frame
pageMod.PageMod({
	include: "*",
	contentScriptFile: [
		self.data.url("axe.js"),
		self.data.url("axe-communicator.js")
	],
	attachTo: ['existing', 'top'],
	onAttach: function(worker) {
		// Set up the channel for communicatig with our panel UI
		var channel = new MessageChannel();
		var workerEntry = matchTabId(worker.tab.id, workers);
		// messages from the panel arrive here
		channel.port1.onmessage = function(event) {
			let message = JSON.parse(event.data);
			switch (message.command) {
				case 'analyze':
					// console.log('analyze');
					worker.port.emit("axe.analyze");
					break;
				case 'highlight':
				case 'inspect':
					// TODO: frames
					let workerEntry = matchTabId(worker.tab.id, workers);
					let toolbox = workerEntry.panel.toolbox;
					let toolpanels = toolbox.getToolPanels();
					let inspector = toolpanels.get('inspector');
					inspector = toolpanels.get('inspector');
					let walker = inspector.walker;
					inspector.inspector.walker.querySelector(inspector.inspector.walker.rootNode, message.target[0])
						.then(function (result) {
							if (message.command === 'inspect') {
								toolbox.selection.setNodeFront(result);
								toolbox.selectTool('inspector');
							} else {
								toolbox.highlighterUtils.highlightNodeFront(result)
							}
							// console.log('inspector.inspector walker selector result: ' + result.nodeName);
						});
					break;
			}
		}
		if (!workerEntry) {
			workers.push({
				worker: worker,
				tabId: worker.tab.id,
				addonSide: channel.port1,
				panelSide: channel.port2
			});
			worker.tab.on('pageshow', function () {
				// Called when the page content is shown, whether from the cache or from the network
				if (!worker || !worker.tab) {
					return;
				}
				var workerEntry = matchTabId(worker.tab.id, workers);
				if (workerEntry) {
					// if the content is from the cache, the refresh message will stay
					workerEntry.addonSide.postMessage({refresh:true});
				}
			});
		} else {
			workerEntry.addonSide = channel.port1;
			workerEntry.panelSide = channel.port2;
			workerEntry.worker = worker;
			if (workerEntry.panel) {
				workerEntry.panel.postMessage("init", [workerEntry.panelSide]);
			}
		}
		worker.on ('detach', function () {
			detachWorker(worker, workers);
		});
		worker.port.on("axe.results", function(results) {
			// Post the results form the document back to the panel for display
			var workerEntry = matchWorker(worker, workers);
			if (workerEntry) {
				workerEntry.addonSide.postMessage(results);
			}
		});
		worker.port.on("axe.loaded", function(results) {
			// when the new document loads, clear the panel results
			var workerEntry = matchWorker(worker, workers);
			if (workerEntry) {
				// content is not from the cache, inform user to click analyze
				workerEntry.addonSide.postMessage({loaded:true});
			}
		});
	}
});

// define a AxePanel class
// that inherits from dev/panel
const AxePanel = Class({
	extends: Panel,
	label: "Accessibility` Audit",
	tooltip: "aXe Accessibility Audit",
	icon: self.data.url("axe.png"),
	url: self.data.url("axe-panel.html"),
	// when the panel is created,
	// take a reference to the debuggee
	setup: function(options) {
		this.debuggee = options.debuggee;
	},
	dispose: function() {
		this.debuggee = null;
	},
	// when the panel's script is ready,
	// send it a message containing
	// the debuggee
	onReady: function() {
		this.debuggee.start();
		// TODO: is the active tab the only way we can do this?
		var workerEntry = matchTabId(tabs.activeTab.id, workers);
		workerEntry.panel = this;
		this.postMessage("init", [workerEntry.panelSide]);
	},
	initialize: function(toolbox) {
		this.toolbox = toolbox;
	}
});
exports.AxePanel = AxePanel;

// create a new tool,
// initialized with the
// AxePanel's constructor

// this code is adapted from http://mxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/dev/toolbox.js?raw=1
// only difference is passing the toolbox into the constructor and removing the themes

const Tool = Class({
  extends: Disposable,
  setup: function(params) {
    const { panels } = params;

    this.panels = panels;

    each(([key, Panel]) => {
      const { url, label, tooltip, icon } = Panel.prototype;
      const { id } = Panel.prototype;

      gDevTools.registerTool({
        id: id,
        url: "about:blank",
        label: label,
        tooltip: tooltip,
        icon: icon,
        isTargetSupported: target => target.isLocalTab,
        build: (window, toolbox) => {
          const panel = new Panel(toolbox);
          setup(panel, { window: window,
                         toolbox: toolbox,
                         url: url });

          return panel.ready();
        }
      });
    }, pairs(panels));
  },
  dispose: function() {
    each(Panel => gDevTools.unregisterTool(Panel.prototype.id),
         values(this.panels));
  }
});

const axeTool = new Tool({
	panels: { axeMain: AxePanel }
});

// this code sucks, but we have to select the inspector when the toolbox inits or else we cannot get hold of the inspector
gDevTools.on('toolbox-ready', function (eventId, toolbox) {
	var toolpanels = toolbox.getToolPanels();
	var inspector = toolpanels.get('inspector');
	toolbox.selectTool('inspector');
});

// console.log('bootstrapped: ');

<commit_msg>add support for highlighting and inspecting in iframes<commit_after>// Bootstrap the extension
let { Cc, Ci, Cu } = require('chrome');
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm");

const { Panel } = require("dev/panel");
const { Disposable, setup } = require("sdk/core/disposable");
const { Class } = require("sdk/core/heritage");
const pageMod = require("sdk/page-mod");
const self = require("sdk/self");
const { MessageChannel } = require("sdk/messaging");
const tabs = require("sdk/tabs");
const { each, pairs, values } = require("sdk/util/sequence");

const workers = []; // for communicating with the Web pages under test

function detachWorker(worker, workerArray) {
	for (var index = 0; index < workerArray.length; index++) {
		if (workerArray[index].worker === worker) {
			break;
		}
	}
	if (index < workerArray.length) {
		// TODO: memory leak?
		workerArray[index].worker = undefined;
		workerArray[index].addonSide = undefined;
		workerArray[index].panelSide = undefined;

	}
}

function matchWorker(worker, workerArray) {
	for (var index = 0; index < workerArray.length; index++) {
		if (workerArray[index].worker === worker) {
			break;
		}
	}
	if (index < workerArray.length) {
		return workerArray[index];
	}
	return undefined;
}

function matchTabId(tabId, workerArray) {
	for (var index = 0; index < workerArray.length; index++) {
		if (workerArray[index].tabId === tabId) {
			break;
		}
	}
	if (index < workerArray.length) {
		return workerArray[index];
	}
	return undefined;

}

// Inject aXe into every frame
pageMod.PageMod({
	include: "*",
	contentScriptFile: self.data.url("axe.js"),
	attachTo: ['existing', 'frame']
});

// Inject aXe and the Web page communicator into the top frame
pageMod.PageMod({
	include: "*",
	contentScriptFile: [
		self.data.url("axe.js"),
		self.data.url("axe-communicator.js")
	],
	attachTo: ['existing', 'top'],
	onAttach: function(worker) {
		// Set up the channel for communicatig with our panel UI
		var channel = new MessageChannel();
		var workerEntry = matchTabId(worker.tab.id, workers);
		// messages from the panel arrive here
		channel.port1.onmessage = function(event) {
			let message = JSON.parse(event.data);
			switch (message.command) {
				case 'analyze':
					// console.log('analyze');
					worker.port.emit("axe.analyze");
					break;
				case 'highlight':
				case 'inspect':
					// TODO: frames
					let workerEntry = matchTabId(worker.tab.id, workers);
					let toolbox = workerEntry.panel.toolbox;
					let toolpanels = toolbox.getToolPanels();
					let inspector = toolpanels.get('inspector');
					inspector = toolpanels.get('inspector');
					let walker = inspector.inspector.walker;
					walker.querySelector(walker.rootNode, message.target[0])
						.then(function (result) {
							var depth = 1, contentDocument;
							while(result.nodeName === 'IFRAME' && message.target.length > depth) {
								contentDocument = result.rawNode().contentDocument;
								result = walker.frontForRawNode(contentDocument.querySelector(message.target[depth]));
								depth += 1;
							}
							if (message.command === 'inspect') {
								toolbox.selection.setNodeFront(result);
								toolbox.selectTool('inspector');
							} else {
								toolbox.highlighterUtils.highlightNodeFront(result)
							}
							// console.log('inspector.inspector walker selector result: ' + result.nodeName);
						});
					break;
			}
		}
		if (!workerEntry) {
			workers.push({
				worker: worker,
				tabId: worker.tab.id,
				addonSide: channel.port1,
				panelSide: channel.port2
			});
			worker.tab.on('pageshow', function () {
				// Called when the page content is shown, whether from the cache or from the network
				if (!worker || !worker.tab) {
					return;
				}
				var workerEntry = matchTabId(worker.tab.id, workers);
				if (workerEntry) {
					// if the content is from the cache, the refresh message will stay
					workerEntry.addonSide.postMessage({refresh:true});
				}
			});
		} else {
			workerEntry.addonSide = channel.port1;
			workerEntry.panelSide = channel.port2;
			workerEntry.worker = worker;
			if (workerEntry.panel) {
				workerEntry.panel.postMessage("init", [workerEntry.panelSide]);
			}
		}
		worker.on ('detach', function () {
			detachWorker(worker, workers);
		});
		worker.port.on("axe.results", function(results) {
			// Post the results form the document back to the panel for display
			var workerEntry = matchWorker(worker, workers);
			if (workerEntry) {
				workerEntry.addonSide.postMessage(results);
			}
		});
		worker.port.on("axe.loaded", function(results) {
			// when the new document loads, clear the panel results
			var workerEntry = matchWorker(worker, workers);
			if (workerEntry) {
				// content is not from the cache, inform user to click analyze
				workerEntry.addonSide.postMessage({loaded:true});
			}
		});
	}
});

// define a AxePanel class
// that inherits from dev/panel
const AxePanel = Class({
	extends: Panel,
	label: "Accessibility` Audit",
	tooltip: "aXe Accessibility Audit",
	icon: self.data.url("axe.png"),
	url: self.data.url("axe-panel.html"),
	// when the panel is created,
	// take a reference to the debuggee
	setup: function(options) {
		this.debuggee = options.debuggee;
	},
	dispose: function() {
		this.debuggee = null;
	},
	// when the panel's script is ready,
	// send it a message containing
	// the debuggee
	onReady: function() {
		this.debuggee.start();
		// TODO: is the active tab the only way we can do this?
		var workerEntry = matchTabId(tabs.activeTab.id, workers);
		workerEntry.panel = this;
		this.postMessage("init", [workerEntry.panelSide]);
	},
	initialize: function(toolbox) {
		this.toolbox = toolbox;
	}
});
exports.AxePanel = AxePanel;

// create a new tool,
// initialized with the
// AxePanel's constructor

// this code is adapted from http://mxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/dev/toolbox.js?raw=1
// only difference is passing the toolbox into the constructor and removing the themes

const Tool = Class({
  extends: Disposable,
  setup: function(params) {
    const { panels } = params;

    this.panels = panels;

    each(([key, Panel]) => {
      const { url, label, tooltip, icon } = Panel.prototype;
      const { id } = Panel.prototype;

      gDevTools.registerTool({
        id: id,
        url: "about:blank",
        label: label,
        tooltip: tooltip,
        icon: icon,
        isTargetSupported: target => target.isLocalTab,
        build: (window, toolbox) => {
          const panel = new Panel(toolbox);
          setup(panel, { window: window,
                         toolbox: toolbox,
                         url: url });

          return panel.ready();
        }
      });
    }, pairs(panels));
  },
  dispose: function() {
    each(Panel => gDevTools.unregisterTool(Panel.prototype.id),
         values(this.panels));
  }
});

const axeTool = new Tool({
	panels: { axeMain: AxePanel }
});

// this code sucks, but we have to select the inspector when the toolbox inits or else we cannot get hold of the inspector
gDevTools.on('toolbox-ready', function (eventId, toolbox) {
	var toolpanels = toolbox.getToolPanels();
	var inspector = toolpanels.get('inspector');
	toolbox.selectTool('inspector');
});

// console.log('bootstrapped: ');

<|endoftext|>


<commit_before>var MiniGame = cc.Node.extend({

	ctor:function () {

		this._super();

		// constants
		var tile = new cc.Sprite(res.Tile_normal_png);
		this.TILE_SIZE = tile.getContentSize();
		this.ROWS = 5;
		this.COLS = 5;

		// variables
		this.tiles = [];
		this.currentTileIdx = -1;
		this.previousTileIdx = -1;
		this.currentCombination = [];

		this.createBoard();

		if ("mouse" in cc.sys.capabilities) {
			cc.eventManager.addListener({
				event: cc.EventListener.MOUSE,

				onMouseDown: function(event) {
					var pos = event.getLocation();
					var target = event.getCurrentTarget();
					var localPos = target.convertToNodeSpace(pos);
					target.selectTileAtPosition(localPos);
				},

				onMouseMove: function(event) {
					if (event.getButton() === cc.EventMouse.BUTTON_LEFT) {
						this.onMouseDown(event);
					}
				},
				onMouseUp: function(event) {
					var target = event.getCurrentTarget();
					target.endWord();
				},
			}, this);
		}

		// No "else" here. some devices (modern notebooks) support both touches and mouse events
		// and if so, it is good to support both input systems
		if ("touches" in cc.sys.capabilities) {
			cc.eventManager.addListener({
				event: cc.EventListener.TOUCH_ALL_AT_ONCE,

				onTouchesBegan: function(touches, event) {
					this.onTouchesMoved(touches, event);
				},
				onTouchesMoved: function(touches, event) {
					var touch = touches[0];
					var pos = touch.getLocation();
					var target = event.getCurrentTarget();
					var localPos = target.convertToNodeSpace(pos);
					target.selectTileAtPosition(localPos);
				},
				onTouchesEnded: function(touches, event) {
					this.onTouchesCancelled(touches, event);
				},
				onTouchesCancelled: function(touches, event) {
					var target = event.getCurrentTarget();
					target.endWord();
				},

			}, this);
		}
	},

  selectTileAtPosition:function(position) {
		if (position.x<0 || position.x>this.TILE_SIZE.width*this.COLS) {
			return;
		}
		if (position.y<0 || position.y>this.TILE_SIZE.height*this.ROWS) {
			return;
		}

		var tile_x = Math.floor(position.x / this.TILE_SIZE.width);
		var tile_y = Math.floor(position.y / this.TILE_SIZE.height);
		var tile_idx = tile_x + this.COLS * tile_y;
		this.tileHighlighted(tile_idx);
	},

	tileHighlighted:function(tile_idx) {
		var idx = this.currentCombination.indexOf(tile_idx);
		if (idx === -1 && tile_idx>=0 && tile_idx<this.ROWS*this.COLS) {
			var spr = this.tiles[tile_idx];
			spr.setTexture(res.Tile_highlight_png);
			this.currentCombination.push(tile_idx);
		}
	},
	endWord: function() {
		for (var i=0; i<this.ROWS*this.COLS; i++)
			this.tiles[i].setTexture(res.Tile_normal_png);
		this.currentCombination = [];
	},

  createBoard:function() {
      for (var y=0; y<this.ROWS; y++) {
        for (var x=0; x<this.COLS; x++) {
          var tile = new cc.Sprite(res.Tile_normal_png);

          this.addChild(tile);
          tile.setAnchorPoint(0,0);
          tile.setPosition(x * this.TILE_SIZE.width, y * this.TILE_SIZE.height);

          this.tiles.push(tile);
        }
      }
  }
});
<commit_msg>supports diagonal tiles... still many things to do<commit_after>var MiniGame = cc.Node.extend({

	ctor:function () {

		this._super();

		// constants
		var tile = new cc.Sprite(res.Tile_normal_png);
		this.TILE_SIZE = tile.getContentSize();
		this.ROWS = 5;
		this.COLS = 5;

		// variables
		this.tiles = [];
		this.currentTileIdx = -1;
		this.previousTileIdx = -1;
		this.currentCombination = [];

		this.createBoard();

		if ("mouse" in cc.sys.capabilities) {
			cc.eventManager.addListener({
				event: cc.EventListener.MOUSE,

				onMouseDown: function(event) {
					var pos = event.getLocation();
					var target = event.getCurrentTarget();
					var localPos = target.convertToNodeSpace(pos);
					target.selectTileAtPosition(localPos);
				},

				onMouseMove: function(event) {
					if (event.getButton() === cc.EventMouse.BUTTON_LEFT) {
						this.onMouseDown(event);
					}
				},
				onMouseUp: function(event) {
					var target = event.getCurrentTarget();
					target.endWord();
				},
			}, this);
		}

		// No "else" here. some devices (modern notebooks) support both touches and mouse events
		// and if so, it is good to support both input systems
		if ("touches" in cc.sys.capabilities) {
			cc.eventManager.addListener({
				event: cc.EventListener.TOUCH_ALL_AT_ONCE,

				onTouchesBegan: function(touches, event) {
					this.onTouchesMoved(touches, event);
				},
				onTouchesMoved: function(touches, event) {
					var touch = touches[0];
					var pos = touch.getLocation();
					var target = event.getCurrentTarget();
					var localPos = target.convertToNodeSpace(pos);
					target.selectTileAtPosition(localPos);
				},
				onTouchesEnded: function(touches, event) {
					this.onTouchesCancelled(touches, event);
				},
				onTouchesCancelled: function(touches, event) {
					var target = event.getCurrentTarget();
					target.endWord();
				},

			}, this);
		}
	},

	selectTileAtPosition:function(position) {
		if (position.x<0 || position.x>this.TILE_SIZE.width*this.COLS) {
			return;
		}
		if (position.y<0 || position.y>this.TILE_SIZE.height*this.ROWS) {
			return;
		}

		var tile_x = Math.floor(position.x / this.TILE_SIZE.width);
		var tile_y = Math.floor(position.y / this.TILE_SIZE.height);
		var tile_idx = tile_x + this.COLS * tile_y;

		var idx = this.currentCombination.indexOf(tile_idx);
		if (idx === -1) {
			var spr = this.tiles[tile_idx];
			if (this.isInDistanceToCenter(position, spr)) {
				spr.setTexture(res.Tile_highlight_png);
				this.currentCombination.push(tile_idx);
			}
		}
	},

	isInDistanceToCenter: function(position, spr) {
		var sprPos = cc.pAdd(spr.getPosition(), {x:this.TILE_SIZE.width/2, y:this.TILE_SIZE.height/2});
		var distance = cc.pDistance(sprPos, position);
		return (distance < (this.TILE_SIZE.height/2)*0.95);
	},

	endWord: function() {
		for (var i=0; i<this.ROWS*this.COLS; i++)
		this.tiles[i].setTexture(res.Tile_normal_png);
		this.currentCombination = [];
	},

	createBoard:function() {
		for (var y=0; y<this.ROWS; y++) {
			for (var x=0; x<this.COLS; x++) {
				var tile = new cc.Sprite(res.Tile_normal_png);

				this.addChild(tile);
				tile.setAnchorPoint(0,0);
				tile.setPosition(x * this.TILE_SIZE.width, y * this.TILE_SIZE.height);

				this.tiles.push(tile);
			}
		}
	}
});
<|endoftext|>