<commit_before>/**
 * guy
 * 异步树
 * @class BI.TreeView
 * @extends BI.Pane
 */
BI.TreeView = BI.inherit(BI.Pane, {
    _defaultConfig: function () {
        return BI.extend(BI.TreeView.superclass._defaultConfig.apply(this, arguments), {
            baseCls: "bi-tree",
            paras: {},
            itemsCreator: BI.emptyFn
        })
    },
    _init: function () {
        BI.TreeView.superclass._init.apply(this, arguments);

        this._stop = false;
        this.container = BI.createWidget();

        this._createTree();
        this.tip = BI.createWidget({
            type: "bi.loading_bar",
            invisible: true,
            handler: BI.bind(this._loadMore, this)
        });
        BI.createWidget({
            type: "bi.vertical",
            scrollable: true,
            scrolly: false,
            element: this,
            items: [this.container, this.tip]
        });

    },

    _createTree: function () {
        this.id = "bi-tree" + BI.UUID();
        if (this.nodes) {
            this.nodes.destroy();
        }
        if (this.tree) {
            this.tree.destroy();
        }
        this.tree = BI.createWidget({
            type: "bi.layout",
            element: "

"
        });
        BI.createWidget({
            type: "bi.default",
            element: this.container,
            items: [this.tree]
        });
    },

    //选择节点触发方法
    _selectTreeNode: function (treeId, treeNode) {
        this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, treeNode, this);
        this.fireEvent(BI.TreeView.EVENT_CHANGE, treeNode, this);
    },

    //配置属性
    _configSetting: function () {
        var paras = this.options.paras;
        var self = this;
        var setting = {
            async: {
                enable: true,
                url: getUrl,
                autoParam: ["id", "name"],
                otherParam: BI.cjkEncodeDO(paras)
            },
            check: {
                enable: true
            },
            data: {
                key: {
                    title: "title",
                    name: "text"
                },
                simpleData: {
                    enable: true
                }
            },
            view: {
                showIcon: false,
                expandSpeed: "",
                nameIsHTML: true,
                dblClickExpand: false
            },
            callback: {
                beforeExpand: beforeExpand,
                onAsyncSuccess: onAsyncSuccess,
                onAsyncError: onAsyncError,
                beforeCheck: beforeCheck,
                onCheck: onCheck,
                onExpand: onExpand,
                onCollapse: onCollapse,
                onClick: onClick
            }
        };
        var className = "dark", perTime = 100;

        function onClick(event, treeId, treeNode) {
            self.nodes.checkNode(treeNode, !treeNode.checked, true, true);
        }

        function getUrl(treeId, treeNode) {
            var parentNode = self._getParentValues(treeNode);
            treeNode.times = treeNode.times || 1;
            var param = "id=" + treeNode.id
                + "&times=" + (treeNode.times++)
                + "&parent_values= " + window.encodeURIComponent(BI.jsonEncode(parentNode))
                + "&check_state=" + window.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus()));

            return BI.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param;
        }

        function beforeExpand(treeId, treeNode) {
            if (!treeNode.isAjaxing) {
                if (!treeNode.children) {
                    treeNode.times = 1;
                    ajaxGetNodes(treeNode, "refresh");
                }
                return true;
            } else {
                BI.Msg.toast("Please Wait。", "warning");
                return false;
            }
        }

        function onAsyncSuccess(event, treeId, treeNode, msg) {
            treeNode.halfCheck = false;
            if (!msg || msg.length === 0 || /^[\s,\S]*<\/html>$/gi.test(msg) || self._stop) {
                return;
            }
            var zTree = self.nodes;
            var totalCount = treeNode.count || 0;

            //尝试去获取下一组节点，若获取值为空数组，表示获取完成
            // TODO by GUY
            if (treeNode.children.length > totalCount) {
                treeNode.count = treeNode.children.length;
                BI.delay(function () {
                    ajaxGetNodes(treeNode);
                }, perTime);
            } else {
                //treeNode.icon = "";
                zTree.updateNode(treeNode);
                zTree.selectNode(treeNode.children[0]);
                //className = (className === "dark" ? "":"dark");
            }
        }

        function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
            var zTree = self.nodes;
            BI.Msg.toast("Error!", "warning");
            //treeNode.icon = "";
            //zTree.updateNode(treeNode);
        }

        function ajaxGetNodes(treeNode, reloadType) {
            var zTree = self.nodes;
            if (reloadType == "refresh") {
                //treeNode.icon = BI.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif";
                zTree.updateNode(treeNode);
            }
            zTree.reAsyncChildNodes(treeNode, reloadType, true);
        }

        function beforeCheck(treeId, treeNode) {
            treeNode.halfCheck = false;
            if (treeNode.checked === true) {
                //将展开的节点halfCheck设为false，解决展开节点存在halfCheck=true的情况 guy
                //所有的半选状态都需要取消halfCheck=true的情况
                function track(children) {
                    BI.each(children, function (i, ch) {
                        if (ch.halfCheck === true) {
                            ch.halfCheck = false;
                            track(ch.children);
                        }
                    })
                }

                track(treeNode.children);
                var treeObj = self.nodes;
                var nodes = treeObj.getSelectedNodes();
                $.each(nodes, function (index, node) {
                    node.halfCheck = false;
                })
            }
        }

        function onCheck(event, treeId, treeNode) {
            self._selectTreeNode(treeId, treeNode);
        }

        function onExpand(event, treeId, treeNode) {
            treeNode.halfCheck = false;
        }

        function onCollapse(event, treeId, treeNode) {
        }

        return setting;
    },

    _getParentValues: function (treeNode) {
        if (!treeNode.getParentNode()) {
            return [];
        }
        var parentNode = treeNode.getParentNode();
        var result = this._getParentValues(parentNode);
        result = result.concat([this._getNodeValue(parentNode)]);
        return result;
    },

    _getNodeValue: function (node) {
        //去除标红
        return node.value || node.text.replace(/<[^>]+>/g, "");
    },

    //获取半选框值
    _getHalfSelectedValues: function (map, node) {
        var self = this;
        var checkState = node.getCheckStatus();
        //将未选的去掉
        if (checkState.checked === false && checkState.half === false) {
            return;
        }
        //如果节点已展开,并且是半选
        if (BI.isNotEmptyArray(node.children) && checkState.half === true) {
            var children = node.children;
            BI.each(children, function (i, ch) {
                self._getHalfSelectedValues(map, ch);
            });
            return;
        }
        var parent = node.parentValues || self._getParentValues(node);
        var path = parent.concat(this._getNodeValue(node));
        if (BI.isNotEmptyArray(node.children) || checkState.half === false) {
            this._buildTree(map, path);
            return;
        }
        var storeValues = BI.deepClone(this.options.paras.selected_values);
        var treeNode = this._getTree(storeValues, path);
        this._addTreeNode(map, parent, this._getNodeValue(node), treeNode);
    },

    _getTree: function (map, values) {
        var cur = map;
        BI.any(values, function (i, value) {
            if (cur[value] == null) {
                return true;
            }
            cur = cur[value];
        });
        return cur;
    },

    _addTreeNode: function (map, values, key, value) {
        var cur = map;
        BI.each(values, function (i, value) {
            if (cur[value] == null) {
                cur[value] = {};
            }
            cur = cur[value];
        });
        cur[key] = value;
    },

    //构造树节点
    _buildTree: function (map, values) {
        var cur = map;
        BI.each(values, function (i, value) {
            if (cur[value] == null) {
                cur[value] = {};
            }
            cur = cur[value];
        })
    },

    //获取选中的值
    _getSelectedValues: function () {
        var self = this;
        var hashMap = {};
        var rootNoots = this.nodes.getNodes();
        track(rootNoots);
        function track(nodes) {
            BI.each(nodes, function (i, node) {
                var checkState = node.getCheckStatus();
                if (checkState.checked === true || checkState.half === true) {
                    if (checkState.half === true) {
                        self._getHalfSelectedValues(hashMap, node);
                    } else {
                        var parentValues = node.parentValues || self._getParentValues(node);
                        var values = parentValues.concat([self._getNodeValue(node)]);
                        self._buildTree(hashMap, values);
                    }
                }
            })
        }

        return hashMap;
    },

    //处理节点
    _dealWidthNodes: function (nodes) {
        var self = this, o = this.options;
        //处理标红
        if (BI.isKey(o.paras.keyword)) {
            var keyword = o.paras.keyword;
            var ns = BI.Tree.arrayFormat(nodes);
            BI.each(ns, function (i, n) {
                n.text = $("
").__textKeywordMarked__(n.text, keyword, n.py).html();
            });
        }
        return nodes;
    },

    _loadMore: function () {
        var self = this, o = this.options;
        this.tip.setLoading();
        var op = BI.extend({}, o.paras, {
            times: ++this.times
        });
        o.itemsCreator(op, function (res) {
            if (self._stop === true) {
                return;
            }
            var hasNext = !!res.hasNext, nodes = res.items || [];

            if (!hasNext) {
                self.tip.setEnd();
            } else {
                self.tip.setLoaded();
            }
            if (nodes.length > 0) {
                self.nodes.addNodes(null, self._dealWidthNodes(nodes));
            }
        });
    },

    //生成树内部方法
    _initTree: function (setting) {
        var self = this, o = this.options;
        self.fireEvent(BI.Events.INIT);
        this.times = 1;
        var tree = this.tree;
        tree.empty();
        this.loading();
        this.tip.setVisible(false);
        var callback = function (nodes) {
            if (self._stop === true) {
                return;
            }
            self.nodes = $.fn.zTree.init(tree.element, setting, nodes);
        };
        var op = BI.extend({}, o.paras, {
            times: 1,
            type: BI.TreeView.REQ_TYPE_INIT_DATA
        });

        o.itemsCreator(op, function (res) {
            if (self._stop === true) {
                return;
            }
            var hasNext = !!res.hasNext, nodes = res.items || [];
            if (nodes.length > 0) {
                callback(self._dealWidthNodes(nodes));
            }
            self.setTipVisible(nodes.length <= 0);
            self.loaded();
            if (!hasNext) {
                self.tip.invisible();
            } else {
                self.tip.setLoaded();
            }
            op.times === 1 && self.fireEvent(BI.Events.AFTERINIT);
        });
    },

    //构造树结构，
    initTree: function (nodes, setting) {
        var setting = setting || {
                async: {
                    enable: false
                },
                check: {
                    enable: false
                },
                data: {
                    key: {
                        title: "title",
                        name: "text"
                    },
                    simpleData: {
                        enable: true
                    }
                },
                view: {
                    showIcon: false,
                    expandSpeed: ""
                },
                callback: {}
            };
        this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes);
    },

    start: function () {
        this._stop = false;
    },

    stop: function () {
        this._stop = true;
    },

    //生成树方法
    stroke: function (config) {
        delete this.options.keyword;
        BI.extend(this.options.paras, config);
        var setting = this._configSetting();
        this._createTree();
        this.start();
        this._initTree(setting);
    },

    populate: function () {
        this.stroke.apply(this, arguments);
    },

    hasChecked: function () {
        var treeObj = this.nodes;
        return treeObj.getCheckedNodes(true).length > 0;
    },

    checkAll: function (checked) {
        this.nodes && this.nodes.checkAllNodes(checked);
    },

    expandAll: function (flag) {
        this.nodes && this.nodes.expandAll(flag);
    },

    setValue: function (value, param) {
        this.setSelectedValue(value);
        this.checkAll(false);
        this.updateValue(value, param);
        this.refresh();
    },

    setSelectedValue: function (value) {
        this.options.paras.selected_values = value || {};
        this.selected_values = BI.deepClone(value) || {};
    },

    updateValue: function (values, param) {
        if (!this.nodes) {
            return;
        }
        param || (param = "value");
        var treeObj = this.nodes;
        BI.each(values, function (v, op) {
            var nodes = treeObj.getNodesByParam(param, v, null);
            BI.each(nodes, function (j, node) {
                BI.extend(node, {checked: true}, op);
                treeObj.updateNode(node);
            })
        });
    },

    refresh: function () {
        this.nodes && this.nodes.refresh();
    },

    getValue: function () {
        if (!this.nodes) {
            return null;
        }
        return this._getSelectedValues();
    },

    empty: function () {
        BI.isNotNull(this.nodes) && this.nodes.destroy();
    },

    destroy: function () {
        this.stop();
        this.nodes && this.nodes.destroy();
        BI.TreeView.superclass.destroy.apply(this, arguments);
    }
});
BI.extend(BI.TreeView, {
    REQ_TYPE_INIT_DATA: 1,
    REQ_TYPE_ADJUST_DATA: 2,
    REQ_TYPE_CALCULATE_SELECT_DATA: 3,
    REQ_TYPE_SELECTED_DATA: 4
});

BI.TreeView.EVENT_CHANGE = "EVENT_CHANGE";
BI.TreeView.EVENT_INIT = BI.Events.INIT;
BI.TreeView.EVENT_AFTERINIT = BI.Events.AFTERINIT;

$.shortcut("bi.tree_view", BI.TreeView);<commit_msg>update<commit_after>/**
 * guy
 * 异步树
 * @class BI.TreeView
 * @extends BI.Pane
 */
BI.TreeView = BI.inherit(BI.Pane, {
    _defaultConfig: function () {
        return BI.extend(BI.TreeView.superclass._defaultConfig.apply(this, arguments), {
            baseCls: "bi-tree",
            paras: {},
            itemsCreator: BI.emptyFn
        })
    },
    _init: function () {
        BI.TreeView.superclass._init.apply(this, arguments);

        this._stop = false;
        this.container = BI.createWidget();

        this._createTree();
        this.tip = BI.createWidget({
            type: "bi.loading_bar",
            invisible: true,
            handler: BI.bind(this._loadMore, this)
        });
        BI.createWidget({
            type: "bi.vertical",
            scrollable: true,
            scrolly: false,
            element: this,
            items: [this.container, this.tip]
        });

    },

    _createTree: function () {
        this.id = "bi-tree" + BI.UUID();
        if (this.nodes) {
            this.nodes.destroy();
        }
        if (this.tree) {
            this.tree.destroy();
        }
        this.tree = BI.createWidget({
            type: "bi.layout",
            element: "

"
        });
        BI.createWidget({
            type: "bi.default",
            element: this.container,
            items: [this.tree]
        });
    },

    //选择节点触发方法
    _selectTreeNode: function (treeId, treeNode) {
        this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, treeNode, this);
        this.fireEvent(BI.TreeView.EVENT_CHANGE, treeNode, this);
    },

    //配置属性
    _configSetting: function () {
        var paras = this.options.paras;
        var self = this;
        var setting = {
            async: {
                enable: true,
                url: getUrl,
                autoParam: ["id", "name"],
                otherParam: BI.cjkEncodeDO(paras)
            },
            check: {
                enable: true
            },
            data: {
                key: {
                    title: "title",
                    name: "text"
                },
                simpleData: {
                    enable: true
                }
            },
            view: {
                showIcon: false,
                expandSpeed: "",
                nameIsHTML: true,
                dblClickExpand: false
            },
            callback: {
                beforeExpand: beforeExpand,
                onAsyncSuccess: onAsyncSuccess,
                onAsyncError: onAsyncError,
                beforeCheck: beforeCheck,
                onCheck: onCheck,
                onExpand: onExpand,
                onCollapse: onCollapse,
                onClick: onClick
            }
        };
        var className = "dark", perTime = 100;

        function onClick(event, treeId, treeNode) {
            self.nodes.checkNode(treeNode, !treeNode.checked, true, true);
        }

        function getUrl(treeId, treeNode) {
            var parentNode = self._getParentValues(treeNode);
            treeNode.times = treeNode.times || 1;
            var param = "id=" + treeNode.id
                + "&times=" + (treeNode.times++)
                + "&parent_values= " + window.encodeURIComponent(BI.jsonEncode(parentNode))
                + "&check_state=" + window.encodeURIComponent(BI.jsonEncode(treeNode.getCheckStatus()));

            return BI.servletURL + '?op=' + self.options.op + '&cmd=' + self.options.cmd + "&" + param;
        }

        function beforeExpand(treeId, treeNode) {
            if (!treeNode.isAjaxing) {
                if (!treeNode.children) {
                    treeNode.times = 1;
                    ajaxGetNodes(treeNode, "refresh");
                }
                return true;
            } else {
                BI.Msg.toast("Please Wait。", "warning");
                return false;
            }
        }

        function onAsyncSuccess(event, treeId, treeNode, msg) {
            treeNode.halfCheck = false;
            if (!msg || msg.length === 0 || /^[\s,\S]*<\/html>$/gi.test(msg) || self._stop) {
                return;
            }
            var zTree = self.nodes;
            var totalCount = treeNode.count || 0;

            //尝试去获取下一组节点，若获取值为空数组，表示获取完成
            // TODO by GUY
            if (treeNode.children.length > totalCount) {
                treeNode.count = treeNode.children.length;
                BI.delay(function () {
                    ajaxGetNodes(treeNode);
                }, perTime);
            } else {
                //treeNode.icon = "";
                zTree.updateNode(treeNode);
                zTree.selectNode(treeNode.children[0]);
                //className = (className === "dark" ? "":"dark");
            }
        }

        function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
            var zTree = self.nodes;
            BI.Msg.toast("Error!", "warning");
            //treeNode.icon = "";
            //zTree.updateNode(treeNode);
        }

        function ajaxGetNodes(treeNode, reloadType) {
            var zTree = self.nodes;
            if (reloadType == "refresh") {
                //treeNode.icon = BI.servletURL +"?op=resource&resource=/com/fr/bi/web/css/base/third/ztree/img/loading.gif";
                zTree.updateNode(treeNode);
            }
            zTree.reAsyncChildNodes(treeNode, reloadType, true);
        }

        function beforeCheck(treeId, treeNode) {
            treeNode.halfCheck = false;
            if (treeNode.checked === true) {
                //将展开的节点halfCheck设为false，解决展开节点存在halfCheck=true的情况 guy
                //所有的半选状态都需要取消halfCheck=true的情况
                function track(children) {
                    BI.each(children, function (i, ch) {
                        if (ch.halfCheck === true) {
                            ch.halfCheck = false;
                            track(ch.children);
                        }
                    })
                }

                track(treeNode.children);
                var treeObj = self.nodes;
                var nodes = treeObj.getSelectedNodes();
                $.each(nodes, function (index, node) {
                    node.halfCheck = false;
                })
            }
        }

        function onCheck(event, treeId, treeNode) {
            self._selectTreeNode(treeId, treeNode);
        }

        function onExpand(event, treeId, treeNode) {
            treeNode.halfCheck = false;
        }

        function onCollapse(event, treeId, treeNode) {
        }

        return setting;
    },

    _getParentValues: function (treeNode) {
        if (!treeNode.getParentNode()) {
            return [];
        }
        var parentNode = treeNode.getParentNode();
        var result = this._getParentValues(parentNode);
        result = result.concat([this._getNodeValue(parentNode)]);
        return result;
    },

    _getNodeValue: function (node) {
        //去除标红
        return node.value || node.text.replace(/<[^>]+>/g, "");
    },

    //获取半选框值
    _getHalfSelectedValues: function (map, node) {
        var self = this;
        var checkState = node.getCheckStatus();
        //将未选的去掉
        if (checkState.checked === false && checkState.half === false) {
            return;
        }
        //如果节点已展开,并且是半选
        if (BI.isNotEmptyArray(node.children) && checkState.half === true) {
            var children = node.children;
            BI.each(children, function (i, ch) {
                self._getHalfSelectedValues(map, ch);
            });
            return;
        }
        var parent = node.parentValues || self._getParentValues(node);
        var path = parent.concat(this._getNodeValue(node));
        if (BI.isNotEmptyArray(node.children) || checkState.half === false) {
            this._buildTree(map, path);
            return;
        }
        var storeValues = BI.deepClone(this.options.paras.selected_values);
        var treeNode = this._getTree(storeValues, path);
        this._addTreeNode(map, parent, this._getNodeValue(node), treeNode);
    },

    _getTree: function (map, values) {
        var cur = map;
        BI.any(values, function (i, value) {
            if (cur[value] == null) {
                return true;
            }
            cur = cur[value];
        });
        return cur;
    },

    _addTreeNode: function (map, values, key, value) {
        var cur = map;
        BI.each(values, function (i, value) {
            if (cur[value] == null) {
                cur[value] = {};
            }
            cur = cur[value];
        });
        cur[key] = value;
    },

    //构造树节点
    _buildTree: function (map, values) {
        var cur = map;
        BI.each(values, function (i, value) {
            if (cur[value] == null) {
                cur[value] = {};
            }
            cur = cur[value];
        })
    },

    //获取选中的值
    _getSelectedValues: function () {
        var self = this;
        var hashMap = {};
        var rootNoots = this.nodes.getNodes();
        track(rootNoots);
        function track(nodes) {
            BI.each(nodes, function (i, node) {
                var checkState = node.getCheckStatus();
                if (checkState.checked === true || checkState.half === true) {
                    if (checkState.half === true) {
                        self._getHalfSelectedValues(hashMap, node);
                    } else {
                        var parentValues = node.parentValues || self._getParentValues(node);
                        var values = parentValues.concat([self._getNodeValue(node)]);
                        self._buildTree(hashMap, values);
                    }
                }
            })
        }

        return hashMap;
    },

    //处理节点
    _dealWidthNodes: function (nodes) {
        var self = this, o = this.options;
        //处理标红
        if (BI.isKey(o.paras.keyword)) {
            var keyword = o.paras.keyword;
            var ns = BI.Tree.arrayFormat(nodes);
            BI.each(ns, function (i, n) {
                n.text = $("
").__textKeywordMarked__(n.text, keyword, n.py).html();
            });
        }
        return nodes;
    },

    _loadMore: function () {
        var self = this, o = this.options;
        this.tip.setLoading();
        var op = BI.extend({}, o.paras, {
            times: ++this.times
        });
        o.itemsCreator(op, function (res) {
            if (self._stop === true) {
                return;
            }
            var hasNext = !!res.hasNext, nodes = res.items || [];

            if (!hasNext) {
                self.tip.setEnd();
            } else {
                self.tip.setLoaded();
            }
            if (nodes.length > 0) {
                self.nodes.addNodes(null, self._dealWidthNodes(nodes));
            }
        });
    },

    //生成树内部方法
    _initTree: function (setting) {
        var self = this, o = this.options;
        self.fireEvent(BI.Events.INIT);
        this.times = 1;
        var tree = this.tree;
        tree.empty();
        this.loading();
        this.tip.setVisible(false);
        var callback = function (nodes) {
            if (self._stop === true) {
                return;
            }
            self.nodes = $.fn.zTree.init(tree.element, setting, nodes);
        };
        var op = BI.extend({}, o.paras, {
            times: 1,
            type: BI.TreeView.REQ_TYPE_INIT_DATA
        });

        o.itemsCreator(op, function (res) {
            if (self._stop === true) {
                return;
            }
            var hasNext = !!res.hasNext, nodes = res.items || [];
            if (nodes.length > 0) {
                callback(self._dealWidthNodes(nodes));
            }
            self.setTipVisible(nodes.length <= 0);
            self.loaded();
            if (!hasNext) {
                self.tip.invisible();
            } else {
                self.tip.setLoaded();
            }
            op.times === 1 && self.fireEvent(BI.Events.AFTERINIT);
        });
    },

    //构造树结构，
    initTree: function (nodes, setting) {
        var setting = setting || {
                async: {
                    enable: false
                },
                check: {
                    enable: false
                },
                data: {
                    key: {
                        title: "title",
                        name: "text"
                    },
                    simpleData: {
                        enable: true
                    }
                },
                view: {
                    showIcon: false,
                    expandSpeed: ""
                },
                callback: {}
            };
        this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes);
    },

    start: function () {
        this._stop = false;
    },

    stop: function () {
        this._stop = true;
    },

    //生成树方法
    stroke: function (config) {
        delete this.options.keyword;
        BI.extend(this.options.paras, config);
        var setting = this._configSetting();
        this._createTree();
        this.start();
        this._initTree(setting);
    },

    populate: function () {
        this.stroke.apply(this, arguments);
    },

    hasChecked: function () {
        var treeObj = this.nodes;
        return treeObj.getCheckedNodes(true).length > 0;
    },

    checkAll: function (checked) {
        this.nodes && this.nodes.checkAllNodes(checked);
    },

    expandAll: function (flag) {
        this.nodes && this.nodes.expandAll(flag);
    },

    setValue: function (value, param) {
        this.setSelectedValue(value);
        this.checkAll(false);
        this.updateValue(value, param);
        this.refresh();
    },

    setSelectedValue: function (value) {
        this.options.paras.selected_values = value || {};
        this.selected_values = BI.deepClone(value) || {};
    },

    updateValue: function (values, param) {
        if (!this.nodes) {
            return;
        }
        param || (param = "value");
        var treeObj = this.nodes;
        BI.each(values, function (v, op) {
            var nodes = treeObj.getNodesByParam(param, v, null);
            BI.each(nodes, function (j, node) {
                BI.extend(node, {checked: true}, op);
                treeObj.updateNode(node);
            })
        });
    },

    refresh: function () {
        this.nodes && this.nodes.refresh();
    },

    getValue: function () {
        if (!this.nodes) {
            return null;
        }
        return this._getSelectedValues();
    },

    empty: function () {
        BI.isNotNull(this.nodes) && this.nodes.destroy();
    },

    destroy: function () {
        this.stop();
        this.nodes && this.nodes.destroy();
        BI.TreeView.superclass.destroy.apply(this, arguments);
    }
});
BI.extend(BI.TreeView, {
    REQ_TYPE_INIT_DATA: 0,
    REQ_TYPE_ADJUST_DATA: 1,
    REQ_TYPE_CALCULATE_SELECT_DATA: 2,
    REQ_TYPE_SELECTED_DATA: 3
});

BI.TreeView.EVENT_CHANGE = "EVENT_CHANGE";
BI.TreeView.EVENT_INIT = BI.Events.INIT;
BI.TreeView.EVENT_AFTERINIT = BI.Events.AFTERINIT;

$.shortcut("bi.tree_view", BI.TreeView);<|endoftext|>


<commit_before>function importPanel(container) {
    container.html('');
    var wrap = container.append('div').attr('class', 'pad1');

    var importSupport = !!(window.FileReader);

    wrap.append('p')
        .attr('class', 'intro')
        .text('Make a map! To start, draw with the tools on the left or import your own data.');

    wrap.append('div')
        .attr('class', 'modal-message')
        .text('Drop files to map!');

    function over() {
        d3.event.stopPropagation();
        d3.event.preventDefault();
        d3.event.dataTransfer.dropEffect = 'copy';
        d3.select('body').classed('dragover', true);
    }

    function exit() {
        d3.event.stopPropagation();
        d3.event.preventDefault();
        d3.event.dataTransfer.dropEffect = 'copy';
        d3.select('body').classed('dragover', false);
    }

    function toDom(x) {
        return (new DOMParser()).parseFromString(x, 'text/xml');
    }

    function trackImport(format, method) {
        analytics.track('Imported Data / ' + method + ' / ' + format);
    }

    function detectIndentationStyle(f) {
        var lines = f.split('\n');
        if (lines.length < 2) return 4;
        var indent = lines[1].match(/^(\s*)/);
        if (!indent || !indent.length) return 4;
        if (indent[0][0] == '\t') {
            return '\t';
        } else {
            return indent[0].length;
        }
    }

    function readFile(f, method) {
        var reader = new FileReader();
        import_landing.classed('dragover', false);

        reader.onload = function(e) {
            var gj;
            var filename = f.name ? f.name.toLowerCase() : '';
            function ext(_) {
                return filename.indexOf(_) !== -1;
            }
            if (f.type === 'application/vnd.google-earth.kml+xml' || ext('.kml')) {
                gj = toGeoJSON.kml(toDom(e.target.result));
                trackImport('KML', method);
            } else if (ext('.gpx')) {
                gj = toGeoJSON.gpx(toDom(e.target.result));
                trackImport('GPX', method);
            } else if (ext('.geojson') || ext('.json')) {
                try {
                    gj = JSON.parse(e.target.result);
                    exportIndentationStyle = detectIndentationStyle(e.target.result);
                    if (gj && gj.type === 'Topology' && gj.objects) {
                        var collection = { type: 'FeatureCollection', features: [] };
                        for (var o in gj.objects) collection.features.push(topojson.feature(gj, gj.objects[o]));
                        gj = collection;
                        trackImport('TopoJSON', method);
                    } else {
                        trackImport('GeoJSON', method);
                    }
                } catch(err) {
                    alert('Invalid JSON file: ' + err);
                    analytics.track('Uploaded invalid JSON');
                    Raven.captureException(err);
                    return;
                }
            } else if (f.type === 'text/csv' || ext('.csv')) {
                gj = csv2geojson.csv2geojson(e.target.result);
                if (gj.type === 'Error') {
                    return handleGeocode(container.append('div'), e.target.result);
                }
                trackImport('CSV', method);
            } else {
                analytics.track('Failed to upload a file with type ' + f.type);
                return alert('Sorry, that file type is not supported');
            }
            if (gj) {
                updates.update_editor(gj);
                updates.zoom_extent();
            }
        };

        reader.readAsText(f);
    }

    if (importSupport) {

        d3.select('body')
            .attr('dropzone', 'copy')
            .on('drop.localgpx', function() {
                d3.event.stopPropagation();
                d3.event.preventDefault();
                d3.select('body').classed('dragover', false);
                var f = d3.event.dataTransfer.files[0];
                readFile(f, 'drag');
            })
            .on('dragenter.localgpx', over)
            .on('dragexit.localgpx', exit)
            .on('dragover.localgpx', over);

        var import_landing = wrap.append('div')
            .attr('class', 'pad fillL');

        var message = import_landing
            .append('div')
            .attr('class', 'center');

        message.append('span').attr('class', 'icon-arrow-down');
        message.append('span').text(' Drop a GeoJSON, TopoJSON, KML, CSV, or GPX file or ');
        message.append('button').text('Choose a file to upload')
            .on('click', function() {
                fileInput.node().click();
            });
        var fileInput = message
            .append('input')
            .attr('type', 'file')
            .style('visibility', 'hidden')
            .style('position', 'absolute')
            .style('height', '0')
            .on('change', function() {
                if (this.files && this.files[0]) readFile(this.files[0], 'click');
            });
    } else {
        wrap.append('p')
            .attr('class', 'blank-banner')
            .text('Sorry, geojson.io supports importing GeoJSON, GPX, KML, and CSV files, but ' +
                  'your browser isn\'t compatible. Please use Google Chrome, Safari 6, IE10, Firefox, or Opera for an optimal experience.');
    }
    wrap.append('p')
        .attr('class', 'intro')
        .style('text-align', 'center')
        .style('color', '#888')
        .html('Submit feedback or get help');

    if (window.chrome) wrap.append('p')
        .attr('class', 'intro-hint pad1')
        .style('color', '#888')
        .html('Use GitHub? The geojson.io chrome extension lets you edit map data in your repositories!');

    wrap.append('div')
        .attr('class', 'pad1');
}

function handleGeocode(container, text) {

    analytics.track('A CSV Required Geocoding');

    var list = csv2geojson.csv(text);

    var button = container.append('div')
        .attr('class', 'bucket-actions')
        .append('button')
        .attr('class', 'major')
        .attr('disabled', true)
        .text('At least one field required to geocode');

    var join = container.append('div')
        .attr('class', 'bucket-deposit')
        .append('div')
        .attr('class', 'bucket-join');

    var buckets = join.selectAll('.bucket')
        .data(['City', 'State', 'ZIP', 'Country'])
        .enter()
        .append('div')
        .attr('class', 'bucket')
        .text(String);

    var example = container.append('div')
        .attr('class', 'example');

    var store = container.append('div')
       .attr('class', 'bucket-store');

    var sources = store.selectAll('bucket-source')
       .data(Object.keys(list[0]))
       .enter()
       .append('div')
       .attr('class', 'bucket-source')
       .text(String);

    function transformRow(fields) {
        return function(obj) {
           return d3.entries(obj)
               .filter(function(e) { return fields.indexOf(e.key) !== -1; })
               .map(function(e) { return e.value; })
               .join(', ');
        };
    }

    function showExample(fields) {
        var i = 0;
        return function() {
            if (++i > list.length) i = 0;
            example.html('');
            example.text(transformRow(fields)(list[i]));
        };
    }

    var ti;
    var broker = bucket();
    buckets.call(broker.deposit());
    sources.call(broker.store().on('chosen', onChosen));

    function onChosen(fields) {
         if (ti) window.clearInterval(ti);
         if (fields.length) {
             button.attr('disabled', null)
                .text('Geocode');
             button.on('click', function() {
                 analytics.track('Ran a Geocode batch');
                 runGeocode(container, list, transformRow(fields));
             });
             var se = showExample(fields);
             se();
             ti = window.setInterval(se, 2000);
         } else {
             button.attr('disabled', true)
                .text('At least one field required to geocode');
             example.text('');
         }
     }
}

function runGeocode(container, list, transform) {
    container.html('');

    var wrap = container.append('div').attr('class', 'pad1');

    var doneBtn = wrap.append('div')
        .style('text-align', 'center')
        .style('padding', '10px')
        .append('button')
        .attr('class', 'major')
        .text('Close')
        .on('click', function() {
            container.html('');
            if (task) task();
        });

    var chartDiv = wrap.append('div');
    var failedDiv = wrap.append('div');

    var geocode = geocodemany('tmcw.map-u4ca5hnt');

    function progressChart(elem, w, h) {
        var c = elem.appendChild(document.createElement('canvas'));
        c.width = w;
        c.height = h;
        var ctx = c.getContext('2d');
        var gap;
        var fill = {
            success: '#e3e4b8',
            error: '#E0A990'
        };

        return function(e) {
            if (!gap) gap = ((e.done) / e.todo * w) - ((e.done - 1) / e.todo * w);
            ctx.fillStyle = fill[e.status];
            ctx.fillRect((e.done - 1) / e.todo * w, 0, gap, h);
        };
    }

    var chart = progressChart(chartDiv.node(), chartDiv.node().offsetWidth, 50);

    function progress(e) {
        chart(e);
    }

    function printObj(o) {
        return '(' + d3.entries(o)
            .map(function(_) {
                return _.key + ': ' + _.value;
            }).join(',') + ')';
    }

    function done(failed, completed) {

        failedDiv
            .selectAll('.fail')
            .data(failed)
            .enter()
            .append('div')
            .attr('class', 'fail')
            .text(function(d) {
                return 'failed: ' + transform(d.data) + ' / ' + printObj(d.data);
            });

        updates.update_editor(csv2geojson.csv2geojson(completed));
    }

    var task = geocode(list, transform, progress, done);
}
<commit_msg>Fix another regression.<commit_after>function detectIndentationStyle(f) {
    var lines = f.split('\n');
    if (lines.length < 2) return 4;
    var indent = lines[1].match(/^(\s*)/);
    if (!indent || !indent.length) return 4;
    if (indent[0][0] == '\t') {
        return '\t';
    } else {
        return indent[0].length;
    }
}

function importPanel(container) {
    container.html('');
    var wrap = container.append('div').attr('class', 'pad1');

    var importSupport = !!(window.FileReader);

    wrap.append('p')
        .attr('class', 'intro')
        .text('Make a map! To start, draw with the tools on the left or import your own data.');

    wrap.append('div')
        .attr('class', 'modal-message')
        .text('Drop files to map!');

    function over() {
        d3.event.stopPropagation();
        d3.event.preventDefault();
        d3.event.dataTransfer.dropEffect = 'copy';
        d3.select('body').classed('dragover', true);
    }

    function exit() {
        d3.event.stopPropagation();
        d3.event.preventDefault();
        d3.event.dataTransfer.dropEffect = 'copy';
        d3.select('body').classed('dragover', false);
    }

    function toDom(x) {
        return (new DOMParser()).parseFromString(x, 'text/xml');
    }

    function trackImport(format, method) {
        analytics.track('Imported Data / ' + method + ' / ' + format);
    }

    function readFile(f, method) {
        var reader = new FileReader();
        import_landing.classed('dragover', false);

        reader.onload = function(e) {
            var gj;
            var filename = f.name ? f.name.toLowerCase() : '';
            function ext(_) {
                return filename.indexOf(_) !== -1;
            }
            if (f.type === 'application/vnd.google-earth.kml+xml' || ext('.kml')) {
                gj = toGeoJSON.kml(toDom(e.target.result));
                trackImport('KML', method);
            } else if (ext('.gpx')) {
                gj = toGeoJSON.gpx(toDom(e.target.result));
                trackImport('GPX', method);
            } else if (ext('.geojson') || ext('.json')) {
                try {
                    gj = JSON.parse(e.target.result);
                    exportIndentationStyle = detectIndentationStyle(e.target.result);
                    if (gj && gj.type === 'Topology' && gj.objects) {
                        var collection = { type: 'FeatureCollection', features: [] };
                        for (var o in gj.objects) collection.features.push(topojson.feature(gj, gj.objects[o]));
                        gj = collection;
                        trackImport('TopoJSON', method);
                    } else {
                        trackImport('GeoJSON', method);
                    }
                } catch(err) {
                    alert('Invalid JSON file: ' + err);
                    analytics.track('Uploaded invalid JSON');
                    Raven.captureException(err);
                    return;
                }
            } else if (f.type === 'text/csv' || ext('.csv')) {
                gj = csv2geojson.csv2geojson(e.target.result);
                if (gj.type === 'Error') {
                    return handleGeocode(container.append('div'), e.target.result);
                }
                trackImport('CSV', method);
            } else {
                analytics.track('Failed to upload a file with type ' + f.type);
                return alert('Sorry, that file type is not supported');
            }
            if (gj) {
                updates.update_editor(gj);
                updates.zoom_extent();
            }
        };

        reader.readAsText(f);
    }

    if (importSupport) {

        d3.select('body')
            .attr('dropzone', 'copy')
            .on('drop.localgpx', function() {
                d3.event.stopPropagation();
                d3.event.preventDefault();
                d3.select('body').classed('dragover', false);
                var f = d3.event.dataTransfer.files[0];
                readFile(f, 'drag');
            })
            .on('dragenter.localgpx', over)
            .on('dragexit.localgpx', exit)
            .on('dragover.localgpx', over);

        var import_landing = wrap.append('div')
            .attr('class', 'pad fillL');

        var message = import_landing
            .append('div')
            .attr('class', 'center');

        message.append('span').attr('class', 'icon-arrow-down');
        message.append('span').text(' Drop a GeoJSON, TopoJSON, KML, CSV, or GPX file or ');
        message.append('button').text('Choose a file to upload')
            .on('click', function() {
                fileInput.node().click();
            });
        var fileInput = message
            .append('input')
            .attr('type', 'file')
            .style('visibility', 'hidden')
            .style('position', 'absolute')
            .style('height', '0')
            .on('change', function() {
                if (this.files && this.files[0]) readFile(this.files[0], 'click');
            });
    } else {
        wrap.append('p')
            .attr('class', 'blank-banner')
            .text('Sorry, geojson.io supports importing GeoJSON, GPX, KML, and CSV files, but ' +
                  'your browser isn\'t compatible. Please use Google Chrome, Safari 6, IE10, Firefox, or Opera for an optimal experience.');
    }
    wrap.append('p')
        .attr('class', 'intro')
        .style('text-align', 'center')
        .style('color', '#888')
        .html('Submit feedback or get help');

    if (window.chrome) wrap.append('p')
        .attr('class', 'intro-hint pad1')
        .style('color', '#888')
        .html('Use GitHub? The geojson.io chrome extension lets you edit map data in your repositories!');

    wrap.append('div')
        .attr('class', 'pad1');
}

function handleGeocode(container, text) {

    analytics.track('A CSV Required Geocoding');

    var list = csv2geojson.csv(text);

    var button = container.append('div')
        .attr('class', 'bucket-actions')
        .append('button')
        .attr('class', 'major')
        .attr('disabled', true)
        .text('At least one field required to geocode');

    var join = container.append('div')
        .attr('class', 'bucket-deposit')
        .append('div')
        .attr('class', 'bucket-join');

    var buckets = join.selectAll('.bucket')
        .data(['City', 'State', 'ZIP', 'Country'])
        .enter()
        .append('div')
        .attr('class', 'bucket')
        .text(String);

    var example = container.append('div')
        .attr('class', 'example');

    var store = container.append('div')
       .attr('class', 'bucket-store');

    var sources = store.selectAll('bucket-source')
       .data(Object.keys(list[0]))
       .enter()
       .append('div')
       .attr('class', 'bucket-source')
       .text(String);

    function transformRow(fields) {
        return function(obj) {
           return d3.entries(obj)
               .filter(function(e) { return fields.indexOf(e.key) !== -1; })
               .map(function(e) { return e.value; })
               .join(', ');
        };
    }

    function showExample(fields) {
        var i = 0;
        return function() {
            if (++i > list.length) i = 0;
            example.html('');
            example.text(transformRow(fields)(list[i]));
        };
    }

    var ti;
    var broker = bucket();
    buckets.call(broker.deposit());
    sources.call(broker.store().on('chosen', onChosen));

    function onChosen(fields) {
         if (ti) window.clearInterval(ti);
         if (fields.length) {
             button.attr('disabled', null)
                .text('Geocode');
             button.on('click', function() {
                 analytics.track('Ran a Geocode batch');
                 runGeocode(container, list, transformRow(fields));
             });
             var se = showExample(fields);
             se();
             ti = window.setInterval(se, 2000);
         } else {
             button.attr('disabled', true)
                .text('At least one field required to geocode');
             example.text('');
         }
     }
}

function runGeocode(container, list, transform) {
    container.html('');

    var wrap = container.append('div').attr('class', 'pad1');

    var doneBtn = wrap.append('div')
        .style('text-align', 'center')
        .style('padding', '10px')
        .append('button')
        .attr('class', 'major')
        .text('Close')
        .on('click', function() {
            container.html('');
            if (task) task();
        });

    var chartDiv = wrap.append('div');
    var failedDiv = wrap.append('div');

    var geocode = geocodemany('tmcw.map-u4ca5hnt');

    function progressChart(elem, w, h) {
        var c = elem.appendChild(document.createElement('canvas'));
        c.width = w;
        c.height = h;
        var ctx = c.getContext('2d');
        var gap;
        var fill = {
            success: '#e3e4b8',
            error: '#E0A990'
        };

        return function(e) {
            if (!gap) gap = ((e.done) / e.todo * w) - ((e.done - 1) / e.todo * w);
            ctx.fillStyle = fill[e.status];
            ctx.fillRect((e.done - 1) / e.todo * w, 0, gap, h);
        };
    }

    var chart = progressChart(chartDiv.node(), chartDiv.node().offsetWidth, 50);

    function progress(e) {
        chart(e);
    }

    function printObj(o) {
        return '(' + d3.entries(o)
            .map(function(_) {
                return _.key + ': ' + _.value;
            }).join(',') + ')';
    }

    function done(failed, completed) {

        failedDiv
            .selectAll('.fail')
            .data(failed)
            .enter()
            .append('div')
            .attr('class', 'fail')
            .text(function(d) {
                return 'failed: ' + transform(d.data) + ' / ' + printObj(d.data);
            });

        updates.update_editor(csv2geojson.csv2geojson(completed));
    }

    var task = geocode(list, transform, progress, done);
}
<|endoftext|>


<commit_before>var indent = (function() {
    var rulesCache = {};

    function filterRules(language) {
        if (rulesCache[language])
            return rulesCache[language];
        var ret = [];
        rulesCache[language] = ret;
        for (var i=0; i<masterRules.length; i++) {
            if (masterRules[i].langs.indexOf(language.toLowerCase()) != -1)
                ret.push(masterRules[i]);
        }
        return ret;
    }

    var NEW_LINE_REGEX = /\r*\n/;

    /**
     * indent - whether rule will cause indent
     * ignore - ignore further rule matching as long as this is last active rule, e.g. string, comments
     * advance - advance the cursor to the end of the endTokens
     * endTokenIndent - keep the indent rule active for the endTokens
     * head - match at beginning of line only
     * langs - used to filter by language later
     * lineOffset - added to the line field when rule is applied
     *
     * Always keep NEW_LINE_REGEX endToken as last element,
     * as otherwise it will be matched first, and subsequent ones may be ignored
     * and skipped permanently by other rules.
     */
    var masterRules = [
        {
            langs: "html",
            name: "comment",
            startToken: [/\<\!\-\-/],
            endToken: [/\-\-\>/],
            ignore: true,
            advance: true
        },
        {
            langs: "html",
            name: "doctype",
            startToken: [/\<\!/],
            endToken: [NEW_LINE_REGEX],
            ignore: true,
            advance: true
        },
        {
            langs: "html",
            name: "link|br|hr|input|img|meta",
            startToken: [/\<(link|br|hr|input|img|meta)/i],
            endToken: [/>/],
            advance: true
        },
        {
            langs: "html",
            name: "mode switch js",
            startToken: [function (string, rule) {
                var start = /<script[\s>].*/i;
                var end = /<\/script>/i;
                var startMatch = start.exec(string);
                var endMatch = end.exec(string);

                if (startMatch && (!endMatch || endMatch.index < startMatch.index)) {
                    return {
                        matchIndex: startMatch.index,
                        length: startMatch[0].length
                    };
                }
                return {matchIndex: -1};
            }],
            endToken: [/<\/script>/i],
            rules: "js",
            advance: true,
            indent: true
        },
        {
            langs: "html",
            name: "mode switch css",
            startToken: [function (string, rule) {
                var start = /<style[\s>].*/i;
                var end = /<\/style>/i;
                var startMatch = start.exec(string);
                var endMatch = end.exec(string);

                if (startMatch && (!endMatch || endMatch.index < startMatch.index)) {
                    return {
                        matchIndex: startMatch.index,
                        length: startMatch[0].length
                    };
                }
                return {matchIndex: -1};
            }],
            endToken: [/<\/style>/i],
            rules: "css",
            advance: true,
            indent: true
        },
        {
            langs: "html",
            name: "close-tag",
            startToken: [/<\/[A-Za-z0-9\-]+>/],
            endToken: [/./],
            indent: true
        },
        {
            langs: "html",
            name: "tag attr",
            startToken: [/<[A-Za-z0-9\-]+/],
            endToken: [/>/],
            indent: true
        },
        {
            langs: "html",
            name: "tag",
            startToken: [/>/],
            endToken: [/<\/[A-Za-z0-9\-]+>/],
            indent: true,
            advance: true
        },
        {
            langs: "js",
            name: "line comment",
            startToken: [/\/\//],
            endToken: [NEW_LINE_REGEX],
            ignore: true
        },
        {
            langs: "js css",
            name: "block comment",
            startToken: [/\/\*/],
            endToken: [/\*\//],
            ignore: true
        },
        {
            langs: "js",
            name: "regex",
            startToken: [function (string, rule) {
                var re = /[(,=:[!&|?{};][\s]*\/[^/]|^[\s]*\/[^/]/;
                var startIndex = string.search(re);
                if (startIndex != -1) {
                    startIndex = string.indexOf('/', startIndex);
                    var substr = string.substring(startIndex + 1);
                    var match = searchAny(substr, rule.endToken, rule);
                    if (match.matchIndex != -1) {
                        substr = substr.substring(0, match.matchIndex);
                        try {
                            (new RegExp(substr));
                            return {
                                matchIndex: startIndex,
                                length: 1
                            };
                        }
                        catch (e) {
                            return {matchIndex: -1};
                        }
                    }
                }
                return {matchIndex: -1};
            }],
            endToken: [function (string, rule) {
                var fromIndex = 0;
                var index = string.indexOf('/');
                while (index != -1) {
                    try {
                        (new RegExp(string.substring(0, index)));
                        break;
                    }
                    catch (e) {
                        index = string.indexOf('/', fromIndex);
                        fromIndex = index + 1;
                    }
                }
                return {
                    matchIndex: index,
                    length: index == -1 ? 0 : 1
                };
            }],
            ignore: true,
            advance: true
        },
        {
            langs: "js css html",
            name: "string",
            startToken: [/\"/],
            endToken: [/\"/, NEW_LINE_REGEX],
            ignore: true,
            advance: true
        },
        {
            langs: "js css html",
            name: "string",
            startToken: [/\'/],
            endToken: [/\'/, NEW_LINE_REGEX],
            ignore: true,
            advance: true
        },
        {
            langs: "js css html",
            name: "string",
            startToken: [/\`/],
            endToken: [/\`/],
            ignore: true,
            advance: true
        },
        {
            langs: "js",
            name: "if",
            startToken: [/^if[\s]*(?=\()/, /[\s]+if[\s]*(?=\()/],
            endToken: [/else[\s]+/, /\{/, /;/],
            indent: true
        },
        {
            langs: "js",
            name: "for",
            startToken: [/^for[\s]*(?=\()/],
            endToken: [/\{/, /;/],
            indent: true
        },
        {
            langs: "js",
            name: "else",
            startToken: [/else[\s]+/],
            endToken: [/if/, /\{/, /;/, NEW_LINE_REGEX],
            indent: true
        },
        {
            langs: "js css",
            name: "bracket",
            startToken: [/\([\s]*(var)?/],
            endToken: [/\)/],
            indent: true,
            advance: true
        },
        {
            langs: "js",
            name: "dot chain",
            startToken: [/^\../],
            endToken: [/;/, NEW_LINE_REGEX],
            indent: true,
            head: true,
            lineOffset: -1
        },
        {
            langs: "js",
            name: "dot chain",
            startToken: [/\.\s*$/],
            endToken: [function (string, rule) {
                return {
                    matchIndex: string.length ? 1 : -1,
                    length: string.length ? 0 : 1
                };
            }],
            indent: true
        },
        {
            langs: "js css",
            name: "array",
            startToken: [/\[/],
            endToken: [/]/],
            indent: true,
            advance: true
        },
        {
            langs: "js css",
            name: "block",
            startToken: [/\{/],
            endToken: [/}/],
            indent: true,
            advance: true
        },
        {
            langs: "js",
            name: "var",
            startToken: [/var[\s]+/],
            endToken: [/;/],
            indent: true
        },
        {
            langs: "js",
            name: "case",
            startToken: [/^case[\s]+/],
            endToken: [/break[\s;]+/, /^case[\s]+/, /^default[\s]+/, /^return([\s]+|;)/, /}/],
            endTokenIndent: true,
            indent: true
        },
        {
            langs: "js",
            name: "default",
            startToken: [/^default[\s]*:/],
            endToken: [/break[\s;]+/, /^case[\s]+/, /^default[\s]+/, /^return([\s]+|;)/, /}/],
            endTokenIndent: true,
            indent: true
        }
    ];

    return {
        css: function (code, indentString) {
            return indent(code || '', filterRules('css'), indentString || '\t');
        },
        js: function (code, indentString) {
            return indent(code || '', filterRules('js'), indentString || '\t');
        },
        html: function (code, indentString) {
            return indent(code || '', filterRules('html'), indentString || '\t');
        }
    };

    function indent(code, baseRules, indentation) {
        var lines = code.split(/[\r]?\n/gi);
        var lineCount = lines.length;
        var newLines = [];
        var indentBuffer = [];
        var activeRules = [];
        var lastRule;
        var indents = 0;
        var l = 0;
        var pos = 0;
        var matchEnd, matchStart;
        var modeRules = null;

        while (l < lineCount) {
            var line = lines[l].trim();
            var lineToMatch = cleanEscapedChars(line) + '\r\n';

            matchStart = matchStartRule(lineToMatch, modeRules || baseRules, pos);

            if (activeRules.length) {
                matchEnd = matchEndRule(lineToMatch, lastRule, pos);
                if (matchEnd.matchIndex == -1) {
                    if (lastRule.ignore) {
                        // last rule is still active, and it's telling us to ignore.
                        incrementLine();
                        continue;
                    }
                }
                else if (lastRule.ignore || matchStart.matchIndex == -1 || matchEnd.matchIndex <= matchStart.matchIndex) {
                    removeLastRule();
                    pos = matchEnd.cursor;
                    continue;  // Repeat process for matching line start/end
                }
            }

            if (matchStart.matchIndex != -1) {
                implementRule(matchStart);
            }
            else {
                // No new token match end, no new match start
                incrementLine();
            }
        }

        return newLines.join('\r\n');

        function implementRule(match) {
            pos = match.cursor;
            lastRule = match.rule;
            activeRules.push(lastRule);
            if (lastRule.indent) {
                incrementIndentation(lastRule.lineOffset);
            }
            if (lastRule.rules) {
                modeRules = filterRules(lastRule.rules);
            }
        }

        function removeLastRule() {
            if (lastRule.indent) {
                consumeIndentation();
                if (!lastRule.endTokenIndent && matchEnd.matchIndex == 0) {
                    calculateIndents();
                }
            }
            if (lastRule.rules) {
                modeRules = null;
            }
            activeRules.pop();
            lastRule = activeRules[activeRules.length - 1];
        }

        function calculateIndents() {
            indents = 0;
            for (var b, i = 0; i < indentBuffer.length; i++) {
                b = indentBuffer[i];
                if (b.open && b.line != l)
                    indents++;
            }
        }

        function incrementLine() {
            newLines[l] = repeatString(indentation, indents) + line;
            l++;
            pos = 0;
            calculateIndents();
        }

        function incrementIndentation(lineOffset) {
            var matched = indentBuffer[indentBuffer.length - 1];
            if (matched && matched.line == l) {
                matched.indent++;
            }
            else {
                indentBuffer.push({
                    indent: 1,
                    open: true,
                    line: lineOffset ? l + lineOffset : l
                });
                if (lineOffset < 0) calculateIndents();
            }
        }

        function consumeIndentation() {
            var lastElem = indentBuffer[indentBuffer.length - 1];
            if (lastElem) {
                lastElem.open = l == lastElem.line;
                if (--lastElem.indent <= 0) {
                    indentBuffer.pop();
                }
            }
        }
    }

    function repeatString(baseString, repeat) {
        return (new Array(repeat + 1)).join(baseString);
    }

    function cleanEscapedChars(string) {
        return string.replace(/\\(u[0-9A-Za-z]{4}|u\{[0-9A-Za-z]{1,6}]\}|x[0-9A-Za-z]{2}|.)/g, '0');
    }

    function matchStartRule(string, rules, index) {
        string = string.substring(index, string.length);
        var result = null;
        var minIndex = string.length;
        var minMatch;
        var match;
        for (var rule, r = 0; r < rules.length; r++) {
            rule = rules[r];
            match = searchAny(string, rule.startToken, rule);
            if (match.matchIndex != -1 && match.matchIndex < minIndex
                && (!rule.head || index == 0)) {
                minIndex = match.matchIndex;
                minMatch = match;
                result = rule;
            }
        }
        return {
            rule: result,
            matchIndex: result ? minIndex + index : -1,
            cursor: result ? minIndex + index + minMatch.matchLength : -1
        };
    }

    function matchEndRule(string, rule, offset) {
        string = string.substr(offset, string.length);
        var match = searchAny(string, rule.endToken, rule);
        var cursor = rule.advance ? match.matchIndex + match.matchLength : match.matchIndex;
        return {
            matchIndex: match.matchIndex == -1 ? -1 : match.matchIndex + offset,
            cursor: cursor == -1 ? -1 : cursor + offset
        };
    }

    function searchAny(string, patterns, rule) {
        var index = -1;
        var length = 0;
        for (var pat, p = 0; p < patterns.length; p++) {
            pat = patterns[p];
            if (typeof pat == 'function') {
                var match = pat(string, rule);
                index = match.matchIndex;
                length = match.length;
            }
            else {
                index = string.search(pat);
                if (index != -1) {
                    length = string.match(pat)[0].length;
                    break;
                }
            }
        }
        return {
            matchIndex: index,
            matchLength: length,
            cursor: index + length,
            patternIndex: p
        };
    }
}());
<commit_msg>add deprecation warnings<commit_after>var indent = (function() {
    var rulesCache = {};

    function filterRules(language) {
        if (rulesCache[language])
            return rulesCache[language];
        var ret = [];
        rulesCache[language] = ret;
        for (var i=0; i<masterRules.length; i++) {
            if (masterRules[i].langs.indexOf(language.toLowerCase()) != -1)
                ret.push(masterRules[i]);
        }
        return ret;
    }

    var NEW_LINE_REGEX = /\r*\n/;

    /**
     * indent - whether rule will cause indent
     * ignore - ignore further rule matching as long as this is last active rule, e.g. string, comments
     * advance - advance the cursor to the end of the endTokens
     * endTokenIndent - keep the indent rule active for the endTokens
     * head - match at beginning of line only
     * langs - used to filter by language later
     * lineOffset - added to the line field when rule is applied
     *
     * Always keep NEW_LINE_REGEX endToken as last element,
     * as otherwise it will be matched first, and subsequent ones may be ignored
     * and skipped permanently by other rules.
     */
    var masterRules = [
        {
            langs: "html",
            name: "comment",
            startToken: [/\<\!\-\-/],
            endToken: [/\-\-\>/],
            ignore: true,
            advance: true
        },
        {
            langs: "html",
            name: "doctype",
            startToken: [/\<\!/],
            endToken: [NEW_LINE_REGEX],
            ignore: true,
            advance: true
        },
        {
            langs: "html",
            name: "link|br|hr|input|img|meta",
            startToken: [/\<(link|br|hr|input|img|meta)/i],
            endToken: [/>/],
            advance: true
        },
        {
            langs: "html",
            name: "mode switch js",
            startToken: [function (string, rule) {
                var start = /<script[\s>].*/i;
                var end = /<\/script>/i;
                var startMatch = start.exec(string);
                var endMatch = end.exec(string);

                if (startMatch && (!endMatch || endMatch.index < startMatch.index)) {
                    return {
                        matchIndex: startMatch.index,
                        length: startMatch[0].length
                    };
                }
                return {matchIndex: -1};
            }],
            endToken: [/<\/script>/i],
            rules: "js",
            advance: true,
            indent: true
        },
        {
            langs: "html",
            name: "mode switch css",
            startToken: [function (string, rule) {
                var start = /<style[\s>].*/i;
                var end = /<\/style>/i;
                var startMatch = start.exec(string);
                var endMatch = end.exec(string);

                if (startMatch && (!endMatch || endMatch.index < startMatch.index)) {
                    return {
                        matchIndex: startMatch.index,
                        length: startMatch[0].length
                    };
                }
                return {matchIndex: -1};
            }],
            endToken: [/<\/style>/i],
            rules: "css",
            advance: true,
            indent: true
        },
        {
            langs: "html",
            name: "close-tag",
            startToken: [/<\/[A-Za-z0-9\-]+>/],
            endToken: [/./],
            indent: true
        },
        {
            langs: "html",
            name: "tag attr",
            startToken: [/<[A-Za-z0-9\-]+/],
            endToken: [/>/],
            indent: true
        },
        {
            langs: "html",
            name: "tag",
            startToken: [/>/],
            endToken: [/<\/[A-Za-z0-9\-]+>/],
            indent: true,
            advance: true
        },
        {
            langs: "js",
            name: "line comment",
            startToken: [/\/\//],
            endToken: [NEW_LINE_REGEX],
            ignore: true
        },
        {
            langs: "js css",
            name: "block comment",
            startToken: [/\/\*/],
            endToken: [/\*\//],
            ignore: true
        },
        {
            langs: "js",
            name: "regex",
            startToken: [function (string, rule) {
                var re = /[(,=:[!&|?{};][\s]*\/[^/]|^[\s]*\/[^/]/;
                var startIndex = string.search(re);
                if (startIndex != -1) {
                    startIndex = string.indexOf('/', startIndex);
                    var substr = string.substring(startIndex + 1);
                    var match = searchAny(substr, rule.endToken, rule);
                    if (match.matchIndex != -1) {
                        substr = substr.substring(0, match.matchIndex);
                        try {
                            (new RegExp(substr));
                            return {
                                matchIndex: startIndex,
                                length: 1
                            };
                        }
                        catch (e) {
                            return {matchIndex: -1};
                        }
                    }
                }
                return {matchIndex: -1};
            }],
            endToken: [function (string, rule) {
                var fromIndex = 0;
                var index = string.indexOf('/');
                while (index != -1) {
                    try {
                        (new RegExp(string.substring(0, index)));
                        break;
                    }
                    catch (e) {
                        index = string.indexOf('/', fromIndex);
                        fromIndex = index + 1;
                    }
                }
                return {
                    matchIndex: index,
                    length: index == -1 ? 0 : 1
                };
            }],
            ignore: true,
            advance: true
        },
        {
            langs: "js css html",
            name: "string",
            startToken: [/\"/],
            endToken: [/\"/, NEW_LINE_REGEX],
            ignore: true,
            advance: true
        },
        {
            langs: "js css html",
            name: "string",
            startToken: [/\'/],
            endToken: [/\'/, NEW_LINE_REGEX],
            ignore: true,
            advance: true
        },
        {
            langs: "js css html",
            name: "string",
            startToken: [/\`/],
            endToken: [/\`/],
            ignore: true,
            advance: true
        },
        {
            langs: "js",
            name: "if",
            startToken: [/^if[\s]*(?=\()/, /[\s]+if[\s]*(?=\()/],
            endToken: [/else[\s]+/, /\{/, /;/],
            indent: true
        },
        {
            langs: "js",
            name: "for",
            startToken: [/^for[\s]*(?=\()/],
            endToken: [/\{/, /;/],
            indent: true
        },
        {
            langs: "js",
            name: "else",
            startToken: [/else[\s]+/],
            endToken: [/if/, /\{/, /;/, NEW_LINE_REGEX],
            indent: true
        },
        {
            langs: "js css",
            name: "bracket",
            startToken: [/\([\s]*(var)?/],
            endToken: [/\)/],
            indent: true,
            advance: true
        },
        {
            langs: "js",
            name: "dot chain",
            startToken: [/^\../],
            endToken: [/;/, NEW_LINE_REGEX],
            indent: true,
            head: true,
            lineOffset: -1
        },
        {
            langs: "js",
            name: "dot chain",
            startToken: [/\.\s*$/],
            endToken: [function (string, rule) {
                return {
                    matchIndex: string.length ? 1 : -1,
                    length: string.length ? 0 : 1
                };
            }],
            indent: true
        },
        {
            langs: "js css",
            name: "array",
            startToken: [/\[/],
            endToken: [/]/],
            indent: true,
            advance: true
        },
        {
            langs: "js css",
            name: "block",
            startToken: [/\{/],
            endToken: [/}/],
            indent: true,
            advance: true
        },
        {
            langs: "js",
            name: "var",
            startToken: [/var[\s]+/],
            endToken: [/;/],
            indent: true
        },
        {
            langs: "js",
            name: "case",
            startToken: [/^case[\s]+/],
            endToken: [/break[\s;]+/, /^case[\s]+/, /^default[\s]+/, /^return([\s]+|;)/, /}/],
            endTokenIndent: true,
            indent: true
        },
        {
            langs: "js",
            name: "default",
            startToken: [/^default[\s]*:/],
            endToken: [/break[\s;]+/, /^case[\s]+/, /^default[\s]+/, /^return([\s]+|;)/, /}/],
            endTokenIndent: true,
            indent: true
        }
    ];

    var exports = {
        css: function (code, indentString) {
            return indent(code || '', filterRules('css'), indentString || '\t');
        },
        js: function (code, indentString) {
            return indent(code || '', filterRules('js'), indentString || '\t');
        },
        html: function (code, indentString) {
            return indent(code || '', filterRules('html'), indentString || '\t');
        },
        /**
         * @deprecated Since version 0.2.0. Will be deleted in version 0.3.0. Use js instead.
         */
        indentJS: function(code, indentString) {
            if (console && console.warn) console.warn("Calling deprecated function!");
            return exports.js(code, indentString);
        },
        /**
         * @deprecated Since version 0.2.0. Will be deleted in version 0.3.0. Use css instead.
         */
        indentCSS: function(code, indentString) {
            if (console && console.warn) console.warn("Calling deprecated function!");
            return exports.css(code, indentString);
        },
        /**
         * @deprecated Since version 0.2.0. Will be deleted in version 0.3.0. Use html instead.
         */
        indentHTML: function(code, indentString) {
            if (console && console.warn) console.warn("Calling deprecated function!");
            return exports.html(code, indentString);
        }
    };

    return exports;

    function indent(code, baseRules, indentation) {
        var lines = code.split(/[\r]?\n/gi);
        var lineCount = lines.length;
        var newLines = [];
        var indentBuffer = [];
        var activeRules = [];
        var lastRule;
        var indents = 0;
        var l = 0;
        var pos = 0;
        var matchEnd, matchStart;
        var modeRules = null;

        while (l < lineCount) {
            var line = lines[l].trim();
            var lineToMatch = cleanEscapedChars(line) + '\r\n';

            matchStart = matchStartRule(lineToMatch, modeRules || baseRules, pos);

            if (activeRules.length) {
                matchEnd = matchEndRule(lineToMatch, lastRule, pos);
                if (matchEnd.matchIndex == -1) {
                    if (lastRule.ignore) {
                        // last rule is still active, and it's telling us to ignore.
                        incrementLine();
                        continue;
                    }
                }
                else if (lastRule.ignore || matchStart.matchIndex == -1 || matchEnd.matchIndex <= matchStart.matchIndex) {
                    removeLastRule();
                    pos = matchEnd.cursor;
                    continue;  // Repeat process for matching line start/end
                }
            }

            if (matchStart.matchIndex != -1) {
                implementRule(matchStart);
            }
            else {
                // No new token match end, no new match start
                incrementLine();
            }
        }

        return newLines.join('\r\n');

        function implementRule(match) {
            pos = match.cursor;
            lastRule = match.rule;
            activeRules.push(lastRule);
            if (lastRule.indent) {
                incrementIndentation(lastRule.lineOffset);
            }
            if (lastRule.rules) {
                modeRules = filterRules(lastRule.rules);
            }
        }

        function removeLastRule() {
            if (lastRule.indent) {
                consumeIndentation();
                if (!lastRule.endTokenIndent && matchEnd.matchIndex == 0) {
                    calculateIndents();
                }
            }
            if (lastRule.rules) {
                modeRules = null;
            }
            activeRules.pop();
            lastRule = activeRules[activeRules.length - 1];
        }

        function calculateIndents() {
            indents = 0;
            for (var b, i = 0; i < indentBuffer.length; i++) {
                b = indentBuffer[i];
                if (b.open && b.line != l)
                    indents++;
            }
        }

        function incrementLine() {
            newLines[l] = repeatString(indentation, indents) + line;
            l++;
            pos = 0;
            calculateIndents();
        }

        function incrementIndentation(lineOffset) {
            var matched = indentBuffer[indentBuffer.length - 1];
            if (matched && matched.line == l) {
                matched.indent++;
            }
            else {
                indentBuffer.push({
                    indent: 1,
                    open: true,
                    line: lineOffset ? l + lineOffset : l
                });
                if (lineOffset < 0) calculateIndents();
            }
        }

        function consumeIndentation() {
            var lastElem = indentBuffer[indentBuffer.length - 1];
            if (lastElem) {
                lastElem.open = l == lastElem.line;
                if (--lastElem.indent <= 0) {
                    indentBuffer.pop();
                }
            }
        }
    }

    function repeatString(baseString, repeat) {
        return (new Array(repeat + 1)).join(baseString);
    }

    function cleanEscapedChars(string) {
        return string.replace(/\\(u[0-9A-Za-z]{4}|u\{[0-9A-Za-z]{1,6}]\}|x[0-9A-Za-z]{2}|.)/g, '0');
    }

    function matchStartRule(string, rules, index) {
        string = string.substring(index, string.length);
        var result = null;
        var minIndex = string.length;
        var minMatch;
        var match;
        for (var rule, r = 0; r < rules.length; r++) {
            rule = rules[r];
            match = searchAny(string, rule.startToken, rule);
            if (match.matchIndex != -1 && match.matchIndex < minIndex
                && (!rule.head || index == 0)) {
                minIndex = match.matchIndex;
                minMatch = match;
                result = rule;
            }
        }
        return {
            rule: result,
            matchIndex: result ? minIndex + index : -1,
            cursor: result ? minIndex + index + minMatch.matchLength : -1
        };
    }

    function matchEndRule(string, rule, offset) {
        string = string.substr(offset, string.length);
        var match = searchAny(string, rule.endToken, rule);
        var cursor = rule.advance ? match.matchIndex + match.matchLength : match.matchIndex;
        return {
            matchIndex: match.matchIndex == -1 ? -1 : match.matchIndex + offset,
            cursor: cursor == -1 ? -1 : cursor + offset
        };
    }

    function searchAny(string, patterns, rule) {
        var index = -1;
        var length = 0;
        for (var pat, p = 0; p < patterns.length; p++) {
            pat = patterns[p];
            if (typeof pat == 'function') {
                var match = pat(string, rule);
                index = match.matchIndex;
                length = match.length;
            }
            else {
                index = string.search(pat);
                if (index != -1) {
                    length = string.match(pat)[0].length;
                    break;
                }
            }
        }
        return {
            matchIndex: index,
            matchLength: length,
            cursor: index + length,
            patternIndex: p
        };
    }
}());
<|endoftext|>


<commit_before>(function() {
    CKEDITOR.plugins.add('concrete5filemanager', {
        init: function () {
            CKEDITOR.on('dialogDefinition', function(event) {
                var editor = event.editor,
                    dialogDefinition = event.data.definition,
                    tabContent = dialogDefinition.contents.length;

                for (var i = 0; i < tabContent; i++) {
                    var browseButton = dialogDefinition.contents[i].get('browse');

                    if (browseButton !== null) {
                        browseButton.hidden = false;
                        browseButton.onClick = function() {
                            editor._.filebrowserSe = this;
                            ConcreteFileManager.launchDialog(function(data) {
                                jQuery.fn.dialog.showLoader();
                                ConcreteFileManager.getFileDetails(data.fID, function(r) {
                                    jQuery.fn.dialog.hideLoader();
                                    var file = r.files[0];
                                    CKEDITOR.tools.callFunction(editor._.filebrowserFn, file.urlDownload);
                                });
                            });
                        }
                    }
                }
            });
        }
    });
})();<commit_msg>Disable width/height resize on image browse selection and use inlnie url for responsive images.<commit_after>(function() {
    CKEDITOR.plugins.add('concrete5filemanager', {
        init: function () {
            CKEDITOR.on('dialogDefinition', function(event) {
                var editor = event.editor,
                    dialogDefinition = event.data.definition,
                    tabContent = dialogDefinition.contents.length;

                for (var i = 0; i < tabContent; i++) {
                    var browseButton = dialogDefinition.contents[i].get('browse');

                    if (browseButton !== null) {
                        browseButton.hidden = false;
                        browseButton.onClick = function() {
                            editor._.filebrowserSe = this;
                            ConcreteFileManager.launchDialog(function(data) {
                                jQuery.fn.dialog.showLoader();
                                ConcreteFileManager.getFileDetails(data.fID, function(r) {
                                    jQuery.fn.dialog.hideLoader();
                                    var file = r.files[0];
                                    CKEDITOR.tools.callFunction(editor._.filebrowserFn, file.urlInline, function() {
                                        var dialog = this.getDialog();
                                        if ( dialog.getName() == 'image' || dialog.getName() == 'image2') {
                                            dialog.dontResetSize = true;
                                            dialog.getContentElement( 'info', 'txtAlt').setValue(file.title);
                                            dialog.getContentElement( 'info', 'txtWidth').setValue('');
                                            dialog.getContentElement( 'info', 'txtHeight').setValue('');
                                            dialog.getContentElement( 'Link', 'txtUrl').setValue(file.urlDownload);
                                        }
                                    });
                                });
                            });
                        }
                    }
                }
            });
        }
    });
})();<|endoftext|>


<commit_before>Module('JEDAI.Application', function(Application) {
	Application.fn.initialize = function(container) {
		var users = [
			{
				profile : 'kassyn',
				email   : 'kassyntec@gmail.com'
			},
			{
				profile : 'guilhermesouza',
				email   : 'guilherme.wd@live.com'
			},
			{
				profile : 'daniloalvess',
				email   : 'danilo.alves@apiki.com'
			},
			{
				profile : 'henrichm',
				email   : 'henrich@apiki.com'
			},
			{
				profile : 'luanramos',
				email   : 'luan@apiki.com'
			},
			{
				profile : 'Emanuel-Souza',
				email   : 'emanuel.inacios@gmail.com'
			}
		];

		//set users for ranking
		JEDAI.Ranking( $( '[data-component-ranking]' ), users ).init();
	};
});<commit_msg>inclusion jhonatan<commit_after>Module('JEDAI.Application', function(Application) {
	Application.fn.initialize = function(container) {
		var users = [
			{
				profile : 'kassyn',
				email   : 'kassyntec@gmail.com'
			},
			{
				profile : 'guilhermesouza',
				email   : 'guilherme.wd@live.com'
			},
			{
				profile : 'daniloalvess',
				email   : 'danilo.alves@apiki.com'
			},
			{
				profile : 'henrichm',
				email   : 'henrich@apiki.com'
			},
			{
				profile : 'luanramos',
				email   : 'luan@apiki.com'
			},
			{
				profile : 'Emanuel-Souza',
				email   : 'emanuel.inacios@gmail.com'
			},
			{
				profile : 'Jhowl',
				email   : 'jhonatan.souza@apiki.com'
			}
		];

		//set users for ranking
		JEDAI.Ranking( $( '[data-component-ranking]' ), users ).init();
	};
});<|endoftext|>


<commit_before>Module('JEDAI.Application', function(Application) {
	Application.fn.initialize = function(container) {
		var users = [
			{
				profile : 'kassyn',
				email   : 'kassyntec@gmail.com'
			},
			{
				profile : 'guilhermesouza',
				email   : 'guilherme.wd@live.com'
			},
			{
				profile : 'daniloalvess',
				email   : 'danilo.alves@apiki.com'
			},
			{
				profile : 'henrichm',
				email   : 'henrich@apiki.com'
			},
			{
				profile : 'luanramos',
				email   : 'luan@apiki.com'
			}
		];

		//set users for ranking
		JEDAI.Ranking( $( '[data-component-ranking]' ), users ).init();
	};
});<commit_msg>add my name<commit_after>Module('JEDAI.Application', function(Application) {
	Application.fn.initialize = function(container) {
		var users = [
			{
				profile : 'kassyn',
				email   : 'kassyntec@gmail.com'
			},
			{
				profile : 'guilhermesouza',
				email   : 'guilherme.wd@live.com'
			},
			{
				profile : 'daniloalvess',
				email   : 'danilo.alves@apiki.com'
			},
			{
				profile : 'henrichm',
				email   : 'henrich@apiki.com'
			},
			{
				profile : 'luanramos',
				email   : 'luan@apiki.com'
			},
			{
				profile : 'Emanuel-Souza',
				email   : 'emanuel.inacios@gmail.com'
			}
		];

		//set users for ranking
		JEDAI.Ranking( $( '[data-component-ranking]' ), users ).init();
	};
});<|endoftext|>


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

/**
 * Internal dependencies
 */
import { render, createTestRegistry, fireEvent, provideUserInfo, provideSiteInfo, act } from '../../../tests/js/test-utils';
import UserMenu from './UserMenu';
import { STORE_NAME as CORE_SITE } from '../googlesitekit/datastore/site/constants';

describe( 'UserMenu', () => {
	let registry;
	const locationAssignMock = jest.fn();

	beforeAll( () => {
		registry = createTestRegistry();

		delete global.location;
		global.location = Object.defineProperties(
			{},
			{
				assign: {
					configurable: true,
					value: locationAssignMock,
				},
			},
		);
	} );

	describe( 'opening and closing the menu', () => {
		let container;
		let menu;
		beforeEach( () => {
			provideUserInfo( registry );
			provideSiteInfo( registry );
			container = render( <UserMenu />, { registry } ).container;
			fireEvent.click( container.querySelector( '.googlesitekit-header__dropdown span' ) );
			menu = container.querySelector( '#user-menu' );
		} );

		it( 'should not show Manage Sites option when not using proxy', () => {
			act( () => {
				provideSiteInfo( registry, {
					usingProxy: false,
					proxyPermissionsURL: null,
				} );
			} );

			expect( container.querySelector( '#user-menu' ).children.length ).toEqual( 1 );
		} );

		it( 'should open the menu when clicked', () => {
			expect( menu ).toHaveAttribute( 'aria-hidden', 'false' );
		} );

		it( 'should close the menu when clicked outside', () => {
			fireEvent.mouseUp( document.body );
			expect( menu ).toHaveAttribute( 'aria-hidden', 'true' );
		} );

		it( 'should close the menu when escape is pressed', () => {
			fireEvent.keyUp( document, { keyCode: 27 } );
			expect( menu ).toHaveAttribute( 'aria-hidden', 'true' );
		} );

		describe( 'clicking the disconnect menu item', () => {
			beforeEach( () => {
				fireEvent.click( menu.children[ 0 ] );
			} );

			it( 'should open the modal dialog', () => {
				expect( document.querySelector( '.mdc-dialog--open' ) ).toBeInTheDocument();
			} );

			it( 'should close the modal dialog after pressing escape key', () => {
				fireEvent.keyUp( document, { keyCode: 27 } );
				expect( document.querySelector( '.mdc-dialog--open' ) ).not.toBeInTheDocument();
			} );

			it( 'should redirect user to Site Kit splash screen and clear storage', () => {
				fireEvent.click( document.querySelector( '.mdc-dialog--open .mdc-button--danger' ) );

				expect( document.querySelector( '.mdc-dialog--open' ) ).not.toBeInTheDocument();
				expect( localStorage.clear ).toHaveBeenCalled();
				expect( sessionStorage.clear ).toHaveBeenCalled();

				expect( locationAssignMock ).toHaveBeenCalled();
				const url = new URL( locationAssignMock.mock.calls[ 0 ][ 0 ] );
				expect( url.pathname ).toBe( '/wp-admin/admin.php' );
				expect( url.href ).toMatchQueryParameters( {
					page: 'googlesitekit-splash',
					googlesitekit_context: 'revoked',
				} );
			} );
		} );

		it( 'clicking Manage Sites option should go to Site Kit permissions page', () => {
			fireEvent.click( menu.children[ 1 ] );
			const proxyPermissionsURL = registry.select( CORE_SITE ).getProxyPermissionsURL();

			expect( locationAssignMock ).toHaveBeenCalled();
			const url = locationAssignMock.mock.calls[ 1 ][ 0 ];
			expect( url ).toEqual( proxyPermissionsURL );
		} );

		it( 'should select a menu option on pressing space', () => {
			fireEvent.keyDown( menu.children[ 0 ], { keyCode: 32 } );
			expect( document.querySelector( '.mdc-dialog--open' ) ).toBeInTheDocument();
		} );

		it( 'should select a menu option on pressing enter', () => {
			fireEvent.keyDown( menu.children[ 0 ], { keyCode: 13 } );
			expect( document.querySelector( '.mdc-dialog--open' ) ).toBeInTheDocument();
		} );
	} );
} );
<commit_msg>Restore the original location object in afterAll.<commit_after>/**
 * UserMenu tests.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import { render, createTestRegistry, fireEvent, provideUserInfo, provideSiteInfo, act } from '../../../tests/js/test-utils';
import UserMenu from './UserMenu';
import { STORE_NAME as CORE_SITE } from '../googlesitekit/datastore/site/constants';

describe( 'UserMenu', () => {
	let registry;
	let oldLocation;
	const locationAssignMock = jest.fn();

	beforeAll( () => {
		registry = createTestRegistry();

		oldLocation = global.location;
		delete global.location;
		global.location = Object.defineProperties(
			{},
			{
				assign: {
					configurable: true,
					value: locationAssignMock,
				},
			},
		);
	} );

	afterAll( () => {
		global.location = oldLocation;
	} );

	describe( 'opening and closing the menu', () => {
		let container;
		let menu;
		beforeEach( () => {
			provideUserInfo( registry );
			provideSiteInfo( registry );
			container = render( <UserMenu />, { registry } ).container;
			fireEvent.click( container.querySelector( '.googlesitekit-header__dropdown span' ) );
			menu = container.querySelector( '#user-menu' );
		} );

		it( 'should not show Manage Sites option when not using proxy', () => {
			act( () => {
				provideSiteInfo( registry, {
					usingProxy: false,
					proxyPermissionsURL: null,
				} );
			} );

			expect( container.querySelector( '#user-menu' ).children.length ).toEqual( 1 );
		} );

		it( 'should open the menu when clicked', () => {
			expect( menu ).toHaveAttribute( 'aria-hidden', 'false' );
		} );

		it( 'should close the menu when clicked outside', () => {
			fireEvent.mouseUp( document.body );
			expect( menu ).toHaveAttribute( 'aria-hidden', 'true' );
		} );

		it( 'should close the menu when escape is pressed', () => {
			fireEvent.keyUp( document, { keyCode: 27 } );
			expect( menu ).toHaveAttribute( 'aria-hidden', 'true' );
		} );

		describe( 'clicking the disconnect menu item', () => {
			beforeEach( () => {
				fireEvent.click( menu.children[ 0 ] );
			} );

			it( 'should open the modal dialog', () => {
				expect( document.querySelector( '.mdc-dialog--open' ) ).toBeInTheDocument();
			} );

			it( 'should close the modal dialog after pressing escape key', () => {
				fireEvent.keyUp( document, { keyCode: 27 } );
				expect( document.querySelector( '.mdc-dialog--open' ) ).not.toBeInTheDocument();
			} );

			it( 'should redirect user to Site Kit splash screen and clear storage', () => {
				fireEvent.click( document.querySelector( '.mdc-dialog--open .mdc-button--danger' ) );

				expect( document.querySelector( '.mdc-dialog--open' ) ).not.toBeInTheDocument();
				expect( localStorage.clear ).toHaveBeenCalled();
				expect( sessionStorage.clear ).toHaveBeenCalled();

				expect( locationAssignMock ).toHaveBeenCalled();
				const url = new URL( locationAssignMock.mock.calls[ 0 ][ 0 ] );
				expect( url.pathname ).toBe( '/wp-admin/admin.php' );
				expect( url.href ).toMatchQueryParameters( {
					page: 'googlesitekit-splash',
					googlesitekit_context: 'revoked',
				} );
			} );
		} );

		it( 'clicking Manage Sites option should go to Site Kit permissions page', () => {
			fireEvent.click( menu.children[ 1 ] );
			const proxyPermissionsURL = registry.select( CORE_SITE ).getProxyPermissionsURL();

			expect( locationAssignMock ).toHaveBeenCalled();
			const url = locationAssignMock.mock.calls[ 1 ][ 0 ];
			expect( url ).toEqual( proxyPermissionsURL );
		} );

		it( 'should select a menu option on pressing space', () => {
			fireEvent.keyDown( menu.children[ 0 ], { keyCode: 32 } );
			expect( document.querySelector( '.mdc-dialog--open' ) ).toBeInTheDocument();
		} );

		it( 'should select a menu option on pressing enter', () => {
			fireEvent.keyDown( menu.children[ 0 ], { keyCode: 13 } );
			expect( document.querySelector( '.mdc-dialog--open' ) ).toBeInTheDocument();
		} );
	} );
} );
<|endoftext|>