github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/httpserver/static-content/jsontree.js (about) 1 var JSONTree = (function() { 2 3 var escapeMap = { 4 '&': '&', 5 '<': '<', 6 '>': '>', 7 '"': '"', 8 '\'': ''', 9 '/': '/' 10 }; 11 12 var defaultSettings = { 13 indent: 2 14 }; 15 16 var id = 0; 17 var instances = 0; 18 var current_collapse_level = null; 19 var ids_to_collapse = []; 20 21 this.create = function(data, settings, collapse_depth) { 22 current_collapse_level = typeof collapse_depth !== 'undefined' ? collapse_depth : -1; 23 instances += 1; 24 return _span(_jsVal(data, 0, false), {class: 'jstValue'}); 25 }; 26 27 this.collapse = function() { 28 var arrayLength = ids_to_collapse.length; 29 for (var i = 0; i < arrayLength; i++) { 30 JSONTree.toggle(ids_to_collapse[i]); 31 } 32 }; 33 34 var _escape = function(text) { 35 return text.replace(/[&<>'"]/g, function(c) { 36 return escapeMap[c]; 37 }); 38 }; 39 40 var _id = function() { 41 return instances + '_' + id++; 42 }; 43 44 var _lastId = function() { 45 return instances + '_' + (id - 1); 46 }; 47 48 var _jsVal = function(value, depth, indent) { 49 if (value !== null) { 50 var type = typeof value; 51 switch (type) { 52 case 'boolean': 53 return _jsBool(value, indent ? depth : 0); 54 case 'number': 55 return _jsNum(value, indent ? depth : 0); 56 case 'string': 57 return _jsStr(value, indent ? depth : 0); 58 default: 59 if (value instanceof Array) { 60 return _jsArr(value, depth, indent); 61 } else { 62 return _jsObj(value, depth, indent); 63 } 64 } 65 } else { 66 return _jsNull(indent ? depth : 0); 67 } 68 }; 69 70 var _jsObj = function(object, depth, indent) { 71 var id = _id(); 72 _decrementCollapseLevel("_jsObj"); 73 var content = Object.keys(object).map(function(property) { 74 return _property(property, object[property], depth + 1, true); 75 }).join(_comma()); 76 var body = [ 77 _openBracket('{', indent ? depth : 0, id), 78 _span(content, {id: id}), 79 _closeBracket('}', depth) 80 ].join('\n'); 81 _incrementCollapseLevel("_jsObj"); 82 return _span(body, {}); 83 }; 84 85 var _jsArr = function(array, depth, indent) { 86 var id = _id(); 87 _decrementCollapseLevel("_jsArr"); 88 var body = array.map(function(element) { 89 return _jsVal(element, depth + 1, true); 90 }).join(_comma()); 91 var arr = [ 92 _openBracket('[', indent ? depth : 0, id), 93 _span(body, {id: id}), 94 _closeBracket(']', depth) 95 ].join('\n'); 96 _incrementCollapseLevel("_jsArr"); 97 return arr; 98 }; 99 100 var _jsStr = function(value, depth) { 101 var jsonString = _escape(JSON.stringify(value)); 102 return _span(_indent(jsonString, depth), {class: 'jstStr'}); 103 }; 104 105 var _jsNum = function(value, depth) { 106 return _span(_indent(value, depth), {class: 'jstNum'}); 107 }; 108 109 var _jsBool = function(value, depth) { 110 return _span(_indent(value, depth), {class: 'jstBool'}); 111 }; 112 113 var _jsNull = function(depth) { 114 return _span(_indent('null', depth), {class: 'jstNull'}); 115 }; 116 117 var _property = function(name, value, depth) { 118 var property = _indent(_escape(JSON.stringify(name)) + ': ', depth); 119 var propertyValue = _span(_jsVal(value, depth, false), {}); 120 return _span(property + propertyValue, {class: 'jstProperty'}); 121 }; 122 123 var _comma = function() { 124 return _span(',\n', {class: 'jstComma'}); 125 }; 126 127 var _span = function(value, attrs) { 128 return _tag('span', attrs, value); 129 }; 130 131 var _tag = function(tag, attrs, content) { 132 return '<' + tag + Object.keys(attrs).map(function(attr) { 133 return ' ' + attr + '="' + attrs[attr] + '"'; 134 }).join('') + '>' + 135 content + 136 '</' + tag + '>'; 137 }; 138 139 var _openBracket = function(symbol, depth, id) { 140 return ( 141 _span(_indent(symbol, depth), {class: 'jstBracket'}) + 142 _span('', {class: 'jstFold', onclick: 'JSONTree.toggle(\'' + id + '\')'}) 143 ); 144 }; 145 146 this.toggle = function(id) { 147 var element = document.getElementById(id); 148 var parent = element.parentNode; 149 var toggleButton = element.previousElementSibling; 150 if (element.className === '') { 151 element.className = 'jstHiddenBlock'; 152 parent.className = 'jstFolded'; 153 toggleButton.className = 'jstExpand'; 154 } else { 155 element.className = ''; 156 parent.className = ''; 157 toggleButton.className = 'jstFold'; 158 } 159 }; 160 161 var _closeBracket = function(symbol, depth) { 162 return _span(_indent(symbol, depth), {}); 163 }; 164 165 var _indent = function(value, depth) { 166 return Array((depth * 2) + 1).join(' ') + value; 167 }; 168 169 var _decrementCollapseLevel = function(caller) { 170 if (current_collapse_level <= 0) { 171 ids_to_collapse.push(_lastId()); 172 } else { 173 } 174 current_collapse_level--; 175 }; 176 177 var _incrementCollapseLevel = function(caller) { 178 current_collapse_level++; 179 }; 180 181 return this; 182 })();