json-viewer-updated

在原作者 0.4 版本上加入支持每行单独为 json 的文本输出

  1. // ==UserScript==
  2. // @name json-viewer-updated
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4.2
  5. // @description 在原作者 0.4 版本上加入支持每行单独为 json 的文本输出
  6. // @description 修复 0.4.1 版本 bug
  7. // @author sgd/robin.cai
  8. // @match *://*/*
  9. // @grant none
  10. // @require https://code.jquery.com/jquery-3.4.1.min.js
  11. // @icon https://www.easyicon.net/api/resizeApi.php?id=501159&size=128
  12. // ==/UserScript==
  13.  
  14.  
  15. // 解决和原网页jquery版本冲突
  16. var jq = jQuery.noConflict(true);
  17.  
  18. // jquery.json-viewer 插件 开始
  19. (function(jq){
  20. function isCollapsable(arg) {
  21. return arg instanceof Object && Object.keys(arg).length > 0;
  22. }
  23. function isUrl(string) {
  24. var regexp = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
  25. return regexp.test(string);
  26. }
  27. function json2html(json, options) {
  28. var html = '';
  29. if (typeof json === 'string') {
  30. /* Escape tags */
  31. json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  32. if (isUrl(json)){
  33. html += '<a href="' + json + '" class="json-string">"' + json + '"</a>';
  34. }
  35. else{
  36. html += '<span class="json-string">"' + json + '"</span>';
  37. }
  38. }
  39. else if (typeof json === 'number') {
  40. html += '<span class="json-literal">' + json + '</span>';
  41. }
  42. else if (typeof json === 'boolean') {
  43. html += '<span class="json-literal">' + json + '</span>';
  44. }
  45. else if (json === null) {
  46. html += '<span class="json-literal">null</span>';
  47. }
  48. else if (json instanceof Array) {
  49. if (json.length > 0) {
  50. html += '[<ol class="json-array">';
  51. for (var i = 0; i < json.length; ++i) {
  52. html += '<li>';
  53. /* Add toggle button if item is collapsable */
  54. if (isCollapsable(json[i])) {
  55. html += '<a href class="json-toggle"></a>';
  56. }
  57. html += json2html(json[i], options);
  58. /* Add comma if item is not last */
  59. if (i < json.length - 1) {
  60. html += ',';
  61. }
  62. html += '</li>';
  63. }
  64. html += '</ol>]';
  65. }
  66. else {
  67. html += '[]';
  68. }
  69. }
  70. else if (typeof json === 'object') {
  71. var key_count = Object.keys(json).length;
  72. if (key_count > 0) {
  73. html += '{<ul class="json-dict">';
  74. for (var key in json) {
  75. if (json.hasOwnProperty(key)) {
  76. html += '<li>';
  77. var keyRepr = options.withQuotes ?
  78. '<span class="json-string">"' + key + '"</span>' : key;
  79. /* Add toggle button if item is collapsable */
  80. if (isCollapsable(json[key])) {
  81. html += '<a href class="json-toggle">' + keyRepr + '</a>';
  82. }
  83. else {
  84. html += keyRepr;
  85. }
  86. html += ': ' + json2html(json[key], options);
  87. /* Add comma if item is not last */
  88. if (--key_count > 0){
  89. html += ',';
  90. }
  91. html += '</li>';
  92. }
  93. }
  94. html += '</ul>}';
  95. }
  96. else {
  97. html += '{}';
  98. }
  99. }
  100. return html;
  101. }
  102. jq.fn.jsonViewer = function(json, options) {
  103. options = options || {};
  104. return this.each(function() {
  105.  
  106. /* Transform to HTML */
  107. var html = json2html(json, options);
  108. if (isCollapsable(json)){
  109. html = '<a href class="json-toggle"></a>' + html;
  110. }
  111. /* Insert HTML in target DOM element */
  112. jq(this).html(html);
  113.  
  114. /* Bind click on toggle buttons */
  115. jq(this).off('click');
  116. jq(this).on('click', 'a.json-toggle', function() {
  117. var target = jq(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
  118. target.toggle();
  119. if (target.is(':visible')) {
  120. target.siblings('.json-placeholder').remove();
  121. }
  122. else {
  123. var count = target.children('li').length;
  124. var placeholder = count + (count > 1 ? ' items' : ' item');
  125. target.after('<a href class="json-placeholder">' + placeholder + '</a>');
  126. }
  127. return false;
  128. });
  129.  
  130. /* Simulate click on toggle button when placeholder is clicked */
  131. jq(this).on('click', 'a.json-placeholder', function() {
  132. jq(this).siblings('a.json-toggle').click();
  133. return false;
  134. });
  135.  
  136. if (options.collapsed == true) {
  137. /* Trigger click to collapse all nodes */
  138. jq(this).find('a.json-toggle').click();
  139. }
  140. });
  141. };
  142. })(jq);
  143. // jquery.json-viewer 插件 结束
  144.  
  145. (function() {
  146. 'use strict';
  147. // 添加样式
  148. var style = document.createElement("style");
  149. style.type = "text/css";
  150. var text = document.createTextNode("body{margin-bottom: 200px;}per{margin:20px;}#btn{position: fixed;top: 20px;right: 20px;background-color: transparent;border: 1px solid rgb(218, 220, 224);border-radius: 4px;box-sizing: border-box;color: rgb(26, 115, 232);cursor: pointer;line-height:30px;}#btn:hover{background-color:rgb(210, 227, 252);} ul.json-dict, ol.json-array {list-style-type: none;margin: 0 0 0 1px;border-left: 1px dotted #ccc;padding-left: 2em;}.json-string {color: #0B7500;}.json-literal {color: #1A01CC;font-weight: bold;}a.json-toggle {position: relative;color: inherit;text-decoration: none;}a.json-toggle:focus {outline: none;}a.json-toggle:before {color: #aaa;content: \"\\25BC\";position: absolute;display: inline-block;width: 1em;left: -1em;}a.json-toggle.collapsed:before {transform: rotate(-90deg);-ms-transform: rotate(-90deg);-webkit-transform: rotate(-90deg);}a.json-placeholder {color: #aaa;padding: 0 1em;text-decoration: none;} a.json-placeholder:hover { text-decoration: underline; }");
  151. style.appendChild(text);
  152. var head = document.getElementsByTagName("head")[0];
  153. head.appendChild(style);
  154.  
  155. var source = jq('pre[style="word-wrap: break-word; white-space: pre-wrap;"]');
  156. // 根据上面这一点没办法确定是需要添加json格式化工具,再加上对内容进行判断是不是json格式的内容
  157.  
  158. if(source.length > 0 && source.first().html().includes("}\n{")){
  159. var rawStr = source.first().html()
  160. var newStr = rawStr.replace(/}\n{/g, "},{")
  161. newStr = "[" + newStr + "]"
  162. if (isJSON(newStr)) {
  163. source.first().html(newStr)
  164. } else {
  165. source.first().html(rawStr)
  166. }
  167. }
  168.  
  169. // 如果是直接打开的json接口地址才需要格式化插件
  170. if(source.length > 0 && isJSON(source.first().html())){
  171. console.log("json-viewer 插件初始化成功");
  172. source = source.first();
  173. source.attr("id", "json-source")
  174. source.hide();
  175. var src = source.html();// 获取到内容
  176. // 添加一个格式化显示的per元素
  177. jq("body").append(jq('<per id="json-renderer"></per>'))
  178. console.log(src);
  179. // 将内容用eval函数处理下
  180. var input = eval('(' + src + ')');
  181. // 调用格式化方法,参数:是否收缩所有的节点 是否为Key添加双引号
  182. jq('#json-renderer').jsonViewer(input, {collapsed: false,withQuotes: true});
  183.  
  184. // 添加原文、格式化后内容的切换按钮
  185. jq("body").append('<input type="button" value="View Source" id="btn"/>');
  186. jq("body").on("click","#btn",function(){
  187. var v = jq(this).val();
  188. if(v=='View Source'){
  189. jq(this).val("Format Content");
  190. // 查看原文
  191. jq('#json-renderer').hide();
  192. jq('#json-source').show();
  193. }else{
  194. jq(this).val("View Source");
  195. // 格式化
  196. jq('#json-renderer').show();
  197. jq('#json-source').hide();
  198. }
  199. });
  200.  
  201. // 所有a标签,看是否是图片,是图片生成预览图
  202. jq(document).on("mouseenter mouseleave","a.json-string",function(event){
  203. if(event.type=='mouseenter'){
  204. // 移入
  205. var href = jq(this).attr('href');
  206. if(isImg(href)){
  207. jq("body").append('<div style="display:none; position: absolute;width:300px;height:200px;" class="preview"><img style="width:100%;height:100%;" src="'+ href +'" /></div>');
  208. var xPos = parseInt(event.pageX) + "px";
  209. var yPos = parseInt(event.pageY) + "px";
  210. jq(".preview").css("left", xPos);
  211. jq(".preview").css("top", yPos);
  212. jq(".preview").show();
  213. }
  214. }else{
  215. // 移除
  216. jq(".preview").remove();
  217. }
  218.  
  219. });
  220. }
  221.  
  222. /*检查是否是图片链接*/
  223. function isImg(pathImg) {
  224. var regexp = /^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?\/([\w#!:.?+=&%@!\-\/])*\.(gif|jpg|jpeg|png|GIF|JPG|PNG)([\w#!:.?+=&%@!\-\/])?/;
  225. return regexp.test(pathImg);
  226. }
  227. /** 检验内容是否是json格式的内容*/
  228. function isJSON(str) {
  229. if (typeof str == 'string') {
  230. try {
  231. var obj=JSON.parse(str);
  232. if(typeof obj == 'object' && obj ){
  233. console.log("is json")
  234. return true;
  235. }else{
  236. console.log("is not json")
  237. return false;
  238. }
  239.  
  240. } catch(e) {
  241. console.log('error:'+str+'!!!'+e);
  242. return false;
  243. }
  244. }
  245. console.log('It is not a string!')
  246. }
  247.  
  248.  
  249. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址