1 2/*! 3jQuery JSONView. 4Licensed under the MIT License. 5 */ 6(function(jQuery) { 7 var $, Collapser, JSONFormatter, JSONView; 8 JSONFormatter = (function() { 9 function JSONFormatter(options) { 10 if (options == null) { 11 options = {}; 12 } 13 this.options = options; 14 } 15 16 JSONFormatter.prototype.htmlEncode = function(html) { 17 if (html !== null) { 18 return html.toString().replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">"); 19 } else { 20 return ''; 21 } 22 }; 23 24 JSONFormatter.prototype.jsString = function(s) { 25 s = JSON.stringify(s).slice(1, -1); 26 return this.htmlEncode(s); 27 }; 28 29 JSONFormatter.prototype.decorateWithSpan = function(value, className) { 30 return "<span class=\"" + className + "\">" + (this.htmlEncode(value)) + "</span>"; 31 }; 32 33 JSONFormatter.prototype.valueToHTML = function(value, level) { 34 var valueType; 35 if (level == null) { 36 level = 0; 37 } 38 valueType = Object.prototype.toString.call(value).match(/\s(.+)]/)[1].toLowerCase(); 39 return this["" + valueType + "ToHTML"].call(this, value, level); 40 }; 41 42 JSONFormatter.prototype.nullToHTML = function(value) { 43 return this.decorateWithSpan('null', 'null'); 44 }; 45 46 JSONFormatter.prototype.numberToHTML = function(value) { 47 return this.decorateWithSpan(value, 'num'); 48 }; 49 50 JSONFormatter.prototype.stringToHTML = function(value) { 51 var multilineClass, newLinePattern; 52 if (/^(http|https|file):\/\/[^\s]+$/i.test(value)) { 53 return "<a href=\"" + (this.htmlEncode(value)) + "\"><span class=\"q\">\"</span>" + (this.jsString(value)) + "<span class=\"q\">\"</span></a>"; 54 } else { 55 multilineClass = ''; 56 value = this.jsString(value); 57 if (this.options.nl2br) { 58 newLinePattern = /([^>\\r\\n]?)(\\r\\n|\\n\\r|\\r|\\n)/g; 59 if (newLinePattern.test(value)) { 60 multilineClass = ' multiline'; 61 value = (value + '').replace(newLinePattern, '$1' + '<br />'); 62 } 63 } 64 return "<span class=\"string" + multilineClass + "\">\"" + value + "\"</span>"; 65 } 66 }; 67 68 JSONFormatter.prototype.booleanToHTML = function(value) { 69 return this.decorateWithSpan(value, 'bool'); 70 }; 71 72 JSONFormatter.prototype.arrayToHTML = function(array, level) { 73 var collapsible, hasContents, index, numProps, output, value, _i, _len; 74 if (level == null) { 75 level = 0; 76 } 77 hasContents = false; 78 output = ''; 79 numProps = array.length; 80 for (index = _i = 0, _len = array.length; _i < _len; index = ++_i) { 81 value = array[index]; 82 hasContents = true; 83 output += '<li>' + this.valueToHTML(value, level + 1); 84 if (numProps > 1) { 85 output += ','; 86 } 87 output += '</li>'; 88 numProps--; 89 } 90 if (hasContents) { 91 collapsible = level === 0 ? '' : ' collapsible'; 92 return "[<ul class=\"array level" + level + collapsible + "\">" + output + "</ul>]"; 93 } else { 94 return '[ ]'; 95 } 96 }; 97 98 JSONFormatter.prototype.objectToHTML = function(object, level) { 99 var collapsible, hasContents, numProps, output, prop, value; 100 if (level == null) { 101 level = 0; 102 } 103 hasContents = false; 104 output = ''; 105 numProps = 0; 106 for (prop in object) { 107 numProps++; 108 } 109 for (prop in object) { 110 value = object[prop]; 111 hasContents = true; 112 output += "<li><span class=\"prop\"><span class=\"q\">\"</span>" + (this.jsString(prop)) + "<span class=\"q\">\"</span></span>: " + (this.valueToHTML(value, level + 1)); 113 if (numProps > 1) { 114 output += ','; 115 } 116 output += '</li>'; 117 numProps--; 118 } 119 if (hasContents) { 120 collapsible = level === 0 ? '' : ' collapsible'; 121 return "{<ul class=\"obj level" + level + collapsible + "\">" + output + "</ul>}"; 122 } else { 123 return '{ }'; 124 } 125 }; 126 127 JSONFormatter.prototype.jsonToHTML = function(json) { 128 return "<div class=\"jsonview\">" + (this.valueToHTML(json)) + "</div>"; 129 }; 130 131 return JSONFormatter; 132 133 })();
134 (typeof module !== "undefined" && module !== null) && (module.exports = JSONFormatter); 135 Collapser = (function() { 136 function Collapser() {} 137 138 Collapser.bindEvent = function(item, options) { 139 var collapser; 140 collapser = document.createElement('div'); 141 collapser.className = 'collapser'; 142 collapser.innerHTML = options.collapsed ? '+' : '-'; 143 collapser.addEventListener('click', (function(_this) { 144 return function(event) { 145 return _this.toggle(event.target, options); 146 }; 147 })(this)); 148 item.insertBefore(collapser, item.firstChild); 149 if (options.collapsed) { 150 return this.collapse(collapser); 151 } 152 }; 153 154 Collapser.expand = function(collapser) { 155 var ellipsis, target; 156 target = this.collapseTarget(collapser); 157 if (target.style.display === '') { 158 return; 159 } 160 ellipsis = target.parentNode.getElementsByClassName('ellipsis')[0]; 161 target.parentNode.removeChild(ellipsis); 162 target.style.display = ''; 163 return collapser.innerHTML = '-'; 164 }; 165 166 Collapser.collapse = function(collapser) { 167 var ellipsis, target; 168 target = this.collapseTarget(collapser); 169 if (target.style.display === 'none') { 170 return; 171 } 172 target.style.display = 'none'; 173 ellipsis = document.createElement('span'); 174 ellipsis.className = 'ellipsis'; 175 ellipsis.innerHTML = ' … '; 176 target.parentNode.insertBefore(ellipsis, target); 177 return collapser.innerHTML = '+'; 178 }; 179 180 Collapser.toggle = function(collapser, options) { 181 var action, collapsers, target, _i, _len, _results; 182 if (options == null) { 183 options = {}; 184 } 185 target = this.collapseTarget(collapser); 186 action = target.style.display === 'none' ? 'expand' : 'collapse'; 187 if (options.recursive_collapser) { 188 collapsers = collapser.parentNode.getElementsByClassName('collapser'); 189 _results = []; 190 for (_i = 0, _len = collapsers.length; _i < _len; _i++) { 191 collapser = collapsers[_i]; 192 _results.push(this[action](collapser)); 193 } 194 return _results; 195 } else { 196 return this[action](collapser); 197 } 198 }; 199 200 Collapser.collapseTarget = function(collapser) { 201 var target, targets; 202 targets = collapser.parentNode.getElementsByClassName('collapsible'); 203 if (!targets.length) { 204 return; 205 } 206 return target = targets[0]; 207 }; 208 209 return Collapser; 210 211 })(); 212 $ = jQuery; 213 JSONView = { 214 collapse: function(el) { 215 if (el.innerHTML === '-') { 216 return Collapser.collapse(el); 217 } 218 }, 219 expand: function(el) { 220 if (el.innerHTML === '+') { 221 return Collapser.expand(el); 222 } 223 }, 224 toggle: function(el) { 225 return Collapser.toggle(el); 226 } 227 }; 228 return $.fn.JSONView = function() { 229 var args, defaultOptions, formatter, json, method, options, outputDoc; 230 args = arguments; 231 if (JSONView[args[0]] != null) { 232 method = args[0]; 233 return this.each(function() { 234 var $this, level; 235 $this = $(this); 236 if (args[1] != null) { 237 level = args[1]; 238 return $this.find(".jsonview .collapsible.level" + level).siblings('.collapser').each(function() { 239 return JSONView[method](this); 240 }); 241 } else { 242 return $this.find('.jsonview > ul > li .collapsible').siblings('.collapser').each(function() { 243 return JSONView[method](this); 244 }); 245 } 246 }); 247 } else { 248 json = args[0]; 249 options = args[1] || {}; 250 defaultOptions = { 251 collapsed: false, 252 nl2br: false, 253 recursive_collapser: false 254 }; 255 options = $.extend(defaultOptions, options); 256 formatter = new JSONFormatter({ 257 nl2br: options.nl2br 258 }); 259 if (Object.prototype.toString.call(json) === '[object String]') { 260 json = JSON.parse(json); 261 } 262 outputDoc = formatter.jsonToHTML(json); 263 return this.each(function() { 264 var $this, item, items, _i, _len, _results; 265 $this = $(this); 266 $this.html(outputDoc); 267 items = $this[0].getElementsByClassName('collapsible'); 268 _results = []; 269 for (_i = 0, _len = items.length; _i < _len; _i++) { 270 item = items[_i]; 271 if (item.parentNode.nodeName === 'LI') { 272 _results.push(Collapser.bindEvent(item.parentNode, options)); 273 } else { 274 _results.push(void 0); 275 } 276 } 277 return _results; 278 }); 279 } 280 }; 281})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.