PageSourceSearch

https://nstatus.org/lib/json-viewer/jquery.json-viewer.js

js nstatus.org collected 2026-09-24 14:26:15 UTC 5,176 bytes, 158 lines download raw bytes

1/**
2 * jQuery json-viewer
3 * @author: Alexandre Bodelot <[email protected]>
4 * @link: https://github.com/abodelot/jquery.json-viewer
5 */
6(function($) {
7
8  /**
9   * Check if arg is either an array with at least 1 element, or a dict with at least 1 key
10   * @return boolean
11   */
12  function isCollapsable(arg) {
13    return arg instanceof Object && Object.keys(arg).length > 0;
14  }
15
16  /**
17   * Check if a string represents a valid url
18   * @return boolean
19   */
20  function isUrl(string) {
21    var urlRegexp = /^(https?:\/\/|ftps?:\/\/)?([a-z0-9%-]+\.){1,}([a-z0-9-]+)?(:(\d{1,5}))?(\/([a-z0-9\-._~:/?#[\]@!$&'()*+,;=%]+)?)?$/i;
22    return urlRegexp.test(string);
23  }
24
25  /**
26   * Transform a json object into html representation
27   * @return string
28   */
29  function json2html(json, options) {
30    var html = '';
31    if (typeof json === 'string') {
32      // Escape tags and quotes
33      json = json
34        .replace(/&/g, '&amp;')
35        .replace(/</g, '&lt;')
36        .replace(/>/g, '&gt;')
37        .replace(/'/g, '&apos;')
38        .replace(/"/g, '&quot;');
39
40      if (options.withLinks && isUrl(json)) {
41        html += '<a href="' + json + '" class="json-string" target="_blank">' + json + '</a>';
42      } else {
43        // Escape double quotes in the rendered non-URL string.
44        json = json.replace(/&quot;/g, '\\&quot;');
45        html += '<span class="json-string">"' + json + '"</span>';
46      }
47    } else if (typeof json === 'number') {
48      html += '<span class="json-literal">' + json + '</span>';
49    } else if (typeof json === 'boolean') {
50      html += '<span class="json-literal">' + json + '</span>';
51    } else if (json === null) {
52      html += '<span class="json-literal">null</span>';
53    } else if (json instanceof Array) {
54      if (json.length > 0) {
55        html += '[<ol class="json-array">';
56        for (var i = 0; i < json.length; ++i) {
57          html += '<li>';
58          // Add toggle button if item is collapsable
59          if (isCollapsable(json[i])) {
60            html += '<a href class="json-toggle"></a>';
61          }
62          html += json2html(json[i], options);
63          // Add comma if item is not last
64          if (i < json.length - 1) {
65            html += ',';
66          }
67          html += '</li>';
68        }
69        html += '</ol>]';
70      } else {
71        html += '[]';
72      }
73    } else if (typeof json === 'object') {
74      var keyCount = Object.keys(json).length;
75      if (keyCount > 0) {
76        html += '{<ul class="json-dict">';
77        for (var key in json) {
78          if (Object.prototype.hasOwnProperty.call(json, key)) {
79            html += '<li>';
80            var keyRepr = options.withQuotes ?
81              '<span class="json-string">"' + key + '"</span>' : key;
82            // Add toggle button if item is collapsable
83            if (isCollapsable(json[key])) {
84              html += '<a href class="json-toggle">' + keyRepr + '</a>';
85            } else {
86              html += keyRepr;
87            }
88            html += ': ' + json2html(json[key], options);
89            // Add comma if item is not last
90            if (--keyCount > 0) {
91              html += ',';
92            }
93            html += '</li>';
94          }
95        }
96        html += '</ul>}';
97      } else {
98        html += '{}';
99      }
100    }
101    return html;
102  }
103
104  /**
105   * jQuery plugin method
106   * @param json: a javascript object
107   * @param options: an optional options hash
108   */
109  $.fn.jsonViewer = function(json, options) {
110    // Merge user options with default options
111    options = Object.assign({}, {
112      collapsed: false,
113      rootCollapsable: true,
114      withQuotes: false,
115      withLinks: true
116    }, options);
117
118    // jQuery chaining
119    return this.each(function() {
120
121      // Transform to HTML
122      var html = json2html(json, options);
123      if (options.rootCollapsable && isCollapsable(json)) {
124        html = '<a href class="json-toggle"></a>' + html;
125      }
126
127      // Insert HTML in target DOM element
128      $(this).html(html);
129      $(this).addClass('json-document');
130
131      // Bind click on toggle buttons
132      $(this).off('click');
133      $(this).on('click', 'a.json-toggle', function() {
134        var target = $(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
135        target.toggle();
136        if (target.is(':visible')) {
137          target.siblings('.json-placeholder').remove();
138        } else {
139          var count = target.children('li').length;
140          var placeholder = count + (count > 1 ? ' items' : ' item');
141          target.after('<a href class="json-placeholder">' + placeholder + '</a>');
142        }
143        return false;
144      });
145
146      // Simulate click on toggle button when placeholder is clicked
147      $(this).on('click', 'a.json-placeholder', function() {
148        $(this).siblings('a.json-toggle').click();
149        return false;
150      });
151
152      if (options.collapsed == true) {
153        // Trigger click to collapse all nodes
154        $(this).find('a.json-toggle').click();
155      }
156    });
157  };
158})(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.