diff --git a/README.md b/README.md
index 550b4bd..bbbf15d 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,18 @@ Chrome extension to show a code tree on GitLab :)
![](https://ws2.sinaimg.cn/large/006tNc79gy1fhpc4wcad7g30z10hzaqs.gif)
+
+## Change Log
+ - v1.2
+ - add css loading
+ - add options setting
+ - search file
+ - load entire tree at once
+ - v1.1
+ - basic function
+ - v1.0
+ - initial version
+
## More
- Email:[linsage@live.com](mailto:linsage@live.com)
diff --git a/css/main.css b/css/main.css
index 2d5e661..9b552cd 100755
--- a/css/main.css
+++ b/css/main.css
@@ -293,7 +293,6 @@
}
.ztree li span.button.ico_close {
- margin-right: 2px;
margin-right: 2px;
background-image: none;
vertical-align: top;
@@ -358,9 +357,21 @@
background-position: -168px 0;
}
+.ztree li span.button.ico_loading:before {
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ content: "\f110";
+ padding-top: 4px;
+ padding-left: 4px;
+}
+
.ztree li span.button.ico_loading {
margin-right: 2px;
- background: url(data:image/gif;base64,R0lGODlhEAAQAKIGAMLY8YSx5HOm4Mjc88/g9Ofw+v///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgAGACwAAAAAEAAQAAADMGi6RbUwGjKIXCAA016PgRBElAVlG/RdLOO0X9nK61W39qvqiwz5Ls/rRqrggsdkAgAh+QQFCgAGACwCAAAABwAFAAADD2hqELAmiFBIYY4MAutdCQAh+QQFCgAGACwGAAAABwAFAAADD1hU1kaDOKMYCGAGEeYFCQAh+QQFCgAGACwKAAIABQAHAAADEFhUZjSkKdZqBQG0IELDQAIAIfkEBQoABgAsCgAGAAUABwAAAxBoVlRKgyjmlAIBqCDCzUoCACH5BAUKAAYALAYACgAHAAUAAAMPaGpFtYYMAgJgLogA610JACH5BAUKAAYALAIACgAHAAUAAAMPCAHWFiI4o1ghZZJB5i0JACH5BAUKAAYALAAABgAFAAcAAAMQCAFmIaEp1motpDQySMNFAgA7) no-repeat scroll 0 0 transparent;
+ background-image: none;
vertical-align: top;
*vertical-align: middle
}
@@ -451,7 +462,7 @@ a.gitlabTreeView_toggle {
font-size: 13px;
font-weight: normal;
text-shadow: none;
- height: 58px;
+ height: auto;
line-height: 2.8;
background: none rgb(250, 251, 252);
border-bottom: 1px solid rgb(225, 228, 232);
@@ -486,3 +497,67 @@ a.gitlabTreeView_toggle {
min-width: 100%;
padding-top: 2px;
}
+
+.gitlabTreeView_cog_icon {
+ float: right;
+ position: relative;
+ top: 6px;
+ right: 6px;
+ cursor: pointer;
+}
+
+.gitlabTreeView_header_search {
+ margin-top: 2px;
+ margin-left: 4px;
+ width: 100%;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ line-height: 30px;
+}
+
+.gitlabTreeView_search_text {
+ border: 1px solid #e5e5e5;
+ font-size: 13px;
+ padding: 4px 16px 4px 6px;
+ line-height: 20px;
+ width: 60%;
+}
+
+.gitlabTreeView_search_icon {
+ position: relative;
+ right: 18px;
+ top: 0;
+ color: #e7e9ed;
+}
+
+.gitlabTreeView_search_icon.active {
+ cursor: pointer;
+ color: rgba(0, 0, 0, 0.85);
+}
+
+.gitlabTreeView_header_setting {
+ margin-top: 4px;
+ margin-left: 4px;
+ width: 100%;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ height: auto;
+ display: none;
+}
+
+.gitlabTreeView_header_setting * {
+ font-weight: normal;
+}
+
+.gitlabTreeView_header_setting_save {
+ cursor: pointer;
+ line-height: 1.5;
+ padding: 4px 6px;
+ font-size: 13px;
+ vertical-align: middle;
+ background-color: #fff;
+ border: 1px solid #e5e5e5;
+ color: rgba(0, 0, 0, 0.85);
+}
\ No newline at end of file
diff --git a/js/jquery.ztree.exhide.min.js b/js/jquery.ztree.exhide.min.js
new file mode 100755
index 0000000..e8af502
--- /dev/null
+++ b/js/jquery.ztree.exhide.min.js
@@ -0,0 +1,22 @@
+/*
+ * JQuery zTree exHideNodes v3.5.29
+ * http://treejs.cn/
+ *
+ * Copyright (c) 2010 Hunter.z
+ *
+ * Licensed same as jquery - MIT License
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * email: hunter.z@263.net
+ * Date: 2017-06-19
+ */
+(function(i){i.extend(!0,i.fn.zTree._z,{view:{clearOldFirstNode:function(c,a){for(var b=a.getNextNode();b;){if(b.isFirstNode){b.isFirstNode=!1;d.setNodeLineIcos(c,b);break}if(b.isLastNode)break;b=b.getNextNode()}},clearOldLastNode:function(c,a,b){for(a=a.getPreNode();a;){if(a.isLastNode){a.isLastNode=!1;b&&d.setNodeLineIcos(c,a);break}if(a.isFirstNode)break;a=a.getPreNode()}},makeDOMNodeMainBefore:function(c,a,b){c.push("
")},showNode:function(c,a){a.isHidden=!1;f.initShowForExCheck(c,a);j(a,c).show()},showNodes:function(c,a,b){if(a&&a.length!=0){var e={},g,k;for(g=0,k=a.length;g0&&!a[b][0].isHidden?
+a[b][0].isFirstNode=!0:e>0&&d.setFirstNodeForHide(c,a[b])},setLastNode:function(c,a){var b=c.data.key.children,e=a[b].length;e>0&&!a[b][0].isHidden?a[b][e-1].isLastNode=!0:e>0&&d.setLastNodeForHide(c,a[b])},setFirstNodeForHide:function(c,a){var b,e,g;for(e=0,g=a.length;e=0;e--){b=a[e];if(b.isLastNode)break;if(!b.isHidden&&!b.isLastNode){b.isLastNode=!0;d.setNodeLineIcos(c,b);break}else b=null}return b},setLastNodeForShow:function(c,a){var b,e,g,f;for(e=a.length-1;e>=0;e--)if(b=a[e],!g&&!b.isHidden&&
+b.isLastNode){g=b;break}else if(!g&&!b.isHidden&&!b.isLastNode)b.isLastNode=!0,g=b,d.setNodeLineIcos(c,b);else if(g&&b.isLastNode){b.isLastNode=!1;f=b;d.setNodeLineIcos(c,b);break}return{"new":g,old:f}}},data:{initHideForExCheck:function(c,a){if(a.isHidden&&c.check&&c.check.enable){if(typeof a._nocheck=="undefined")a._nocheck=!!a.nocheck,a.nocheck=!0;a.check_Child_State=-1;d.repairParentChkClassWithSelf&&d.repairParentChkClassWithSelf(c,a)}},initShowForExCheck:function(c,a){if(!a.isHidden&&c.check&&
+c.check.enable){if(typeof a._nocheck!="undefined")a.nocheck=a._nocheck,delete a._nocheck;if(d.setChkClass){var b=j(a,l.id.CHECK,c);d.setChkClass(c,b,a)}d.repairParentChkClassWithSelf&&d.repairParentChkClassWithSelf(c,a)}}}});var i=i.fn.zTree,m=i._z.tools,l=i.consts,d=i._z.view,f=i._z.data,j=m.$;f.addInitNode(function(c,a,b){if(typeof b.isHidden=="string")b.isHidden=m.eqs(b.isHidden,"true");b.isHidden=!!b.isHidden;f.initHideForExCheck(c,b)});f.addBeforeA(function(){});f.addZTreeTools(function(c,a){a.showNodes=
+function(a,b){d.showNodes(c,a,b)};a.showNode=function(a,b){a&&d.showNodes(c,[a],b)};a.hideNodes=function(a,b){d.hideNodes(c,a,b)};a.hideNode=function(a,b){a&&d.hideNodes(c,[a],b)};var b=a.checkNode;if(b)a.checkNode=function(c,d,f,h){(!c||!c.isHidden)&&b.apply(a,arguments)}});var n=f.initNode;f.initNode=function(c,a,b,e,g,i,h){var j=(e?e:f.getRoot(c))[c.data.key.children];f.tmpHideFirstNode=d.setFirstNodeForHide(c,j);f.tmpHideLastNode=d.setLastNodeForHide(c,j);h&&(d.setNodeLineIcos(c,f.tmpHideFirstNode),
+d.setNodeLineIcos(c,f.tmpHideLastNode));g=f.tmpHideFirstNode===b;i=f.tmpHideLastNode===b;n&&n.apply(f,arguments);h&&i&&d.clearOldLastNode(c,b,h)};var o=f.makeChkFlag;if(o)f.makeChkFlag=function(c,a){(!a||!a.isHidden)&&o.apply(f,arguments)};var p=f.getTreeCheckedNodes;if(p)f.getTreeCheckedNodes=function(c,a,b,e){if(a&&a.length>0){var d=a[0].getParentNode();if(d&&d.isHidden)return[]}return p.apply(f,arguments)};var q=f.getTreeChangeCheckedNodes;if(q)f.getTreeChangeCheckedNodes=function(c,a,b){if(a&&
+a.length>0){var d=a[0].getParentNode();if(d&&d.isHidden)return[]}return q.apply(f,arguments)};var r=d.expandCollapseSonNode;if(r)d.expandCollapseSonNode=function(c,a,b,e,f){(!a||!a.isHidden)&&r.apply(d,arguments)};var s=d.setSonNodeCheckBox;if(s)d.setSonNodeCheckBox=function(c,a,b,e){(!a||!a.isHidden)&&s.apply(d,arguments)};var t=d.repairParentChkClassWithSelf;if(t)d.repairParentChkClassWithSelf=function(c,a){(!a||!a.isHidden)&&t.apply(d,arguments)}})(jQuery);
diff --git a/main.js b/main.js
index 5fe6f1f..a67d44b 100644
--- a/main.js
+++ b/main.js
@@ -6,6 +6,11 @@ var vm = {
project_id: null,
repository_ref: null,
shortcuts_project: null,
+ /* default setting */
+ setting: {
+ toggle: true,
+ recursive: true
+ },
/* Detection if we are on GitLab page */
isGitLab: function () {
var isGitLab = document.querySelector("meta[content^='GitLab']");
@@ -30,17 +35,55 @@ var vm = {
vm.repository_ref = $('#repository_ref').val();
//console.info(vm)
},
- fetchFileTree: function (callback) {
+ loadNode: function (parentNode) {
+ if (parentNode && (parentNode.zAsync || parentNode.isAjaxing)) {
+ return;
+ }
+
+ if (parentNode) {
+ parentNode.isAjaxing = true;
+ vm.getZTree().updateNode(parentNode);
+ //ztree class update
+ $("#" + parentNode.tId + "_ico").attr({
+ style: "",
+ "class": "button" + " " + "ico_loading"
+ });
+ }
+
+ $.get(vm.apiRepoTree, {
+ id: vm.project_id,
+ path: parentNode ? parentNode.path : null,
+ ref_name: vm.repository_ref,
+ private_token: vm.private_token
+ }, function (result) {
+ if (parentNode) {
+ parentNode.isAjaxing = false;
+ parentNode.zAsync = true;
+ vm.getZTree().updateNode(parentNode);
+ }
+
+ var treeArr = [];
+
+ if (result) {
+ for (var i = 0; i < result.length; i++) {
+ var node = result[i];
+ if (node.type === 'tree') {
+ node.isParent = true;
+ }
+ treeArr.push(node);
+ }
+ }
+ vm.getZTree().addNodes(parentNode, i, treeArr);
+ });
+ },
+ loadRecursiveNode: function () {
$.get(vm.apiRepoTree, {
id: vm.project_id,
recursive: true,
ref_name: vm.repository_ref,
private_token: vm.private_token
}, function (result) {
- var tree = {
- // This array is used in order to meet the structure requirments by ztree.
- 'tree_arr': []
- };
+ var treeArr = [];
if (result) {
// Convert the response data to another structure which can be accepted by ztree.
@@ -53,11 +96,11 @@ var vm = {
}
var path_fragments = node.path.split('/');
- if (path_fragments.length === 1) { // root level
- tree[path_fragments[0]] = node;
- tree['tree_arr'].push(node);
- } else { // sub level
- var parent = tree[path_fragments[0]];
+ if (path_fragments.length === 1) { // root level
+ treeArr[path_fragments[0]] = node;
+ treeArr.push(node);
+ } else { // sub level
+ var parent = treeArr[path_fragments[0]];
for (var j = 1; j < path_fragments.length - 1; j++) {
parent = parent.children_map[path_fragments[j]];
}
@@ -67,13 +110,12 @@ var vm = {
}
}
- if (callback && typeof callback === "function") {
- callback(tree['tree_arr']);
- }
+ vm.getZTree().addNodes(null, i, treeArr);
});
},
showTree: function () {
- localStorage.setItem('toggle', 'show');
+ vm.setting.toggle = true;
+ vm.saveSetting();
$("html").css("margin-left", "230px");
$(".gitlabTreeView_sidebar").animate({
@@ -83,7 +125,8 @@ var vm = {
});
},
hideTree: function () {
- localStorage.setItem('toggle', 'hide');
+ vm.setting.toggle = false;
+ vm.saveSetting();
$("html").css("margin-left", "0px");
$(".gitlabTreeView_sidebar").animate({
@@ -111,13 +154,17 @@ var vm = {
callback: {
onClick: function (event, treeId, treeNode) {
vm.selectNode(treeNode);
+ },
+ onExpand: function (event, treeId, treeNode) {
+ if (vm.recursive) {
+ return;
+ }
+ vm.loadNode(treeNode);
}
}
};
- vm.fetchFileTree(function (tree) {
- $.fn.zTree.init($("#gitlabTreeView"), setting, tree);
- });
+ $.fn.zTree.init($("#gitlabTreeView"), setting);
},
selectNode: function (treeNode) {
if (treeNode.type === 'blob') {
@@ -171,6 +218,72 @@ var vm = {
getZTree: function () {
return $.fn.zTree.getZTreeObj("gitlabTreeView");
},
+ getLocalStorage: function (k) {
+ try {
+ return localStorage.getItem(k) ? JSON.parse(localStorage.getItem(k)) : null;
+ } catch (err) {
+ //console.info(err);
+ localStorage.removeItem(k);
+ return null;
+ }
+ },
+ setLocalStorage: function (k, v) {
+ localStorage.setItem(k, JSON.stringify(v));
+ },
+ getSetting: function () {
+ return vm.getLocalStorage("setting");
+ },
+ saveSetting: function () {
+ return vm.setLocalStorage("setting", vm.setting);
+ },
+ isNull: function (obj) {
+ if (typeof (obj) == "undefined" || obj == "undefined") {
+ return true;
+ } else {
+ return (obj == null || obj.length <= 0) ? true : false;
+ }
+ },
+ search: function (searchValue) {
+ var treeObj = vm.getZTree();
+ var allNode = treeObj.transformToArray(treeObj.getNodes());
+
+ if (!vm.isNull(searchValue)) {
+ var nodeList = treeObj.getNodesByParamFuzzy("name", searchValue);
+ if (nodeList.length > 0) {
+ treeObj.hideNodes(allNode);
+ vm.showTreeNodes(nodeList, treeObj);
+ treeObj.expandAll(true);
+ } else {
+ treeObj.hideNodes(allNode);
+ }
+ } else {
+ treeObj.showNodes(allNode);
+ //折叠所有节点
+ treeObj.expandAll(false);
+ }
+ },
+ findParentNodes: [],
+ findParent: function (node, zTree) {
+ var pNode = node.getParentNode();
+ if (pNode != null) {
+ vm.findParentNodes.push(pNode);
+ vm.findParent(pNode, zTree);
+ }
+ },
+ showTreeNodes: function (nodeList, zTree) {
+ vm.findParentNodes = [];
+ for (var i = 0; i < nodeList.length; i++) {
+ vm.findParent(nodeList[i], zTree);
+ //显示结果节点的子节点
+ if (nodeList[i].children != null) {
+ zTree.showNodes(zTree.transformToArray(nodeList[i].children));
+ }
+ }
+ //显示所有对应父节点
+ zTree.showNodes(vm.findParentNodes);
+ //显示搜索结果叶子节点
+ zTree.showNodes(nodeList);
+ },
init: function () {
if (!vm.isGitLab() || !vm.isFilePage()) {
return;
@@ -188,15 +301,25 @@ var vm = {
nav += "";
nav += "";
nav += "";
nav += "";
$("body").append($(nav));
- var toggle = localStorage.getItem('toggle') ? localStorage.getItem('toggle') : 'show';
+ //setting
+ vm.setting = vm.getSetting() != null ? vm.getSetting() : vm.setting;
+
- if (toggle == 'show') {
+ if (vm.setting.toggle) {
vm.showTree();
} else {
vm.hideTree();
@@ -209,11 +332,61 @@ var vm = {
vm.showTree();
}
});
+ /** search */
+ $(".gitlabTreeView_search_text").on("keyup", function (event) {
+ var searchValue = $(".gitlabTreeView_search_text").val();
+
+ if (vm.isNull(searchValue)) {
+ $(".gitlabTreeView_search_icon").addClass("fa-search").removeClass("fa-remove active");
+ } else {
+ $(".gitlabTreeView_search_icon").addClass("fa-remove active").removeClass("fa-search");
+ }
+
+ if (event.keyCode == 13) {
+ vm.search(searchValue);
+ }
+ });
+
+ /** clear value and search */
+ $(".gitlabTreeView_search_icon").on('click', function () {
+ $(".gitlabTreeView_search_text").val('');
+ var e = $.Event("keyup");
+ e.keyCode = 13;
+ $(".gitlabTreeView_search_text").trigger(e);
+ });
+
+ $(".gitlabTreeView_cog_icon").on("click", function () {
+ $(".gitlabTreeView_header_setting").slideToggle();
+ })
+
+ /** saveSetting */
+ $(".gitlabTreeView_header_setting_save").on("click", function () {
+ $(".gitlabTreeView_header_setting input[type=checkbox]").each(function () {
+ var name = $(this).attr('name');
+ vm.setting[name] = $(this).is(':checked');
+ vm.saveSetting();
+ });
+
+ $(".gitlabTreeView_header_setting").slideUp();
+ })
+
+ $(".gitlabTreeView_header_setting input[type=checkbox]").each(function () {
+ var name = $(this).attr('name');
+ var value = vm.setting[name];
+ $(this).prop('checked', value);
+ });
+
vm.initTree();
+
+ if (vm.setting.recursive) {
+ vm.loadRecursiveNode();
+ } else {
+ vm.loadNode(null);
+ }
}
};
$(function () {
vm.init();
-});
+});
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 784d55f..edf80de 100755
--- a/manifest.json
+++ b/manifest.json
@@ -1,6 +1,6 @@
{
"name": "Gitlab TreeView",
- "version": "1.1",
+ "version": "1.2",
"manifest_version": 2,
"author": "linsage",
"description": "Code tree for Gitlab",
@@ -36,6 +36,7 @@
"js": [
"js/jquery-1.12.4.min.js",
"js/jquery.ztree.all.min.js",
+ "js/jquery.ztree.exhide.min.js",
"main.js"
],
"run_at": "document_start"