<commit_before>/*global $:false, jQuery:false */
//counters = new Array();
//$box = new Array();
var counters = {};
var abnormal = false;
var undo = false;
var keyboard_active = false;
var img_displayed = false;

$(document).ready(function() {
    "use strict";
    var key, name, img;
    $("#myCounts").tablesorter();

    $('.count').each(function () {
            //access to element via $(this)
            key = $(this).find('div#key').text();
            name = $(this).find('font2').text();
            img = $(this).find('a#img').text();
            counters[name] = {};
            counters[name].key = key.toUpperCase();
            counters[name].count = 0;
            counters[name].abnormal = 0;
            counters[name].box = $(this);
            counters[name].img = img;

            //$count[key] = 0;
            //$count[key + "_abnormal"] = 0;
            //$box[key] = $(this);
            //$box[key + "_abnormal"] = $(this);
    });

    $('#openkeyboard').click(function () {
        $('#fuzz').fadeIn('slow', function () {
            $('#counterbox').slideDown('slow', function () {
            $("#fuzz").css("height", $(document).height());
            keyboard_active = true;
            });
        });
    });

    $('#fuzz').click(function () {
        var output, total, percent, per;

        if (keyboard_active) {
            keyboard_active = false;
            output = {};
            total = 0;

            for (var prop in counters) {
                if (counters.hasOwnProperty(prop)) {
                    // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
                    output[prop] = {};
                    output[prop].normal = counters[prop].count;
                    output[prop].abnormal = counters[prop].abnormal;

                    total += counters[prop].count;
                    total += counters[prop].count;
                }
            }

            // Put counts into the ModelForms
            for (var cell in output) {
                if (output.hasOwnProperty(cell)) {
                    $("#"+cell+"").children()[1].value=output[cell].normal;
                    $("#"+cell+"").children()[2].value=output[cell].abnormal;
                }
            }

            percent = {};
            per = "";

            for (var prop in counters) {
                if (counters.hasOwnProperty(prop)) {
                    // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
                    percent[prop] = (counters[prop].count + counters[prop].abnormal) / total * 100;
                    per += '
' + prop + '	' + parseFloat(percent[prop]).toFixed(2) + "%
";
                }
            }

            if(total > 0) {
                $('div#statistics').empty().append('
Count statistics

' + per + '
');
            }

            $('#counterbox').slideUp('slow', function () {
                $('#fuzz').fadeOut('slow', function () {
                });
            });
        }
    });

    //Adjust height of overlay to fill screen when browser gets resized
    $(window).bind("resize", function (){
        $("#fuzz").css("height", $(document).height());
        //$("#fuzz").css("top", $(window).top());
    });
    //$("#fuzz").css("height", $(document).height());

    //$(document).keypress(function(e) {
    jQuery(document).bind('keydown', function (e) {
        var key, code, shift_pressed, el, count_total, abnormal_total;
        //Event.stop(e);
        if (keyboard_active) {
            key = String.fromCharCode(e.which).toUpperCase();
            code = e.which;
            shift_pressed = e.shiftKey;
            if (code === 188) {
                key = ","; // XXX: WTF
            }
            if (code === 173) {
                key = "-"; // XXX: WTF
            }
            if (key === " ") {
                abnormal = true;
                //Event.stop(e);
                return false;
                //$("div#imagebox").css("background-image", "");
            } else if (code === 8) {
                undo = true;
                return false;
            }

            if (shift_pressed) {
                for (var prop in counters) {
                    if (counters.hasOwnProperty(prop)) {
                        if(counters[prop].key === key) {
                            el = $("div#imagebox");
                            el.css("display", "block");
                            el.find("div#imgdisplay").css("background-image", "url(" + counters[prop].img + ")");
                            img_displayed = true;
                        }
                    }
                }
            } else if (img_displayed) {
                $("div#imagebox").css("display", "none");
                img_displayed = false;
                return;
            }

            count_total = 0;
            abnormal_total = 0;
            for (var prop in counters) {
                if (counters.hasOwnProperty(prop))  {
                    if (counters[prop].key === key) {
                        if(abnormal === true) {
                            if(undo) {
                                if(counters[prop].abnormal > 0) {
                                    counters[prop].abnormal--;
                                }
                            } else {
                                counters[prop].abnormal++;
                                $(counters[prop].box).find("span#abnormal").text(counters[prop].abnormal);
                            }
                        } else if(undo) {
                            if(counters[prop].count > 0) {
                                counters[prop].count--;
                            }
                        } else {
                            counters[prop].count++;
                            $(counters[prop].box).find("span#countval").text(counters[prop].count);
                        }
                    }
                }
                count_total += counters[prop].abnormal;
                count_total += counters[prop].count;
            }
            $("#total").text(count_total);
        }
    });

    jQuery(document).bind('keyup', function (e){
        var key, code;
        if (keyboard_active) {
            code = e.which;
            key = String.fromCharCode(code).toUpperCase();
            if (code === 173) {
                key = "-";// XXX: WTF
            }
            if (key === " ") {
                abnormal = false;
            }
            if (code === 8) {
                undo = false;
            }
        }
    });
});

/*window.onkeydown=function(e){
if(e.keyCode==32){
return false;
}
}; */

function ironstain() {
    "use strict";
    if ($("#id_ironstain-stain_performed").prop('checked') === true) {
        $("#id_ironstain-ringed_sideroblasts").prop('disabled', false);
        $("#id_ironstain-iron_content").prop('disabled', false);
        $("#id_ironstain-comment").prop('disabled', false);
    } else {
        $("#id_ironstain-ringed_sideroblasts").prop('disabled', true);
        $("#id_ironstain-iron_content").prop('disabled', true);
        $("#id_ironstain-comment").prop('disabled', true);

    }
}

function granulopoiesis () {
    "use strict";
    if ($("#id_granulopoiesis-no_dysplasia").prop('checked') === true) {
        $("#id_granulopoiesis-hypogranular").prop('checked', false);
        $("#id_granulopoiesis-hypogranular").prop('disabled', true);
        $("#id_granulopoiesis-pelger").prop('checked', false);
        $("#id_granulopoiesis-pelger").prop('disabled', true);
        $("#id_granulopoiesis-nuclear_atypia").prop('checked', false);
        $("#id_granulopoiesis-nuclear_atypia").prop('disabled', true);
        $("#id_granulopoiesis-dohle_bodies").prop('checked', false);
        $("#id_granulopoiesis-dohle_bodies").prop('disabled', true);
    } else {
        $("#id_granulopoiesis-hypogranular").prop('disabled', false);
        $("#id_granulopoiesis-pelger").prop('disabled', false);
        $("#id_granulopoiesis-nuclear_atypia").prop('disabled', false);
        $("#id_granulopoiesis-dohle_bodies").prop('disabled', false);
    }
}

function erythropoiesis () {
    "use strict";
    if ($("#id_erythropoiesis-no_dysplasia").prop('checked') === true) {
        $("#id_erythropoiesis-nuclear_asynchrony").prop('checked', false);
        $("#id_erythropoiesis-nuclear_asynchrony").prop('disabled', true);
        $("#id_erythropoiesis-multinucleated_forms").prop('checked', false);
        $("#id_erythropoiesis-multinucleated_forms").prop('disabled', true);
        $("#id_erythropoiesis-ragged_haemoglobinisation").prop('checked', false);
        $("#id_erythropoiesis-ragged_haemoglobinisation").prop('disabled', true);
        $("#id_erythropoiesis-megaloblastic_change").prop('checked', false);
        $("#id_erythropoiesis-megaloblastic_change").prop('disabled', true);
    } else {
        $("#id_erythropoiesis-nuclear_asynchrony").prop('disabled', false);
        $("#id_erythropoiesis-multinucleated_forms").prop('disabled', false);
        $("#id_erythropoiesis-ragged_haemoglobinisation").prop('disabled', false);
        $("#id_erythropoiesis-megaloblastic_change").prop('disabled', false);
    }
}

function megakaryocytes () {
    "use strict";
    if ($("#id_megakaryocyte-no_dysplasia").prop('checked') === true) {
        $("#id_megakaryocyte-hypolobulated").prop('checked', false);
        $("#id_megakaryocyte-hypolobulated").prop('disabled', true);
        $("#id_megakaryocyte-fragmented").prop('checked', false);
        $("#id_megakaryocyte-fragmented").prop('disabled', true);
        $("#id_megakaryocyte-micromegakaryocytes").prop('checked', false);
        $("#id_megakaryocyte-micromegakaryocytes").prop('disabled', true);
    } else {
        $("#id_megakaryocyte-hypolobulated").prop('disabled', false);
        $("#id_megakaryocyte-fragmented").prop('disabled', false);
        $("#id_megakaryocyte-micromegakaryocytes").prop('disabled', false);
    }
}
<commit_msg>Implement dysplasia enable/disable feature via JQuery/JS<commit_after>/*global $:false, jQuery:false */
//counters = new Array();
//$box = new Array();
var counters = {};
var abnormal = false;
var undo = false;
var keyboard_active = false;
var img_displayed = false;

$(document).ready(function() {
    "use strict";
    var key, name, img;
    $("#myCounts").tablesorter();

    $('.count').each(function () {
            //access to element via $(this)
            key = $(this).find('div#key').text();
            name = $(this).find('font2').text();
            img = $(this).find('a#img').text();
            counters[name] = {};
            counters[name].key = key.toUpperCase();
            counters[name].count = 0;
            counters[name].abnormal = 0;
            counters[name].box = $(this);
            counters[name].img = img;

            //$count[key] = 0;
            //$count[key + "_abnormal"] = 0;
            //$box[key] = $(this);
            //$box[key + "_abnormal"] = $(this);
    });

    $('#openkeyboard').click(function () {
        $('#fuzz').fadeIn('slow', function () {
            $('#counterbox').slideDown('slow', function () {
            $("#fuzz").css("height", $(document).height());
            keyboard_active = true;
            });
        });
    });

    $('#fuzz').click(function () {
        var output, total, percent, per;

        if (keyboard_active) {
            keyboard_active = false;
            output = {};
            total = 0;

            for (var prop in counters) {
                if (counters.hasOwnProperty(prop)) {
                    // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
                    output[prop] = {};
                    output[prop].normal = counters[prop].count;
                    output[prop].abnormal = counters[prop].abnormal;

                    total += counters[prop].count;
                    total += counters[prop].count;
                }
            }

            // Put counts into the ModelForms
            for (var cell in output) {
                if (output.hasOwnProperty(cell)) {
                    $("#"+cell+"").children()[1].value=output[cell].normal;
                    $("#"+cell+"").children()[2].value=output[cell].abnormal;
                }
            }

            percent = {};
            per = "";

            for (var prop in counters) {
                if (counters.hasOwnProperty(prop)) {
                    // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
                    percent[prop] = (counters[prop].count + counters[prop].abnormal) / total * 100;
                    per += '
' + prop + '	' + parseFloat(percent[prop]).toFixed(2) + "%
";
                }
            }

            if(total > 0) {
                $('div#statistics').empty().append('
Count statistics

' + per + '
');
            }

            $('#counterbox').slideUp('slow', function () {
                $('#fuzz').fadeOut('slow', function () {
                });
            });
        }
    });

    //Adjust height of overlay to fill screen when browser gets resized
    $(window).bind("resize", function (){
        $("#fuzz").css("height", $(document).height());
        //$("#fuzz").css("top", $(window).top());
    });
    //$("#fuzz").css("height", $(document).height());

    //$(document).keypress(function(e) {
    jQuery(document).bind('keydown', function (e) {
        var key, code, shift_pressed, el, count_total, abnormal_total;
        //Event.stop(e);
        if (keyboard_active) {
            key = String.fromCharCode(e.which).toUpperCase();
            code = e.which;
            shift_pressed = e.shiftKey;
            if (code === 188) {
                key = ","; // XXX: WTF
            }
            if (code === 173) {
                key = "-"; // XXX: WTF
            }
            if (key === " ") {
                abnormal = true;
                //Event.stop(e);
                return false;
                //$("div#imagebox").css("background-image", "");
            } else if (code === 8) {
                undo = true;
                return false;
            }

            if (shift_pressed) {
                for (var prop in counters) {
                    if (counters.hasOwnProperty(prop)) {
                        if(counters[prop].key === key) {
                            el = $("div#imagebox");
                            el.css("display", "block");
                            el.find("div#imgdisplay").css("background-image", "url(" + counters[prop].img + ")");
                            img_displayed = true;
                        }
                    }
                }
            } else if (img_displayed) {
                $("div#imagebox").css("display", "none");
                img_displayed = false;
                return;
            }

            count_total = 0;
            abnormal_total = 0;
            for (var prop in counters) {
                if (counters.hasOwnProperty(prop))  {
                    if (counters[prop].key === key) {
                        if(abnormal === true) {
                            if(undo) {
                                if(counters[prop].abnormal > 0) {
                                    counters[prop].abnormal--;
                                }
                            } else {
                                counters[prop].abnormal++;
                                $(counters[prop].box).find("span#abnormal").text(counters[prop].abnormal);
                            }
                        } else if(undo) {
                            if(counters[prop].count > 0) {
                                counters[prop].count--;
                            }
                        } else {
                            counters[prop].count++;
                            $(counters[prop].box).find("span#countval").text(counters[prop].count);
                        }
                    }
                }
                count_total += counters[prop].abnormal;
                count_total += counters[prop].count;
            }
            $("#total").text(count_total);
        }
    });

    jQuery(document).bind('keyup', function (e){
        var key, code;
        if (keyboard_active) {
            code = e.which;
            key = String.fromCharCode(code).toUpperCase();
            if (code === 173) {
                key = "-";// XXX: WTF
            }
            if (key === " ") {
                abnormal = false;
            }
            if (code === 8) {
                undo = false;
            }
        }
    });
});

/*window.onkeydown=function(e){
if(e.keyCode==32){
return false;
}
}; */

function ironstain() {
    "use strict";
    if ($("#id_ironstain-stain_performed").prop("checked")) {
        $("#id_ironstain-ringed_sideroblasts").prop("disabled", false);
        $("#id_ironstain-iron_content").prop("disabled", false);
        $("#id_ironstain-comment").prop("disabled", false);
    } else {
        $("#id_ironstain-ringed_sideroblasts").prop("disabled", true);
        $("#id_ironstain-iron_content").prop("disabled", true);
        $("#id_ironstain-comment").prop("disabled", true);
    }
}

function granulopoiesis() {
    "use strict";
    if ($("#id_granulopoiesis-no_dysplasia").prop("checked")) {
        $("#id_granulopoiesis-hypogranular").prop("disabled", true);
        $("#id_granulopoiesis-hypogranular").prop("checked", false);
        $("#id_granulopoiesis-pelger").prop("disabled", true);
        $("#id_granulopoiesis-pelger").prop("checked", false);
        $("#id_granulopoiesis-nuclear_atypia").prop("disabled", true);
        $("#id_granulopoiesis-nuclear_atypia").prop("checked", false);
        $("#id_granulopoiesis-dohle_bodies").prop("disabled", true);
        $("#id_granulopoiesis-dohle_bodies").prop("checked", false);
   } else {
        $("#id_granulopoiesis-hypogranular").prop("disabled", false);
        $("#id_granulopoiesis-pelger").prop("disabled", false);
        $("#id_granulopoiesis-nuclear_atypia").prop("disabled", false);
        $("#id_granulopoiesis-dohle_bodies").prop("disabled", false);
    }
}

function erythropoiesis() {
    "use strict";
    if ($("#id_erythropoiesis-no_dysplasia").prop("checked")) {
        $("#id_erythropoiesis-nuclear_asynchrony").prop("disabled", true);
        $("#id_erythropoiesis-nuclear_asynchrony").prop("checked", false);
        $("#id_erythropoiesis-multinucleated_forms").prop("disabled", true);
        $("#id_erythropoiesis-multinucleated_forms").prop("checked", false);
        $("#id_erythropoiesis-ragged_haemoglobinisation").prop("disabled", true);
        $("#id_erythropoiesis-ragged_haemoglobinisation").prop("checked", false);
        $("#id_erythropoiesis-megaloblastic_change").prop("disabled", true);
        $("#id_erythropoiesis-megaloblastic_change").prop("checked", false);
    } else {
        $("#id_erythropoiesis-nuclear_asynchrony").prop("disabled", false);
        $("#id_erythropoiesis-multinucleated_forms").prop("disabled", false);
        $("#id_erythropoiesis-ragged_haemoglobinisation").prop("disabled", false);
        $("#id_erythropoiesis-megaloblastic_change").prop("disabled", false);
    }
}

function megakaryocytes() {
    "use strict";
    if ($("#id_megakaryocyte-no_dysplasia").prop("checked")) {
        $("#id_megakaryocyte-hypolobulated").prop("disabled", true);
        $("#id_megakaryocyte-hypolobulated").prop("checked", false);
        $("#id_megakaryocyte-fragmented").prop("disabled", true);
        $("#id_megakaryocyte-fragmented").prop("checked", false);
        $("#id_megakaryocyte-micromegakaryocytes").prop("disabled", true);
        $("#id_megakaryocyte-micromegakaryocytes").prop("checked", false);
    } else {
        $("#id_megakaryocyte-hypolobulated").prop("disabled", false);
        $("#id_megakaryocyte-fragmented").prop("disabled", false);
        $("#id_megakaryocyte-micromegakaryocytes").prop("disabled", false);
    }
}
<|endoftext|>


<commit_before>angular.module("omniControllers")
	.controller("ExplorerAssetsController",[function ExplorerAssetsController($scope, PropertyManager){
	    $scope.assets = [];
	    PropertyManager.list().then(function(result){
	      $scope.assets=result.data.properties;
	    });

	}])<commit_msg>Add missing dependencies to ExplorerAssetsController<commit_after>angular.module("omniControllers")
	.controller("ExplorerAssetsController",["$scope", "PropertyManager", function ExplorerAssetsController($scope, PropertyManager){
	    $scope.assets = [];
	    PropertyManager.list().then(function(result){
	      $scope.assets=result.data.properties;
	    });

	}])<|endoftext|>


<commit_before>const windowStateKeeper = require('electron-window-state');
const {app, BrowserWindow, Menu, MenuItem} = require('electron');
const path = require('path');

var mainWindow = null;

require('electron-context-menu')({
    prepend: (params, browserWindow) => [{
        label: 'Movim',
        // only show it when right-clicking images
        visible: params.mediaType === 'image'
    }],
    showInspectElement: false
});

app.commandLine.appendSwitch('force-color-profile', 'srgb');

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
    // Set default dimensions if a previous state isn't available
    let mainWindowState = windowStateKeeper({
        defaultWidth: 1280,
        defaultHeight: 768
    });

    // Create the browser window.
    mainWindow = new BrowserWindow(
        {
            "x": mainWindowState.x,
            "y": mainWindowState.y,
            "width": mainWindowState.width,
            "height": mainWindowState.height,
            /*"minWidth": 1152,*/
            "minHeight": 600,
            backgroundColor: '#3F51B5',
            icon: path.join(__dirname, 'img/logo.png'),
            "webPreferences": {
                "zoomFactor": 0.975,
                "allowDisplayingInsecureContent": true
            }
        }
    );
    mainWindowState.manage(mainWindow);

    // and load the index.html of the app.
    mainWindow.loadURL('file://' + __dirname + '/index.html');

    //mainWindow.openDevTools();

    mainWindow.setMenuBarVisibility(false);

    // Emitted when the window is closed.
    mainWindow.on('closed', function() {
        mainWindow = null;
    });

    /*
    mainWindow.on('blur', function() {
        console.log('blur');
        mainWindow.blurWebView();
    });

    mainWindow.on('focus', function() {
        console.log('focus');
        mainWindow.focusOnWebView();
    });*/

    /*
    var appIcon = new Tray(__dirname + '/img/logo_tray.png');
    appIcon.setToolTip('Movim - Kickass Social Network');

    appIcon.on('clicked', function() {
        //if(mainWindow.isVisible()) {
        //    mainWindow.hide();
        //else {
            mainWindow.show();
        //}
    });*/

    mainWindow.webContents.on('new-window', function(e, url) {
        e.preventDefault();
        if(url.search('/?visio/') > -1) {
            var win = new BrowserWindow()
            win.setMenuBarVisibility(false)
            win.loadURL(url)
            win.on('closed', function() {
                win = null;
            });
        } else {
            require('electron').shell.openExternal(url);
        }
    });

    mainWindow.notification = function(counter) {
        app.setBadgeCount(counter);
        if(counter > 0) {
            if(app.dock) {
                app.dock.bounce();
            }
            //appIcon.setImage(__dirname + '/img/logo_tray_notifs.png');
        } else {
            //appIcon.setImage(__dirname + '/img/logo_tray.png');
        }
    }
});
<commit_msg>Clean up.<commit_after>const windowStateKeeper = require('electron-window-state');
const {app, BrowserWindow, Menu, MenuItem} = require('electron');
const path = require('path');

var mainWindow = null;

require('electron-context-menu')({
    showInspectElement: false
});

app.commandLine.appendSwitch('force-color-profile', 'srgb');

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
    // Set default dimensions if a previous state isn't available
    let mainWindowState = windowStateKeeper({
        defaultWidth: 1280,
        defaultHeight: 768
    });

    // Create the browser window.
    mainWindow = new BrowserWindow(
        {
            "x": mainWindowState.x,
            "y": mainWindowState.y,
            "width": mainWindowState.width,
            "height": mainWindowState.height,
            /*"minWidth": 1152,*/
            "minHeight": 600,
            backgroundColor: '#3F51B5',
            icon: path.join(__dirname, 'img/logo.png'),
            "webPreferences": {
                "zoomFactor": 0.975,
                "allowDisplayingInsecureContent": true
            }
        }
    );
    mainWindowState.manage(mainWindow);

    // and load the index.html of the app.
    mainWindow.loadURL('file://' + __dirname + '/index.html');

    //mainWindow.openDevTools();

    mainWindow.setMenuBarVisibility(false);

    // Emitted when the window is closed.
    mainWindow.on('closed', function() {
        mainWindow = null;
    });

    /*
    mainWindow.on('blur', function() {
        console.log('blur');
        mainWindow.blurWebView();
    });

    mainWindow.on('focus', function() {
        console.log('focus');
        mainWindow.focusOnWebView();
    });*/

    /*
    var appIcon = new Tray(__dirname + '/img/logo_tray.png');
    appIcon.setToolTip('Movim - Kickass Social Network');

    appIcon.on('clicked', function() {
        //if(mainWindow.isVisible()) {
        //    mainWindow.hide();
        //else {
            mainWindow.show();
        //}
    });*/

    mainWindow.webContents.on('new-window', function(e, url) {
        e.preventDefault();
        if(url.search('/?visio/') > -1) {
            var win = new BrowserWindow()
            win.setMenuBarVisibility(false)
            win.loadURL(url)
            win.on('closed', function() {
                win = null;
            });
        } else {
            require('electron').shell.openExternal(url);
        }
    });

    mainWindow.notification = function(counter) {
        app.setBadgeCount(counter);
        if(counter > 0) {
            if(app.dock) {
                app.dock.bounce();
            }
            //appIcon.setImage(__dirname + '/img/logo_tray_notifs.png');
        } else {
            //appIcon.setImage(__dirname + '/img/logo_tray.png');
        }
    }
});
<|endoftext|>


<commit_before>/*
 @author Zakai Hamilton
 @component KabTerms
 */

package.require("kab.terms", "browser");

package.kab.terms = function KabTerms(me) {
    me.terms = __json__;
    me.init = function() {
        me.ui.theme.useStylesheet("kab.terms");
    };
    me.parse = function (wordsString, options) {
        return me.core.string.parseWords(wordsString, function(words) {
            for (var wordIndex = 0; wordIndex < words.length; wordIndex++) {
                for (var term in me.terms.terms) {
                    if(term.startsWith("!")) {
                        continue;
                    }
                    var item = me.terms.terms[term];
                    var termWords = term.split(" ");
                    var numTermWords = termWords.length;
                    var collectedWords = me.toCase(item, words[wordIndex]);
                    for (var termWordIndex = 1; termWordIndex < numTermWords; termWordIndex++) {
                        if (wordIndex + termWordIndex >= words.length) {
                            break;
                        }
                        var word = words[wordIndex + termWordIndex];
                        var matchingTerm = me.terms.terms[word];
                        if(matchingTerm && matchingTerm.ignore) {
                            numTermWords++;
                            continue;
                        }
                        collectedWords += " " + word.toLowerCase();
                    }
                    if (me.toCase(item, term) === collectedWords) {
                        var expansion = item.expansion;
                        if (expansion) {
                            expansion = [].concat(expansion);
                            expansion = expansion.map(function(item) {
                                return me.parse(item, options);
                            });
                            if (expansion.length > 1) {
                                expansion = expansion.slice(0, -1).join(", ") + " and " + expansion.slice(-1).toString();
                            } else {
                                expansion = expansion.slice(-1).toString();
                            }
                            words.splice(wordIndex, numTermWords);
                            me.modify(words, wordIndex, item, term, " (", expansion, ")", options, true);
                        }
                        var translation = item.translation;
                        if (translation) {
                            translation = me.parse(translation, me.duplicateOptions(options, {"addStyles":false}));
                            words.splice(wordIndex, numTermWords);
                            me.modify(words, wordIndex, item, term, " [", translation, "]", options);
                        }
                        if(options.addStyles && !translation && !expansion) {
                            words.splice(wordIndex, numTermWords);
                            me.modify(words, wordIndex, item, term, "", term, "", me.duplicateOptions(options, {"keepSource":false}));
                        }
                        break;
                    }
                }
            }
        });
    };
    me.toCase = function(item, string) {
        if(item.case !== "sensitive") {
            string = string.toLowerCase();
        }
        return string;
    }
    me.duplicateOptions = function(options, overrides) {
        var duplicate = {};
        for(var key in options) {
            duplicate[key] = options[key];
        }
        if(overrides) {
            for(var key in overrides) {
                duplicate[key] = overrides[key];
            }
        }
        return duplicate;
    };
    me.modify = function (words, wordIndex, item, term, prefix, replacement, suffix, options, expansion) {
        if (!options.doTranslation) {
            replacement = term;
        }
        else if (options.keepSource) {
            replacement = term + prefix + replacement + suffix;
        }
        if (options.addStyles && (item.style || replacement !== term)) {
            replacement = me.applyStyles(term, item.style, replacement, options, expansion);
        }
        words.splice(wordIndex, 0, replacement);
    };
    me.applyStyles = function(term, styles, text, options, expansion) {
        var html = "";
        for(var style in styles) {
            if(style === "heading") {
                html += "" + styles[style] + "";
            }
        }
        if(styles && styles.phase) {
            html += "" + text + "";
        }
        else if(!options.keepSource && !expansion) {
            html += "" + text + "";
        }
        else {
            html += text;
        }
        return html;
    };
};<commit_msg>sorting terms by longest terms first<commit_after>/*
 @author Zakai Hamilton
 @component KabTerms
 */

package.require("kab.terms", "browser");

package.kab.terms = function KabTerms(me) {
    me.terms = __json__;
    me.init = function () {
        me.ui.theme.useStylesheet("kab.terms");
    };
    me.parse = function (wordsString, options) {
        return me.core.string.parseWords(wordsString, function (words) {
            var terms = Object.keys(me.terms.terms).sort(function (source, target) {
                return target.length - source.length;
            });
            for (var wordIndex = 0; wordIndex < words.length; wordIndex++) {
                for (var termIndex = 0; termIndex < terms.length; termIndex++) {
                    var term = terms[termIndex];
                    if (term.startsWith("!")) {
                        continue;
                    }
                    var item = me.terms.terms[term];
                    var termWords = term.split(" ");
                    var numTermWords = termWords.length;
                    var collectedWords = me.toCase(item, words[wordIndex]);
                    for (var termWordIndex = 1; termWordIndex < numTermWords; termWordIndex++) {
                        if (wordIndex + termWordIndex >= words.length) {
                            break;
                        }
                        var word = words[wordIndex + termWordIndex];
                        var matchingTerm = me.terms.terms[word];
                        if (matchingTerm && matchingTerm.ignore) {
                            numTermWords++;
                            continue;
                        }
                        collectedWords += " " + word.toLowerCase();
                    }
                    if (me.toCase(item, term) === collectedWords) {
                        var expansion = item.expansion;
                        if (expansion) {
                            expansion = [].concat(expansion);
                            expansion = expansion.map(function (item) {
                                return me.parse(item, options);
                            });
                            if (expansion.length > 1) {
                                expansion = expansion.slice(0, -1).join(", ") + " and " + expansion.slice(-1).toString();
                            } else {
                                expansion = expansion.slice(-1).toString();
                            }
                            words.splice(wordIndex, numTermWords);
                            me.modify(words, wordIndex, item, term, " (", expansion, ")", options, true);
                        }
                        var translation = item.translation;
                        if (translation) {
                            translation = me.parse(translation, me.duplicateOptions(options, {"addStyles": false}));
                            words.splice(wordIndex, numTermWords);
                            me.modify(words, wordIndex, item, term, " [", translation, "]", options);
                        }
                        if (options.addStyles && !translation && !expansion) {
                            words.splice(wordIndex, numTermWords);
                            me.modify(words, wordIndex, item, term, "", term, "", me.duplicateOptions(options, {"keepSource": false}));
                        }
                        break;
                    }
                }
            }
        });
    };
    me.toCase = function (item, string) {
        if (item.case !== "sensitive") {
            string = string.toLowerCase();
        }
        return string;
    }
    me.duplicateOptions = function (options, overrides) {
        var duplicate = {};
        for (var key in options) {
            duplicate[key] = options[key];
        }
        if (overrides) {
            for (var key in overrides) {
                duplicate[key] = overrides[key];
            }
        }
        return duplicate;
    };
    me.modify = function (words, wordIndex, item, term, prefix, replacement, suffix, options, expansion) {
        if (!options.doTranslation) {
            replacement = term;
        } else if (options.keepSource) {
            replacement = term + prefix + replacement + suffix;
        }
        if (options.addStyles && (item.style || replacement !== term)) {
            replacement = me.applyStyles(term, item.style, replacement, options, expansion);
        }
        words.splice(wordIndex, 0, replacement);
    };
    me.applyStyles = function (term, styles, text, options, expansion) {
        var html = "";
        for (var style in styles) {
            if (style === "heading") {
                html += "" + styles[style] + "";
            }
        }
        if (styles && styles.phase) {
            html += "" + text + "";
        } else if (!options.keepSource && !expansion) {
            html += "" + text + "";
        } else {
            html += text;
        }
        return html;
    };
};<|endoftext|>


<commit_before>/* Author: Florian Schmitt <florian@outils-reseaux.org> under GPL licence */

var DATATABLE_OPTIONS = {
  paging: false,
  language: {
    "sProcessing": "Traitement en cours...",
    "sSearch": "Rechercher :",
    "sLengthMenu": "Afficher _MENU_ éléments",
    "sInfo": "Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments",
    "sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément",
    "sInfoFiltered": "(filtré de _MAX_ éléments au total)",
    "sInfoPostFix": "",
    "sLoadingRecords": "Chargement en cours...",
    "sZeroRecords": "Aucun élément à afficher",
    "sEmptyTable": "Aucune donnée disponible dans le tableau",
    "oPaginate": {
      "sFirst": "Premier",
      "sPrevious": "Précédent",
      "sNext": "Suivant",
      "sLast": "Dernier"
    },
    "oAria": {
      "sSortAscending": ": activer pour trier la colonne par ordre croissant",
      "sSortDescending": ": activer pour trier la colonne par ordre décroissant"
    }
  },
  fixedHeader: {
    header: true,
    footer: false
}
}

function toastMessage(message) {
  var $toast = $('

' + message + '

');
  $('body').after($toast);
  $toast.css('top', $('#yw-topnav').outerHeight(true) + 20 + 'px');
  $toast.css('opacity', 1);
  setTimeout(function() { $toast.css('opacity', 0) }, 10000);
  setTimeout(function() { $toast.remove() }, 11000);
  $toast.addClass('visible');
}
// polyfill placeholder
(function($) {
  // gestion des classes actives pour les menus
  $("a.active-link")
    .parent()
    .addClass("active-list")
    .parents("ul")
    .prev("a")
    .addClass("active-parent-link")
    .parent()
    .addClass("active-list");

  // fenetres modales
  function openModal(e) {
    e.stopPropagation();
    e.preventDefault();
    var $this = $(this);
    var text = $this.attr("title") || "";
    var size = " " + $this.data("size");
    var iframe = $this.data("iframe");
    if (text.length > 0) {
      text = "
" + $.trim(text) + "
";
    } else {
      text = "

";
    }

    $("body").append(
      '
' +
        '
' +
        '
' +
        '
' +
        '<button type="button" class="close" data-dismiss="modal">×</button>' +
        text +
        "
" +
        '
' +
        "
" +
        "
" +
        "
" +
        "
"
    );

    var link = $this.attr("href");
    var $modal = $("#YesWikiModal");
    if (/\.(gif|jpg|jpeg|tiff|png)$/i.test(link)) {
      $modal
        .find(".modal-body")
        .html(
          ''
        );
    } else if (iframe === 1) {
      $modal
        .find(".modal-body")
        .html(
          '' +
            ''
        );
      $("#yw-modal-iframe").on("load", function() {
        $("#yw-modal-loading").hide();
      });
    } else {
      $modal
        .find(".modal-body")
        .load(link + " .page", function(response, status, xhr) {
          $(document).trigger("yw-modal-open");
          return false;
        });
    }
    $modal
      .modal({
        keyboard: false
      })
      .modal("show")
      .on("hidden hidden.bs.modal", function() {
        $modal.remove();
      });

    return false;
  }
  $(document).on("click", "a.modalbox, .modalbox a", openModal);

  // on change l'icone de l'accordeon
  $(".accordion-trigger").on("click", function() {
    if (
      $(this)
        .next()
        .find(".collapse")
        .hasClass("in")
    ) {
      $(this)
        .find(".arrow")
        .html("►");
    } else {
      $(this)
        .find(".arrow")
        .html("▼");
    }
  });

  // on enleve la fonction doubleclic dans des cas ou cela pourrait etre indesirable
  $(".no-dblclick, form, .page a, button, .dropdown-menu").on(
    "dblclick",
    function(e) {
      return false;
    }
  );

  // deplacer les fenetres modales en bas de body pour eviter que des styles s'appliquent
  $(".modal").appendTo(document.body);

  // Remove hidden div by ACL
  $('.remove-this-div-on-page-load').remove();

  // Pour l'apercu des themes, on recharge la page avec le theme selectionne
  $("#form_theme_selector select").on("change", function() {
    if ($(this).attr("id") === "changetheme") {
      // On change le theme dynamiquement
      var val = $(this).val();

      // pour vider la liste
      var squelette = $("#changesquelette")[0];
      squelette.options.length = 0;
      var i;
      for (i = 0; i < tab1[val].length; i++) {
        o = new Option(tab1[val][i], tab1[val][i]);
        squelette.options[squelette.options.length] = o;
      }

      var style = $("#changestyle")[0];
      style.options.length = 0;
      for (i = 0; i < tab2[val].length; i++) {
        o = new Option(tab2[val][i], tab2[val][i]);
        style.options[style.options.length] = o;
      }
    }

    var url = window.location.toString();
    var urlAux = url.split("&theme=");
    window.location =
      urlAux[0] +
      "&theme=" +
      $("#changetheme").val() +
      "&squelette=" +
      $("#changesquelette").val() +
      "&style=" +
      $("#changestyle").val();
  });

  /* tooltips */
  $("[data-toggle='tooltip']").tooltip();

  // detecte quand on scrolle en dessus de la barre horizontale, afin de la fixer en haut
  var $topnav = $("#yw-topnav.fixable");
  if ($topnav.length > 0) {
    var topoffset = $topnav.data("offset") || $topnav.offset().top;
    $topnav.affix({
      offset: topoffset
    });
  }

  // moteur de recherche utilisé dans un template
  $('a[href="#search"]').on("click", function(e) {
    e.preventDefault();
    $("#search").addClass("open");
    $("#search .search-query").focus();
  });

  $("#search, #search button.close-search").on("click keyup", function(e) {
    if (
      e.target == this ||
      $(e.target).hasClass("close-search") ||
      e.keyCode == 27
    ) {
      $(this).removeClass("open");
    }
  });

  // se souvenir des tabs navigués
  $.fn.historyTabs = function() {
    var that = this;
    window.addEventListener("popstate", function(event) {
      if (event.state) {
        $(that)
          .filter('[href="' + event.state.url + '"]')
          .tab("show");
      }
    });
    return this.each(function(index, element) {
      $(element).on("show.bs.tab", function() {
        var stateObject = {
          url: $(this).attr("href")
        };

        if (window.location.hash && stateObject.url !== window.location.hash) {
          window.history.pushState(
            stateObject,
            document.title,
            window.location.pathname +
              window.location.search +
              $(this).attr("href")
          );
        } else {
          window.history.replaceState(
            stateObject,
            document.title,
            window.location.pathname +
              window.location.search +
              $(this).attr("href")
          );
        }
      });
      if (!window.location.hash && $(element).is(".active")) {
        // Shows the first element if there are no query parameters.
        $(element).tab("show");
      } else if ($(this).attr("href") === window.location.hash) {
        $(element).tab("show");
      }
    });
  };
  $('a[data-toggle="tab"]').historyTabs();

  // double clic
  $(".navbar").on("dblclick", function(e) {
    e.stopPropagation();
    $("body").append(
      '
' +
        '
' +
        '
' +
        '
' +
        '<button type="button" class="close" data-dismiss="modal">×</button>' +
        "
Editer une zone du menu horizontal
" +
        "
" +
        '
' +
        "
" +
        "
" +
        "
" +
        "
"
    );

    var $editmodal = $("#YesWikiModal");
    $(this)
      .find(".include")
      .each(function() {
        var href = $(this)
          .attr("ondblclick")
          .replace("document.location='", "")
          .replace("';", "");
        var pagewiki = href
          .replace("/edit", "")
          .replace("http://yeswiki.dev/wakka.php?wiki=", "");
        $editmodal
          .find(".modal-body")
          .append(
            '' +
              ' Editer la page ' +
              pagewiki +
              ""
          );
      });

    $editmodal
      .find(".modal-body")
      .append(
        '' +
          "En fait, je ne voulais pas double-cliquer..."
      );

    $editmodal
      .modal({
        keyboard: true
      })
      .modal("show")
      .on("hidden hidden.bs.modal", function() {
        $editmodal.remove();
      });

    return false;
  });

  // AUTO RESIZE IFRAME
  var iframes = $("iframe.auto-resize");
  if (iframes.length > 0) {
    $.getScript("tools/templates/libs/vendor/iframeResizer.min.js")
      .done(function(script, textStatus) {
        iframes.iFrameResize();
      })
      .fail(function(jqxhr, settings, exception) {
        console.log(
          "Error getting script tools/templates/libs/vendor/iframeResizer.min.js",
          exception
        );
      });
  }

  // get the html from a yeswiki page
  function getText(url, link) {
    var html;
    $.get(url, function(data) {
      html = data;
    }).done(function() {
      link.attr("data-content", html);
    });
  }

  $(".modalbox-hover").each(function(index) {
    getText($(this).attr("href") + "/html", $(this));
  });
  $(".modalbox-hover").popover({
    trigger: "hover",
    html: true, // permet d'utiliser du html
    placement: "right" // position de la popover (top ou bottom ou left ou right)
  });

  // ouvrir les liens dans une nouvelle fenetre
  $(".new-window").attr("target", "_blank");

  // acl switch
  $("#acl-switch-mode")
    .change(function() {
      if ($(this).prop("checked")) {
        // show advanced
        $(".acl-simple")
          .hide()
          .val(null);
        $(".acl-advanced").slideDown();
      } else {
        $(".acl-single-container label").each(function() {
          $(this).after($("select[name=" + $(this).data("input") + "]"));
        });
        $(".acl-simple").show();
        $(".acl-advanced")
          .hide()
          .val(null);
      }
    })
    .trigger("change");

  // tables
  if (typeof $(".table").DataTable === "function") {
    $(".table:not(.prevent-auto-init)").DataTable(DATATABLE_OPTIONS);
  }
})(jQuery);
<commit_msg>feat(toast) : change toast duration to 3s, permit paramaters to change duration and css class<commit_after>/* Author: Florian Schmitt <florian@outils-reseaux.org> under GPL licence */

var DATATABLE_OPTIONS = {
  paging: false,
  language: {
    "sProcessing": "Traitement en cours...",
    "sSearch": "Rechercher :",
    "sLengthMenu": "Afficher _MENU_ éléments",
    "sInfo": "Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments",
    "sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément",
    "sInfoFiltered": "(filtré de _MAX_ éléments au total)",
    "sInfoPostFix": "",
    "sLoadingRecords": "Chargement en cours...",
    "sZeroRecords": "Aucun élément à afficher",
    "sEmptyTable": "Aucune donnée disponible dans le tableau",
    "oPaginate": {
      "sFirst": "Premier",
      "sPrevious": "Précédent",
      "sNext": "Suivant",
      "sLast": "Dernier"
    },
    "oAria": {
      "sSortAscending": ": activer pour trier la colonne par ordre croissant",
      "sSortDescending": ": activer pour trier la colonne par ordre décroissant"
    }
  },
  fixedHeader: {
    header: true,
    footer: false
}
}

function toastMessage(message, duration = 3000, toastClass = 'alert alert-secondary-1') {
  var $toast = $('

' + message + '

');
  $('body').after($toast);
  $toast.css('top', $('#yw-topnav').outerHeight(true) + 20 + 'px');
  $toast.css('opacity', 1);
  setTimeout(function() { $toast.css('opacity', 0) }, duration);
  setTimeout(function() { $toast.remove() }, (duration + 300) );
  $toast.addClass('visible');
}
// polyfill placeholder
(function($) {
  // gestion des classes actives pour les menus
  $("a.active-link")
    .parent()
    .addClass("active-list")
    .parents("ul")
    .prev("a")
    .addClass("active-parent-link")
    .parent()
    .addClass("active-list");

  // fenetres modales
  function openModal(e) {
    e.stopPropagation();
    e.preventDefault();
    var $this = $(this);
    var text = $this.attr("title") || "";
    var size = " " + $this.data("size");
    var iframe = $this.data("iframe");
    if (text.length > 0) {
      text = "
" + $.trim(text) + "
";
    } else {
      text = "

";
    }

    $("body").append(
      '
' +
        '
' +
        '
' +
        '
' +
        '<button type="button" class="close" data-dismiss="modal">×</button>' +
        text +
        "
" +
        '
' +
        "
" +
        "
" +
        "
" +
        "
"
    );

    var link = $this.attr("href");
    var $modal = $("#YesWikiModal");
    if (/\.(gif|jpg|jpeg|tiff|png)$/i.test(link)) {
      $modal
        .find(".modal-body")
        .html(
          ''
        );
    } else if (iframe === 1) {
      $modal
        .find(".modal-body")
        .html(
          '' +
            ''
        );
      $("#yw-modal-iframe").on("load", function() {
        $("#yw-modal-loading").hide();
      });
    } else {
      $modal
        .find(".modal-body")
        .load(link + " .page", function(response, status, xhr) {
          $(document).trigger("yw-modal-open");
          return false;
        });
    }
    $modal
      .modal({
        keyboard: false
      })
      .modal("show")
      .on("hidden hidden.bs.modal", function() {
        $modal.remove();
      });

    return false;
  }
  $(document).on("click", "a.modalbox, .modalbox a", openModal);

  // on change l'icone de l'accordeon
  $(".accordion-trigger").on("click", function() {
    if (
      $(this)
        .next()
        .find(".collapse")
        .hasClass("in")
    ) {
      $(this)
        .find(".arrow")
        .html("►");
    } else {
      $(this)
        .find(".arrow")
        .html("▼");
    }
  });

  // on enleve la fonction doubleclic dans des cas ou cela pourrait etre indesirable
  $(".no-dblclick, form, .page a, button, .dropdown-menu").on(
    "dblclick",
    function(e) {
      return false;
    }
  );

  // deplacer les fenetres modales en bas de body pour eviter que des styles s'appliquent
  $(".modal").appendTo(document.body);

  // Remove hidden div by ACL
  $('.remove-this-div-on-page-load').remove();

  // Pour l'apercu des themes, on recharge la page avec le theme selectionne
  $("#form_theme_selector select").on("change", function() {
    if ($(this).attr("id") === "changetheme") {
      // On change le theme dynamiquement
      var val = $(this).val();

      // pour vider la liste
      var squelette = $("#changesquelette")[0];
      squelette.options.length = 0;
      var i;
      for (i = 0; i < tab1[val].length; i++) {
        o = new Option(tab1[val][i], tab1[val][i]);
        squelette.options[squelette.options.length] = o;
      }

      var style = $("#changestyle")[0];
      style.options.length = 0;
      for (i = 0; i < tab2[val].length; i++) {
        o = new Option(tab2[val][i], tab2[val][i]);
        style.options[style.options.length] = o;
      }
    }

    var url = window.location.toString();
    var urlAux = url.split("&theme=");
    window.location =
      urlAux[0] +
      "&theme=" +
      $("#changetheme").val() +
      "&squelette=" +
      $("#changesquelette").val() +
      "&style=" +
      $("#changestyle").val();
  });

  /* tooltips */
  $("[data-toggle='tooltip']").tooltip();

  // detecte quand on scrolle en dessus de la barre horizontale, afin de la fixer en haut
  var $topnav = $("#yw-topnav.fixable");
  if ($topnav.length > 0) {
    var topoffset = $topnav.data("offset") || $topnav.offset().top;
    $topnav.affix({
      offset: topoffset
    });
  }

  // moteur de recherche utilisé dans un template
  $('a[href="#search"]').on("click", function(e) {
    e.preventDefault();
    $("#search").addClass("open");
    $("#search .search-query").focus();
  });

  $("#search, #search button.close-search").on("click keyup", function(e) {
    if (
      e.target == this ||
      $(e.target).hasClass("close-search") ||
      e.keyCode == 27
    ) {
      $(this).removeClass("open");
    }
  });

  // se souvenir des tabs navigués
  $.fn.historyTabs = function() {
    var that = this;
    window.addEventListener("popstate", function(event) {
      if (event.state) {
        $(that)
          .filter('[href="' + event.state.url + '"]')
          .tab("show");
      }
    });
    return this.each(function(index, element) {
      $(element).on("show.bs.tab", function() {
        var stateObject = {
          url: $(this).attr("href")
        };

        if (window.location.hash && stateObject.url !== window.location.hash) {
          window.history.pushState(
            stateObject,
            document.title,
            window.location.pathname +
              window.location.search +
              $(this).attr("href")
          );
        } else {
          window.history.replaceState(
            stateObject,
            document.title,
            window.location.pathname +
              window.location.search +
              $(this).attr("href")
          );
        }
      });
      if (!window.location.hash && $(element).is(".active")) {
        // Shows the first element if there are no query parameters.
        $(element).tab("show");
      } else if ($(this).attr("href") === window.location.hash) {
        $(element).tab("show");
      }
    });
  };
  $('a[data-toggle="tab"]').historyTabs();

  // double clic
  $(".navbar").on("dblclick", function(e) {
    e.stopPropagation();
    $("body").append(
      '
' +
        '
' +
        '
' +
        '
' +
        '<button type="button" class="close" data-dismiss="modal">×</button>' +
        "
Editer une zone du menu horizontal
" +
        "
" +
        '
' +
        "
" +
        "
" +
        "
" +
        "
"
    );

    var $editmodal = $("#YesWikiModal");
    $(this)
      .find(".include")
      .each(function() {
        var href = $(this)
          .attr("ondblclick")
          .replace("document.location='", "")
          .replace("';", "");
        var pagewiki = href
          .replace("/edit", "")
          .replace("http://yeswiki.dev/wakka.php?wiki=", "");
        $editmodal
          .find(".modal-body")
          .append(
            '' +
              ' Editer la page ' +
              pagewiki +
              ""
          );
      });

    $editmodal
      .find(".modal-body")
      .append(
        '' +
          "En fait, je ne voulais pas double-cliquer..."
      );

    $editmodal
      .modal({
        keyboard: true
      })
      .modal("show")
      .on("hidden hidden.bs.modal", function() {
        $editmodal.remove();
      });

    return false;
  });

  // AUTO RESIZE IFRAME
  var iframes = $("iframe.auto-resize");
  if (iframes.length > 0) {
    $.getScript("tools/templates/libs/vendor/iframeResizer.min.js")
      .done(function(script, textStatus) {
        iframes.iFrameResize();
      })
      .fail(function(jqxhr, settings, exception) {
        console.log(
          "Error getting script tools/templates/libs/vendor/iframeResizer.min.js",
          exception
        );
      });
  }

  // get the html from a yeswiki page
  function getText(url, link) {
    var html;
    $.get(url, function(data) {
      html = data;
    }).done(function() {
      link.attr("data-content", html);
    });
  }

  $(".modalbox-hover").each(function(index) {
    getText($(this).attr("href") + "/html", $(this));
  });
  $(".modalbox-hover").popover({
    trigger: "hover",
    html: true, // permet d'utiliser du html
    placement: "right" // position de la popover (top ou bottom ou left ou right)
  });

  // ouvrir les liens dans une nouvelle fenetre
  $(".new-window").attr("target", "_blank");

  // acl switch
  $("#acl-switch-mode")
    .change(function() {
      if ($(this).prop("checked")) {
        // show advanced
        $(".acl-simple")
          .hide()
          .val(null);
        $(".acl-advanced").slideDown();
      } else {
        $(".acl-single-container label").each(function() {
          $(this).after($("select[name=" + $(this).data("input") + "]"));
        });
        $(".acl-simple").show();
        $(".acl-advanced")
          .hide()
          .val(null);
      }
    })
    .trigger("change");

  // tables
  if (typeof $(".table").DataTable === "function") {
    $(".table:not(.prevent-auto-init)").DataTable(DATATABLE_OPTIONS);
  }
})(jQuery);
<|endoftext|>


<commit_before>class BaseEvent {
    constructor(bot) {
        if (this.constructor === BaseEvent)
            throw new Error('Cannot instantiate abstract BaseEvent.')
        if (typeof this.event === 'string')
            throw new Error('Must override Event.');
        this.bot = bot;
    }

    load() {
        if (this.eventHandler === null) {
            throw new Error('Must override eventHandler.')
        }
        this.bot.on(this.event, this.eventHandler);
    }

    remove() {
        this.bot.removeListener(this.event, this.eventHandler);
    }

}

module.exports = BaseEvent;<commit_msg>Added the ability for events to only be ran once by setting the once property to true on events<commit_after>class BaseEvent {
    constructor(bot) {
        if (this.constructor === BaseEvent)
            throw new Error('Cannot instantiate abstract BaseEvent.')
        if (typeof this.event === 'string')
            throw new Error('Must override Event.');
        this.bot = bot;
        this.once = true;
    }

    load() {
        if (this.eventHandler === null) {
            throw new Error('Must override eventHandler.')
        }
        if (this.once)
            this.bot.once(this.event, this.eventHandler);
        else
            this.bot.on(this.event, this.eventHandler);
    }

    remove() {
        this.bot.removeListener(this.event, this.eventHandler);
    }

}

module.exports = BaseEvent;<|endoftext|>


<commit_before>function Interpreter() {
  var that = Object.create(Interpreter.prototype);

  that.CodePointer = CodePointer;

  return that;
}

Interpreter.JUST_MAKE_INSTRUCTION = {Interpreter:"JUST_MAKE_INSTRUCTION"};

Interpreter.GLOBAL = this;

Interpreter.prototype
.symbol = function(instructionMaker) {
  var interpreter = this;
  var that = function(code, justMakeInstruction) {
    if(justMakeInstruction) {
      return instructionMaker(code);
    }

    var codePointer = interpreter.CodePointer(code);
    var instruction = instructionMaker(codePointer);
    if(!instruction || codePointer.getUnparsed() !== "") {
      throw new Error();
    }

    var isMethodCall = this !== Interpreter.GLOBAL;
    var thisBinding = isMethodCall ? this : interpreter;
    return instruction.call(thisBinding);
  };

  that.makeInstruction = instructionMaker;
  return that;
};

Interpreter.prototype
.terminal = function(token, interpretation){
  var makeInstruction = function(codePointer) {
    var lexeme = codePointer.parse(token);
    if(!lexeme) {
      return null;
    }

    var instruction = function() {
      return interpretation.apply(this, lexeme);
    };

    return instruction;
  };

  var terminal = this.symbol(makeInstruction);
  return terminal;
};

Interpreter.prototype
.nonTerminalSequence = function (symbols) {
  var makeInstruction = function(codePointer) {
    var instructions = [];
    var lastMade = true;

    var makeInstructionIfAllPreviousWasSuccessful = function(symbol) {
      lastMade = lastMade && symbol(codePointer, Interpreter.JUST_MAKE_INSTRUCTION);
      instructions.push(lastMade);
    };

    symbols.map(makeInstructionIfAllPreviousWasSuccessful);

    if(!lastMade) {
      return null;
    }

    var instruction = function() {
      var that = this;
      var lastResult;
      instructions.map(function(instruction) {
        lastResult = instruction.call(that);
      });

      return lastResult;
    };

    return instruction;
  };

  return this.symbol(makeInstruction);
};

Interpreter.prototype
.nonTerminalAlternative = function(alternatives) {
  var makeInstruction = function(codePointer) {
    var backup = codePointer.backup();
    var instruction = alternatives.reduce(function(instruction, alternative) {
      if(!instruction)codePointer.restore(backup);
      return instruction || alternative(codePointer, Interpreter.JUST_MAKE_INSTRUCTION);
    }, null);

    return instruction;
  };

  return this.symbol(makeInstruction);
};

Interpreter.prototype
.nonTerminalAsterisk = function(symbol) {
  var makeInstruction = function(codePointer) {
    var instructions = [];
    var madeInstruction = true;
    while(madeInstruction) {
      var backup = codePointer.backup();
      madeInstruction = symbol(codePointer, Interpreter.JUST_MAKE_INSTRUCTION);
      if(madeInstruction){
        instructions.push(madeInstruction);
      } else {
        codePointer.restore(backup);
      }

    }

    var instruction = function() {
      var lastResult;
      var that = this;
      instructions.map(function(instruction) {
        lastResult = instruction.call(that);
      });

      return lastResult;
    };

    return instruction;
  };

  return this.symbol(makeInstruction);
};
<commit_msg>makeInstruction => instructionMaker to put emphasis on its functional nature.<commit_after>function Interpreter() {
  var that = Object.create(Interpreter.prototype);

  that.CodePointer = CodePointer;

  return that;
}

Interpreter.JUST_MAKE_INSTRUCTION = {Interpreter:"JUST_MAKE_INSTRUCTION"};

Interpreter.GLOBAL = this;

Interpreter.prototype
.symbol = function(instructionMaker) {
  var interpreter = this;
  var that = function(code, justMakeInstruction) {
    if(justMakeInstruction) {
      return instructionMaker(code);
    }

    var codePointer = interpreter.CodePointer(code);
    var instruction = instructionMaker(codePointer);
    if(!instruction || codePointer.getUnparsed() !== "") {
      throw new Error();
    }

    var isMethodCall = this !== Interpreter.GLOBAL;
    var thisBinding = isMethodCall ? this : interpreter;
    return instruction.call(thisBinding);
  };

  that.makeInstruction = instructionMaker;
  return that;
};

Interpreter.prototype
.terminal = function(token, interpretation){
  var instructionMaker = function(codePointer) {
    var lexeme = codePointer.parse(token);
    if(!lexeme) {
      return null;
    }

    var instruction = function() {
      return interpretation.apply(this, lexeme);
    };

    return instruction;
  };

  var terminal = this.symbol(instructionMaker);
  return terminal;
};

Interpreter.prototype
.nonTerminalSequence = function (symbols) {
  var instructionMaker = function(codePointer) {
    var instructions = [];
    var lastMade = true;

    var makeInstructionIfAllPreviousWasSuccessful = function(symbol) {
      lastMade = lastMade && symbol(codePointer, Interpreter.JUST_MAKE_INSTRUCTION);
      instructions.push(lastMade);
    };

    symbols.map(makeInstructionIfAllPreviousWasSuccessful);

    if(!lastMade) {
      return null;
    }

    var instruction = function() {
      var that = this;
      var lastResult;
      instructions.map(function(instruction) {
        lastResult = instruction.call(that);
      });

      return lastResult;
    };

    return instruction;
  };

  return this.symbol(instructionMaker);
};

Interpreter.prototype
.nonTerminalAlternative = function(alternatives) {
  var instructionMaker = function(codePointer) {
    var backup = codePointer.backup();
    var instruction = alternatives.reduce(function(instruction, alternative) {
      if(!instruction)codePointer.restore(backup);
      return instruction || alternative(codePointer, Interpreter.JUST_MAKE_INSTRUCTION);
    }, null);

    return instruction;
  };

  return this.symbol(instructionMaker);
};

Interpreter.prototype
.nonTerminalAsterisk = function(symbol) {
  var instructionMaker = function(codePointer) {
    var instructions = [];
    var madeInstruction = true;
    while(madeInstruction) {
      var backup = codePointer.backup();
      madeInstruction = symbol(codePointer, Interpreter.JUST_MAKE_INSTRUCTION);
      if(madeInstruction){
        instructions.push(madeInstruction);
      } else {
        codePointer.restore(backup);
      }

    }

    var instruction = function() {
      var lastResult;
      var that = this;
      instructions.map(function(instruction) {
        lastResult = instruction.call(that);
      });

      return lastResult;
    };

    return instruction;
  };

  return this.symbol(instructionMaker);
};
<|endoftext|>


<commit_before>/*!
 * OS.js - JavaScript Operating System
 *
 * Copyright (c) 2011-2014, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
(function(StandardDialog, Utils, API) {
  'use strict';

  function replaceExtension(orig, rep) {
    var spl = orig.split('.');
    spl.pop();
    spl.push(rep);
    return spl.join('.');
  }

  /**
   * Init
   *
   * Arguments:
   *  type                  Dialog type: "open" or "save"
   *  select                Selection type: "file" or "dir"
   *  path                  Current path
   *  filename              Current filename
   *  mime                  Current file MIME
   *  mimes                 Browse filetype filter (defaults to [none] all files)
   *  filetypes             Save filetypes dict (ext => mime)
   *  defaultFilename       Default filename
   *  defaultFilemime       Default filemime (defaults to given MIME)
   */
  var FileDialog = function(args, onClose) {
    args = args || {};

    // Arguments
    this.type             = args.type             || 'open';
    this.path             = args.path;
    this.select           = args.select           || 'file';
    this.filename         = args.filename         || '';
    this.filemime         = args.mime             || '';
    this.filter           = args.mimes            || [];
    this.filetypes        = args.filetypes        || null;
    this.defaultFilename  = args.defaultFilename  || 'New File';
    this.defaultFilemime  = args.defaultFilemime  || this.filemime || '';

    if ( !this.path && this.filename ) {
      if ( this.filename.match(/\//) ) {
        this.path     = Utils.dirname(this.filename);
        this.filename = Utils.filename(this.filename);
      }
    }

    if ( !this.path ) {
      this.path = API.getDefaultPath('/');
    }

    // Stored elements etc.
    this.errors       = 0;
    this.selectedFile = null;
    this.$input       = null;
    this.$fileView    = null;
    this.$statusBar   = null;
    this.$select      = null;

    // Window
    var title     = OSjs._(this.type === 'save' ? 'Save' : 'Open');
    var className = this.type === 'save' ? 'FileSaveDialog' : 'FileOpenDialog';

    StandardDialog.apply(this, [className, {title: title}, {width:600, height:380}, onClose]);

    if ( this.type === 'open' ) {
      this._icon = 'actions/gtk-open.png';
    } else {
      this._icon = 'actions/gtk-save-as.png';
    }
  };

  FileDialog.prototype = Object.create(StandardDialog.prototype);

  /**
   * Destroy
   */
  FileDialog.prototype.destroy = function() {
    StandardDialog.prototype.destroy.apply(this, arguments);
  };

  /**
   * Create
   */
  FileDialog.prototype.init = function() {
    var self = this;
    var root = StandardDialog.prototype.init.apply(this, arguments);

    this.$fileView = this._addGUIElement(new OSjs.GUI.FileView('FileDialogFileView', {
      mimeFilter: this.filter,
      typeFilter: (this.select === 'path' ? 'dir' : null)
    }), this.$element);
    this.$fileView.onError = function() {
      self.onError.apply(self, arguments);
    };
    this.$fileView.onContextMenu = function(ev) {
      self.createContextMenu(ev);
    };
    this.$fileView.onViewContextMenu = function(ev) {
      self.createContextMenu(ev);
    };
    this.$fileView.onSelected = function(item) {
      self.onFileSelected(item);
    };
    this.$fileView.onFinished = function() {
      self.onFileFinished();
    };
    this.$fileView.onRefresh = function() {
      self.onFileRefresh();
    };
    this.$fileView.onActivated = function(path, type, mime) {
      self.onFileActivated(path, type, mime);
    };

    this.$statusBar = this._addGUIElement(new OSjs.GUI.StatusBar('FileDialogStatusBar'), this.$element);
    this.$statusBar.setText('');

    if ( this.type === 'save' ) {
      var curval = Utils.escapeFilename(this.filename ? this.filename : this.defaultFilename);

      if ( this.filetypes ) {
        var types = {};
        var val;
        var MIMEDescriptions = OSjs.Settings.DefaultConfig().MIME || {};
        for ( var i in this.filetypes ) {
          if ( this.filetypes.hasOwnProperty(i) ) {
            val = this.filetypes[i];
            types[i] = '';

            if ( MIMEDescriptions[val] ) {
              types[i] += MIMEDescriptions[val] + ' ';
            }

            types[i] += val + ' (.' + i + ')';
          }
        }

        this.$select = this._addGUIElement(new OSjs.GUI.Select('FileDialogFiletypeSelect', {onChange: function(sobj, sdom, val) {
          self.onSelectChange(val);
        }}), this.$element);
        this.$select.addItems(types);
        Utils.$addClass(root.firstChild, 'HasFileTypes');
      }

      this.$input = this._addGUIElement(new OSjs.GUI.Text('FileName', {value: curval, onKeyPress: function(ev) {
        self.onInputKey(ev);
        if ( ev.keyCode === Utils.Keys.ENTER ) {
          self.onInputEnter(ev);
          return;
        }
      }, onChange: function(ev) {
        self.onInputKey(ev);
      }, onKeyUp: function(ev) {
        self.onInputKey(ev);
      }}), this.$element);
    }

    return root;
  };

  /**
   * Window has been displayed
   */
  FileDialog.prototype._inited = function() {
    StandardDialog.prototype._inited.apply(this, arguments);

    // Force override of default MIME if we have a selector
    if ( this.filetypes && this.$select ) {
      for ( var i in this.filetypes ) {
        if ( this.filetypes.hasOwnProperty(i) ) {
          this.filemime = i;
          this.defaultFilemime = i;
          break;
        }
      }
    }

    if ( this.$fileView ) {
      this.$fileView.chdir(this.path);
    }

    if ( this.buttonConfirm ) {
      if ( this.type === 'save' && this.$input && this.$input.getValue() ) {
        this.buttonConfirm.setDisabled(false);
      }
    }

    this.highlightFilename();
  };

  /**
   * Window has been focused
   */
  FileDialog.prototype._focus = function() {
    StandardDialog.prototype._focus.apply(this, arguments);

    this.highlightFilename();
  };

  /**
   * File has been chosen
   */
  FileDialog.prototype.finishDialog = function(path, mime) {
    var self = this;

    function _getSelected() {
      var result = '';

      if ( this.select === 'path' ) {
        result = this.selectedFile;
      } else {
        if ( this.$fileView ) {
          var root = this.$fileView.getPath();
          if ( this.$input ) {
            result = root + '/' + this.$input.getValue();
          } else {
            result = this.selectedFile;
          }
        }
      }

      return result;
    }

    mime = mime || this.defaultFilemime;
    path = path || _getSelected.call(this);

    function _confirm() {
      var wm = API.getWMInstance();
      if ( wm ) {
        this._toggleDisabled(true);
        var conf = new OSjs.Dialogs.Confirm(OSjs._('Are you sure you want to overwrite the file \'{0}\'?', Utils.filename(path)), function(btn) {
          self._toggleDisabled(false);
          if ( btn === 'ok' ) {
            self.end('ok', path, mime);
          }
        });
        wm.addWindow(conf);
        this._addChild(conf);
      }
    }

    if ( this.type === 'open' ) {
      this.end('ok', path, mime);
    } else {
      API.call('fs', {method: 'exists', 'arguments' : [path]}, function(res) {
        res = res || {};

        if ( res.error ) {
          self.onError((res.error || 'Failed to stat file'), path);
          return;
        }

        if ( res.result ) {
          _confirm.call(self);
        } else {
          self.end('ok', path, mime);
        }
      }, function(error) {
        self.onError(error, path);
      });
    }
  };

  /**
   * Highlights the filename in input
   */
  FileDialog.prototype.highlightFilename = function() {
    if ( this.$input ) {
      this.$input.focus();

      var val = this.$input.getValue();
      var range = {
        min: 0,
        max: val.length
      };

      if ( val.match(/\.(\w+)$/) ) {
        var m = val.split(/\.(\w+)$/);
        if ( m ) {
          range.max -= (m.length + 1);
        }
      }

      this.$input.select(range);
    }
  };

  FileDialog.prototype.checkInput = function() {
    if ( this.type !== 'save' ) { return; }
    if ( !this.buttonConfirm ) { return; }

    if ( this.$input.getValue().length ) {
      this.buttonConfirm.setDisabled(false);
    } else {
      this.buttonConfirm.setDisabled(true);
    }
  };

  /**
   * Create Context Menu
   */
  FileDialog.prototype.createContextMenu = function(ev) {
    var self = this;
    var fileList = this.$fileView;
    if ( !fileList ) { return; }
    var viewType = fileList.viewType || '';

    OSjs.GUI.createMenu([
      {name: 'ListView', title: OSjs._('View type'), menu: [
        {name: 'ListView', title: OSjs._('List View'), disabled: (viewType.toLowerCase() === 'listview'), onClick: function() {
          self.onMenuSelect('ListView');
        }},
        {name: 'IconView', title: OSjs._('Icon View'), disabled: (viewType.toLowerCase() === 'iconview'), onClick: function() {
          self.onMenuSelect('IconView');
        }},
        {name: 'TreeView', title: OSjs._('Tree View'), disabled: (viewType.toLowerCase() === 'treeview'), onClick: function() {
          self.onMenuSelect('TreeView');
        }}
      ]}
    ], {x: ev.clientX, y: ev.clientY});
  };

  /**
   * Error wrapper
   */
  FileDialog.prototype.onError = function(err, dirname, fatal) {
    this._toggleLoading(false);

    if ( err ) {
      if ( !fatal ) {
        if ( this.errors < 2 ) {
          if ( this.$fileView ) {
            this.$fileView.chdir(API.getDefaultPath('/'));
          }
        } else {
          this.errors = 0;
        }
        this.errors++;
      }

      this._error(OSjs._('FileDialog Error'), OSjs._('Failed listing directory \'{0}\' because an error occured', dirname), err);
    }
  };

  /**
   * Menu: Item selected
   */
  FileDialog.prototype.onMenuSelect = function(type) {
    if ( this.$fileView ) {
      this.$fileView.setViewType(type);
    }
    this._focus();
  };

  /**
   * FileView: Selection
   */
  FileDialog.prototype.onFileSelected = function(item) {
    var selected = null;

    if ( this.select === 'path' ) {
      if ( item && item.type === 'dir' ) {
        selected = item.path;
      }
    } else {
      if ( item && item.type === 'file' ) {
        selected = item.path;
      }
    }

    if ( this.buttonConfirm ) {
      this.buttonConfirm.setDisabled(selected === null);
    }

    if ( this.$input ) {
      var fname = Utils.filename(selected ? selected : this.defaultFilename);
      this.$input.setValue(Utils.escapeFilename(fname));
    }

    this.selectedFile = selected;
  };

  /**
   * FileView: Refresh Finished
   */
  FileDialog.prototype.onFileFinished = function() {
    if ( this.$statusBar && this.$fileView ) {
      this.path = this.$fileView.getPath();
      this.$statusBar.setText(this.path);
    }
    this._toggleLoading(false);

    if ( this.select === 'path' ) {
      this.selectedFile = this.path; // Dir selection dialog needs to start on default
      this.buttonConfirm.setDisabled(false);
    }

    this.checkInput();
  };

  /**
   * FileView: Refresh
   */
  FileDialog.prototype.onFileRefresh = function() {
    this.selectedFile = null;

    if ( this.$statusBar && this.$fileView ) {
      this.$statusBar.setText(this.$fileView.getPath());
    }
    this._toggleLoading(true);

    if ( this.buttonConfirm ) {
      this.buttonConfirm.setDisabled(true);
    }
  };

  /**
   * FileView: Activated
   */
  FileDialog.prototype.onFileActivated = function(path, type, mime) {
    this.selectedFile = null;

    function _activated() {
      this.buttonConfirm.setDisabled(false);
      this.finishDialog.call(this, path, mime);
    }

    if ( this.select === 'file' && type === 'file' ) {
      _activated.call(this);
    } else if ( this.select === 'path' && type === 'dir' && Utils.filename(path) !== '..' ) {
      _activated.call(this);
    }
  };

  /**
   * Select: Item changed
   */
  FileDialog.prototype.onSelectChange = function(type) {
    this.filemime = this.filetypes[type];

    if ( this.$input ) {
      var newval = replaceExtension(this.$input.getValue(), type);
      this.$input.setValue(newval);
    }

    this.highlightFilename();
  };

  /**
   * Input: key pressed
   */
  FileDialog.prototype.onInputKey = function() {
    this.checkInput();
  };

  /**
   * Input: enter pressed
   */
  FileDialog.prototype.onInputEnter = function(ev) {
    if ( this.buttonConfirm && this.buttonConfirm.getDisabled() ) {
      return;
    }

    this.onConfirmClick(ev);
  };

  /**
   * Button: pressed
   */
  FileDialog.prototype.onConfirmClick = function(ev) {
    if ( !this.buttonConfirm ) { return; }

    var sel = this.$input ? this.$input.getValue() : this.selectedFile;
    if ( !sel ) {
      var wm = API.getWMInstance();
      if ( wm ) {
        var dwin;
        if ( this.type === 'save' ) {
          dwin = new OSjs.Dialogs.Alert(OSjs._('You need to select a file or enter new filename!'));
        } else {
          dwin = new OSjs.Dialogs.Alert(OSjs._('You need to select a file!'));
        }
        wm.addWindow(dwin);
        this._addChild(dwin);
      }
      return;
    }

    this.finishDialog();
  };

  /////////////////////////////////////////////////////////////////////////////
  // EXPORTS
  /////////////////////////////////////////////////////////////////////////////

  OSjs.Dialogs.File               = FileDialog;

})(OSjs.Dialogs.StandardDialog, OSjs.Utils, OSjs.API);
<commit_msg>Dialogs - File: Fixed highlighting of filename<commit_after>/*!
 * OS.js - JavaScript Operating System
 *
 * Copyright (c) 2011-2014, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
(function(StandardDialog, Utils, API) {
  'use strict';

  function replaceExtension(orig, rep) {
    var spl = orig.split('.');
    spl.pop();
    spl.push(rep);
    return spl.join('.');
  }

  /**
   * Init
   *
   * Arguments:
   *  type                  Dialog type: "open" or "save"
   *  select                Selection type: "file" or "dir"
   *  path                  Current path
   *  filename              Current filename
   *  mime                  Current file MIME
   *  mimes                 Browse filetype filter (defaults to [none] all files)
   *  filetypes             Save filetypes dict (ext => mime)
   *  defaultFilename       Default filename
   *  defaultFilemime       Default filemime (defaults to given MIME)
   */
  var FileDialog = function(args, onClose) {
    args = args || {};

    // Arguments
    this.type             = args.type             || 'open';
    this.path             = args.path;
    this.select           = args.select           || 'file';
    this.filename         = args.filename         || '';
    this.filemime         = args.mime             || '';
    this.filter           = args.mimes            || [];
    this.filetypes        = args.filetypes        || null;
    this.defaultFilename  = args.defaultFilename  || 'New File';
    this.defaultFilemime  = args.defaultFilemime  || this.filemime || '';

    if ( !this.path && this.filename ) {
      if ( this.filename.match(/\//) ) {
        this.path     = Utils.dirname(this.filename);
        this.filename = Utils.filename(this.filename);
      }
    }

    if ( !this.path ) {
      this.path = API.getDefaultPath('/');
    }

    // Stored elements etc.
    this.errors       = 0;
    this.selectedFile = null;
    this.$input       = null;
    this.$fileView    = null;
    this.$statusBar   = null;
    this.$select      = null;

    // Window
    var title     = OSjs._(this.type === 'save' ? 'Save' : 'Open');
    var className = this.type === 'save' ? 'FileSaveDialog' : 'FileOpenDialog';

    StandardDialog.apply(this, [className, {title: title}, {width:600, height:380}, onClose]);

    if ( this.type === 'open' ) {
      this._icon = 'actions/gtk-open.png';
    } else {
      this._icon = 'actions/gtk-save-as.png';
    }
  };

  FileDialog.prototype = Object.create(StandardDialog.prototype);

  /**
   * Destroy
   */
  FileDialog.prototype.destroy = function() {
    StandardDialog.prototype.destroy.apply(this, arguments);
  };

  /**
   * Create
   */
  FileDialog.prototype.init = function() {
    var self = this;
    var root = StandardDialog.prototype.init.apply(this, arguments);

    this.$fileView = this._addGUIElement(new OSjs.GUI.FileView('FileDialogFileView', {
      mimeFilter: this.filter,
      typeFilter: (this.select === 'path' ? 'dir' : null)
    }), this.$element);
    this.$fileView.onError = function() {
      self.onError.apply(self, arguments);
    };
    this.$fileView.onContextMenu = function(ev) {
      self.createContextMenu(ev);
    };
    this.$fileView.onViewContextMenu = function(ev) {
      self.createContextMenu(ev);
    };
    this.$fileView.onSelected = function(item) {
      self.onFileSelected(item);
    };
    this.$fileView.onFinished = function() {
      self.onFileFinished();
    };
    this.$fileView.onRefresh = function() {
      self.onFileRefresh();
    };
    this.$fileView.onActivated = function(path, type, mime) {
      self.onFileActivated(path, type, mime);
    };

    this.$statusBar = this._addGUIElement(new OSjs.GUI.StatusBar('FileDialogStatusBar'), this.$element);
    this.$statusBar.setText('');

    if ( this.type === 'save' ) {
      var curval = Utils.escapeFilename(this.filename ? this.filename : this.defaultFilename);

      if ( this.filetypes ) {
        var types = {};
        var val;
        var MIMEDescriptions = OSjs.Settings.DefaultConfig().MIME || {};
        for ( var i in this.filetypes ) {
          if ( this.filetypes.hasOwnProperty(i) ) {
            val = this.filetypes[i];
            types[i] = '';

            if ( MIMEDescriptions[val] ) {
              types[i] += MIMEDescriptions[val] + ' ';
            }

            types[i] += val + ' (.' + i + ')';
          }
        }

        this.$select = this._addGUIElement(new OSjs.GUI.Select('FileDialogFiletypeSelect', {onChange: function(sobj, sdom, val) {
          self.onSelectChange(val);
        }}), this.$element);
        this.$select.addItems(types);
        Utils.$addClass(root.firstChild, 'HasFileTypes');
      }

      this.$input = this._addGUIElement(new OSjs.GUI.Text('FileName', {value: curval, onKeyPress: function(ev) {
        self.onInputKey(ev);
        if ( ev.keyCode === Utils.Keys.ENTER ) {
          self.onInputEnter(ev);
          return;
        }
      }, onChange: function(ev) {
        self.onInputKey(ev);
      }, onKeyUp: function(ev) {
        self.onInputKey(ev);
      }}), this.$element);
    }

    return root;
  };

  /**
   * Window has been displayed
   */
  FileDialog.prototype._inited = function() {
    StandardDialog.prototype._inited.apply(this, arguments);

    // Force override of default MIME if we have a selector
    if ( this.filetypes && this.$select ) {
      for ( var i in this.filetypes ) {
        if ( this.filetypes.hasOwnProperty(i) ) {
          this.filemime = i;
          this.defaultFilemime = i;
          break;
        }
      }
    }

    if ( this.$fileView ) {
      this.$fileView.chdir(this.path);
    }

    if ( this.buttonConfirm ) {
      if ( this.type === 'save' && this.$input && this.$input.getValue() ) {
        this.buttonConfirm.setDisabled(false);
      }
    }

    this.highlightFilename();
  };

  /**
   * Window has been focused
   */
  FileDialog.prototype._focus = function() {
    StandardDialog.prototype._focus.apply(this, arguments);

    this.highlightFilename();
  };

  /**
   * File has been chosen
   */
  FileDialog.prototype.finishDialog = function(path, mime) {
    var self = this;

    function _getSelected() {
      var result = '';

      if ( this.select === 'path' ) {
        result = this.selectedFile;
      } else {
        if ( this.$fileView ) {
          var root = this.$fileView.getPath();
          if ( this.$input ) {
            result = root + '/' + this.$input.getValue();
          } else {
            result = this.selectedFile;
          }
        }
      }

      return result;
    }

    mime = mime || this.defaultFilemime;
    path = path || _getSelected.call(this);

    function _confirm() {
      var wm = API.getWMInstance();
      if ( wm ) {
        this._toggleDisabled(true);
        var conf = new OSjs.Dialogs.Confirm(OSjs._('Are you sure you want to overwrite the file \'{0}\'?', Utils.filename(path)), function(btn) {
          self._toggleDisabled(false);
          if ( btn === 'ok' ) {
            self.end('ok', path, mime);
          }
        });
        wm.addWindow(conf);
        this._addChild(conf);
      }
    }

    if ( this.type === 'open' ) {
      this.end('ok', path, mime);
    } else {
      API.call('fs', {method: 'exists', 'arguments' : [path]}, function(res) {
        res = res || {};

        if ( res.error ) {
          self.onError((res.error || 'Failed to stat file'), path);
          return;
        }

        if ( res.result ) {
          _confirm.call(self);
        } else {
          self.end('ok', path, mime);
        }
      }, function(error) {
        self.onError(error, path);
      });
    }
  };

  /**
   * Highlights the filename in input
   */
  FileDialog.prototype.highlightFilename = function() {
    if ( this.$input ) {
      this.$input.focus();

      var val = this.$input.getValue();
      var range = {
        min: 0,
        max: val.length
      };

      if ( val.match(/\.(\w+)$/) ) {
        var m = val.split(/\.(\w+)$/);
        for ( var i = m.length - 1; i >= 0; i-- ) {
          if ( m[i].length ) {
            range.max = val.length - m[i].length - 1;
            break;
          }
        }
      }

      this.$input.select(range);
    }
  };

  FileDialog.prototype.checkInput = function() {
    if ( this.type !== 'save' ) { return; }
    if ( !this.buttonConfirm ) { return; }

    if ( this.$input.getValue().length ) {
      this.buttonConfirm.setDisabled(false);
    } else {
      this.buttonConfirm.setDisabled(true);
    }
  };

  /**
   * Create Context Menu
   */
  FileDialog.prototype.createContextMenu = function(ev) {
    var self = this;
    var fileList = this.$fileView;
    if ( !fileList ) { return; }
    var viewType = fileList.viewType || '';

    OSjs.GUI.createMenu([
      {name: 'ListView', title: OSjs._('View type'), menu: [
        {name: 'ListView', title: OSjs._('List View'), disabled: (viewType.toLowerCase() === 'listview'), onClick: function() {
          self.onMenuSelect('ListView');
        }},
        {name: 'IconView', title: OSjs._('Icon View'), disabled: (viewType.toLowerCase() === 'iconview'), onClick: function() {
          self.onMenuSelect('IconView');
        }},
        {name: 'TreeView', title: OSjs._('Tree View'), disabled: (viewType.toLowerCase() === 'treeview'), onClick: function() {
          self.onMenuSelect('TreeView');
        }}
      ]}
    ], {x: ev.clientX, y: ev.clientY});
  };

  /**
   * Error wrapper
   */
  FileDialog.prototype.onError = function(err, dirname, fatal) {
    this._toggleLoading(false);

    if ( err ) {
      if ( !fatal ) {
        if ( this.errors < 2 ) {
          if ( this.$fileView ) {
            this.$fileView.chdir(API.getDefaultPath('/'));
          }
        } else {
          this.errors = 0;
        }
        this.errors++;
      }

      this._error(OSjs._('FileDialog Error'), OSjs._('Failed listing directory \'{0}\' because an error occured', dirname), err);
    }
  };

  /**
   * Menu: Item selected
   */
  FileDialog.prototype.onMenuSelect = function(type) {
    if ( this.$fileView ) {
      this.$fileView.setViewType(type);
    }
    this._focus();
  };

  /**
   * FileView: Selection
   */
  FileDialog.prototype.onFileSelected = function(item) {
    var selected = null;

    if ( this.select === 'path' ) {
      if ( item && item.type === 'dir' ) {
        selected = item.path;
      }
    } else {
      if ( item && item.type === 'file' ) {
        selected = item.path;
      }
    }

    if ( this.buttonConfirm ) {
      this.buttonConfirm.setDisabled(selected === null);
    }

    if ( this.$input ) {
      var fname = Utils.filename(selected ? selected : this.defaultFilename);
      this.$input.setValue(Utils.escapeFilename(fname));
    }

    this.selectedFile = selected;
  };

  /**
   * FileView: Refresh Finished
   */
  FileDialog.prototype.onFileFinished = function() {
    if ( this.$statusBar && this.$fileView ) {
      this.path = this.$fileView.getPath();
      this.$statusBar.setText(this.path);
    }
    this._toggleLoading(false);

    if ( this.select === 'path' ) {
      this.selectedFile = this.path; // Dir selection dialog needs to start on default
      this.buttonConfirm.setDisabled(false);
    }

    this.checkInput();
  };

  /**
   * FileView: Refresh
   */
  FileDialog.prototype.onFileRefresh = function() {
    this.selectedFile = null;

    if ( this.$statusBar && this.$fileView ) {
      this.$statusBar.setText(this.$fileView.getPath());
    }
    this._toggleLoading(true);

    if ( this.buttonConfirm ) {
      this.buttonConfirm.setDisabled(true);
    }
  };

  /**
   * FileView: Activated
   */
  FileDialog.prototype.onFileActivated = function(path, type, mime) {
    this.selectedFile = null;

    function _activated() {
      this.buttonConfirm.setDisabled(false);
      this.finishDialog.call(this, path, mime);
    }

    if ( this.select === 'file' && type === 'file' ) {
      _activated.call(this);
    } else if ( this.select === 'path' && type === 'dir' && Utils.filename(path) !== '..' ) {
      _activated.call(this);
    }
  };

  /**
   * Select: Item changed
   */
  FileDialog.prototype.onSelectChange = function(type) {
    this.filemime = this.filetypes[type];

    if ( this.$input ) {
      var newval = replaceExtension(this.$input.getValue(), type);
      this.$input.setValue(newval);
    }

    this.highlightFilename();
  };

  /**
   * Input: key pressed
   */
  FileDialog.prototype.onInputKey = function() {
    this.checkInput();
  };

  /**
   * Input: enter pressed
   */
  FileDialog.prototype.onInputEnter = function(ev) {
    if ( this.buttonConfirm && this.buttonConfirm.getDisabled() ) {
      return;
    }

    this.onConfirmClick(ev);
  };

  /**
   * Button: pressed
   */
  FileDialog.prototype.onConfirmClick = function(ev) {
    if ( !this.buttonConfirm ) { return; }

    var sel = this.$input ? this.$input.getValue() : this.selectedFile;
    if ( !sel ) {
      var wm = API.getWMInstance();
      if ( wm ) {
        var dwin;
        if ( this.type === 'save' ) {
          dwin = new OSjs.Dialogs.Alert(OSjs._('You need to select a file or enter new filename!'));
        } else {
          dwin = new OSjs.Dialogs.Alert(OSjs._('You need to select a file!'));
        }
        wm.addWindow(dwin);
        this._addChild(dwin);
      }
      return;
    }

    this.finishDialog();
  };

  /////////////////////////////////////////////////////////////////////////////
  // EXPORTS
  /////////////////////////////////////////////////////////////////////////////

  OSjs.Dialogs.File               = FileDialog;

})(OSjs.Dialogs.StandardDialog, OSjs.Utils, OSjs.API);
<|endoftext|>