<commit_before>'use strict';

var drawerIsOpen = false;
var treatmentDrawerIsOpen = false;
var defaultSettings = {
    'units': 'mg/dl',
    'alarmUrgentHigh': true,
    'alarmHigh': true,
    'alarmLow': true,
    'alarmUrgentLow': true,
    'nightMode': false,
    'theme': 'default',
    'timeFormat': '12'
};

function getBrowserSettings(storage) {
    var json = {};

    function scaleBg(bg) {
        if (json.units == 'mmol') {
            return (Math.round((bg / 18) * 10) / 10).toFixed(1);
        } else {
            return bg;
        }
    }

    function appendThresholdValue(threshold) {
        return app.alarm_types.indexOf('simple') == -1 ? '' : ' (' + scaleBg(threshold) + ')';
    }

    try {
        var json = {
            'units': storage.get('units'),
            'alarmUrgentHigh': storage.get('alarmUrgentHigh'),
            'alarmHigh': storage.get('alarmHigh'),
            'alarmLow': storage.get('alarmLow'),
            'alarmUrgentLow': storage.get('alarmUrgentLow'),
            'nightMode': storage.get('nightMode'),
            'showRawbg': storage.get('showRawbg'),
            'customTitle': storage.get('customTitle'),
            'theme': storage.get('theme'),
            'timeFormat': storage.get('timeFormat')
        };

        // Default browser units to server units if undefined.
        json.units = setDefault(json.units, app.units);
        if (json.units == 'mmol') {
            $('#mmol-browser').prop('checked', true);
        } else {
            $('#mgdl-browser').prop('checked', true);
        }

        json.alarmUrgentHigh = setDefault(json.alarmUrgentHigh, defaultSettings.alarmUrgentHigh);
        json.alarmHigh = setDefault(json.alarmHigh, defaultSettings.alarmHigh);
        json.alarmLow = setDefault(json.alarmLow, defaultSettings.alarmLow);
        json.alarmUrgentLow = setDefault(json.alarmUrgentLow, defaultSettings.alarmUrgentLow);
        $('#alarm-urgenthigh-browser').prop('checked', json.alarmUrgentHigh).next().text('Urgent High Alarm' + appendThresholdValue(app.thresholds.bg_high));
        $('#alarm-high-browser').prop('checked', json.alarmHigh).next().text('High Alarm' + appendThresholdValue(app.thresholds.bg_target_top));
        $('#alarm-low-browser').prop('checked', json.alarmLow).next().text('Low Alarm' + appendThresholdValue(app.thresholds.bg_target_bottom));
        $('#alarm-urgentlow-browser').prop('checked', json.alarmUrgentLow).next().text('Urgent Low Alarm' + appendThresholdValue(app.thresholds.bg_low));

        json.nightMode = setDefault(json.nightMode, defaultSettings.nightMode);
        $('#nightmode-browser').prop('checked', json.nightMode);

        if (app.enabledOptions.indexOf('rawbg') == -1) {
            json.showRawbg = false;
            $('#show-rawbg-option').hide();
        } else {
            $('#show-rawbg-option').show();
            if (json.showRawbg === false) {
                json.showRawbg = 'never';
            } else if (json.showRawbg === true) {
                json.showRawbg = 'noise';
            }
            json.showRawbg = setDefault(json.showRawbg, (app.enabledOptions.indexOf('rawbg-on') > -1 ? 'noise' : 'never'));
            $('#show-rawbg-' + json.showRawbg).prop('checked', true);
        }

        if (json.customTitle) {
            $('h1.customTitle').text(json.customTitle);
            $('input#customTitle').prop('value', json.customTitle);
            document.title = 'Nightscout: ' + json.customTitle;
        }

        if (json.theme == 'colors') {
            $('#theme-colors-browser').prop('checked', true);
        } else {
            $('#theme-default-browser').prop('checked', true);
        }

        json.timeFormat = setDefault(json.timeFormat, defaultSettings.timeFormat);

        if (json.timeFormat == '24') {
            $('#24-browser').prop('checked', true);
        } else {
            $('#12-browser').prop('checked', true);
        }
    }
    catch(err) {
        console.error(err);
        showLocalstorageError();
    }

    return json;
}

function setDefault(variable, defaultValue) {
    if (typeof(variable) === 'object') {
        return defaultValue;
    }
    return variable;
}

function storeInBrowser(data) {

    for (var k in data) {
        if (data.hasOwnProperty(k)) {
            browserStorage.set(k, data[k]);
        }
    }

}

function getQueryParms() {
    var params = {};
    if (location.search) {
        location.search.substr(1).split('&').forEach(function(item) {
            params[item.split('=')[0]] = item.split('=')[1].replace(/[_\+]/g, ' ');
        });
    }
    return params;
}

function isTouch() {
    try { document.createEvent('TouchEvent'); return true; }
    catch (e) { return false; }
}

function closeDrawer(callback) {
    $('#container').animate({marginLeft: '0px'}, 300, callback);
    $('#chartContainer').animate({marginLeft: '0px'}, 300);
    $('#drawer').animate({right: '-300px'}, 300, function() {
        $('#drawer').css('display', 'none');
    });
    drawerIsOpen = false;
}

function openDrawer()  {
    drawerIsOpen = true;
    $('#container').animate({marginLeft: '-300px'}, 300);
    $('#chartContainer').animate({marginLeft: '-300px'}, 300);
    $('#drawer').css('display', 'block').animate({right: '0'}, 300);
}

function closeTreatmentDrawer(callback) {
    $('#container').animate({marginLeft: '0px'}, 400, callback);
    $('#chartContainer').animate({marginLeft: '0px'}, 400);
    $('#treatmentDrawer').animate({right: '-300px'}, 400, function() {
        $('#treatmentDrawer').css('display', 'none');
    });
    treatmentDrawerIsOpen = false;
}

function openTreatmentDrawer()  {
    treatmentDrawerIsOpen = true;
    $('#container').animate({marginLeft: '-300px'}, 400);
    $('#chartContainer').animate({marginLeft: '-300px'}, 400);
    $('#treatmentDrawer').css('display', 'block').animate({right: '0'}, 400);

    $('#eventType').val('BG Check').focus();
    $('#glucoseValue').val('').attr('placeholder', 'Value in ' + browserSettings.units);
    $('#meter').prop('checked', true);
    $('#carbsGiven').val('');
    $('#insulinGiven').val('');
    $('#preBolus').val(0);
    $('#notes').val('');
    $('#enteredBy').val(browserStorage.get('enteredBy') || '');
    $('#nowtime').prop('checked', true);
    $('#eventTimeValue').val(currentTime());
}

function currentTime() {
    var now = new Date();
    var hours = now.getHours();
    var minutes = now.getMinutes();

    if (hours<10) hours = '0' + hours;
    if (minutes<10) minutes = '0' + minutes;

    return ''+ hours + ':' + minutes;
}

function formatTime(date) {
    var hours = date.getHours();
    var minutes = date.getMinutes();
    var ampm = hours >= 12 ? 'pm' : 'am';
    hours = hours % 12;
    hours = hours ? hours : 12; // the hour '0' should be '12'
    minutes = minutes < 10 ? '0' + minutes : minutes;
    return hours + ':' + minutes + ' ' + ampm;
}

function closeNotification() {
    var notify = $('#notification');
    notify.hide();
    notify.find('span').html('');
}

function showNotification(note, type)  {
    var notify = $('#notification');
    notify.hide();

    // Notification types: 'info', 'warn', 'success', 'urgent'.
    // - default: 'urgent'
    notify.removeClass('info warn urgent');
    notify.addClass(type ? type : 'urgent');

    notify.find('span').html(note);
    notify.css('left', 'calc(50% - ' + (notify.width() / 2) + 'px)');
    notify.show();
}

function showLocalstorageError() {
    var msg = 'Settings are disabled.

Please enable cookies so you may customize your Nightscout site.'
    $('.browserSettings').html('<legend>Settings</legend>'+msg+'');
    $('#save').hide();
}

function treatmentSubmit(event) {

    var data = {};
    data.enteredBy = document.getElementById('enteredBy').value;
    data.eventType = document.getElementById('eventType').value;
    data.glucose = document.getElementById('glucoseValue').value;
    data.glucoseType = $('#treatment-form input[name=glucoseType]:checked').val();
    data.carbs = document.getElementById('carbsGiven').value;
    data.insulin = document.getElementById('insulinGiven').value;
    data.preBolus = document.getElementById('preBolus').value;
    data.notes = document.getElementById('notes').value;

    var eventTimeDisplay = '';
    if ($('#treatment-form input[name=nowOrOther]:checked').val() != 'now') {
        var value = document.getElementById('eventTimeValue').value;
        var eventTimeParts = value.split(':');
        data.eventTime = new Date();
        data.eventTime.setHours(eventTimeParts[0]);
        data.eventTime.setMinutes(eventTimeParts[1]);
        data.eventTime.setSeconds(0);
        data.eventTime.setMilliseconds(0);
        eventTimeDisplay = formatTime(data.eventTime);
    }

    var dataJson = JSON.stringify(data, null, ' ');

    var ok = window.confirm(
            'Please verify that the data entered is correct: ' +
            '\nEvent type: ' + data.eventType +
            '\nBlood glucose: ' + data.glucose +
            '\nMethod: ' + data.glucoseType +
            '\nCarbs Given: ' + data.carbs +
            '\nInsulin Given: ' + data.insulin +
            '\nPre Bolus: ' + data.preBolus +
            '\nNotes: ' + data.notes +
            '\nEntered By: ' + data.enteredBy +
            '\nEvent Time: ' + eventTimeDisplay);

    if (ok) {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/api/v1/treatments/', true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        xhr.send(dataJson);

        browserStorage.set('enteredBy', data.enteredBy);

        closeTreatmentDrawer();
    }

    if (event) {
        event.preventDefault();
    }
}

var querystring = getQueryParms();

function Dropdown(el) {
    this.ddmenuitem = 0;

    this.$el = $(el);
    var that = this;

    $(document).click(function() { that.close(); });
}
Dropdown.prototype.close = function () {
    if (this.ddmenuitem) {
        this.ddmenuitem.css('visibility', 'hidden');
        this.ddmenuitem = 0;
    }
};
Dropdown.prototype.open = function (e) {
    this.close();
    this.ddmenuitem = $(this.$el).css('visibility', 'visible');
    e.stopPropagation();
};

$('#drawerToggle').click(function(event) {
    //close other drawers
    if(treatmentDrawerIsOpen) {
        closeTreatmentDrawer();
        treatmentDrawerIsOpen = false;
    }

    if(drawerIsOpen) {
        closeDrawer();
        drawerIsOpen = false;
    }  else {
        openDrawer();
        drawerIsOpen = true;
    }
    event.preventDefault();
});

$('#treatmentDrawerToggle').click(function(event) {
    //close other drawers
    if(drawerIsOpen) {
        closeDrawer();
        drawerIsOpen = false;
    }

    if(treatmentDrawerIsOpen) {
        closeTreatmentDrawer();
        treatmentDrawerIsOpen = false;
    }  else {
        openTreatmentDrawer();
        treatmentDrawerIsOpen = true;
    }
    event.preventDefault();
});

$('#treatmentDrawer').find('button').click(treatmentSubmit);

$('#eventTime input:radio').change(function (){
    if ($('#othertime').attr('checked')) {
        $('#eventTimeValue').focus();
    }
});

$('#eventTimeValue').focus(function () {
    $('#othertime').attr('checked', 'checked');
});

$('#notification').click(function(event) {
    closeNotification();
    event.preventDefault();
});

$('input#save').click(function(event) {
    storeInBrowser({
        'units': $('input:radio[name=units-browser]:checked').val(),
        'alarmUrgentHigh': $('#alarm-urgenthigh-browser').prop('checked'),
        'alarmHigh': $('#alarm-high-browser').prop('checked'),
        'alarmLow': $('#alarm-low-browser').prop('checked'),
        'alarmUrgentLow': $('#alarm-urgentlow-browser').prop('checked'),
        'nightMode': $('#nightmode-browser').prop('checked'),
        'showRawbg': $('input:radio[name=show-rawbg]:checked').val(),
        'customTitle': $('input#customTitle').prop('value'),
        'theme': $('input:radio[name=theme-browser]:checked').val(),
        'timeFormat': $('input:radio[name=timeformat-browser]:checked').val()
    });

    event.preventDefault();

    // reload for changes to take effect
    // -- strip '#' so form submission does not fail
    var url = window.location.href;
    url = url.replace(/#$/, '');
    window.location = url;
});

$(function() {
    // Tooltips can remain in the way on touch screens.
    var notTouchScreen = (!isTouch());
    if (notTouchScreen) {
        $('.tip').tipsy();
    } else {
        // Drawer info tips should be displayed on touchscreens.
        $('#drawer').find('.tip').tipsy();
    }
    $.fn.tipsy.defaults = {
        fade: true,
        gravity: 'n',
        opacity: 0.75
    }

    if (querystring.notify) {
        showNotification(querystring.notify, querystring.notifytype);
    }

    if (querystring.drawer) {
        openDrawer();
    }
});
<commit_msg>colors by deault<commit_after>'use strict';

var drawerIsOpen = false;
var treatmentDrawerIsOpen = false;
var defaultSettings = {
    'units': 'mg/dl',
    'alarmUrgentHigh': true,
    'alarmHigh': true,
    'alarmLow': true,
    'alarmUrgentLow': true,
    'nightMode': false,
    'theme': 'default',
    'timeFormat': '12'
};

function getBrowserSettings(storage) {
    var json = {};

    function scaleBg(bg) {
        if (json.units == 'mmol') {
            return (Math.round((bg / 18) * 10) / 10).toFixed(1);
        } else {
            return bg;
        }
    }

    function appendThresholdValue(threshold) {
        return app.alarm_types.indexOf('simple') == -1 ? '' : ' (' + scaleBg(threshold) + ')';
    }

    try {
        var json = {
            'units': storage.get('units'),
            'alarmUrgentHigh': storage.get('alarmUrgentHigh'),
            'alarmHigh': storage.get('alarmHigh'),
            'alarmLow': storage.get('alarmLow'),
            'alarmUrgentLow': storage.get('alarmUrgentLow'),
            'nightMode': storage.get('nightMode'),
            'showRawbg': storage.get('showRawbg'),
            'customTitle': storage.get('customTitle'),
            'theme': storage.get('theme') || 'colors',
            'timeFormat': storage.get('timeFormat')
        };

        // Default browser units to server units if undefined.
        json.units = setDefault(json.units, app.units);
        if (json.units == 'mmol') {
            $('#mmol-browser').prop('checked', true);
        } else {
            $('#mgdl-browser').prop('checked', true);
        }

        json.alarmUrgentHigh = setDefault(json.alarmUrgentHigh, defaultSettings.alarmUrgentHigh);
        json.alarmHigh = setDefault(json.alarmHigh, defaultSettings.alarmHigh);
        json.alarmLow = setDefault(json.alarmLow, defaultSettings.alarmLow);
        json.alarmUrgentLow = setDefault(json.alarmUrgentLow, defaultSettings.alarmUrgentLow);
        $('#alarm-urgenthigh-browser').prop('checked', json.alarmUrgentHigh).next().text('Urgent High Alarm' + appendThresholdValue(app.thresholds.bg_high));
        $('#alarm-high-browser').prop('checked', json.alarmHigh).next().text('High Alarm' + appendThresholdValue(app.thresholds.bg_target_top));
        $('#alarm-low-browser').prop('checked', json.alarmLow).next().text('Low Alarm' + appendThresholdValue(app.thresholds.bg_target_bottom));
        $('#alarm-urgentlow-browser').prop('checked', json.alarmUrgentLow).next().text('Urgent Low Alarm' + appendThresholdValue(app.thresholds.bg_low));

        json.nightMode = setDefault(json.nightMode, defaultSettings.nightMode);
        $('#nightmode-browser').prop('checked', json.nightMode);

        if (app.enabledOptions.indexOf('rawbg') == -1) {
            json.showRawbg = false;
            $('#show-rawbg-option').hide();
        } else {
            $('#show-rawbg-option').show();
            if (json.showRawbg === false) {
                json.showRawbg = 'never';
            } else if (json.showRawbg === true) {
                json.showRawbg = 'noise';
            }
            json.showRawbg = setDefault(json.showRawbg, (app.enabledOptions.indexOf('rawbg-on') > -1 ? 'noise' : 'never'));
            $('#show-rawbg-' + json.showRawbg).prop('checked', true);
        }

        if (json.customTitle) {
            $('h1.customTitle').text(json.customTitle);
            $('input#customTitle').prop('value', json.customTitle);
            document.title = 'Nightscout: ' + json.customTitle;
        }

        if (json.theme == 'colors') {
            $('#theme-colors-browser').prop('checked', true);
        } else {
            $('#theme-default-browser').prop('checked', true);
        }

        json.timeFormat = setDefault(json.timeFormat, defaultSettings.timeFormat);

        if (json.timeFormat == '24') {
            $('#24-browser').prop('checked', true);
        } else {
            $('#12-browser').prop('checked', true);
        }
    }
    catch(err) {
        console.error(err);
        showLocalstorageError();
    }

    return json;
}

function setDefault(variable, defaultValue) {
    if (typeof(variable) === 'object') {
        return defaultValue;
    }
    return variable;
}

function storeInBrowser(data) {

    for (var k in data) {
        if (data.hasOwnProperty(k)) {
            browserStorage.set(k, data[k]);
        }
    }

}

function getQueryParms() {
    var params = {};
    if (location.search) {
        location.search.substr(1).split('&').forEach(function(item) {
            params[item.split('=')[0]] = item.split('=')[1].replace(/[_\+]/g, ' ');
        });
    }
    return params;
}

function isTouch() {
    try { document.createEvent('TouchEvent'); return true; }
    catch (e) { return false; }
}

function closeDrawer(callback) {
    $('#container').animate({marginLeft: '0px'}, 300, callback);
    $('#chartContainer').animate({marginLeft: '0px'}, 300);
    $('#drawer').animate({right: '-300px'}, 300, function() {
        $('#drawer').css('display', 'none');
    });
    drawerIsOpen = false;
}

function openDrawer()  {
    drawerIsOpen = true;
    $('#container').animate({marginLeft: '-300px'}, 300);
    $('#chartContainer').animate({marginLeft: '-300px'}, 300);
    $('#drawer').css('display', 'block').animate({right: '0'}, 300);
}

function closeTreatmentDrawer(callback) {
    $('#container').animate({marginLeft: '0px'}, 400, callback);
    $('#chartContainer').animate({marginLeft: '0px'}, 400);
    $('#treatmentDrawer').animate({right: '-300px'}, 400, function() {
        $('#treatmentDrawer').css('display', 'none');
    });
    treatmentDrawerIsOpen = false;
}

function openTreatmentDrawer()  {
    treatmentDrawerIsOpen = true;
    $('#container').animate({marginLeft: '-300px'}, 400);
    $('#chartContainer').animate({marginLeft: '-300px'}, 400);
    $('#treatmentDrawer').css('display', 'block').animate({right: '0'}, 400);

    $('#eventType').val('BG Check').focus();
    $('#glucoseValue').val('').attr('placeholder', 'Value in ' + browserSettings.units);
    $('#meter').prop('checked', true);
    $('#carbsGiven').val('');
    $('#insulinGiven').val('');
    $('#preBolus').val(0);
    $('#notes').val('');
    $('#enteredBy').val(browserStorage.get('enteredBy') || '');
    $('#nowtime').prop('checked', true);
    $('#eventTimeValue').val(currentTime());
}

function currentTime() {
    var now = new Date();
    var hours = now.getHours();
    var minutes = now.getMinutes();

    if (hours<10) hours = '0' + hours;
    if (minutes<10) minutes = '0' + minutes;

    return ''+ hours + ':' + minutes;
}

function formatTime(date) {
    var hours = date.getHours();
    var minutes = date.getMinutes();
    var ampm = hours >= 12 ? 'pm' : 'am';
    hours = hours % 12;
    hours = hours ? hours : 12; // the hour '0' should be '12'
    minutes = minutes < 10 ? '0' + minutes : minutes;
    return hours + ':' + minutes + ' ' + ampm;
}

function closeNotification() {
    var notify = $('#notification');
    notify.hide();
    notify.find('span').html('');
}

function showNotification(note, type)  {
    var notify = $('#notification');
    notify.hide();

    // Notification types: 'info', 'warn', 'success', 'urgent'.
    // - default: 'urgent'
    notify.removeClass('info warn urgent');
    notify.addClass(type ? type : 'urgent');

    notify.find('span').html(note);
    notify.css('left', 'calc(50% - ' + (notify.width() / 2) + 'px)');
    notify.show();
}

function showLocalstorageError() {
    var msg = 'Settings are disabled.

Please enable cookies so you may customize your Nightscout site.'
    $('.browserSettings').html('<legend>Settings</legend>'+msg+'');
    $('#save').hide();
}

function treatmentSubmit(event) {

    var data = {};
    data.enteredBy = document.getElementById('enteredBy').value;
    data.eventType = document.getElementById('eventType').value;
    data.glucose = document.getElementById('glucoseValue').value;
    data.glucoseType = $('#treatment-form input[name=glucoseType]:checked').val();
    data.carbs = document.getElementById('carbsGiven').value;
    data.insulin = document.getElementById('insulinGiven').value;
    data.preBolus = document.getElementById('preBolus').value;
    data.notes = document.getElementById('notes').value;

    var eventTimeDisplay = '';
    if ($('#treatment-form input[name=nowOrOther]:checked').val() != 'now') {
        var value = document.getElementById('eventTimeValue').value;
        var eventTimeParts = value.split(':');
        data.eventTime = new Date();
        data.eventTime.setHours(eventTimeParts[0]);
        data.eventTime.setMinutes(eventTimeParts[1]);
        data.eventTime.setSeconds(0);
        data.eventTime.setMilliseconds(0);
        eventTimeDisplay = formatTime(data.eventTime);
    }

    var dataJson = JSON.stringify(data, null, ' ');

    var ok = window.confirm(
            'Please verify that the data entered is correct: ' +
            '\nEvent type: ' + data.eventType +
            '\nBlood glucose: ' + data.glucose +
            '\nMethod: ' + data.glucoseType +
            '\nCarbs Given: ' + data.carbs +
            '\nInsulin Given: ' + data.insulin +
            '\nPre Bolus: ' + data.preBolus +
            '\nNotes: ' + data.notes +
            '\nEntered By: ' + data.enteredBy +
            '\nEvent Time: ' + eventTimeDisplay);

    if (ok) {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/api/v1/treatments/', true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        xhr.send(dataJson);

        browserStorage.set('enteredBy', data.enteredBy);

        closeTreatmentDrawer();
    }

    if (event) {
        event.preventDefault();
    }
}

var querystring = getQueryParms();

function Dropdown(el) {
    this.ddmenuitem = 0;

    this.$el = $(el);
    var that = this;

    $(document).click(function() { that.close(); });
}
Dropdown.prototype.close = function () {
    if (this.ddmenuitem) {
        this.ddmenuitem.css('visibility', 'hidden');
        this.ddmenuitem = 0;
    }
};
Dropdown.prototype.open = function (e) {
    this.close();
    this.ddmenuitem = $(this.$el).css('visibility', 'visible');
    e.stopPropagation();
};

$('#drawerToggle').click(function(event) {
    //close other drawers
    if(treatmentDrawerIsOpen) {
        closeTreatmentDrawer();
        treatmentDrawerIsOpen = false;
    }

    if(drawerIsOpen) {
        closeDrawer();
        drawerIsOpen = false;
    }  else {
        openDrawer();
        drawerIsOpen = true;
    }
    event.preventDefault();
});

$('#treatmentDrawerToggle').click(function(event) {
    //close other drawers
    if(drawerIsOpen) {
        closeDrawer();
        drawerIsOpen = false;
    }

    if(treatmentDrawerIsOpen) {
        closeTreatmentDrawer();
        treatmentDrawerIsOpen = false;
    }  else {
        openTreatmentDrawer();
        treatmentDrawerIsOpen = true;
    }
    event.preventDefault();
});

$('#treatmentDrawer').find('button').click(treatmentSubmit);

$('#eventTime input:radio').change(function (){
    if ($('#othertime').attr('checked')) {
        $('#eventTimeValue').focus();
    }
});

$('#eventTimeValue').focus(function () {
    $('#othertime').attr('checked', 'checked');
});

$('#notification').click(function(event) {
    closeNotification();
    event.preventDefault();
});

$('input#save').click(function(event) {
    storeInBrowser({
        'units': $('input:radio[name=units-browser]:checked').val(),
        'alarmUrgentHigh': $('#alarm-urgenthigh-browser').prop('checked'),
        'alarmHigh': $('#alarm-high-browser').prop('checked'),
        'alarmLow': $('#alarm-low-browser').prop('checked'),
        'alarmUrgentLow': $('#alarm-urgentlow-browser').prop('checked'),
        'nightMode': $('#nightmode-browser').prop('checked'),
        'showRawbg': $('input:radio[name=show-rawbg]:checked').val(),
        'customTitle': $('input#customTitle').prop('value'),
        'theme': $('input:radio[name=theme-browser]:checked').val(),
        'timeFormat': $('input:radio[name=timeformat-browser]:checked').val()
    });

    event.preventDefault();

    // reload for changes to take effect
    // -- strip '#' so form submission does not fail
    var url = window.location.href;
    url = url.replace(/#$/, '');
    window.location = url;
});

$(function() {
    // Tooltips can remain in the way on touch screens.
    var notTouchScreen = (!isTouch());
    if (notTouchScreen) {
        $('.tip').tipsy();
    } else {
        // Drawer info tips should be displayed on touchscreens.
        $('#drawer').find('.tip').tipsy();
    }
    $.fn.tipsy.defaults = {
        fade: true,
        gravity: 'n',
        opacity: 0.75
    }

    if (querystring.notify) {
        showNotification(querystring.notify, querystring.notifytype);
    }

    if (querystring.drawer) {
        openDrawer();
    }
});
<|endoftext|>


<commit_before>'use strict';

if (!waitlist) {
	var waitlist = {};
}

waitlist.linemember = (function() {
	var getMetaData = waitlist.base.getMetaData;
	const disableGong  = waitlist.gong.disableGong;
	var settings = {};

	function getFitUpdateUrl(fitID) {
		return settings.fit_update_url.replace('-1', fitID);
	}

	function removeSelf() {
		var settings = {
			dataType: "text",
			headers: {
				'X-CSRFToken': getMetaData('csrf-token')
			},
			method: 'DELETE',
			success: function(data, status, jqxhr) {
			},
			url: getMetaData('url-self-remove-all')
		};
		$.ajax(settings);
	}

	function removeOwnEntry(wlId, charId, entryId) {
		var settings = {
			dataType: "text",
			headers: {
				'X-CSRFToken': getMetaData('csrf-token')
			},
			method: 'DELETE',
			success: function(data, status, jqxhr) {
			},
			url: "/api/self/wlentry/remove/" + entryId
		};
		$.ajax(settings);
	}

	function removeOwnFit(event) {
		var target = $(event.currentTarget);
		var fitId = Number(target.attr('data-fit'));
		var wlId = Number(target.attr('data-wlId'));
		var entryId = Number(target.attr('data-entryId'));
		event.stopPropagation();
		var settings = {
			dataType: "text",
			headers: {
				'X-CSRFToken': getMetaData('csrf-token')
			},
			method: 'DELETE',
			success: function(data, status, jqxhr) {
			},
			url: "/api/self/fittings/remove/" + fitId
		};
		$.ajax(settings);
	}

	function updateFit(event) {
		event.stopPropagation();
		var target = $(event.currentTarget);
		var fitId = Number(target.attr('data-fit'));
		var updateUrl = getFitUpdateUrl(fitId);
		window.location = updateUrl;
	}

	function removeOwnEntryHandler(event) {
		var target = $(event.currentTarget);
		var wlId = target.attr('data-wlId');
		var charId = target.attr('data-characterid');
		var entryId = target.attr('data-entryId');
		removeOwnEntry(wlId, charId, entryId);
	}

	function removeSelfHandler(event) {
		removeSelf();
		disableGong();
		$('.wlb').remove();
	}

	function init() {
		settings.fit_update_url = getMetaData('api-fit-update');

		// setup handler for the leave waitlist button
		$('body').on('click', '[data-action="removeSelfFromWaitlists"]',
			removeSelfHandler);

		// setup fit button handler related to linemembers
		$("#waitlists").on("click", '[data-action="remove-own-fit"]',
			removeOwnFit);
		$("#waitlists").on("click", '[data-action="update-fit"]', updateFit);
		$("#waitlists").on('click', '[data-action="removeOwnEntry"]',
			removeOwnEntryHandler);
	}

	$(document).ready(init);

	return {};
})();
<commit_msg>Removed extra whitespace.<commit_after>'use strict';

if (!waitlist) {
	var waitlist = {};
}

waitlist.linemember = (function() {
	var getMetaData = waitlist.base.getMetaData;
	const disableGong = waitlist.gong.disableGong;
	var settings = {};

	function getFitUpdateUrl(fitID) {
		return settings.fit_update_url.replace('-1', fitID);
	}

	function removeSelf() {
		var settings = {
			dataType: "text",
			headers: {
				'X-CSRFToken': getMetaData('csrf-token')
			},
			method: 'DELETE',
			success: function(data, status, jqxhr) {
			},
			url: getMetaData('url-self-remove-all')
		};
		$.ajax(settings);
	}

	function removeOwnEntry(wlId, charId, entryId) {
		var settings = {
			dataType: "text",
			headers: {
				'X-CSRFToken': getMetaData('csrf-token')
			},
			method: 'DELETE',
			success: function(data, status, jqxhr) {
			},
			url: "/api/self/wlentry/remove/" + entryId
		};
		$.ajax(settings);
	}

	function removeOwnFit(event) {
		var target = $(event.currentTarget);
		var fitId = Number(target.attr('data-fit'));
		var wlId = Number(target.attr('data-wlId'));
		var entryId = Number(target.attr('data-entryId'));
		event.stopPropagation();
		var settings = {
			dataType: "text",
			headers: {
				'X-CSRFToken': getMetaData('csrf-token')
			},
			method: 'DELETE',
			success: function(data, status, jqxhr) {
			},
			url: "/api/self/fittings/remove/" + fitId
		};
		$.ajax(settings);
	}

	function updateFit(event) {
		event.stopPropagation();
		var target = $(event.currentTarget);
		var fitId = Number(target.attr('data-fit'));
		var updateUrl = getFitUpdateUrl(fitId);
		window.location = updateUrl;
	}

	function removeOwnEntryHandler(event) {
		var target = $(event.currentTarget);
		var wlId = target.attr('data-wlId');
		var charId = target.attr('data-characterid');
		var entryId = target.attr('data-entryId');
		removeOwnEntry(wlId, charId, entryId);
	}

	function removeSelfHandler(event) {
		removeSelf();
		disableGong();
		$('.wlb').remove();
	}

	function init() {
		settings.fit_update_url = getMetaData('api-fit-update');

		// setup handler for the leave waitlist button
		$('body').on('click', '[data-action="removeSelfFromWaitlists"]',
			removeSelfHandler);

		// setup fit button handler related to linemembers
		$("#waitlists").on("click", '[data-action="remove-own-fit"]',
			removeOwnFit);
		$("#waitlists").on("click", '[data-action="update-fit"]', updateFit);
		$("#waitlists").on('click', '[data-action="removeOwnEntry"]',
			removeOwnEntryHandler);
	}

	$(document).ready(init);

	return {};
})();
<|endoftext|>


<commit_before><commit_msg>Increase thumbnail size to avoid watermarks on social media<commit_after><|endoftext|>


<commit_before><commit_msg>Fix callback ULR<commit_after><|endoftext|>


<commit_before>var display_next_nux_step = function(res) {
    $('.nux_step_two').html(res.nux_service_step_two);
    $('.nux_step_one').hide();
    $('.nux_submit').click(nux_add_account);
    $('.reset_nux_form').click(function() {
        $('.nux_step_one').show();
        $('.nux_step_two').html('');
        document.getElementById('service_select').getElementsByTagName('option')[0].selected = 'selected';
        $('.nux_username').val('');
        return false;
    });
};

var nux_add_account = function() {
    $('.nux_password').css('border', nux_border);
    var service = $('#nux_service').val();
    var name = $('.nux_name').val();
    var email = $('#nux_email').val();
    var pass = $('.nux_password').val();
    if (name.length && service.length && email.length && pass.length) {
        Hm_Ajax.request(
            [{'name': 'hm_ajax_hook', 'value': 'ajax_nux_add_service'},
            {'name': 'nux_service', 'value': service},
            {'name': 'nux_email', 'value': email},
            {'name': 'nux_name', 'value': name},
            {'name': 'nux_pass', 'value': pass}],
            display_final_nux_step,
            [],
            false
        );
    }
    else {
        if (!pass.length) {
            $('.nux_password').css('border', 'solid red 1px');
        }
    }
    return false;
};

var display_final_nux_step = function(res) {
    if (res.nux_account_added) {
        window.location.href = "?page=servers";
    }
};

var nux_service_select = function() {
    var el = document.getElementById('service_select');
    var service = el.options[el.selectedIndex].value;
    var email = $('.nux_username').val();
    var account = $('.nux_account_name').val();
    if (email.length && service.length) {
        Hm_Ajax.request(
            [{'name': 'hm_ajax_hook', 'value': 'ajax_nux_service_select'},
            {'name': 'nux_service', 'value': service},
            {'name': 'nux_account_name', 'value': account},
            {'name': 'nux_email', 'value': email}],
            display_next_nux_step,
            [],
            false
        );
    }
    else {
        if (!email.length) {
            $('.nux_username').css('border', 'solid 1px red');
        }
        else {
            $('.nux_username').css('border', nux_border);
        }
        if (!service.length) {
            $('#service_select').css('border', 'solid 1px red');
        }
        else {
            $('#service_select').css('border', nux_border);
        }
    }
};

var expand_server_settings = function() {
    var dsp;
    var i;
    var hash = window.location.hash;
    var sections = ['.feeds_section', '.quick_add_section', '.smtp_section', '.imap_section', '.pop3_section'];
    for (i=0;i<sections.length;i++) {
        dsp = Hm_Utils.get_from_local_storage(sections[i]);
        if (hash) {
            if (hash.replace('#', '.') != sections[i]) {
                dsp = 'none';
            }
            else {
                dsp = 'block';
            }
        }
        if (dsp === 'block' || dsp === 'none') {
            $(sections[i]).css('display', dsp);
            Hm_Utils.save_to_local_storage(sections[i], dsp);
        }
    }
};

if (hm_page_name() === 'servers') {
    expand_server_settings();
    var nux_border = $('.nux_username').css('border');
    $('.nux_next_button').click(nux_service_select);
}
else if (hm_page_name() === 'message_list') {
    var data_sources = hm_data_sources();
    if (data_sources.length === 0) {
        $('.nux_empty_combined_view').show();
    }
}
<commit_msg>js fix for nux<commit_after>var display_next_nux_step = function(res) {
    $('.nux_step_two').html(res.nux_service_step_two);
    $('.nux_step_one').hide();
    $('.nux_submit').click(nux_add_account);
    $('.reset_nux_form').click(function() {
        $('.nux_step_one').show();
        $('.nux_step_two').html('');
        document.getElementById('service_select').getElementsByTagName('option')[0].selected = 'selected';
        $('.nux_username').val('');
        return false;
    });
};

var nux_add_account = function() {
    $('.nux_password').css('border', nux_border);
    var service = $('#nux_service').val();
    var name = $('.nux_name').val();
    var email = $('#nux_email').val();
    var pass = $('.nux_password').val();
    if (name.length && service.length && email.length && pass.length) {
        Hm_Ajax.request(
            [{'name': 'hm_ajax_hook', 'value': 'ajax_nux_add_service'},
            {'name': 'nux_service', 'value': service},
            {'name': 'nux_email', 'value': email},
            {'name': 'nux_name', 'value': name},
            {'name': 'nux_pass', 'value': pass}],
            display_final_nux_step,
            [],
            false
        );
    }
    else {
        if (!pass.length) {
            $('.nux_password').css('border', 'solid red 1px');
        }
    }
    return false;
};

var display_final_nux_step = function(res) {
    if (res.nux_account_added) {
        window.location.href = "?page=servers";
    }
};

var nux_service_select = function() {
    var el = document.getElementById('service_select');
    var service = el.options[el.selectedIndex].value;
    var email = $('.nux_username').val();
    var account = $('.nux_account_name').val();
    if (email.length && service.length) {
        Hm_Ajax.request(
            [{'name': 'hm_ajax_hook', 'value': 'ajax_nux_service_select'},
            {'name': 'nux_service', 'value': service},
            {'name': 'nux_account_name', 'value': account},
            {'name': 'nux_email', 'value': email}],
            display_next_nux_step,
            [],
            false
        );
    }
    else {
        if (!email.length) {
            $('.nux_username').css('border', 'solid 1px red');
        }
        else {
            $('.nux_username').css('border', nux_border);
        }
        if (!service.length) {
            $('#service_select').css('border', 'solid 1px red');
        }
        else {
            $('#service_select').css('border', nux_border);
        }
    }
};

var expand_server_settings = function() {
    var dsp;
    var i;
    var hash = window.location.hash;
    var sections = ['.feeds_section', '.quick_add_section', '.smtp_section', '.imap_section', '.pop3_section'];
    for (i=0;i<sections.length;i++) {
        dsp = Hm_Utils.get_from_local_storage(sections[i]);
        if (hash) {
            if (hash.replace('#', '.') != sections[i]) {
                dsp = 'none';
            }
            else {
                dsp = 'block';
            }
        }
        if (dsp === 'block' || dsp === 'none') {
            $(sections[i]).css('display', dsp);
            Hm_Utils.save_to_local_storage(sections[i], dsp);
        }
    }
};

if (hm_page_name() === 'servers') {
    expand_server_settings();
    var nux_border = $('.nux_username').css('border');
    $('.nux_next_button').click(nux_service_select);
}
else if (hm_page_name() === 'message_list') {
    var list_path = hm_list_path();
    if (list_path === 'unread' || list_path === 'everything' || list_path === 'flagged') {
        var data_sources = hm_data_sources();
        if (data_sources.length === 0) {
            $('.nux_empty_combined_view').show();
        }
    }
}
<|endoftext|>


<commit_before>/**
 * @fileoverview This module provides support for loading CommonJS and Narwhal packages.
 */

var system = require('system');
var engine = require('ringo/engine');
var log = require('ringo/logging').getLogger(module.id);

export('load', 'loadPackages', 'loadPackage', 'normalize', 'catalog');

/**
 * @ignore
 */
var catalog;

/**
 * Load packages from the default `packages` directory.
 */
function load() {
    // Check if we're either already set up or running in secure sandbox mode.
    if (catalog || !require.paths) {
        return;
    }
    catalog = {};
    loadPackages(engine.getPackageRepository());
	discoverClasspathModules();
}

/**
 * Load all packages contained in `repository`.
 * @param repository String|Repository a path or Ringo repository
 */
function loadPackages(repository) {
    if (typeof repository === "string") {
        repository = getRepository(repository);
    }
    if (repository && repository.exists()) {
        repository.getRepositories().forEach(loadPackage);
    }
}

/**
 * Load a single package located in `repository`.
 * @param repository String|Repository a path or Ringo repository
 */
function loadPackage(repository) {
    if (typeof repository === "string") {
        repository = getRepository(repository);
    }
    try {
        var jsonPath = repository.getResource("package.json");
        var pkg = JSON.parse(jsonPath.getContent());
        var name = pkg.name || repository.getName();
        if (catalog[name]) {
            system.stderr.print(
                    "Tried to load package `" + name + "` " +
                    "from `" + repository + "`, but a package with the same " +
                    "name has already been loaded " +
                    "from `" + catalog[name].directory + "`.");
            return;
        }

        pkg.directory = repository;

        // check engine specific libs
        handleResource(pkg.engines || "engines", function(engines) {
            var dir = repository.getChildRepository("engines");
            for each (var engine in system.engines) {
                var path = dir.getChildRepository(engine + "/lib");
                if (path.exists()) {
                    require.paths.push(path);
                }
            }
        });

        var lib = (pkg.directories && pkg.directories.lib) || pkg.lib || "lib";
        handleResource(lib, function(lib) {
            require.paths.push(repository.getChildRepository(lib));
        });

        var jars = (pkg.directories && pkg.directories.jars) || pkg.jars;
        handleResource(jars, function(res) {
            var files;
            var path = repository.getChildRepository(res);
            if (path.exists()) {
                files = [p for each (p in path.getResources())
                           if (p.getName().match(/\.jar$/))];
            } else {
                files = [repository.getResource(res)];
            }
            for each (var file in files) {
                addToClasspath(file);
            }
        });

        catalog[name] = pkg;

    } catch (error) {
        system.stderr.print(
                "Error configuring package " + repository + ": " + error);
    }
}

/**
 * @ignore
 */
function normalize(catalog) {
    // TODO
}

// helper function to set up package resources
function handleResource(res, callback) {
    if (Array.isArray(res)) {
        res.forEach(callback);
    } else if (res) {
        callback(res);
    }
}

/**
 * Scour the current classpath looking for Common-JS packages to be added to the repository
 * list for package resolution. A Common-JS package is identified as an archive on the Java
 * classpath containing a package.json resource in the root folder.
 * (@see http://wiki.commonjs.org/wiki/Packages/1.0)
 */
function discoverClasspathModules() {

	var loader = java.lang.Thread.currentThread().getContextClassLoader();

	log.debug('Seeking for Common-JS packages on the classpath');

	var resources = loader.getResources('package.json');

	while (resources.hasMoreElements()) {
		var url = resources.nextElement();
		var path = url.getPath();

		// If the package.json file is found in a jar/zip file, we need to strip the url
		// down to resolve the root.
		if (/^file:/.test(path)) path = path.substring(5);
		var paths = path.split('!');

		log.info('Found package.json at ' + paths[0] + ' in url: ' + url.getPath());

		loadPackage(new org.ringojs.repository.ZipRepository(paths[0]));
	}
}
<commit_msg>Improved the autodiscovery of packages on classpaths with code to differentiate between creating a ZipReository or a FileRepository. The FileRepository should work, but fails on my test setup. I think this is due to sime unicode characters in my project path and Java's file loading not liking that. Loading Common-JS packages bundled as zip/jar archives works fine.<commit_after>/**
 * @fileoverview This module provides support for loading CommonJS and Narwhal packages.
 */

var system = require('system');
var engine = require('ringo/engine');
var log = require('ringo/logging').getLogger(module.id);

export('load', 'loadPackages', 'loadPackage', 'normalize', 'catalog');

/**
 * @ignore
 */
var catalog;

/**
 * Load packages from the default `packages` directory.
 */
function load() {
    // Check if we're either already set up or running in secure sandbox mode.
    if (catalog || !require.paths) {
        return;
    }
    catalog = {};
    loadPackages(engine.getPackageRepository());
	discoverClasspathModules();
}

/**
 * Load all packages contained in `repository`.
 * @param repository String|Repository a path or Ringo repository
 */
function loadPackages(repository) {
    if (typeof repository === "string") {
        repository = getRepository(repository);
    }
    if (repository && repository.exists()) {
        repository.getRepositories().forEach(loadPackage);
    }
}

/**
 * Load a single package located in `repository`.
 * @param repository String|Repository a path or Ringo repository
 */
function loadPackage(repository) {
    if (typeof repository === "string") {
        repository = getRepository(repository);
    }
    try {
        var jsonPath = repository.getResource("package.json");
        var pkg = JSON.parse(jsonPath.getContent());
        var name = pkg.name || repository.getName();
        if (catalog[name]) {
            system.stderr.print(
                    "Tried to load package `" + name + "` " +
                    "from `" + repository + "`, but a package with the same " +
                    "name has already been loaded " +
                    "from `" + catalog[name].directory + "`.");
            return;
        }

        pkg.directory = repository;

        // check engine specific libs
        handleResource(pkg.engines || "engines", function(engines) {
            var dir = repository.getChildRepository("engines");
            for each (var engine in system.engines) {
                var path = dir.getChildRepository(engine + "/lib");
                if (path.exists()) {
                    require.paths.push(path);
                }
            }
        });

        var lib = (pkg.directories && pkg.directories.lib) || pkg.lib || "lib";
        handleResource(lib, function(lib) {
            require.paths.push(repository.getChildRepository(lib));
        });

        var jars = (pkg.directories && pkg.directories.jars) || pkg.jars;
        handleResource(jars, function(res) {
            var files;
            var path = repository.getChildRepository(res);
            if (path.exists()) {
                files = [p for each (p in path.getResources())
                           if (p.getName().match(/\.jar$/))];
            } else {
                files = [repository.getResource(res)];
            }
            for each (var file in files) {
                addToClasspath(file);
            }
        });

        catalog[name] = pkg;

    } catch (error) {
        system.stderr.print(
                "Error configuring package " + repository + ": " + error);
    }
}

/**
 * @ignore
 */
function normalize(catalog) {
    // TODO
}

// helper function to set up package resources
function handleResource(res, callback) {
    if (Array.isArray(res)) {
        res.forEach(callback);
    } else if (res) {
        callback(res);
    }
}

/**
 * Scour the current classpath looking for Common-JS packages to be added to the repository
 * list for package resolution. A Common-JS package is identified as an archive on the Java
 * classpath containing a package.json resource in the root folder.
 * (@see http://wiki.commonjs.org/wiki/Packages/1.0)
 *
 * Note: Discovering packages that are not in an archive does not currently work. I create a
 * FileRepository object passing in the directory which holds the package.json, however when the
 * FileRpository attempts to access the package.json it says the file cannot be found. Perhaps this
 * is do to some encoded characters in my file paths? todo: Investigate
 * java.io.FileNotFoundException: /Users/jcook/Projects/Tracermedia/PPKC1001%20Web%20Site/Development/trunk/toplevel/target/classes/package.json (No such file or directory)
 */
function discoverClasspathModules() {

	var loader = java.lang.Thread.currentThread().getContextClassLoader();

	log.debug('Seeking for Common-JS packages on the classpath');

	var resources = loader.getResources('package.json');

	while (resources.hasMoreElements()) {
		var url = resources.nextElement();
		var path = url.getPath();

		var repoRoot = null;

		// If the package.json file is found in a jar/zip file, we need to strip the url
		// down to resolve the root.
		if (/^file:/.test(path)) {
			path = path.substring(5);
			repoRoot = path.split('!')[0];
		}

		// If the package.json file is found on the classpath, the path will represent the absolute
		// path to the resource which will end with '/package.json'.
		else {
			repoRoot = path.substring(0, path.lastIndexOf('/'));
		}

		if (repoRoot) {
			var repo = /\.zip$|\.jar$/.test(repoRoot)
				? new org.ringojs.repository.ZipRepository(repoRoot)
				: new org.ringojs.repository.FileRepository(repoRoot);

			log.info('Found package.json in url: ' + url.getPath() + ', repository: ' + repo);

			loadPackage(repo);
		}
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2019 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
window.env = parent;
let params = new URLSearchParams(window.location.search);
let position = {
    pageX: 0,
    pageY: 0,
    path: params.get('path')
};

function savePosition() {
    sessionStorage.setItem('position', JSON.stringify(position));
};

function loadPosition() {
    let savedPosition = sessionStorage.getItem('position');
    if (savedPosition && savedPosition != "undefined") {
        position = JSON.parse(savedPosition)
    }
};
window.onscroll = event => {
    position.pageX = event.pageX;
    position.pageY = event.pageY;
};
window.onload = () => {
    loadPosition();
};
(() => {
    let shelf = {};
    let contents = {};

    function linkCodeBlocks(elem, linkable = true) {
        codeworldKeywords = {};
        registerStandardHints(() => {
            let pres = elem.getElementsByTagName('pre');
            for (let i = 0; i < pres.length; ++i) {
                (() => {
                    let pre = pres[i];

                    // Markdeep buries the class annotations a bit, so we dig.
                    let clickable =
                        pre.classList.contains('clickable') ||
                        (pre.firstChild && pre.firstChild.classList &&
                            pre.firstChild.classList.contains(
                                'clickable')) ||
                        (pre.firstChild && pre.firstChild.firstChild &&
                            pre.firstChild.firstChild.classList &&
                            pre.firstChild.firstChild.classList
                            .contains('clickable'));

                    let text = pre.textContent;
                    pre.innerHTML = '';
                    CodeMirror.runMode(text, {
                        name: 'codeworld',
                        overrideKeywords: codeworldKeywords
                    }, pre);
                    pre.classList.add('cm-s-default');

                    if (linkable && clickable) {
                        pre.classList.add('clickable');
                        pre.onclick = () => {
                            if (env && env.loadSample) {
                                env.loadSample(text);
                            }
                        }
                    }
                })();
            }
        });
    }

    function activateCollapsible(root) {
        let elems = root.getElementsByClassName('collapsible');
        for (let i = 0; i < elems.length; ++i) {
            let elem = elems[i];
            elem.onclick = () => {
                if (elem.classList.contains('expanded')) {
                    elem.classList.remove('expanded');
                } else {
                    elem.classList.add('expanded');
                }
            }
        }
    }

    function linkFunBlocks(elem) {
        let blocks = elem.getElementsByTagName('xml');
        let i = 0;

        while (blocks != null && blocks.length > 0) {
            let block = blocks[0];
            let text = block.outerHTML;

            let iframe = document.createElement('iframe');
            iframe.setAttribute('frameborder', '0');
            iframe.setAttribute('scrolling', 'no');

            iframe.addEventListener("load", () => {
                this.contentWindow.setParent(parent);
                this.contentWindow.setId(iframe);
                this.contentWindow.loadXml.call(iframe.contentWindow,
                    text);
            });

            iframe.src = 'blockframe.html';
            iframe.classList.add('clickable');

            let parent = block.parentNode;
            parent.insertBefore(iframe, block);
            parent.removeChild(block);

            blocks = elem.getElementsByTagName('xml');
            i++;
        }
    }

    function addTableOfContents(body, outline) {
        let contents = document.createElement('div');
        contents.id = 'helpcontents';
        contents.classList.add('contents');

        let elems = body.getElementsByTagName('*');

        let currentLevel = 0;
        let currentElem = contents;
        let n = 0;
        for (let i = 0; i < elems.length; ++i) {
            let header = elems[i];
            let match = (/h([1-3])/i).exec(header.tagName);
            if (match == null) continue;
            let level = parseInt(match[1]);

            while (currentLevel < level) {
                let sub = document.createElement('ul');
                currentElem.appendChild(sub);
                ++currentLevel;
                currentElem = sub;
            }

            while (currentLevel > level) {
                currentElem = currentElem.parentNode;
                --currentLevel;
            }

            ++n;

            let anchor = document.createElement('a');
            anchor.setAttribute('name', n);
            anchor.innerHTML = header.innerHTML;
            header.innerHTML = '';
            header.appendChild(anchor);

            let li = document.createElement('li');
            let link = document.createElement('a');
            link.setAttribute('href', '#' + n);
            link.textContent = header.textContent;
            li.appendChild(link);
            currentElem.appendChild(li);
        }

        while (outline.firstChild) {
            outline.removeChild(outline.firstChild);
        }
        outline.appendChild(contents);
    }

    function addPopout(help) {
        let popdiv = document.createElement('div');
        popdiv.id = 'popout';
        popdiv.style = 'text-align: right';
        let popout = document.createElement('a');
        popout.innerHTML =
            ' Open the Help in a New Tab';
        popout.target = '_blank';
        popout.href = document.location.href;
        popout.onclick = e => {
            let tab = open(this.href);
            tab.addEventListener("load", () => {
                tab.env = parent;
                if (parent.sweetAlert) {
                    parent.sweetAlert.close();
                }
                if (parent.sweetAlert2) {
                    parent.sweetAlert2.close();
                }
            });
            e.preventDefault();
        };
        popdiv.appendChild(popout);
        help.appendChild(popdiv);
    }

    function relativizeLinks(base, root, tag, attr) {
        let elems = root.getElementsByTagName(tag);
        for (let elem of elems) {
            if (elem.hasAttribute(attr)) {
                let url = new URL(elem.getAttribute(attr), base);
                if (base.origin == url.origin && base.pathname == url.pathname) {
                    url = url.hash;
                } else {
                    url = url.href;
                }
                elem.setAttribute(attr, url);
            }
        }
    }

    function removeCallStacks(node) {
        if (node.nodeType == Node.TEXT_NODE) {
            node.nodeValue = node.nodeValue.replace(/HasCallStack => /, '');
        } else {
            for (let child of node.childNodes) removeCallStacks(child);
        }
    }

    function setContent(elem) {
        let help = document.getElementById('help');
        while (help.firstChild) {
            help.removeChild(help.firstChild);
        }
        if (parent && parent !== window) {
            addPopout(help);
        }
        help.appendChild(elem)

        document.body.scrollTop = position.pageY;
        if (document.firstElementChild) document.firstElementChild.scrollTop =
            position.pageY;
    }

    function loadPath(path) {
        if (!path && shelf) path = shelf.default || shelf.named[0][1];
        position.path = path;
        if (contents[path] && contents[path].elem) {
            setContent(contents[path].elem);
        } else {
            let request = new XMLHttpRequest();
            request.open('GET', path, true);
            request.onreadystatechange = () => {
                if (request.readyState != 4) {
                    return;
                }

                let source = new URL(path, location.href);
                let content = document.createElement('div');
                let raw = request.responseText;

                if (path.endsWith('.md')) {
                    content.innerHTML = window.markdeep.format(raw,
                        false);
                    relativizeLinks(source, content, 'img', 'src');
                    if (shelf && shelf.blocks) {
                        linkFunBlocks(content);
                        linkCodeBlocks(content, false);
                        activateCollapsible(content);
                    } else {
                        linkCodeBlocks(content);
                        activateCollapsible(content);
                    }
                } else {
                    content.innerHTML = raw;
                    relativizeLinks(source, content, 'script', 'src');
                    relativizeLinks(source, content, 'link', 'href');
                    relativizeLinks(source, content, 'a', 'href');
                    relativizeLinks(source, content, 'img', 'src');
                    removeCallStacks(content);
                }

                let spacerDiv = document.createElement('div');
                spacerDiv.style = 'height: 90vh'
                content.appendChild(spacerDiv);

                if (!contents[path]) contents[path] = {};
                contents[path].elem = content;

                if (contents[path].outline) {
                    addTableOfContents(content, contents[path].outline);
                }
                setContent(content);
            }
            request.send(null);
        };
    }

    function loadSidebar() {
        let path = position.path;
        if (!path) path = shelf.default;

        let activeIndex = false;

        let acc = document.createElement('div')
        acc.id = 'helpacc';

        let paneNum = 0;
        for (let doc in shelf.named) {
            let hdr = document.createElement('h3');
            hdr.innerText = doc;
            acc.appendChild(hdr);

            let entry = document.createElement('div');
            entry.classList.add('accentry');
            entry.innerHTML = '
Loading...
';
            acc.appendChild(entry);

            contents[shelf.named[doc]] = {
                title: doc,
                header: hdr,
                outline: entry,
                index: paneNum,
                elem: null
            }

            if (shelf.named[doc] == path) activeIndex = paneNum;
            paneNum++;
        }

        document.body.insertBefore(acc, document.body.firstChild);
        $(acc).accordion({
            collapsible: true,
            active: activeIndex,
            heightStyle: 'content',
            beforeActivate: (event, ui) => {
                position.pageX = 0;
                position.pageY = 0;
                let name = ui.newHeader.text();
                let path = name && shelf.named[name];
                if (path) loadPath(path);
            }
        });
    }

    let markdeepStyle = document.createElement('style');
    document.head.appendChild(markdeepStyle);
    markdeepStyle.outerHTML = window.markdeep.stylesheet();

    if (params.get('shelf')) {
        let request = new XMLHttpRequest();
        request.open('GET', params.get('shelf'), true);
        request.onreadystatechange = () => {
            if (request.readyState != 4) {
                return;
            }

            shelf = JSON.parse(request.responseText);
            loadSidebar();
            loadPath(position.path);
        };
        request.send(null);
    } else {
        shelf = null;
        loadPath(params.get('path'));
    }
})();
<commit_msg>Fix scrolling code.<commit_after>/*
 * Copyright 2019 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
window.env = parent;
let params = new URLSearchParams(window.location.search);
let position = {
    scrollLeft: 0,
    scrollTop: 0,
    path: params.get('path')
};

function savePosition() {
    sessionStorage.setItem('position', JSON.stringify(position));
};

function loadPosition() {
    let savedPosition = sessionStorage.getItem('position');
    if (savedPosition && savedPosition != "undefined") {
        position = JSON.parse(savedPosition)
    }
};
window.onscroll = event => {
    position.scrollLeft = event.target.scrollingElement.scrollLeft;
    position.scrollTop = event.target.scrollingElement.scrollTop;
};
window.onload = () => {
    loadPosition();
};
(() => {
    let shelf = {};
    let contents = {};

    function linkCodeBlocks(elem, linkable = true) {
        codeworldKeywords = {};
        registerStandardHints(() => {
            let pres = elem.getElementsByTagName('pre');
            for (let i = 0; i < pres.length; ++i) {
                (() => {
                    let pre = pres[i];

                    // Markdeep buries the class annotations a bit, so we dig.
                    let clickable =
                        pre.classList.contains('clickable') ||
                        (pre.firstChild && pre.firstChild.classList &&
                            pre.firstChild.classList.contains(
                                'clickable')) ||
                        (pre.firstChild && pre.firstChild.firstChild &&
                            pre.firstChild.firstChild.classList &&
                            pre.firstChild.firstChild.classList
                            .contains('clickable'));

                    let text = pre.textContent;
                    pre.innerHTML = '';
                    CodeMirror.runMode(text, {
                        name: 'codeworld',
                        overrideKeywords: codeworldKeywords
                    }, pre);
                    pre.classList.add('cm-s-default');

                    if (linkable && clickable) {
                        pre.classList.add('clickable');
                        pre.onclick = () => {
                            if (env && env.loadSample) {
                                env.loadSample(text);
                            }
                        }
                    }
                })();
            }
        });
    }

    function activateCollapsible(root) {
        let elems = root.getElementsByClassName('collapsible');
        for (let i = 0; i < elems.length; ++i) {
            let elem = elems[i];
            elem.onclick = () => {
                if (elem.classList.contains('expanded')) {
                    elem.classList.remove('expanded');
                } else {
                    elem.classList.add('expanded');
                }
            }
        }
    }

    function linkFunBlocks(elem) {
        let blocks = elem.getElementsByTagName('xml');
        let i = 0;

        while (blocks != null && blocks.length > 0) {
            let block = blocks[0];
            let text = block.outerHTML;

            let iframe = document.createElement('iframe');
            iframe.setAttribute('frameborder', '0');
            iframe.setAttribute('scrolling', 'no');

            iframe.addEventListener("load", () => {
                this.contentWindow.setParent(parent);
                this.contentWindow.setId(iframe);
                this.contentWindow.loadXml.call(iframe.contentWindow,
                    text);
            });

            iframe.src = 'blockframe.html';
            iframe.classList.add('clickable');

            let parent = block.parentNode;
            parent.insertBefore(iframe, block);
            parent.removeChild(block);

            blocks = elem.getElementsByTagName('xml');
            i++;
        }
    }

    function addTableOfContents(body, outline) {
        let contents = document.createElement('div');
        contents.id = 'helpcontents';
        contents.classList.add('contents');

        let elems = body.getElementsByTagName('*');

        let currentLevel = 0;
        let currentElem = contents;
        let n = 0;
        for (let i = 0; i < elems.length; ++i) {
            let header = elems[i];
            let match = (/h([1-3])/i).exec(header.tagName);
            if (match == null) continue;
            let level = parseInt(match[1]);

            while (currentLevel < level) {
                let sub = document.createElement('ul');
                currentElem.appendChild(sub);
                ++currentLevel;
                currentElem = sub;
            }

            while (currentLevel > level) {
                currentElem = currentElem.parentNode;
                --currentLevel;
            }

            ++n;

            let anchor = document.createElement('a');
            anchor.setAttribute('name', n);
            anchor.innerHTML = header.innerHTML;
            header.innerHTML = '';
            header.appendChild(anchor);

            let li = document.createElement('li');
            let link = document.createElement('a');
            link.setAttribute('href', '#' + n);
            link.textContent = header.textContent;
            li.appendChild(link);
            currentElem.appendChild(li);
        }

        while (outline.firstChild) {
            outline.removeChild(outline.firstChild);
        }
        outline.appendChild(contents);
    }

    function addPopout(help) {
        let popdiv = document.createElement('div');
        popdiv.id = 'popout';
        popdiv.style = 'text-align: right';
        let popout = document.createElement('a');
        popout.innerHTML =
            ' Open the Help in a New Tab';
        popout.target = '_blank';
        popout.href = document.location.href;
        popout.onclick = e => {
            let tab = open(this.href);
            tab.addEventListener("load", () => {
                tab.env = parent;
                if (parent.sweetAlert) {
                    parent.sweetAlert.close();
                }
                if (parent.sweetAlert2) {
                    parent.sweetAlert2.close();
                }
            });
            e.preventDefault();
        };
        popdiv.appendChild(popout);
        help.appendChild(popdiv);
    }

    function relativizeLinks(base, root, tag, attr) {
        let elems = root.getElementsByTagName(tag);
        for (let elem of elems) {
            if (elem.hasAttribute(attr)) {
                let url = new URL(elem.getAttribute(attr), base);
                if (base.origin == url.origin && base.pathname == url.pathname) {
                    url = url.hash;
                } else {
                    url = url.href;
                }
                elem.setAttribute(attr, url);
            }
        }
    }

    function removeCallStacks(node) {
        if (node.nodeType == Node.TEXT_NODE) {
            node.nodeValue = node.nodeValue.replace(/HasCallStack => /, '');
        } else {
            for (let child of node.childNodes) removeCallStacks(child);
        }
    }

    function setContent(elem) {
        let help = document.getElementById('help');
        while (help.firstChild) {
            help.removeChild(help.firstChild);
        }
        if (parent && parent !== window) {
            addPopout(help);
        }
        help.appendChild(elem)

        document.scrollingElement.scrollLeft = position.scrollLeft;
        document.scrollingElement.scrollTop = position.scrollTop;
    }

    function loadPath(path) {
        if (!path && shelf) path = shelf.default || shelf.named[0][1];
        position.path = path;
        if (contents[path] && contents[path].elem) {
            setContent(contents[path].elem);
        } else {
            let request = new XMLHttpRequest();
            request.open('GET', path, true);
            request.onreadystatechange = () => {
                if (request.readyState != 4) {
                    return;
                }

                let source = new URL(path, location.href);
                let content = document.createElement('div');
                let raw = request.responseText;

                if (path.endsWith('.md')) {
                    content.innerHTML = window.markdeep.format(raw,
                        false);
                    relativizeLinks(source, content, 'img', 'src');
                    if (shelf && shelf.blocks) {
                        linkFunBlocks(content);
                        linkCodeBlocks(content, false);
                        activateCollapsible(content);
                    } else {
                        linkCodeBlocks(content);
                        activateCollapsible(content);
                    }
                } else {
                    content.innerHTML = raw;
                    relativizeLinks(source, content, 'script', 'src');
                    relativizeLinks(source, content, 'link', 'href');
                    relativizeLinks(source, content, 'a', 'href');
                    relativizeLinks(source, content, 'img', 'src');
                    removeCallStacks(content);
                }

                let spacerDiv = document.createElement('div');
                spacerDiv.style = 'height: 90vh'
                content.appendChild(spacerDiv);

                if (!contents[path]) contents[path] = {};
                contents[path].elem = content;

                if (contents[path].outline) {
                    addTableOfContents(content, contents[path].outline);
                }
                setContent(content);
            }
            request.send(null);
        };
    }

    function loadSidebar() {
        let path = position.path;
        if (!path) path = shelf.default;

        let activeIndex = false;

        let acc = document.createElement('div')
        acc.id = 'helpacc';

        let paneNum = 0;
        for (let doc in shelf.named) {
            let hdr = document.createElement('h3');
            hdr.innerText = doc;
            acc.appendChild(hdr);

            let entry = document.createElement('div');
            entry.classList.add('accentry');
            entry.innerHTML = '
Loading...
';
            acc.appendChild(entry);

            contents[shelf.named[doc]] = {
                title: doc,
                header: hdr,
                outline: entry,
                index: paneNum,
                elem: null
            }

            if (shelf.named[doc] == path) activeIndex = paneNum;
            paneNum++;
        }

        document.body.insertBefore(acc, document.body.firstChild);
        $(acc).accordion({
            collapsible: true,
            active: activeIndex,
            heightStyle: 'content',
            beforeActivate: (event, ui) => {
                position.scrollLeft = 0;
                position.scrollTop = 0;
                let name = ui.newHeader.text();
                let path = name && shelf.named[name];
                if (path) loadPath(path);
            }
        });
    }

    let markdeepStyle = document.createElement('style');
    document.head.appendChild(markdeepStyle);
    markdeepStyle.outerHTML = window.markdeep.stylesheet();

    if (params.get('shelf')) {
        let request = new XMLHttpRequest();
        request.open('GET', params.get('shelf'), true);
        request.onreadystatechange = () => {
            if (request.readyState != 4) {
                return;
            }

            shelf = JSON.parse(request.responseText);
            loadSidebar();
            loadPath(position.path);
        };
        request.send(null);
    } else {
        shelf = null;
        loadPath(params.get('path'));
    }
})();
<|endoftext|>