| 1 | // Human Readable JSON Greasemonkey Script v0.1.1 |
|---|
| 2 | // Copyright 2007 Gerald Kaszuba |
|---|
| 3 | // Released under the GPL license |
|---|
| 4 | // http://www.gnu.org/copyleft/gpl.html |
|---|
| 5 | // -------------------------------------------------------------------- |
|---|
| 6 | // |
|---|
| 7 | // ==UserScript== |
|---|
| 8 | // @name Human Readable JSON |
|---|
| 9 | // @namespace http://misc.slowchop.com/misc/wiki/HumanReadableJSONGreasemonkey |
|---|
| 10 | // @description Adds line breaks and indentation to a JSON response, making it easier to read. |
|---|
| 11 | // @include http://misc.slowchop.com/misc/wiki/HumanReadableJSONGreasemonkey/JsonExample?format=txt |
|---|
| 12 | // ==/UserScript== |
|---|
| 13 | |
|---|
| 14 | /* |
|---|
| 15 | JSON pretty print borrowed and slightly modified from http://www.matsblog.com/stories/2075888/ |
|---|
| 16 | */ |
|---|
| 17 | (function () { |
|---|
| 18 | var INTEND = " "; |
|---|
| 19 | var NEWLINE = "\n"; |
|---|
| 20 | var pPr = false; |
|---|
| 21 | var intendLevel = 0; |
|---|
| 22 | var intend = function(a) { |
|---|
| 23 | if (!pPr) return a; |
|---|
| 24 | for (var l=0; l<intendLevel; l++) { |
|---|
| 25 | a[a.length] = INTEND; |
|---|
| 26 | } |
|---|
| 27 | return a; |
|---|
| 28 | }; |
|---|
| 29 | |
|---|
| 30 | var newline = function(a) { |
|---|
| 31 | if (pPr) a[a.length] = NEWLINE; |
|---|
| 32 | return a; |
|---|
| 33 | }; |
|---|
| 34 | |
|---|
| 35 | var m = { |
|---|
| 36 | '\b': '\\b', |
|---|
| 37 | '\t': '\\t', |
|---|
| 38 | '\n': '\\n', |
|---|
| 39 | '\f': '\\f', |
|---|
| 40 | '\r': '\\r', |
|---|
| 41 | '"' : '\\"', |
|---|
| 42 | '\\': '\\\\' |
|---|
| 43 | }, |
|---|
| 44 | s = { |
|---|
| 45 | array: function (x) { |
|---|
| 46 | var a = ['['], b, f, i, l = x.length, v; |
|---|
| 47 | a = newline(a); |
|---|
| 48 | intendLevel++; |
|---|
| 49 | for (i = 0; i < l; i += 1) { |
|---|
| 50 | v = x[i]; |
|---|
| 51 | f = s[typeof v]; |
|---|
| 52 | if (f) { |
|---|
| 53 | v = f(v); |
|---|
| 54 | if (typeof v == 'string') { |
|---|
| 55 | if (b) { |
|---|
| 56 | a[a.length] = ','; |
|---|
| 57 | a = newline(a); |
|---|
| 58 | } |
|---|
| 59 | a = intend(a); |
|---|
| 60 | a[a.length] = v; |
|---|
| 61 | b = true; |
|---|
| 62 | } |
|---|
| 63 | } |
|---|
| 64 | } |
|---|
| 65 | intendLevel--; |
|---|
| 66 | a = newline(a); |
|---|
| 67 | a = intend(a); |
|---|
| 68 | a[a.length] = ']'; |
|---|
| 69 | return a.join(''); |
|---|
| 70 | }, |
|---|
| 71 | 'boolean': function (x) { |
|---|
| 72 | return String(x); |
|---|
| 73 | }, |
|---|
| 74 | 'null': function (x) { |
|---|
| 75 | return "null"; |
|---|
| 76 | }, |
|---|
| 77 | number: function (x) { |
|---|
| 78 | return isFinite(x) ? String(x) : 'null'; |
|---|
| 79 | }, |
|---|
| 80 | object: function (x, formatedOutput) { |
|---|
| 81 | if (x) { |
|---|
| 82 | if (x instanceof Array) { |
|---|
| 83 | return s.array(x); |
|---|
| 84 | } |
|---|
| 85 | var a = ['{'], b, f, i, v; |
|---|
| 86 | a = newline(a); |
|---|
| 87 | intendLevel++; |
|---|
| 88 | for (i in x) { |
|---|
| 89 | v = x[i]; |
|---|
| 90 | f = s[typeof v]; |
|---|
| 91 | if (f) { |
|---|
| 92 | v = f(v); |
|---|
| 93 | if (typeof v == 'string') { |
|---|
| 94 | if (b) { |
|---|
| 95 | a[a.length] = ','; |
|---|
| 96 | a = newline(a); |
|---|
| 97 | } |
|---|
| 98 | a = intend(a); |
|---|
| 99 | a.push(s.string(i), ((pPr) ? ': ' : ':'), v); |
|---|
| 100 | b = true; |
|---|
| 101 | } |
|---|
| 102 | } |
|---|
| 103 | } |
|---|
| 104 | intendLevel--; |
|---|
| 105 | a = newline(a); |
|---|
| 106 | a = intend(a); |
|---|
| 107 | a[a.length] = '}'; |
|---|
| 108 | return a.join(''); |
|---|
| 109 | } |
|---|
| 110 | return 'null'; |
|---|
| 111 | }, |
|---|
| 112 | string: function (x) { |
|---|
| 113 | if (/["\\\x00-\x1f]/.test(x)) { |
|---|
| 114 | x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) { |
|---|
| 115 | var c = m[b]; |
|---|
| 116 | if (c) { |
|---|
| 117 | return c; |
|---|
| 118 | } |
|---|
| 119 | c = b.charCodeAt(); |
|---|
| 120 | return '\\u00' + |
|---|
| 121 | Math.floor(c / 16).toString(16) + |
|---|
| 122 | (c % 16).toString(16); |
|---|
| 123 | }); |
|---|
| 124 | } |
|---|
| 125 | return '"' + x + '"'; |
|---|
| 126 | } |
|---|
| 127 | }; |
|---|
| 128 | |
|---|
| 129 | Object.prototype.toJSONString = function (prettyPrint) { |
|---|
| 130 | pPr = prettyPrint; |
|---|
| 131 | return s.object(this); |
|---|
| 132 | }; |
|---|
| 133 | |
|---|
| 134 | Array.prototype.toJSONString = function (prettyPrint) { |
|---|
| 135 | pPr = prettyPrint; |
|---|
| 136 | return s.array(this); |
|---|
| 137 | }; |
|---|
| 138 | })(); |
|---|
| 139 | |
|---|
| 140 | String.prototype.parseJSON = function () { |
|---|
| 141 | try { |
|---|
| 142 | return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( |
|---|
| 143 | this.replace(/"(\\.|[^"\\])*"/g, ''))) && |
|---|
| 144 | eval('(' + this + ')'); |
|---|
| 145 | } catch (e) { |
|---|
| 146 | return false; |
|---|
| 147 | } |
|---|
| 148 | }; |
|---|
| 149 | |
|---|
| 150 | window.addEventListener( |
|---|
| 151 | 'load', |
|---|
| 152 | function() { |
|---|
| 153 | jsonTag = document.getElementsByTagName('pre')[0]; |
|---|
| 154 | if (!jsonTag) return; |
|---|
| 155 | jsonText = jsonTag.textContent; |
|---|
| 156 | jsonObj = jsonText.parseJSON(); |
|---|
| 157 | prettyJson = jsonObj.toJSONString(true); |
|---|
| 158 | jsonTag.textContent = prettyJson; |
|---|
| 159 | }, |
|---|
| 160 | true); |
|---|
| 161 | |
|---|
| 162 | // vim: ts=4 sw=4 expandtab |
|---|