<commit_before>// WebKit的编码转换有点奇怪的

var conv_data = {
    id_index: 0,
    config: {},
    global_options: [],
    groups: {},
    items: {},
    run_seq: 0
};

function generate_id() {
    ++ conv_data.id_index;

    return conv_data.id_index;
}

function alert_error(content, title) {
    jQuery('

')
        .html('' + content + '

')
        .dialog({
        modal: true,
        'title': title || '出错啦',
        minWidth: 480,
        minHeight: 200
    });
}

(function ($, window) {

    function build_conv_tree(context) {
        // $("#conv_list").empty();

        // 初始化
        var jdom = $(context);
        conv_data.config = {};
        conv_data.groups = {};
        conv_data.global_options = [];

        // 加载全局配置
        $.each(jdom.children("global").children(), function(k, dom){
            var tn = dom.tagName.toLowerCase();
            var val = $(dom).html().trim();

            if ("work_dir" == tn) {
                $("#conv_list_work_dir").val(val);
            } else if ("xresloader_path" == tn) {
                $("#conv_list_xresloader").val(val);
            } else if ("proto_file" == tn) {
                $("#conv_list_proto_file").val(val);
            }else if ("output_dir" == tn) {
                $("#conv_list_output_dir").val(val);
            } else if ("data_src_dir" == tn) {
                $("#conv_list_data_src_dir").val(val);
            } else if ("rename" == tn) {
                $("#conv_list_rename").val(val);
            } else if ("proto" == tn) {
                $("#conv_list_protocol").get(0).selectedIndex = $("#conv_list_protocol option[value=" + val + "]").get(0).index;
            } else if ("output_type" == tn) {
                $("#conv_list_output_type").get(0).selectedIndex = $("#conv_list_output_type option[value=" + val + "]").get(0).index;
            } else if ("option" == tn && val) {
                conv_data.global_options.push({
                    name: $(dom).attr('name') || val,
                    desc: $(dom).attr('desc') || val,
                    value: val
                });
            }
        });

        // 加载分类信息
        var treeData = [];
        var cat_map = {};
        function build_tree_fn(root, xml_dom) {
            $.each($(xml_dom).children("tree"), function(k, xml_node) {
                var nj_node = $(xml_node);
                var new_option = {
                    title: nj_node.attr("name") || nj_node.attr("id"),
                    tooltip: nj_node.attr("name") || nj_node.attr("id"),
                    folder: true,
                    children: []
                };

                if (nj_node.attr('id')) {
                    cat_map[nj_node.attr('id')] = new_option;
                }

                build_tree_fn(new_option.children, nj_node);
                root.push(new_option);
            });
        };
        build_tree_fn(treeData, jdom.children("category"));

        conv_data.items = {};
        $.each(jdom.children("list").children("item"), function(k, item_node) {
            var jitem = $(item_node);
            var id = generate_id();
            var item_data = {
                id: id,
                file: jitem.attr('file'),
                scheme: jitem.attr('scheme'),
                name: jitem.attr('name').trim() || jitem.attr('scheme'),
                cat: jitem.attr('cat'),
                options: []
            };

            $.each(jitem.children('option'), function(k, v){
                item_data.options.push({
                    name: $(v).attr('name'),
                    desc: $(v).attr('desc'),
                    value: $(v).html()
                });
            });
            conv_data.items[item_data.id] = item_data;

            var ft_node = {
                title: item_data.name,
                tooltip: item_data.name,
                key: item_data.id
            };
            if (item_data.cat && cat_map[item_data.cat]) {
                cat_map[item_data.cat].children.push(ft_node);
            } else {
                treeData.push(ft_node);
            }
        });

        $("#conv_list").fancytree({
            checkbox: true,
            selectMode: 3,
            source: treeData,
            dblclick: function(event, data) {
                data.node.toggleSelected();
            },
            keydown: function(event, data) {
                if( event.which === 32 ) {
                    data.node.toggleSelected();
                    return false;
                }
            },
            cookieId: "conv_list-ft",
            idPrefix: "conv_list-ft-"
        });
    }

    function conv_start() {
        var work_dir = $("#conv_list_work_dir").val();
        if (work_dir && work_dir[0] != '/' && work_dir[1] != ':') {
            var list_dir = $("#conv_list_file").val();
            var anchor_1 = list_dir.lastIndexOf('/');
            var anchor_2 = list_dir.lastIndexOf("\\");
            if (anchor_2 < 0 || anchor_2 >= list_dir.length || anchor_2 < anchor_1) {
                anchor_2 = anchor_1;
            }
            work_dir = list_dir.substr(0, anchor_2) + "/" + work_dir;
        }

        var xresloader_path = $("#conv_list_xresloader").val();

        var global_options = {
            "-p": $("#conv_list_protocol").val(),
            "-t": $("#conv_list_output_type").val(),
            "-f": $("#conv_list_proto_file").val(),
            "-o": $("#conv_list_output_dir").val(),
            "-d": $("#conv_list_data_src_dir").val(),
            "-n": $("#conv_list_rename").val()
        };

        var tree = $("#conv_list").fancytree("getTree");
        var selNodes = tree.getSelectedNodes();

        var cmd_params = "java -jar \"" + xresloader_path + "\"";
        for(var k in global_options) {
            if (global_options[k]) {
                cmd_params += " " + k + " \"" + global_options[k] + "\"";
            }
        }

        $.each(conv_data.global_options, function(k, v){
            cmd_params += " " + v.value;
        });

        var run_log = $("#conv_list_run_res");
        run_log.empty();

        var pending_script = [];

        selNodes.forEach(function(node) {
            if (node.key && conv_data.items[node.key]) {
                var item_data = conv_data.items[node.key];
                var cmd_args = cmd_params;
                $.each(item_data.options, function(k, v){
                    cmd_args += " " + v.value;
                });

                cmd_args += " -s \"" + item_data.file + "\" -m \"" + item_data.scheme + "\"";

                pending_script.push(cmd_args);
            }
        });

        var run_seq = generate_id();
        conv_data.run_seq = run_seq;

        function run_one_cmd() {
            if (pending_script.length > 0 && conv_data.run_seq == run_seq) {
                var cmd = pending_script.pop();

                run_log.append("[" + work_dir + "] " + cmd + "\r\n");
                run_log.scrollTop(run_log.prop('scrollHeight'));

                require('child_process').exec(cmd, {
                    cwd: work_dir
                }, function(error, stdout, stderr){
                    run_log.append("" + stdout +
                    "\r\n" + stderr + "\r\n");

                    run_log.scrollTop(run_log.prop('scrollHeight'));
                    run_one_cmd();
                });
            }
        }
        run_one_cmd();
    }

    $(document).ready(function(){
        $("#conv_list_file_btn").click(function(){
            $("#conv_list_file").val("");
            $("#conv_list_file").click();
        });
        $("#conv_list_file").click(function(){
            $(this).val("");
        });

        $("#conv_list_file").bind("change", function(){
            $("#conv_list_file_val").val($(conv_list_file).val());

            var file_loader = new FileReader();

            file_loader.onload = function(ev) {
                build_conv_tree(ev.target.result);
            }

            var sel_dom = document.getElementById("conv_list_file");
            if (sel_dom.files.length > 0) {
                file_loader.readAsText(sel_dom.files[0]);
            }
        });

        $("#conv_list_btn_select_all").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setSelected(true);
            });
        });

        $("#conv_list_btn_select_none").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setSelected(false);
            });
        });

        $("#conv_list_btn_expand").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setExpanded(true);
            });
        });

        $("#conv_list_btn_collapse").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setExpanded(false);
            });
        });

        $("#conv_list_btn_start_conv").click(function(){
            conv_start();
        });

        var rename_templates = [{
                value: "/\\.bin$/.lua/",
                label: ".bin后缀 => .lua"
            },{
                value: "/\\.bin$/.json/",
                label: ".bin后缀 => .json"
            },{
                value: "/\\.bin$/.msgpack.bin/",
                label: ".bin后缀 => .msgpack.bin"
            }
        ];

        $( "#conv_list_rename" ).autocomplete({
            minLength: 0,
            source: rename_templates,
            focus: function( event, ui ) {
                $( "#conv_list_rename" ).val( ui.item.value );
                return false;
            },
            select: function( event, ui ) {
                $( "#project" ).val( ui.item.value );
                return false;
            }
        }).autocomplete( "instance" )._renderItem = function( ul, item ) {
            return $( "
" )
            .append( "" + item.label + "" )
            .appendTo( ul );
        };
        $("#conv_list_rename").dblclick(function(){
            $( "#conv_list_rename" ).autocomplete("search", "");
        });
    });
})(jQuery, window);
<commit_msg>添加新功能。允许改显示名称<commit_after>// WebKit的编码转换有点奇怪的

var conv_data = {};

function generate_id() {
    ++ conv_data.id_index;

    return conv_data.id_index;
}

function alert_error(content, title) {
    jQuery('

')
        .html('' + content + '

')
        .dialog({
        modal: true,
        'title': title || '出错啦',
        minWidth: 480,
        minHeight: 200
    });
}

(function ($, window) {

    function reset_conv_data() {
        conv_data = {
            id_index: 0,
            config: {},
            global_options: [],
            groups: {},
            items: {},
            run_seq: 0,
            gui: {
                set_name: null
            }
        };
    }

    function build_conv_tree(context) {
        // $("#conv_list").empty();
        reset_conv_data();

        // 初始化
        var jdom = $(context);

        // 加载全局配置
        $.each(jdom.children("global").children(), function(k, dom){
            var tn = dom.tagName.toLowerCase();
            var val = $(dom).html().trim();

            if ("work_dir" == tn) {
                $("#conv_list_work_dir").val(val);
            } else if ("xresloader_path" == tn) {
                $("#conv_list_xresloader").val(val);
            } else if ("proto_file" == tn) {
                $("#conv_list_proto_file").val(val);
            }else if ("output_dir" == tn) {
                $("#conv_list_output_dir").val(val);
            } else if ("data_src_dir" == tn) {
                $("#conv_list_data_src_dir").val(val);
            } else if ("rename" == tn) {
                $("#conv_list_rename").val(val);
            } else if ("proto" == tn) {
                $("#conv_list_protocol").get(0).selectedIndex = $("#conv_list_protocol option[value=" + val + "]").get(0).index;
            } else if ("output_type" == tn) {
                $("#conv_list_output_type").get(0).selectedIndex = $("#conv_list_output_type option[value=" + val + "]").get(0).index;
            } else if ("option" == tn && val) {
                conv_data.global_options.push({
                    name: $(dom).attr('name') || val,
                    desc: $(dom).attr('desc') || val,
                    value: val
                });
            }
        });

        // 加载分类信息
        var treeData = [];
        var cat_map = {};
        function build_tree_fn(root, xml_dom) {
            $.each($(xml_dom).children("tree"), function(k, xml_node) {
                var nj_node = $(xml_node);
                var new_option = {
                    title: nj_node.attr("name") || nj_node.attr("id"),
                    tooltip: nj_node.attr("name") || nj_node.attr("id"),
                    folder: true,
                    children: []
                };

                if (nj_node.attr('id')) {
                    cat_map[nj_node.attr('id')] = new_option;
                }

                build_tree_fn(new_option.children, nj_node);
                root.push(new_option);
            });
        };
        build_tree_fn(treeData, jdom.children("category"));

        // GUI 显示规则
        $.each(jdom.children("gui").children("set_name"), function(k, dom){
            conv_data.gui.set_name = eval($(dom).html());
        });

        $.each(jdom.children("list").children("item"), function(k, item_node) {
            var jitem = $(item_node);
            var id = generate_id();

            var item_data = {
                id: id,
                file: jitem.attr('file'),
                scheme: jitem.attr('scheme'),
                name: (jitem.attr('name').trim() || ""),
                cat: jitem.attr('cat'),
                options: [],
                desc: (jitem.attr('name').trim() || jitem.attr('desc').trim() || "")  + " -- 文件名: \"" + jitem.attr("file") + "\" 描述信息: \"" + jitem.attr("scheme") + "\""
            };

            // GUI 显示规则
            if (conv_data.gui.set_name) {
                try {
                    item_data = conv_data.gui.set_name(item_data) || item_data;
                } catch (err) {
                    assert("ERROR: " + err.toString());
                }
            }

            $.each(jitem.children('option'), function(k, v){
                var nj_node = $(v);
                item_data.options.push({
                    name: nj_node.attr('name'),
                    desc: nj_node.attr('desc'),
                    value: nj_node.html()
                });
            });
            conv_data.items[item_data.id] = item_data;

            var ft_node = {
                title: item_data.name,
                tooltip: item_data.desc,
                key: item_data.id
            };
            if (item_data.cat && cat_map[item_data.cat]) {
                cat_map[item_data.cat].children.push(ft_node);
            } else {
                treeData.push(ft_node);
            }
        });

        $("#conv_list").fancytree({
            checkbox: true,
            selectMode: 3,
            source: treeData,
            dblclick: function(event, data) {
                data.node.toggleSelected();
            },
            keydown: function(event, data) {
                if( event.which === 32 ) {
                    data.node.toggleSelected();
                    return false;
                }
            },
            cookieId: "conv_list-ft",
            idPrefix: "conv_list-ft-"
        });
    }

    function conv_start() {
        var work_dir = $("#conv_list_work_dir").val();
        if (work_dir && work_dir[0] != '/' && work_dir[1] != ':') {
            var list_dir = $("#conv_list_file").val();
            var anchor_1 = list_dir.lastIndexOf('/');
            var anchor_2 = list_dir.lastIndexOf("\\");
            if (anchor_2 < 0 || anchor_2 >= list_dir.length || anchor_2 < anchor_1) {
                anchor_2 = anchor_1;
            }
            work_dir = list_dir.substr(0, anchor_2) + "/" + work_dir;
        }

        var xresloader_path = $("#conv_list_xresloader").val();

        var global_options = {
            "-p": $("#conv_list_protocol").val(),
            "-t": $("#conv_list_output_type").val(),
            "-f": $("#conv_list_proto_file").val(),
            "-o": $("#conv_list_output_dir").val(),
            "-d": $("#conv_list_data_src_dir").val(),
            "-n": $("#conv_list_rename").val()
        };

        var tree = $("#conv_list").fancytree("getTree");
        var selNodes = tree.getSelectedNodes();

        var cmd_params = "java -jar \"" + xresloader_path + "\"";
        for(var k in global_options) {
            if (global_options[k]) {
                cmd_params += " " + k + " \"" + global_options[k] + "\"";
            }
        }

        $.each(conv_data.global_options, function(k, v){
            cmd_params += " " + v.value;
        });

        var run_log = $("#conv_list_run_res");
        run_log.empty();

        var pending_script = [];

        selNodes.forEach(function(node) {
            if (node.key && conv_data.items[node.key]) {
                var item_data = conv_data.items[node.key];
                var cmd_args = cmd_params;
                $.each(item_data.options, function(k, v){
                    cmd_args += " " + v.value;
                });

                cmd_args += " -s \"" + item_data.file + "\" -m \"" + item_data.scheme + "\"";

                pending_script.push(cmd_args);
            }
        });

        var run_seq = generate_id();
        conv_data.run_seq = run_seq;

        function run_one_cmd() {
            if (pending_script.length > 0 && conv_data.run_seq == run_seq) {
                var cmd = pending_script.pop();

                run_log.append("[" + work_dir + "] " + cmd + "\r\n");
                run_log.scrollTop(run_log.prop('scrollHeight'));

                require('child_process').exec(cmd, {
                    cwd: work_dir
                }, function(error, stdout, stderr){
                    run_log.append("" + stdout +
                    "\r\n" + stderr + "\r\n");

                    run_log.scrollTop(run_log.prop('scrollHeight'));
                    run_one_cmd();
                });
            }
        }
        run_one_cmd();
    }

    $(document).ready(function(){
        $("#conv_list_file_btn").click(function(){
            $("#conv_list_file").val("");
            $("#conv_list_file").click();
        });
        $("#conv_list_file").click(function(){
            $(this).val("");
        });

        $("#conv_list_file").bind("change", function(){
            $("#conv_list_file_val").val($(conv_list_file).val());

            var file_loader = new FileReader();

            file_loader.onload = function(ev) {
                build_conv_tree(ev.target.result);
            }

            var sel_dom = document.getElementById("conv_list_file");
            if (sel_dom.files.length > 0) {
                file_loader.readAsText(sel_dom.files[0]);
            }
        });

        $("#conv_list_btn_select_all").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setSelected(true);
            });
        });

        $("#conv_list_btn_select_none").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setSelected(false);
            });
        });

        $("#conv_list_btn_expand").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setExpanded(true);
            });
        });

        $("#conv_list_btn_collapse").click(function(){
            $("#conv_list").fancytree("getRootNode").visit(function(node){
                node.setExpanded(false);
            });
        });

        $("#conv_list_btn_start_conv").click(function(){
            conv_start();
        });

        var rename_templates = [{
                value: "/\\.bin$/.lua/",
                label: ".bin后缀 => .lua"
            },{
                value: "/\\.bin$/.json/",
                label: ".bin后缀 => .json"
            },{
                value: "/\\.bin$/.msgpack.bin/",
                label: ".bin后缀 => .msgpack.bin"
            }
        ];

        $( "#conv_list_rename" ).autocomplete({
            minLength: 0,
            source: rename_templates,
            focus: function( event, ui ) {
                $( "#conv_list_rename" ).val( ui.item.value );
                return false;
            },
            select: function( event, ui ) {
                $( "#project" ).val( ui.item.value );
                return false;
            }
        }).autocomplete( "instance" )._renderItem = function( ul, item ) {
            return $( "
" )
            .append( "" + item.label + "" )
            .appendTo( ul );
        };
        $("#conv_list_rename").dblclick(function(){
            $( "#conv_list_rename" ).autocomplete("search", "");
        });
    });
})(jQuery, window);
<|endoftext|>


<commit_before>ZBase.registerView((function() {
  var kPathPrefix = "/a/datastore/tables/";

  var load = function(path) {
    var table_id = path.substr(kPathPrefix.length);

    $.showLoader();

    $.httpGet("/api/v1/tables/" + table_id, function(r) {
      if (r.status == 200) {
        render(JSON.parse(r.response).table);
      } else {
        renderError(r.statusText, kPathPrefix + table_id);
      }
      $.hideLoader();
    });
  };

  var render = function(schema) {
    var page = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_tpl");

    var table_breadcrumb = $(".table_name_breadcrumb", page);
    table_breadcrumb.innerHTML = schema.name;
    table_breadcrumb.href = kPathPrefix + schema.name;

    $("z-tab.schema a", page).href = kPathPrefix + schema.name;
    $("z-tab.settings a", page).href = kPathPrefix + schema.name;

    $("z-dropdown.open_in", page).addEventListener("change", function() {
      switch (this.getValue()) {
        case "sql_editor":
          openTableInSQLEditor(schema.name);
          break;

        case "tableviewer":
          $.navigateTo("/a/datastore/tables/view/" + schema.name);
          break;
      }
    }, false);

    $("z-dropdown.edit", page).addEventListener("change", function() {
      switch (this.getValue()) {
        case "add_column":
          displayAddColumnModal(schema);
          break;

        case "delete_column":
          displayDeleteColumnModal(schema);
          break;
      }
      this.setValue([]);
    }, false);

    renderTable(schema.schema.columns, $("tbody", page), "");

    $.handleLinks(page);
    $.replaceViewport(page);
  };

  var renderError = function(msg, path) {
    var error_elem = document.createElement("div");
    error_elem.classList.add("zbase_error");
    error_elem.innerHTML =
        "" +
        "
We're sorry
" +
        "
An error occured.

" + msg + "
 " +
        "
Please try it again or contact support if the problem persists.
" +
        "" +
        " Back" +
        "" +
        " Reload" +
        "";

    $.replaceViewport(error_elem);
  };

  var renderTable = function(columns, tbody, prefix) {
    var row_tpl = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_row_tpl");

    columns.forEach(function(column) {
      var tr = row_tpl.cloneNode(true);
      var column_name = prefix + column.name;
      $(".name", tr).innerHTML = column_name;
      $(".type", tr).innerHTML = column.type;
      $(".is_nullable", tr).innerHTML = column.optional;

      tbody.appendChild(tr);

      if (column.type == "OBJECT") {
        renderTable(column.schema.columns, tbody, column_name + ".");
      }
    });
  };

  var displayAddColumnModal = function(schema) {
    var modal = $(".zbase_table_editor z-modal.add_column");
    var tpl = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_add_modal_tpl");

    var input = $("input", tpl);

    $.onClick($("button.submit", tpl), function() {
      if (input.value.length == 0) {
        $(".error_note.name", modal).classList.remove("hidden");
        input.classList.add("error");
        input.focus();
        return;
      }

      var url = "/api/v1/tables/add_field?" + $.buildQueryString({
          table: schema.name,
          field_name: input.value,
          field_type: $("z-dropdown.type", modal).getValue(),
          optional: "true",
          repeated: $("z-dropdown.is_repeated", modal).getValue()});

      $.httpPost(url, "", function(r) {
        if (r.status == 201) {
          var info_message = ZbaseInfoMessage($(".zbase_app"));
          info_message.renderSuccess(
              "The table column " + input.value + " has been successfully added.");
          $.navigateTo(kPathPrefix + schema.name);
        } else {
          $(".error_message .msg", modal).innerHTML = r.response;
          $(".error_message", modal).classList.remove("hidden");
          console.log(r);
        }
      });

    });

    $.onClick($("button.close", tpl), function() {
      modal.close();
    });

    $.replaceContent($(".container", modal), tpl);
    modal.show();
    input.focus();
  };

  var displayDeleteColumnModal = function(schema) {
    var modal = $(".zbase_table_editor z-modal.delete_column");
    var tpl = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_delete_modal_tpl");

    var input = $("input", tpl);

    $.onClick($("button.submit", tpl), function() {
      var url = "/api/v1/tables/remove_field?table=" + schema.name +
        "&field_name=" + input.value;

      $.httpPost(url, "", function(r) {
        if (r.status == 201) {
          var info_message = ZbaseInfoMessage($(".zbase_app"));
          info_message.renderSuccess("The table column has been removed.");
          $.navigateTo(kPathPrefix + schema.name);
        } else {
          $(".error_message", modal).classList.remove("hidden");
          $(".error_message .msg", modal).innerHTML = r.response;
        }
      });

    });

    $.onClick($("button.close", tpl), function() {
      modal.close();
    });

    $.replaceContent($(".container", modal), tpl);

    modal.show();
    input.focus();
  };

  var openTableInSQLEditor = function(table_name) {
    var postdata = $.buildQueryString({
      name: "Describe table " + table_name,
      type: "sql_query"
    });

    var querydata = $.buildQueryString({
      content: "DESCRIBE `" + table_name + "`;"
    });

    $.httpPost("/api/v1/documents", postdata, function(r) {
      if (r.status == 201) {
        var doc = JSON.parse(r.response);

        $.httpPost("/api/v1/documents/" + doc.uuid, querydata, function(r) {
          if (r.status == 201) {
            $.navigateTo("/a/sql/" + doc.uuid);
          } else {
            renderError("Table could not be opened in SQL Editor");
          }
        });

        return;
      } else {
        renderError("Table could not be opened in SQL Editor");
      }
    });
  };

  return {
    name: "table_editor",
    loadView: function(params) { load(params.path); },
    unloadView: function() {},
    handleNavigationChange: load
  };
})());
<commit_msg>table editor path prefix<commit_after>ZBase.registerView((function() {
  var kPathPrefix = "/a/datastore/tables/edit/";

  var load = function(path) {
    var table_id = path.substr(kPathPrefix.length);

    $.showLoader();

    $.httpGet("/api/v1/tables/" + table_id, function(r) {
      if (r.status == 200) {
        render(JSON.parse(r.response).table);
      } else {
        renderError(r.statusText, kPathPrefix + table_id);
      }
      $.hideLoader();
    });
  };

  var render = function(schema) {
    var page = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_tpl");

    var table_breadcrumb = $(".table_name_breadcrumb", page);
    table_breadcrumb.innerHTML = schema.name;
    table_breadcrumb.href = kPathPrefix + schema.name;

    $("z-tab.schema a", page).href = kPathPrefix + schema.name;
    $("z-tab.settings a", page).href = kPathPrefix + schema.name;

    $("z-dropdown.open_in", page).addEventListener("change", function() {
      switch (this.getValue()) {
        case "sql_editor":
          openTableInSQLEditor(schema.name);
          break;

        case "tableviewer":
          $.navigateTo("/a/datastore/tables/view/" + schema.name);
          break;
      }
    }, false);

    $("z-dropdown.edit", page).addEventListener("change", function() {
      switch (this.getValue()) {
        case "add_column":
          displayAddColumnModal(schema);
          break;

        case "delete_column":
          displayDeleteColumnModal(schema);
          break;
      }
      this.setValue([]);
    }, false);

    renderTable(schema.schema.columns, $("tbody", page), "");

    $.handleLinks(page);
    $.replaceViewport(page);
  };

  var renderError = function(msg, path) {
    var error_elem = document.createElement("div");
    error_elem.classList.add("zbase_error");
    error_elem.innerHTML =
        "" +
        "
We're sorry
" +
        "
An error occured.

" + msg + "
 " +
        "
Please try it again or contact support if the problem persists.
" +
        "" +
        " Back" +
        "" +
        " Reload" +
        "";

    $.replaceViewport(error_elem);
  };

  var renderTable = function(columns, tbody, prefix) {
    var row_tpl = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_row_tpl");

    columns.forEach(function(column) {
      var tr = row_tpl.cloneNode(true);
      var column_name = prefix + column.name;
      $(".name", tr).innerHTML = column_name;
      $(".type", tr).innerHTML = column.type;
      $(".is_nullable", tr).innerHTML = column.optional;

      tbody.appendChild(tr);

      if (column.type == "OBJECT") {
        renderTable(column.schema.columns, tbody, column_name + ".");
      }
    });
  };

  var displayAddColumnModal = function(schema) {
    var modal = $(".zbase_table_editor z-modal.add_column");
    var tpl = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_add_modal_tpl");

    var input = $("input", tpl);

    $.onClick($("button.submit", tpl), function() {
      if (input.value.length == 0) {
        $(".error_note.name", modal).classList.remove("hidden");
        input.classList.add("error");
        input.focus();
        return;
      }

      var url = "/api/v1/tables/add_field?" + $.buildQueryString({
          table: schema.name,
          field_name: input.value,
          field_type: $("z-dropdown.type", modal).getValue(),
          optional: "true",
          repeated: $("z-dropdown.is_repeated", modal).getValue()});

      $.httpPost(url, "", function(r) {
        if (r.status == 201) {
          var info_message = ZbaseInfoMessage($(".zbase_app"));
          info_message.renderSuccess(
              "The table column " + input.value + " has been successfully added.");
          $.navigateTo(kPathPrefix + schema.name);
        } else {
          $(".error_message .msg", modal).innerHTML = r.response;
          $(".error_message", modal).classList.remove("hidden");
          console.log(r);
        }
      });

    });

    $.onClick($("button.close", tpl), function() {
      modal.close();
    });

    $.replaceContent($(".container", modal), tpl);
    modal.show();
    input.focus();
  };

  var displayDeleteColumnModal = function(schema) {
    var modal = $(".zbase_table_editor z-modal.delete_column");
    var tpl = $.getTemplate(
        "views/table_editor",
        "zbase_table_editor_delete_modal_tpl");

    var input = $("input", tpl);

    $.onClick($("button.submit", tpl), function() {
      var url = "/api/v1/tables/remove_field?table=" + schema.name +
        "&field_name=" + input.value;

      $.httpPost(url, "", function(r) {
        if (r.status == 201) {
          var info_message = ZbaseInfoMessage($(".zbase_app"));
          info_message.renderSuccess("The table column has been removed.");
          $.navigateTo(kPathPrefix + schema.name);
        } else {
          $(".error_message", modal).classList.remove("hidden");
          $(".error_message .msg", modal).innerHTML = r.response;
        }
      });

    });

    $.onClick($("button.close", tpl), function() {
      modal.close();
    });

    $.replaceContent($(".container", modal), tpl);

    modal.show();
    input.focus();
  };

  var openTableInSQLEditor = function(table_name) {
    var postdata = $.buildQueryString({
      name: "Describe table " + table_name,
      type: "sql_query"
    });

    var querydata = $.buildQueryString({
      content: "DESCRIBE `" + table_name + "`;"
    });

    $.httpPost("/api/v1/documents", postdata, function(r) {
      if (r.status == 201) {
        var doc = JSON.parse(r.response);

        $.httpPost("/api/v1/documents/" + doc.uuid, querydata, function(r) {
          if (r.status == 201) {
            $.navigateTo("/a/sql/" + doc.uuid);
          } else {
            renderError("Table could not be opened in SQL Editor");
          }
        });

        return;
      } else {
        renderError("Table could not be opened in SQL Editor");
      }
    });
  };

  return {
    name: "table_editor",
    loadView: function(params) { load(params.path); },
    unloadView: function() {},
    handleNavigationChange: load
  };
})());
<|endoftext|>


<commit_before>import {Events, Styler, UICorePlugin, template} from 'Clappr'
import pluginHtml from './public/level-selector.html'
import pluginStyle from './public/style.scss'

const AUTO = -1

export default class LevelSelector extends UICorePlugin {

  static get version() { return VERSION }

  get name() { return 'level_selector' }
  get template() { return template(pluginHtml) }

  get attributes() {
    return {
      'class': this.name,
      'data-level-selector': ''
    }
  }

  get events() {
    return {
      'click [data-level-selector-select]': 'onLevelSelect',
      'click [data-level-selector-button]': 'onShowLevelSelectMenu'
    }
  }

  constructor(core) {
    super(core)
    this.init()
    this.render()
  }

  init() {
    this.levels = []
    this.selectedLevelId = AUTO
    this.options = this.core.options
  }

  bindEvents() {
    this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED, this.reload)
    this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_RENDERED, this.render)
    this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVELS_AVAILABLE, this.fillLevels)
    this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_START, this.startAnimation)
    this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_END, this.stopAnimation)

    var playbackLevelsAvaialbeWasTriggered = this.core.getCurrentPlayback().levels && this.core.getCurrentPlayback().levels.length > 0
    playbackLevelsAvaialbeWasTriggered && this.fillLevels(this.core.getCurrentPlayback().levels)
  }

  unBindEvents() {
    this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED)
    this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_RENDERED)
    this.stopListening(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVELS_AVAILABLE)
    this.stopListening(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_START)
    this.stopListening(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_END)
  }

  reload() {
    this.unBindEvents()
    this.init()
    this.bindEvents()
  }

  shouldRender() {
    if (!this.core.getCurrentPlayback()) return false

    var respondsToCurrentLevel = !!this.core.getCurrentPlayback().currentLevel
    var hasLevels = !!(this.core.getCurrentPlayback().levels && this.core.getCurrentPlayback().levels.length > 0)
    return respondsToCurrentLevel && hasLevels
  }

  render() {
    if (this.shouldRender()) {
      var style = Styler.getStyleFor(pluginStyle, {baseUrl: this.options.baseUrl})

      this.$el.html(this.template({'levels':this.levels, 'title': this.getTitle()}))
      this.$el.append(style)
      this.core.mediaControl.$('.media-control-right-panel').append(this.el)
      this.updateText(this.selectedLevelId)
    }
    return this
  }

  fillLevels(levels) {
    this.levels = levels
    this.configureLevelsLabels()
    this.render()
  }

  configureLevelsLabels() {
    if (this.options.levelSelectorConfig === undefined) return

    for(var levelId in (this.options.levelSelectorConfig.labels || {})){
      var thereIsLevel = !!this.findLevelBy(levelId)
      thereIsLevel && this.changeLevelLabelBy(levelId, this.options.levelSelectorConfig.labels[labelId])
    }
  }

  findLevelBy(id) {
    var foundLevel
    this.levels.forEach((level) => { if (level.id === id) {foundLevel = level} })
    return foundLevel
  }

  changeLevelLabelBy(id, newLabel) {
    this.levels.forEach((level, index) => {
      if (level.id === id) {
        this.levels[index] = newLabel
      }
    })
  }

  onLevelSelect(event) {
    this.selectedLevelId = parseInt(event.target.dataset.levelSelectorSelect, 10)
    this.core.getCurrentPlayback().currentLevel = this.selectedLevelId

    this.toggleContextMenu()
    this.render()

    event.stopPropagation()
    return false
  }

  onShowLevelSelectMenu(event) { this.toggleContextMenu() }

  toggleContextMenu() { this.$('.level_selector ul').toggle() }

  buttonElement() { return this.$('.level_selector button') }

  startAnimation() { this.buttonElement().addClass('changing') }

  stopAnimation() { this.buttonElement().removeClass('changing') }

  getTitle() { return (this.options.levelSelectorConfig || {}).title }

  updateText(level) { this.buttonElement().text((level === AUTO)? 'AUTO' : this.findLevelBy(level).label) }
}
<commit_msg>uses options by core<commit_after>import {Events, Styler, UICorePlugin, template} from 'Clappr'
import pluginHtml from './public/level-selector.html'
import pluginStyle from './public/style.scss'

const AUTO = -1

export default class LevelSelector extends UICorePlugin {

  static get version() { return VERSION }

  get name() { return 'level_selector' }
  get template() { return template(pluginHtml) }

  get attributes() {
    return {
      'class': this.name,
      'data-level-selector': ''
    }
  }

  get events() {
    return {
      'click [data-level-selector-select]': 'onLevelSelect',
      'click [data-level-selector-button]': 'onShowLevelSelectMenu'
    }
  }

  constructor(core) {
    super(core)
    this.init()
    this.render()
  }

  init() {
    this.levels = []
    this.selectedLevelId = AUTO
  }

  bindEvents() {
    this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED, this.reload)
    this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_RENDERED, this.render)
    this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVELS_AVAILABLE, this.fillLevels)
    this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_START, this.startAnimation)
    this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_END, this.stopAnimation)

    var playbackLevelsAvaialbeWasTriggered = this.core.getCurrentPlayback().levels && this.core.getCurrentPlayback().levels.length > 0
    playbackLevelsAvaialbeWasTriggered && this.fillLevels(this.core.getCurrentPlayback().levels)
  }

  unBindEvents() {
    this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED)
    this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_RENDERED)
    this.stopListening(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVELS_AVAILABLE)
    this.stopListening(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_START)
    this.stopListening(this.core.getCurrentPlayback(), Events.PLAYBACK_LEVEL_SWITCH_END)
  }

  reload() {
    this.unBindEvents()
    this.init()
    this.bindEvents()
  }

  shouldRender() {
    if (!this.core.getCurrentPlayback()) return false

    var respondsToCurrentLevel = !!this.core.getCurrentPlayback().currentLevel
    var hasLevels = !!(this.core.getCurrentPlayback().levels && this.core.getCurrentPlayback().levels.length > 0)
    return respondsToCurrentLevel && hasLevels
  }

  render() {
    if (this.shouldRender()) {
      var style = Styler.getStyleFor(pluginStyle, {baseUrl: this.core.options.baseUrl})

      this.$el.html(this.template({'levels':this.levels, 'title': this.getTitle()}))
      this.$el.append(style)
      this.core.mediaControl.$('.media-control-right-panel').append(this.el)
      this.updateText(this.selectedLevelId)
    }
    return this
  }

  fillLevels(levels) {
    this.levels = levels
    this.configureLevelsLabels()
    this.render()
  }

  configureLevelsLabels() {
    if (this.core.options.levelSelectorConfig === undefined) return

    for(var levelId in (this.core.options.levelSelectorConfig.labels || {})){
      var thereIsLevel = !!this.findLevelBy(levelId)
      thereIsLevel && this.changeLevelLabelBy(levelId, this.core.options.levelSelectorConfig.labels[labelId])
    }
  }

  findLevelBy(id) {
    var foundLevel
    this.levels.forEach((level) => { if (level.id === id) {foundLevel = level} })
    return foundLevel
  }

  changeLevelLabelBy(id, newLabel) {
    this.levels.forEach((level, index) => {
      if (level.id === id) {
        this.levels[index] = newLabel
      }
    })
  }

  onLevelSelect(event) {
    this.selectedLevelId = parseInt(event.target.dataset.levelSelectorSelect, 10)
    this.core.getCurrentPlayback().currentLevel = this.selectedLevelId

    this.toggleContextMenu()
    this.render()

    event.stopPropagation()
    return false
  }

  onShowLevelSelectMenu(event) { this.toggleContextMenu() }

  toggleContextMenu() { this.$('.level_selector ul').toggle() }

  buttonElement() { return this.$('.level_selector button') }

  startAnimation() { this.buttonElement().addClass('changing') }

  stopAnimation() { this.buttonElement().removeClass('changing') }

  getTitle() { return (this.core.options.levelSelectorConfig || {}).title }

  updateText(level) { this.buttonElement().text((level === AUTO)? 'AUTO' : this.findLevelBy(level).label) }
}
<|endoftext|>


<commit_before>ZBase.registerView((function() {
  var query_mgr = null;

  var load = function(path) {
    $.showLoader();
    query_mgr = EventSourceHandler();

    var path_prefix = "/a/datastore/tables/view/";
    var table = path.substr(path_prefix.length);

    var tpl = $.getTemplate(
        "views/table_viewer",
        "zbase_table_viewer_tpl");

    var main_menu = ZBaseMainMenu();
    main_menu.render($(".zbase_main_menu", tpl), "/a/datastore/tables");

    var table_link = $(".pagetitle a.table_name", tpl);
    table_link.innerHTML = table;
    table_link.setAttribute("href", path_prefix + table);

    $.handleLinks(tpl);
    $.replaceViewport(tpl);
    $.hideLoader();
    showLoadingBar();

    var params = getQueryParams();
    params.table = table;
    var url = "/api/v1/events/scan?" + $.buildQueryString(params);
    var query = query_mgr.get("table_viewer", url);
    var event_counter = 0;

    query.addEventListener("result", function(e) {
      renderJSONView(e.data, event_counter);
      event_counter++;
    }, false);

    query.addEventListener("progress", function(e) {
      var data = JSON.parse(e.data);
      if (data.status == "finished") {
        query_mgr.close("table_viewer");
        hideLoadingBar();
      }
    }, false);

    query.addEventListener("error", function(e) {
      $.fatalError();
      console.log(e);
    }, false);
  };

  var destroy = function() {
    if (query_mgr) {
      query_mgr.closeAll();
    }
  };

  var getQueryParams = function() {
    var params = {};

    //limit param
    //FIXME
    params.limit = 10;

    //filter param
    params.filter_type = $(".zbase_table_viewer .filter_type_control").getValue();
    params.filter = $(".zbase_table_viewer .filter_control").getValue();

    return params;
  };

  var renderJSONView = function(json, event_counter) {
    var elem = document.createElement("div");
    elem.setAttribute("id", "json_" + event_counter);
    $(".zbase_table_viewer .json_viewer").appendChild(elem);

    var inspector = new InspectorJSON({
      element: 'json_' + event_counter,
      json: json
    });

    $("ul li", elem).classList.add("collapsed");
  };

  var showLoadingBar = function() {
    $(".zbase_table_viewer .loading_bar").classList.remove("hidden");
  };

  var hideLoadingBar = function() {
    $(".zbase_table_viewer .loading_bar").classList.add("hidden");
  };

  return {
    name: "table_viewer",
    loadView: function(params) { load(params.path); },
    unloadView: destroy,
    handleNavigationChange: load
  };
})());
<commit_msg>handle control submit<commit_after>ZBase.registerView((function() {
  var path_prefix = "/a/datastore/tables/view/";
  var query_mgr = null;
  var table;

  var load = function(path) {
    $.showLoader();
    query_mgr = EventSourceHandler();

    table = path.substr(path_prefix.length);

    var tpl = $.getTemplate(
        "views/table_viewer",
        "zbase_table_viewer_tpl");

    var main_menu = ZBaseMainMenu();
    main_menu.render($(".zbase_main_menu", tpl), "/a/datastore/tables");

    var table_link = $(".pagetitle a.table_name", tpl);
    table_link.innerHTML = table;
    table_link.setAttribute("href", path_prefix + table);

    $(".filter_type_control", tpl).addEventListener(
        "change", submitControls);
    $(".filter_control", tpl).addEventListener(
        "z-search-submit", submitControls);

    $.handleLinks(tpl);
    $.replaceViewport(tpl);
    $.hideLoader();

    //setQueryParams();
    executeQuery();
  };

  var destroy = function() {
    if (query_mgr) {
      query_mgr.closeAll();
    }
  };

  var executeQuery = function() {
    showLoadingBar();

    var query = query_mgr.get("table_viewer", getQueryUrl());
    var event_counter = 0;

    query.addEventListener("result", function(e) {
      renderJSONView(e.data, event_counter);
      event_counter++;
    }, false);

    query.addEventListener("progress", function(e) {
      var data = JSON.parse(e.data);
      if (data.status == "finished") {
        query_mgr.close("table_viewer");
        hideLoadingBar();
      }
    }, false);

    query.addEventListener("error", function(e) {
      console.log(e);
      $.fatalError();
    }, false);
  };

  var submitControls = function() {
    $.navigateTo(getViewUrl());
  };

  var getViewUrl = function() {
    return path_prefix + table + "?" + $.buildQueryString(getViewParams());
  };

  var getQueryUrl = function() {
    return "/api/v1/events/scan?" + $.buildQueryString(getQueryParams())
  };

  var getViewParams = function() {
    var params = {};
    //limit param
    //FIXME
    params.limit = 10;

    //filter param
    params.filter_type = $(".zbase_table_viewer .filter_type_control").getValue();
    params.filter = $(".zbase_table_viewer .filter_control").getValue();

    return params;
  };

  var getQueryParams = function() {
    var params = getViewParams();
    params.table = table;

    return params;
  };

  var renderJSONView = function(json, event_counter) {
    var elem = document.createElement("div");
    elem.setAttribute("id", "json_" + event_counter);
    $(".zbase_table_viewer .json_viewer").appendChild(elem);

    var inspector = new InspectorJSON({
      element: 'json_' + event_counter,
      json: json
    });

    $("ul li", elem).classList.add("collapsed");
  };

  var showLoadingBar = function() {
    $(".zbase_table_viewer .loading_bar").classList.remove("hidden");
  };

  var hideLoadingBar = function() {
    $(".zbase_table_viewer .loading_bar").classList.add("hidden");
  };

  return {
    name: "table_viewer",
    loadView: function(params) { load(params.path); },
    unloadView: destroy,
    handleNavigationChange: load
  };
})());
<|endoftext|>


<commit_before>import Vue from 'vue'
import router from './router'
import App from './App'

// inclusion: application
import Splash from './components/splash/Splash'

// inclusion: mon garde-manger
import Foodkeeper from './components/foodkeeper/Foodkeeper'
import AddFoodkeeper from './components/foodkeeper/AddFoodkeeper'
import AddProductFoodkeeper from './components/foodkeeper/AddProductFoodkeeper'
import DetailsFoodkeeper from './components/foodkeeper/DetailsFoodkeeper'
import DetailsFoodkeeperProducts from './components/foodkeeper/DetailsFoodkeeperProducts'
import DetailsFoodkeeperStats from './components/foodkeeper/DetailsFoodkeeperStats'
import DetailsFoodkeeperTimeline from './components/foodkeeper/DetailsFoodkeeperTimeline'

// inclusion: la place du marché
import Market from './components/market/Market'
import AddMarket from './components/market/AddMarket'
import DetailsMarket from './components/market/DetailsMarket'
import DetailsMarketStats from './components/market/DetailsMarketStats'
import DetailsMarketLocation from './components/market/DetailsMarketLocation'
import DetailsMarketMembers from './components/market/DetailsMarketMembers'
import ProductMarket from './components/market/ProductMarket'

// inclusion: mes alliances
import Alliances from './components/alliances/Alliances'
import DetailsAlliance from './components/alliances/DetailsAlliance'

// inclusion: profile
import MemberProfile from './components/profile/MemberProfile';
import Profile from './components/profile/Profile';
import DetailsProfileMe from './components/profile/DetailsProfileMe';
import DetailsProfileReviews from './components/profile/DetailsProfileReviews';
import DetailsProfileStatistics from './components/profile/DetailsProfileStatistics';

// configuration de vuejs
Vue.config.debug = true
Vue.config.devtools = true

// définition des routes de l'application
router.map({

  // route par défaut
  '/': {
    name: 'Splash',
    component: Splash,
    page:{
      title: 'Pain Perdu',
      wrap: '',
      bgClass: 'background1',
      header: {
        enable: false,
      },
      footer: {
        enable: false,
      },
    },
  },

  // mon garde-manger
  '/foodkeeper': {
    name: 'Foodkeeper',
    component: Foodkeeper,
    page: {
      title: 'Mes gardes-mangers',
      wrap: 'wrap-header-footer',
      bgClass: 'background2',
      header: {
        enable: true,
        profile: true,
        add: true,
      },
      footer: {
        enable: true,
      },
    },
  },
  '/foodkeeper/add': {
    name: 'AddFoodkeeper',
    component: AddFoodkeeper,
    page: {
      title: 'Ajouter un garde-manger',
      wrap: 'wrap-header',
      bgClass: 'background2',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/foodkeeper/add/product': {
    name: 'AddProductFoodkeeper',
    component: AddProductFoodkeeper,
    page: {
      title: 'Ajouter une denrée',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/foodkeeper/details': {
    name: 'DetailsFoodkeeper',
    component: DetailsFoodkeeper,
    page: {
      title: 'Mon garde-manger',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
        basket: true,
        product: true,
      },
      footer: {
        enable: false,
      },
    },
    subRoutes: {
      '/products/:id': {
        name: 'DetailsFoodkeeperProducts',
        component: DetailsFoodkeeperProducts,
      },
      '/stats/:id': {
        name: 'DetailsFoodkeeperStats',
        component: DetailsFoodkeeperStats,
      },
      '/timeline/:id': {
        name: 'DetailsFoodkeeperTimeline',
        component: DetailsFoodkeeperTimeline,
      },
    },
  },

  // place du marché
  '/market': {
    name: 'Market',
    component: Market,
    page: {
      title: 'Pain Perdu',
      wrap: 'wrap-header-footer',
      bgClass: 'background1',
      header: {
        enable: true,
        profile: true,
        add: true,
      },
      footer: {
        enable: true,
      },
    },
  },
  '/market/add': {
    name: 'AddMarket',
    component: AddMarket,
    page: {
      title: 'Ajouter une place du marché',
      wrap: 'wrap-header',
      bgClass: 'background3',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/market/product': {
    name: 'ProductMarket',
    component: ProductMarket,
    page: {
      title: 'Fiche denrée',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
        flag: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/market/details': {
    name: 'DetailsMarket',
    component: DetailsMarket,
    page: {
      title: 'Fiche place du marché',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
    subRoutes: {
      '/members/:id': {
        name: 'DetailsMarketMembers',
        component: DetailsMarketMembers,
      },
      '/location/:id': {
        name: 'DetailsMarketLocation',
        component: DetailsMarketLocation,
      },
      '/stats/:id': {
        name: 'DetailsMarketStats',
        component: DetailsMarketStats,
      },
    },
  },

  // mes alliances
  '/alliances': {
    name: 'Alliances',
    component: Alliances,
    page: {
      title: 'Mes alliances',
      wrap: 'wrap-header-footer',
      bgClass: 'background4',
      header: {
        enable: true,
        profile: true,
      },
      footer: {
        enable: true,
      },
    },
  },
  'alliances/details': {
    name: 'DetailsAlliance',
    component: DetailsAlliance,
    page: {
      title: 'Mon alliance',
      wrap: 'wrap-header-footer',
      bgClass: 'background4',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },

  // profile
  '/profile/member/:id': {
    name: 'MemberProfile',
    component: MemberProfile,
    page: {
      title: 'Fiche compère',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        close: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/profile': {
    name: 'Profile',
    component: Profile,
    page: {
      title: 'Mon profil',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        menu: true,
        close: true,
      },
      footer: {
        enable: false,
      },
    },
    subRoutes: {
      '/me/:id': {
        name: 'DetailsProfileMe',
        component: DetailsProfileMe,
      },
      '/reviews/:id': {
        name: 'DetailsProfileReviews',
        component: DetailsProfileReviews,
      },
      '/stats/:id': {
        name: 'DetailsProfileStatistics',
        component: DetailsProfileStatistics,
      },
    },
  },
})

// initialisation du routeur
router.start(App, 'painperdu-app')
<commit_msg>Title fiche user<commit_after>import Vue from 'vue'
import router from './router'
import App from './App'

// inclusion: application
import Splash from './components/splash/Splash'

// inclusion: mon garde-manger
import Foodkeeper from './components/foodkeeper/Foodkeeper'
import AddFoodkeeper from './components/foodkeeper/AddFoodkeeper'
import AddProductFoodkeeper from './components/foodkeeper/AddProductFoodkeeper'
import DetailsFoodkeeper from './components/foodkeeper/DetailsFoodkeeper'
import DetailsFoodkeeperProducts from './components/foodkeeper/DetailsFoodkeeperProducts'
import DetailsFoodkeeperStats from './components/foodkeeper/DetailsFoodkeeperStats'
import DetailsFoodkeeperTimeline from './components/foodkeeper/DetailsFoodkeeperTimeline'

// inclusion: la place du marché
import Market from './components/market/Market'
import AddMarket from './components/market/AddMarket'
import DetailsMarket from './components/market/DetailsMarket'
import DetailsMarketStats from './components/market/DetailsMarketStats'
import DetailsMarketLocation from './components/market/DetailsMarketLocation'
import DetailsMarketMembers from './components/market/DetailsMarketMembers'
import ProductMarket from './components/market/ProductMarket'

// inclusion: mes alliances
import Alliances from './components/alliances/Alliances'
import DetailsAlliance from './components/alliances/DetailsAlliance'

// inclusion: profile
import MemberProfile from './components/profile/MemberProfile';
import Profile from './components/profile/Profile';
import DetailsProfileMe from './components/profile/DetailsProfileMe';
import DetailsProfileReviews from './components/profile/DetailsProfileReviews';
import DetailsProfileStatistics from './components/profile/DetailsProfileStatistics';

// configuration de vuejs
Vue.config.debug = true
Vue.config.devtools = true

// définition des routes de l'application
router.map({

  // route par défaut
  '/': {
    name: 'Splash',
    component: Splash,
    page:{
      title: 'Pain Perdu',
      wrap: '',
      bgClass: 'background1',
      header: {
        enable: false,
      },
      footer: {
        enable: false,
      },
    },
  },

  // mon garde-manger
  '/foodkeeper': {
    name: 'Foodkeeper',
    component: Foodkeeper,
    page: {
      title: 'Mes gardes-mangers',
      wrap: 'wrap-header-footer',
      bgClass: 'background2',
      header: {
        enable: true,
        profile: true,
        add: true,
      },
      footer: {
        enable: true,
      },
    },
  },
  '/foodkeeper/add': {
    name: 'AddFoodkeeper',
    component: AddFoodkeeper,
    page: {
      title: 'Ajouter un garde-manger',
      wrap: 'wrap-header',
      bgClass: 'background2',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/foodkeeper/add/product': {
    name: 'AddProductFoodkeeper',
    component: AddProductFoodkeeper,
    page: {
      title: 'Ajouter une denrée',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/foodkeeper/details': {
    name: 'DetailsFoodkeeper',
    component: DetailsFoodkeeper,
    page: {
      title: 'Mon garde-manger',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
        basket: true,
        product: true,
      },
      footer: {
        enable: false,
      },
    },
    subRoutes: {
      '/products/:id': {
        name: 'DetailsFoodkeeperProducts',
        component: DetailsFoodkeeperProducts,
      },
      '/stats/:id': {
        name: 'DetailsFoodkeeperStats',
        component: DetailsFoodkeeperStats,
      },
      '/timeline/:id': {
        name: 'DetailsFoodkeeperTimeline',
        component: DetailsFoodkeeperTimeline,
      },
    },
  },

  // place du marché
  '/market': {
    name: 'Market',
    component: Market,
    page: {
      title: 'Pain Perdu',
      wrap: 'wrap-header-footer',
      bgClass: 'background1',
      header: {
        enable: true,
        profile: true,
        add: true,
      },
      footer: {
        enable: true,
      },
    },
  },
  '/market/add': {
    name: 'AddMarket',
    component: AddMarket,
    page: {
      title: 'Ajouter une place du marché',
      wrap: 'wrap-header',
      bgClass: 'background3',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/market/product': {
    name: 'ProductMarket',
    component: ProductMarket,
    page: {
      title: 'Fiche denrée',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
        flag: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/market/details': {
    name: 'DetailsMarket',
    component: DetailsMarket,
    page: {
      title: 'Fiche place du marché',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
    subRoutes: {
      '/members/:id': {
        name: 'DetailsMarketMembers',
        component: DetailsMarketMembers,
      },
      '/location/:id': {
        name: 'DetailsMarketLocation',
        component: DetailsMarketLocation,
      },
      '/stats/:id': {
        name: 'DetailsMarketStats',
        component: DetailsMarketStats,
      },
    },
  },

  // mes alliances
  '/alliances': {
    name: 'Alliances',
    component: Alliances,
    page: {
      title: 'Mes alliances',
      wrap: 'wrap-header-footer',
      bgClass: 'background4',
      header: {
        enable: true,
        profile: true,
      },
      footer: {
        enable: true,
      },
    },
  },
  'alliances/details': {
    name: 'DetailsAlliance',
    component: DetailsAlliance,
    page: {
      title: 'Mon alliance',
      wrap: 'wrap-header-footer',
      bgClass: 'background4',
      header: {
        enable: true,
        previous: true,
      },
      footer: {
        enable: false,
      },
    },
  },

  // profile
  '/profile/member/:id': {
    name: 'MemberProfile',
    component: MemberProfile,
    page: {
      title: 'Fiche allié',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        close: true,
      },
      footer: {
        enable: false,
      },
    },
  },
  '/profile': {
    name: 'Profile',
    component: Profile,
    page: {
      title: 'Mon profil',
      wrap: 'wrap-header',
      bgClass: 'background1',
      header: {
        enable: true,
        menu: true,
        close: true,
      },
      footer: {
        enable: false,
      },
    },
    subRoutes: {
      '/me/:id': {
        name: 'DetailsProfileMe',
        component: DetailsProfileMe,
      },
      '/reviews/:id': {
        name: 'DetailsProfileReviews',
        component: DetailsProfileReviews,
      },
      '/stats/:id': {
        name: 'DetailsProfileStatistics',
        component: DetailsProfileStatistics,
      },
    },
  },
})

// initialisation du routeur
router.start(App, 'painperdu-app')
<|endoftext|>


<commit_before>(function(DOM, BASE, VK_SPACE, VK_TAB, VK_ENTER, VK_ESCAPE, VK_BACKSPACE, VK_DELETE, VK_CONTROL) {
    "use strict";

    var HTML = DOM.get("documentElement"),
        ampm = (pos, neg) => HTML.lang === "en-US" ? pos : neg,
        formatISODate = (value) => value.toISOString().split("T")[0],
        PICKER_TEMPLATE = DOM.create(DOM.emmet(`div.${BASE}-calendar>(p.${BASE}-calendar-header>a[unselectable=on]*2+time[is=local-time data-format='MMMM yyyy' aria-hidden=true unselectable=on].${BASE}-calendar-caption)`)),
        DAYS_TEMPLATE = DOM.create(DOM.emmet(`table[aria-hidden=true].${BASE}-calendar-days>(thead>(tr>th[unselectable=on]*7>time[is=local-time data-format=E]))+(tbody.${BASE}-calendar-body*2>tr*6>td*7)`)),
        MONTHS_TEMPLATE = DOM.create(DOM.emmet(`table[aria-hidden=true].${BASE}-calendar-months>tbody>tr*3>td*4>time[is=local-time data-format=MMM])`)),
        LABEL_TEMPLATE = DOM.create(DOM.emmet(`time[is=local-time aria-hidden=true].${BASE}-value`)),
        readDateRange = (el) => ["min", "max"].map((x) => new Date(el.get(x) || ""));

    MONTHS_TEMPLATE.findAll("time").forEach((time, index) => {
        time.set("datetime", new Date(2001, index, 9).toISOString());
    });

    DAYS_TEMPLATE.findAll("time").forEach((time, index) => {
        time.set("datetime", new Date(ampm(2001, 2002), 0, index).toISOString());
    });

    PICKER_TEMPLATE.append(DAYS_TEMPLATE).append(MONTHS_TEMPLATE);

    DOM.extend("input[type=date]", {
        constructor() {
            if (this._isNative()) return false;

            var picker = PICKER_TEMPLATE.clone(true),
                label = LABEL_TEMPLATE.clone(true),
                calenderDays = picker.findAll(`.${BASE}-calendar-body`),
                calendarMonths = picker.find(`.${BASE}-calendar-months`),
                calendarCaption = picker.find(`.${BASE}-calendar-caption`),
                changeValue = this._changeValue.bind(this, calendarCaption, calendarMonths, calenderDays, picker);

            this
                // sync picker visibility on focus/blur
                .on(["focus", "click"], this._focusPicker.bind(this, picker))
                .on("blur", this._blurPicker.bind(this, picker))
                .on("change", this._syncDateValue.bind(this, label))
                .before(picker.hide(), label);

            label
                .set("data-format", this.get("data-format") || "E, dd MMM yyyy")
                .css(this.css(["width", "font", "padding", "text-align", "border-width", "box-sizing"]))
                .css("line-height", "") // IE10 returns invalid line-height for hidden elements
                .on("click", this._clickLabel.bind(this));

            calenderDays[1].hide().remove();
            calendarCaption.on("click", this._clickPickerCaption.bind(this, picker, calendarCaption, changeValue));

            // handle arrow keys, esc etc.
            this
                .on("keydown", ["which"], this._keydownPicker.bind(this, picker, calendarCaption))
                .watch("value", changeValue);

            this.closest("form").on("reset", this._resetForm.bind(this));
            // trigger watchers to build the calendar
            changeValue(this.get("defaultValue"));

            picker
                .on("mousedown", ["target"], this._clickPicker.bind(this, picker, calendarMonths))
                .css("z-index", 1 + (this.css("z-index") | 0))
                .hide(); // hide calendar to trigger show animation properly later

            // hide original input text
            // IE8 doesn't suport color:transparent - use background-color instead
            this.css("color", document.addEventListener ? "transparent" : this.css("background-color"));
            // display calendar for autofocused elements
            if (this.matches(":focus")) picker.show();
        },
        _isNative() {
            var polyfillType = this.get("data-polyfill"),
                deviceType = "orientation" in window ? "mobile" : "desktop";

            if (polyfillType === "none") return true;

            if (!polyfillType || polyfillType === deviceType && polyfillType !== "all") {
                // use a stronger type support detection that handles old WebKit browsers:
                // http://www.quirksmode.org/blog/archives/2015/03/better_modern_i.html
                if (this[0].type === "date") return true;
                // persist current value to restore it later
                this.set("defaultValue", this.value());
                // if browser allows invalid value then it doesn't support the feature
                return this.value("_").value() !== "_";
            } else {
                // remove native control
                this.set("type", "text");
                // force applying the polyfill
                return false;
            }
        },
        _changeValue(caption, calendarMonths, calenderDays, picker, value, prevValue) {
            // #47: do not proceed if animation is in progress still
            if (calenderDays.every((days) => picker.contains(days))) return false;

            var year, month, date, iterDate;

            value = new Date(value);

            if (!value.getTime()) {
                value = new Date();
            }

            month = value.getUTCMonth();
            date = value.getUTCDate();
            year = value.getUTCFullYear();
            // update calendar caption
            caption.set("datetime", new Date(year, month).toISOString());
            // update calendar content
            iterDate = new Date(Date.UTC(year, month, 1));

            var range = readDateRange(this);

            if (picker.get("aria-expanded") === "true") {
                calendarMonths.findAll("td").forEach((day, index) => {
                    iterDate.setUTCMonth(index);

                    var mDiff = month - iterDate.getUTCMonth(),
                        className = `${BASE}-calendar-`;

                    if (iterDate < range[0] || iterDate > range[1]) {
                        className += "out";
                    } else if (!mDiff) {
                        className += "today";
                    } else {
                        className = "";
                    }

                    day.set("class", className);
                });
            } else {
                // move to beginning of current month week
                iterDate.setUTCDate(iterDate.getUTCDate() - iterDate.getUTCDay() - ampm(1, 0));

                prevValue = new Date(prevValue);

                var delta = value.getUTCMonth() - prevValue.getUTCMonth() + 100 * (value.getUTCFullYear() - prevValue.getUTCFullYear());
                var currenDays = calenderDays[picker.contains(calenderDays[0]) ? 0 : 1];
                var targetDays = delta ? calenderDays[calenderDays[0] === currenDays ? 1 : 0] : currenDays;
                // update days
                targetDays.findAll("td").forEach((day) => {
                    iterDate.setUTCDate(iterDate.getUTCDate() + 1);

                    var mDiff = month - iterDate.getUTCMonth(),
                        className = `${BASE}-calendar-`;

                    if (year !== iterDate.getUTCFullYear()) mDiff *= -1;

                    if (iterDate < range[0] || iterDate > range[1]) {
                        className += "out";
                    } else if (mDiff > 0) {
                        className += "past";
                    } else if (mDiff < 0) {
                        className += "future";
                    } else if (date === iterDate.getUTCDate()) {
                        className += "today";
                    } else {
                        className = "";
                    }

                    day
                        .set("class", className)
                        .data("ts", iterDate.getTime())
                        .value(iterDate.getUTCDate());
                });

                if (delta) {
                    currenDays[delta > 0 ? "after" : "before"](targetDays);
                    currenDays.hide(() => { currenDays.remove() });
                    targetDays.show();
                }
            }

            // trigger event manually to notify about changes
            this.fire("change");
        },
        _syncDateValue(time) {
            time.set("datetime", this.value());
        },
        _clickPicker(picker, calendarMonths, target) {
            var targetDate;

            if (target.matches("a")) {
                targetDate = new Date(this.value());

                if (!targetDate.getTime()) targetDate = new Date();

                var sign = target.next("a")[0] ? -1 : 1;

                if (picker.get("aria-expanded") === "true") {
                    targetDate.setUTCFullYear(targetDate.getUTCFullYear() + sign);
                } else {
                    targetDate.setUTCMonth(targetDate.getUTCMonth() + sign);
                }
            } else if (calendarMonths.contains(target)) {
                target = target.closest("time");

                targetDate = new Date(this.value());
                targetDate.setUTCMonth(new Date(target.get("datetime")).getUTCMonth());

                picker.hide();
            } else if (target.matches("td")) {
                targetDate = target.data("ts");

                if (targetDate) {
                    targetDate = new Date(targetDate);
                    picker.hide();
                }
            }

            if (targetDate != null) {
                var range = readDateRange(this);

                if (targetDate < range[0]) {
                    targetDate = range[0];
                } else if (targetDate > range[1]) {
                    targetDate = range[1];
                }

                this.value(formatISODate(targetDate));
            }
            // prevent input from loosing focus
            return false;
        },
        _keydownPicker(picker, calendarCaption, which) {
            var delta, currentDate;
            // ENTER key should submit form if calendar is hidden
            if (picker.matches(":hidden") && which === VK_ENTER) return true;

            if (which === VK_SPACE) {
                picker.toggle(); // SPACE key toggles calendar visibility
            } else if (which === VK_ESCAPE || which === VK_TAB || which === VK_ENTER) {
                picker.hide(); // ESC, TAB or ENTER keys hide calendar
            } else if (which === VK_BACKSPACE || which === VK_DELETE) {
                this.value(""); // BACKSPACE, DELETE clear value
            } else if (which === VK_CONTROL) {
                calendarCaption.fire("click"); // CONTROL toggles calendar mode
            } else {
                currentDate = new Date(this.value());

                if (!currentDate.getTime()) currentDate = new Date();

                if (which === 74 || which === 40) { delta = 7; }
                else if (which === 75 || which === 38) { delta = -7; }
                else if (which === 76 || which === 39) { delta = 1; }
                else if (which === 72 || which === 37) { delta = -1; }

                if (delta) {
                    var expanded = picker.get("aria-expanded") === "true";

                    if (expanded && (which === 40 || which === 38)) {
                        currentDate.setUTCMonth(currentDate.getUTCMonth() + (delta > 0 ? 4 : -4));
                    } else if (expanded && (which === 37 || which === 39)) {
                        currentDate.setUTCMonth(currentDate.getUTCMonth() + (delta > 0 ? 1 : -1));
                    } else {
                        currentDate.setUTCDate(currentDate.getUTCDate() + delta);
                    }

                    var range = readDateRange(this);

                    if (!(currentDate < range[0] || currentDate > range[1])) {
                        this.value(formatISODate(currentDate));
                    }
                }
            }
            // prevent default action except if it was TAB so
            // do not allow to change the value manually
            return which === VK_TAB;
        },
        _blurPicker(picker) {
            picker.hide();
        },
        _focusPicker(picker) {
            if (this.get("readonly")) return false;

            var offset = this.offset();
            var pickerOffset = picker.offset();
            var marginTop = offset.height;

            // #3: move calendar to the top when passing cross browser window bounds
            if (HTML.clientHeight < offset.bottom + pickerOffset.height) {
                marginTop = -pickerOffset.height;
            }

            picker
                // always recalculate picker top position
                .css("margin-top", marginTop)
                // always reset picker mode to default
                .set("aria-expanded", "false")
                .show();

            // use the trick below to reset text selection on focus
            /* istanbul ignore next */
            setTimeout(() => {
                var node = this[0];

                if ("selectionStart" in node) {
                    node.selectionStart = 0;
                    node.selectionEnd = 0;
                } else {
                    var inputRange = node.createTextRange();

                    inputRange.moveStart("character", 0);
                    inputRange.collapse();
                    inputRange.moveEnd("character", 0);
                    inputRange.select();
                }
            }, 0);
        },
        _clickPickerCaption(picker, calendarCaption, changeValue) {
            var expanded = picker.get("aria-expanded") === "true";

            picker.set("aria-expanded", String(!expanded));
            calendarCaption.set("data-format", expanded ? "MMMM yyyy" : "yyyy");

            changeValue(this.value());
        },
        _clickLabel() {
            this.fire("focus");
        },
        _resetForm() {
            this.value(this.get("defaultValue"));
        }
    });
}(window.DOM, "btr-dateinput", 32, 9, 13, 27, 8, 46, 17));
<commit_msg>do not fire change in changeValue<commit_after>(function(DOM, BASE, VK_SPACE, VK_TAB, VK_ENTER, VK_ESCAPE, VK_BACKSPACE, VK_DELETE, VK_CONTROL) {
    "use strict";

    var HTML = DOM.get("documentElement"),
        ampm = (pos, neg) => HTML.lang === "en-US" ? pos : neg,
        formatISODate = (value) => value.toISOString().split("T")[0],
        PICKER_TEMPLATE = DOM.create(DOM.emmet(`div.${BASE}-calendar>(p.${BASE}-calendar-header>a[unselectable=on]*2+time[is=local-time data-format='MMMM yyyy' aria-hidden=true unselectable=on].${BASE}-calendar-caption)`)),
        DAYS_TEMPLATE = DOM.create(DOM.emmet(`table[aria-hidden=true].${BASE}-calendar-days>(thead>(tr>th[unselectable=on]*7>time[is=local-time data-format=E]))+(tbody.${BASE}-calendar-body*2>tr*6>td*7)`)),
        MONTHS_TEMPLATE = DOM.create(DOM.emmet(`table[aria-hidden=true].${BASE}-calendar-months>tbody>tr*3>td*4>time[is=local-time data-format=MMM])`)),
        LABEL_TEMPLATE = DOM.create(DOM.emmet(`time[is=local-time aria-hidden=true].${BASE}-value`)),
        readDateRange = (el) => ["min", "max"].map((x) => new Date(el.get(x) || ""));

    MONTHS_TEMPLATE.findAll("time").forEach((time, index) => {
        time.set("datetime", new Date(2001, index, 9).toISOString());
    });

    DAYS_TEMPLATE.findAll("time").forEach((time, index) => {
        time.set("datetime", new Date(ampm(2001, 2002), 0, index).toISOString());
    });

    PICKER_TEMPLATE.append(DAYS_TEMPLATE).append(MONTHS_TEMPLATE);

    DOM.extend("input[type=date]", {
        constructor() {
            if (this._isNative()) return false;

            var picker = PICKER_TEMPLATE.clone(true),
                label = LABEL_TEMPLATE.clone(true),
                calenderDays = picker.findAll(`.${BASE}-calendar-body`),
                calendarMonths = picker.find(`.${BASE}-calendar-months`),
                calendarCaption = picker.find(`.${BASE}-calendar-caption`),
                changeValue = this._changeValue.bind(this, calendarCaption, calendarMonths, calenderDays, picker);

            this
                // sync picker visibility on focus/blur
                .on(["focus", "click"], this._focusPicker.bind(this, picker))
                .on("blur", this._blurPicker.bind(this, picker))
                .on("change", this._syncDateValue.bind(this, label))
                .before(picker.hide(), label);

            label
                .set("data-format", this.get("data-format") || "E, dd MMM yyyy")
                .watch("datetime", changeValue)
                .watch("data-format", changeValue)
                .css(this.css(["width", "font", "padding", "text-align", "border-width", "box-sizing"]))
                .css("line-height", "") // IE10 returns invalid line-height for hidden elements
                .on("click", this._clickLabel.bind(this));

            calenderDays[1].hide().remove();
            calendarCaption.on("click", this._clickPickerCaption.bind(this, picker, calendarCaption));

            // handle arrow keys, esc etc.
            this
                .on("keydown", ["which"], this._keydownPicker.bind(this, picker, calendarCaption))
                .watch("value", changeValue);

            this.closest("form").on("reset", this._resetForm.bind(this));
            // trigger watchers to build the calendar
            changeValue(this.get("defaultValue"));

            this._syncDateValue(label);

            picker
                .on("mousedown", ["target"], this._clickPicker.bind(this, picker, calendarMonths))
                .css("z-index", 1 + (this.css("z-index") | 0))
                .hide(); // hide calendar to trigger show animation properly later

            // hide original input text
            // IE8 doesn't suport color:transparent - use background-color instead
            this.css("color", document.addEventListener ? "transparent" : this.css("background-color"));
            // display calendar for autofocused elements
            if (this.matches(":focus")) picker.show();
        },
        _isNative() {
            var polyfillType = this.get("data-polyfill"),
                deviceType = "orientation" in window ? "mobile" : "desktop";

            if (polyfillType === "none") return true;

            if (!polyfillType || polyfillType === deviceType && polyfillType !== "all") {
                // use a stronger type support detection that handles old WebKit browsers:
                // http://www.quirksmode.org/blog/archives/2015/03/better_modern_i.html
                if (this[0].type === "date") return true;
                // persist current value to restore it later
                this.set("defaultValue", this.value());
                // if browser allows invalid value then it doesn't support the feature
                return this.value("_").value() !== "_";
            } else {
                // remove native control
                this.set("type", "text");
                // force applying the polyfill
                return false;
            }
        },
        _changeValue(caption, calendarMonths, calenderDays, picker, value, prevValue) {
            // #47: do not proceed if animation is in progress still
            if (calenderDays.every((days) => picker.contains(days))) return false;

            var year, month, date, iterDate;

            value = new Date(value);

            if (!value.getTime()) {
                value = new Date();
            }

            month = value.getUTCMonth();
            date = value.getUTCDate();
            year = value.getUTCFullYear();
            // update calendar caption
            caption.set("datetime", new Date(year, month).toISOString());
            // update calendar content
            iterDate = new Date(Date.UTC(year, month, 1));

            var range = readDateRange(this);

            if (picker.get("aria-expanded") === "true") {
                calendarMonths.findAll("td").forEach((day, index) => {
                    iterDate.setUTCMonth(index);

                    var mDiff = month - iterDate.getUTCMonth(),
                        className = `${BASE}-calendar-`;

                    if (iterDate < range[0] || iterDate > range[1]) {
                        className += "out";
                    } else if (!mDiff) {
                        className += "today";
                    } else {
                        className = "";
                    }

                    day.set("class", className);
                });
            } else {
                // move to beginning of current month week
                iterDate.setUTCDate(iterDate.getUTCDate() - iterDate.getUTCDay() - ampm(1, 0));

                prevValue = new Date(prevValue);

                var delta = value.getUTCMonth() - prevValue.getUTCMonth() + 100 * (value.getUTCFullYear() - prevValue.getUTCFullYear());
                var currenDays = calenderDays[picker.contains(calenderDays[0]) ? 0 : 1];
                var targetDays = delta ? calenderDays[calenderDays[0] === currenDays ? 1 : 0] : currenDays;
                // update days
                targetDays.findAll("td").forEach((day) => {
                    iterDate.setUTCDate(iterDate.getUTCDate() + 1);

                    var mDiff = month - iterDate.getUTCMonth(),
                        className = `${BASE}-calendar-`;

                    if (year !== iterDate.getUTCFullYear()) mDiff *= -1;

                    if (iterDate < range[0] || iterDate > range[1]) {
                        className += "out";
                    } else if (mDiff > 0) {
                        className += "past";
                    } else if (mDiff < 0) {
                        className += "future";
                    } else if (date === iterDate.getUTCDate()) {
                        className += "today";
                    } else {
                        className = "";
                    }

                    day
                        .set("class", className)
                        .data("ts", iterDate.getTime())
                        .value(iterDate.getUTCDate());
                });

                if (delta) {
                    currenDays[delta > 0 ? "after" : "before"](targetDays);
                    currenDays.hide(() => { currenDays.remove() });
                    targetDays.show();
                }
            }
        },
        _syncDateValue(time) {
            time.set("datetime", this.value());
        },
        _clickPicker(picker, calendarMonths, target) {
            var targetDate;

            if (target.matches("a")) {
                targetDate = new Date(this.value());

                if (!targetDate.getTime()) targetDate = new Date();

                var sign = target.next("a")[0] ? -1 : 1;

                if (picker.get("aria-expanded") === "true") {
                    targetDate.setUTCFullYear(targetDate.getUTCFullYear() + sign);
                } else {
                    targetDate.setUTCMonth(targetDate.getUTCMonth() + sign);
                }
            } else if (calendarMonths.contains(target)) {
                target = target.closest("time");

                targetDate = new Date(this.value());
                targetDate.setUTCMonth(new Date(target.get("datetime")).getUTCMonth());

                picker.hide();
            } else if (target.matches("td")) {
                targetDate = target.data("ts");

                if (targetDate) {
                    targetDate = new Date(targetDate);
                    picker.hide();
                }
            }

            if (targetDate != null) {
                var range = readDateRange(this);

                if (targetDate < range[0]) {
                    targetDate = range[0];
                } else if (targetDate > range[1]) {
                    targetDate = range[1];
                }

                this.value(formatISODate(targetDate)).fire("change");
            }
            // prevent input from loosing focus
            return false;
        },
        _keydownPicker(picker, calendarCaption, which) {
            var delta, currentDate;
            // ENTER key should submit form if calendar is hidden
            if (picker.matches(":hidden") && which === VK_ENTER) return true;

            if (which === VK_SPACE) {
                picker.toggle(); // SPACE key toggles calendar visibility
            } else if (which === VK_ESCAPE || which === VK_TAB || which === VK_ENTER) {
                picker.hide(); // ESC, TAB or ENTER keys hide calendar
            } else if (which === VK_BACKSPACE || which === VK_DELETE) {
                this.value("").fire("change"); // BACKSPACE, DELETE clear value
            } else if (which === VK_CONTROL) {
                calendarCaption.fire("click"); // CONTROL toggles calendar mode
            } else {
                currentDate = new Date(this.value());

                if (!currentDate.getTime()) currentDate = new Date();

                if (which === 74 || which === 40) { delta = 7; }
                else if (which === 75 || which === 38) { delta = -7; }
                else if (which === 76 || which === 39) { delta = 1; }
                else if (which === 72 || which === 37) { delta = -1; }

                if (delta) {
                    var expanded = picker.get("aria-expanded") === "true";

                    if (expanded && (which === 40 || which === 38)) {
                        currentDate.setUTCMonth(currentDate.getUTCMonth() + (delta > 0 ? 4 : -4));
                    } else if (expanded && (which === 37 || which === 39)) {
                        currentDate.setUTCMonth(currentDate.getUTCMonth() + (delta > 0 ? 1 : -1));
                    } else {
                        currentDate.setUTCDate(currentDate.getUTCDate() + delta);
                    }

                    var range = readDateRange(this);

                    if (!(currentDate < range[0] || currentDate > range[1])) {
                        this.value(formatISODate(currentDate)).fire("change");
                    }
                }
            }
            // prevent default action except if it was TAB so
            // do not allow to change the value manually
            return which === VK_TAB;
        },
        _blurPicker(picker) {
            picker.hide();
        },
        _focusPicker(picker) {
            if (this.get("readonly")) return false;

            var offset = this.offset();
            var pickerOffset = picker.offset();
            var marginTop = offset.height;

            // #3: move calendar to the top when passing cross browser window bounds
            if (HTML.clientHeight < offset.bottom + pickerOffset.height) {
                marginTop = -pickerOffset.height;
            }

            picker
                // always recalculate picker top position
                .css("margin-top", marginTop)
                // always reset picker mode to default
                .set("aria-expanded", "false")
                .show();

            // use the trick below to reset text selection on focus
            /* istanbul ignore next */
            setTimeout(() => {
                var node = this[0];

                if ("selectionStart" in node) {
                    node.selectionStart = 0;
                    node.selectionEnd = 0;
                } else {
                    var inputRange = node.createTextRange();

                    inputRange.moveStart("character", 0);
                    inputRange.collapse();
                    inputRange.moveEnd("character", 0);
                    inputRange.select();
                }
            }, 0);
        },
        _clickPickerCaption(picker, calendarCaption) {
            var expanded = picker.get("aria-expanded") === "true";

            picker.set("aria-expanded", String(!expanded));
            calendarCaption.set("data-format", expanded ? "MMMM yyyy" : "yyyy");
        },
        _clickLabel() {
            this.fire("focus");
        },
        _resetForm() {
            this.value(this.get("defaultValue"));
        }
    });
}(window.DOM, "btr-dateinput", 32, 9, 13, 27, 8, 46, 17));
<|endoftext|>


<commit_before>import Vue from 'vue'
import Router from 'vue-router'
import FastClick from 'fastclick'

import Vum from './vum.js'

// demos
import Index from './demos/Index'
import Page from './demos/Page'
import Buttons from './demos/Buttons'
import Column from './demos/Column'
import Grid from './demos/Grid'
import Modal from './demos/Modal'
import List from './demos/List'
import Contacts from './demos/Contacts'
import Form from './demos/Form'
import Icons from './demos/Icons'
import Tab from './demos/Tab'
import Scroll from './demos/Scroll'
import Popup from './demos/Popup'
import PopWindow from './demos/PopWindow'
import Preloader from './demos/Preloader'
import Actions from './demos/Actions'
import Toast from './demos/Toast'
import Searchbar from './demos/Searchbar'
import Calendar from './demos/Calendar'
import Result from './demos/result'
import Slide from './demos/Slide'
import SidePanel from './demos/SidePanel'
import Menu from './demos/Menu'
import Stars from './demos/Stars'
import CircleProgress from './demos/CircleProgress'

Vue.config.debug = true

Vue.use(Router)
Vue.use(Vum)

let App = Vue.extend()

let router = new Router()

router.map({
  '/': {
    name: 'index',
    component: Index
  },
  '/page': {
    component: Page
  },
  '/buttons': {
    component: Buttons
  },
  '/column': {
    component: Column
  },
  '/grid': {
    component: Grid
  },
  '/modal': {
    component: Modal
  },
  '/list': {
    component: List
  },
  '/contacts': {
    component: Contacts
  },
  '/form': {
    component: Form
  },
  '/icons': {
    name: 'icons',
    component: Icons
  },
  '/tab': {
    component: Tab
  },
  '/scroll': {
    component: Scroll
  },
  '/popup': {
    component: Popup
  },
  '/popwindow': {
    component: PopWindow
  },
  '/preloader': {
    component: Preloader
  },
  '/toast': {
    name: 'toast',
    component: Toast
  },
  '/actions': {
    component: Actions
  },
  '/searchbar': {
    component: Searchbar
  },
  '/calendar': {
    component: Calendar
  },
  '/result': {
    name: 'result',
    component: Result
  },
  '/slide': {
    name: 'slide',
    component: Slide
  },
  '/side-panel': {
    name: 'side-panel',
    component: SidePanel
  },
  '/menu': {
    name: 'menu',
    component: Menu
  },
  '/stars': {
    name: 'stars',
    component: Stars
  },
  '/circle': {
    name: 'circle',
    component: CircleProgress
  }
})

router.start(App, '#app')

Vum.router(router)

FastClick.attach(document.body)
<commit_msg>fix https://github.com/vum-team/vum/issues/29<commit_after>import Vue from 'vue'
import Router from 'vue-router'
import FastClick from 'fastclick'

import Vum from './vum.js'

// demos
import Index from './demos/Index'
import Page from './demos/Page'
import Buttons from './demos/Buttons'
import Column from './demos/Column'
import Grid from './demos/Grid'
import Modal from './demos/Modal'
import List from './demos/List'
import Contacts from './demos/Contacts'
import Form from './demos/Form'
import Icons from './demos/Icons'
import Tab from './demos/Tab'
import Scroll from './demos/Scroll'
import Popup from './demos/Popup'
import PopWindow from './demos/PopWindow'
import Preloader from './demos/Preloader'
import Actions from './demos/Actions'
import Toast from './demos/Toast'
import Searchbar from './demos/Searchbar'
import Calendar from './demos/Calendar'
import Result from './demos/Result'
import Slide from './demos/Slide'
import SidePanel from './demos/SidePanel'
import Menu from './demos/Menu'
import Stars from './demos/Stars'
import CircleProgress from './demos/CircleProgress'

Vue.config.debug = true

Vue.use(Router)
Vue.use(Vum)

let App = Vue.extend()

let router = new Router()

router.map({
  '/': {
    name: 'index',
    component: Index
  },
  '/page': {
    component: Page
  },
  '/buttons': {
    component: Buttons
  },
  '/column': {
    component: Column
  },
  '/grid': {
    component: Grid
  },
  '/modal': {
    component: Modal
  },
  '/list': {
    component: List
  },
  '/contacts': {
    component: Contacts
  },
  '/form': {
    component: Form
  },
  '/icons': {
    name: 'icons',
    component: Icons
  },
  '/tab': {
    component: Tab
  },
  '/scroll': {
    component: Scroll
  },
  '/popup': {
    component: Popup
  },
  '/popwindow': {
    component: PopWindow
  },
  '/preloader': {
    component: Preloader
  },
  '/toast': {
    name: 'toast',
    component: Toast
  },
  '/actions': {
    component: Actions
  },
  '/searchbar': {
    component: Searchbar
  },
  '/calendar': {
    component: Calendar
  },
  '/result': {
    name: 'result',
    component: Result
  },
  '/slide': {
    name: 'slide',
    component: Slide
  },
  '/side-panel': {
    name: 'side-panel',
    component: SidePanel
  },
  '/menu': {
    name: 'menu',
    component: Menu
  },
  '/stars': {
    name: 'stars',
    component: Stars
  },
  '/circle': {
    name: 'circle',
    component: CircleProgress
  }
})

router.start(App, '#app')

Vum.router(router)

FastClick.attach(document.body)
<|endoftext|>