JSON Response Formatter

Toggle between beautified and raw JSON display at top of the page, with copy functionality.

  1. // ==UserScript==
  2. // @name JSON Response Formatter
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Toggle between beautified and raw JSON display at top of the page, with copy functionality.
  6. // @author taky@taky.com
  7. // @match *://*/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Set to false if you don't want to beautify JSON by default
  15. const autoBeautify = true;
  16.  
  17. function createLink(textContent, active, onclickHandler) {
  18. let link = document.createElement('a');
  19. link.style.fontFamily = 'monospace';
  20. link.style.color = 'blue';
  21. link.style.textDecoration = active ? 'underline' : 'none';
  22. link.style.cursor = 'pointer';
  23. link.style.display = 'inline';
  24. link.style.marginRight = '10px';
  25. link.textContent = textContent.toLowerCase();
  26. link.href = '#';
  27. link.onclick = onclickHandler;
  28. return link;
  29. }
  30.  
  31. function initializeJsonFormatter() {
  32. let content = document.body.innerText.trim();
  33. let firstChar = content.charAt(0);
  34.  
  35. if (firstChar === '{' || firstChar === '[') {
  36. try {
  37. let json = JSON.parse(content);
  38.  
  39. let rawPre = document.createElement('pre');
  40. let beautifiedPre = document.createElement('pre');
  41.  
  42. rawPre.style.fontFamily = 'monospace';
  43. rawPre.style.margin = '0';
  44. rawPre.style.padding = '0';
  45. rawPre.textContent = content;
  46.  
  47. beautifiedPre.style.fontFamily = 'monospace';
  48. beautifiedPre.style.margin = '0';
  49. beautifiedPre.style.padding = '0';
  50. beautifiedPre.textContent = JSON.stringify(json, null, 2);
  51.  
  52. if (!autoBeautify) {
  53. beautifiedPre.style.display = 'none';
  54. } else {
  55. rawPre.style.display = 'none';
  56. }
  57.  
  58. let toggleRaw = function(e) {
  59. e.preventDefault();
  60. beautifiedPre.style.display = 'none';
  61. rawPre.style.display = 'block';
  62. rawLink.style.textDecoration = 'underline';
  63. beautifiedLink.style.textDecoration = 'none';
  64. };
  65.  
  66. let toggleBeautified = function(e) {
  67. e.preventDefault();
  68. beautifiedPre.style.display = 'block';
  69. rawPre.style.display = 'none';
  70. rawLink.style.textDecoration = 'none';
  71. beautifiedLink.style.textDecoration = 'underline';
  72. };
  73.  
  74. let copyVisibleContent = function(e) {
  75. e.preventDefault();
  76. let contentToCopy = beautifiedPre.style.display === 'block' ? beautifiedPre.textContent : rawPre.textContent;
  77. navigator.clipboard.writeText(contentToCopy).then(function() {
  78. copyLink.textContent = 'copied';
  79. setTimeout(function() {
  80. copyLink.textContent = 'copy';
  81. }, 1000);
  82. }, function(err) {
  83. copyLink.textContent = 'failed to copy';
  84. setTimeout(function() {
  85. copyLink.textContent = 'copy';
  86. }, 1000);
  87. console.error('Could not copy text: ', err);
  88. });
  89. };
  90.  
  91. let rawLink = createLink('Raw', !autoBeautify, toggleRaw);
  92. let beautifiedLink = createLink('Beautified', autoBeautify, toggleBeautified);
  93. let copyLink = createLink('Copy', false, copyVisibleContent);
  94.  
  95. let linksContainer = document.createElement('div');
  96. linksContainer.style.marginBottom = '10px';
  97. linksContainer.appendChild(rawLink);
  98. linksContainer.appendChild(beautifiedLink);
  99. linksContainer.appendChild(copyLink);
  100.  
  101. document.body.innerHTML = '';
  102. document.body.appendChild(linksContainer);
  103. document.body.appendChild(rawPre);
  104. document.body.appendChild(beautifiedPre);
  105. } catch (e) {
  106. // console.error('Document is not pure JSON: ', e);
  107. }
  108. }
  109. }
  110.  
  111. if (document.readyState === 'loading') {
  112. document.addEventListener('DOMContentLoaded', initializeJsonFormatter);
  113. } else {
  114. initializeJsonFormatter();
  115. }
  116. })();