jsonFormater.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. function JsonFormater(opt) {
  2. this.options = $.extend({
  3. dom: '',
  4. tabSize: 2,
  5. singleTab: " ",
  6. quoteKeys: true,
  7. imgCollapsed: "../js/jsonFormater/images/Collapsed.gif",
  8. imgExpanded: "../js/jsonFormater/images/Expanded.gif",
  9. isCollapsible: true
  10. }, opt || {});
  11. this.isFormated = false;
  12. this.obj = {
  13. _dateObj: new Date(),
  14. _regexpObj: new RegExp()
  15. };
  16. this.init();
  17. }
  18. JsonFormater.prototype = {
  19. init: function () {
  20. this.tab = this.multiplyString(this.options.tabSize, this.options.singleTab);
  21. this.bindEvent();
  22. },
  23. doFormat: function (json) {
  24. var html;
  25. var obj;
  26. try {
  27. if(typeof json == 'object'){
  28. obj = [json];
  29. }else{
  30. if (json == ""){
  31. json = "\"\"";
  32. }
  33. obj = eval("[" + json + "]");
  34. }
  35. html = this.ProcessObject(obj[0], 0, false, false, false);
  36. $(this.options.dom).html("<pre class='jf-CodeContainer'>" + html + "</pre>");
  37. this.isFormated = true;
  38. } catch (e) {
  39. alert("JSON数据格式不正确:\n" + e.message);
  40. $(this.options.dom).html("");
  41. this.isFormated = false;
  42. }
  43. },
  44. bindEvent: function () {
  45. var that = this;
  46. $(this.options.dom).on('click', '.imgToggle', function () {
  47. if (that.isFormated == false) {
  48. return;
  49. }
  50. that.makeContentVisible($(this).parent().next(), !$(this).data('status'));
  51. });
  52. },
  53. expandAll: function () {
  54. if (this.isFormated == false) {
  55. return;
  56. }
  57. var that = this;
  58. this.traverseChildren($(this.options.dom), function(element){
  59. if(element.hasClass('jf-collapsible')){
  60. that.makeContentVisible(element, true);
  61. }
  62. }, 0);
  63. },
  64. collapseAll: function () {
  65. if (this.isFormated == false) {
  66. return;
  67. }
  68. var that = this;
  69. this.traverseChildren($(this.options.dom), function(element){
  70. if(element.hasClass('jf-collapsible')){
  71. that.makeContentVisible(element, false);
  72. }
  73. }, 0);
  74. },
  75. collapseLevel: function(level){
  76. if (this.isFormated == false) {
  77. return;
  78. }
  79. var that = this;
  80. this.traverseChildren($(this.options.dom), function(element, depth){
  81. if(element.hasClass('jf-collapsible')){
  82. if(depth >= level){
  83. that.makeContentVisible(element, false);
  84. }else{
  85. that.makeContentVisible(element, true);
  86. }
  87. }
  88. }, 0);
  89. },
  90. isArray: function (obj) {
  91. return obj &&
  92. typeof obj === 'object' &&
  93. typeof obj.length === 'number' && !(obj.propertyIsEnumerable('length'));
  94. },
  95. getRow: function (indent, data, isPropertyContent) {
  96. var tabs = "";
  97. if (!isPropertyContent) {
  98. tabs = this.multiplyString(indent, this.tab);
  99. }
  100. if (data != null && data.length > 0 && data.charAt(data.length - 1) != "\n") {
  101. data = data + "\n";
  102. }
  103. return tabs + data;
  104. },
  105. formatLiteral: function (literal, quote, comma, indent, isArray, style) {
  106. if (typeof literal == 'string') {
  107. literal = literal.split("<").join("&lt;").split(">").join("&gt;");
  108. }
  109. var str = "<span class='jf-" + style + "'>" + quote + literal + quote + comma + "</span>";
  110. if (isArray) str = this.getRow(indent, str);
  111. return str;
  112. },
  113. formatFunction: function (indent, obj) {
  114. var tabs;
  115. var i;
  116. var funcStrArray = obj.toString().split("\n");
  117. var str = "";
  118. tabs = this.multiplyString(indent, this.tab);
  119. for (i = 0; i < funcStrArray.length; i++) {
  120. str += ((i == 0) ? "" : tabs) + funcStrArray[i] + "\n";
  121. }
  122. return str;
  123. },
  124. multiplyString: function (num, str) {
  125. var result = '';
  126. for (var i = 0; i < num; i++) {
  127. result += str;
  128. }
  129. return result;
  130. },
  131. traverseChildren: function (element, func, depth) {
  132. var length = element.children().length;
  133. for (var i = 0; i < length; i++) {
  134. this.traverseChildren(element.children().eq(i), func, depth + 1);
  135. }
  136. func(element, depth);
  137. },
  138. makeContentVisible : function(element, visible){
  139. var img = element.prev().find('img');
  140. if(visible){
  141. element.show();
  142. img.attr('src', this.options.imgExpanded);
  143. img.data('status', 1);
  144. }else{
  145. element.hide();
  146. img.attr('src', this.options.imgCollapsed);
  147. img.data('status', 0);
  148. }
  149. },
  150. ProcessObject: function (obj, indent, addComma, isArray, isPropertyContent) {
  151. var html = "";
  152. var comma = (addComma) ? "<span class='jf-Comma'>,</span> " : "";
  153. var type = typeof obj;
  154. var clpsHtml = "";
  155. var prop;
  156. if (this.isArray(obj)) {
  157. if (obj.length == 0) {
  158. html += this.getRow(indent, "<span class='jf-ArrayBrace'>[ ]</span>" + comma, isPropertyContent);
  159. } else {
  160. clpsHtml = this.options.isCollapsible ? "<span><img class='imgToggle' data-status='1' src='" + this.options.imgExpanded + "'/></span><span class='jf-collapsible'>" : "";
  161. html += this.getRow(indent, "<span class='jf-ArrayBrace'>[</span>" + clpsHtml, isPropertyContent);
  162. for (var i = 0; i < obj.length; i++) {
  163. html += this.ProcessObject(obj[i], indent + 1, i < (obj.length - 1), true, false);
  164. }
  165. clpsHtml = this.options.isCollapsible ? "</span>" : "";
  166. html += this.getRow(indent, clpsHtml + "<span class='jf-ArrayBrace'>]</span>" + comma);
  167. }
  168. } else if (type == 'object') {
  169. if (obj == null) {
  170. html += this.formatLiteral("null", "", comma, indent, isArray, "Null");
  171. } else {
  172. var numProps = 0;
  173. for (prop in obj) numProps++;
  174. if (numProps == 0) {
  175. html += this.getRow(indent, "<span class='jf-ObjectBrace'>{ }</span>" + comma, isPropertyContent);
  176. } else {
  177. clpsHtml = this.options.isCollapsible ? "<span><img class='imgToggle' data-status='1' src='" + this.options.imgExpanded + "'/></span><span class='jf-collapsible'>" : "";
  178. html += this.getRow(indent, "<span class='jf-ObjectBrace'>{</span>" + clpsHtml, isPropertyContent);
  179. var j = 0;
  180. for (prop in obj) {
  181. var quote = this.options.quoteKeys ? "\"" : "";
  182. html += this.getRow(indent + 1, "<span class='jf-PropertyName'>" + quote + prop + quote + "</span>: " + this.ProcessObject(obj[prop], indent + 1, ++j < numProps, false, true));
  183. }
  184. clpsHtml = this.options.isCollapsible ? "</span>" : "";
  185. html += this.getRow(indent, clpsHtml + "<span class='jf-ObjectBrace'>}</span>" + comma);
  186. }
  187. }
  188. } else if (type == 'number') {
  189. html += this.formatLiteral(obj, "", comma, indent, isArray, "Number");
  190. } else if (type == 'boolean') {
  191. html += this.formatLiteral(obj, "", comma, indent, isArray, "Boolean");
  192. }else if (type == 'undefined') {
  193. html += this.formatLiteral("undefined", "", comma, indent, isArray, "Null");
  194. } else {
  195. html += this.formatLiteral(obj.toString().split("\\").join("\\\\").split('"').join('\\"'), "\"", comma, indent, isArray, "String");
  196. }
  197. return html;
  198. }
  199. };