Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/format/jsonprettyprinter.js
2868 views
1
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Creates a string of a JSON object, properly indented for
17
* display.
18
*
19
*/
20
21
goog.provide('goog.format.JsonPrettyPrinter');
22
goog.provide('goog.format.JsonPrettyPrinter.SafeHtmlDelimiters');
23
goog.provide('goog.format.JsonPrettyPrinter.TextDelimiters');
24
25
goog.require('goog.html.SafeHtml');
26
goog.require('goog.json');
27
goog.require('goog.json.Serializer');
28
goog.require('goog.string');
29
goog.require('goog.string.format');
30
31
32
33
/**
34
* Formats a JSON object as a string, properly indented for display. Supports
35
* displaying the string as text or html. Users can also specify their own
36
* set of delimiters for different environments. For example, the JSON object:
37
*
38
* <code>{"a": 1, "b": {"c": null, "d": true, "e": [1, 2]}}</code>
39
*
40
* Will be displayed like this:
41
*
42
* <code>{
43
* "a": 1,
44
* "b": {
45
* "c": null,
46
* "d": true,
47
* "e": [
48
* 1,
49
* 2
50
* ]
51
* }
52
* }</code>
53
* @param {?goog.format.JsonPrettyPrinter.TextDelimiters=} opt_delimiters
54
* Container for the various strings to use to delimit objects, arrays,
55
* newlines, and other pieces of the output.
56
* @constructor
57
*/
58
goog.format.JsonPrettyPrinter = function(opt_delimiters) {
59
60
/**
61
* The set of characters to use as delimiters.
62
* @private @const {!goog.format.JsonPrettyPrinter.TextDelimiters}
63
*/
64
this.delimiters_ =
65
opt_delimiters || new goog.format.JsonPrettyPrinter.TextDelimiters();
66
67
/**
68
* Used to serialize property names and values.
69
* @private @const {!goog.json.Serializer}
70
*/
71
this.jsonSerializer_ = new goog.json.Serializer();
72
};
73
74
75
/**
76
* Formats a JSON object as a string, properly indented for display.
77
* @param {*} json The object to pretty print. It could be a JSON object, a
78
* string representing a JSON object, or any other type.
79
* @return {string} Returns a string of the JSON object, properly indented for
80
* display.
81
*/
82
goog.format.JsonPrettyPrinter.prototype.format = function(json) {
83
var buffer = this.format_(json);
84
var output = '';
85
for (var i = 0; i < buffer.length; i++) {
86
var item = buffer[i];
87
output += item instanceof goog.html.SafeHtml ?
88
goog.html.SafeHtml.unwrap(item) :
89
item;
90
}
91
return output;
92
};
93
94
95
/**
96
* Formats a JSON object as a SafeHtml, properly indented for display.
97
* @param {*} json The object to pretty print. It could be a JSON object, a
98
* string representing a JSON object, or any other type.
99
* @return {!goog.html.SafeHtml} A HTML code of the JSON object.
100
*/
101
goog.format.JsonPrettyPrinter.prototype.formatSafeHtml = function(json) {
102
return goog.html.SafeHtml.concat(this.format_(json));
103
};
104
105
106
/**
107
* Formats a JSON object and returns an output buffer.
108
* @param {*} json The object to pretty print.
109
* @return {!Array<string|!goog.html.SafeHtml>}
110
* @private
111
*/
112
goog.format.JsonPrettyPrinter.prototype.format_ = function(json) {
113
// If input is undefined, null, or empty, return an empty string.
114
if (!goog.isDefAndNotNull(json)) {
115
return [];
116
}
117
if (goog.isString(json)) {
118
if (goog.string.isEmptyOrWhitespace(json)) {
119
return [];
120
}
121
// Try to coerce a string into a JSON object.
122
json = goog.json.parse(json);
123
}
124
var outputBuffer = [];
125
this.printObject_(json, outputBuffer, 0);
126
return outputBuffer;
127
};
128
129
130
/**
131
* Formats a property value based on the type of the propery.
132
* @param {*} val The object to format.
133
* @param {!Array<string|!goog.html.SafeHtml>} outputBuffer The buffer to write
134
* the response to.
135
* @param {number} indent The number of spaces to indent each line of the
136
* output.
137
* @private
138
*/
139
goog.format.JsonPrettyPrinter.prototype.printObject_ = function(
140
val, outputBuffer, indent) {
141
var typeOf = goog.typeOf(val);
142
switch (typeOf) {
143
case 'null':
144
case 'boolean':
145
case 'number':
146
case 'string':
147
// "null", "boolean", "number" and "string" properties are printed
148
// directly to the output.
149
this.printValue_(
150
/** @type {null|string|boolean|number} */ (val), typeOf,
151
outputBuffer);
152
break;
153
case 'array':
154
// Example of how an array looks when formatted
155
// (using the default delimiters):
156
// [
157
// 1,
158
// 2,
159
// 3
160
// ]
161
outputBuffer.push(this.delimiters_.arrayStart);
162
var i = 0;
163
// Iterate through the array and format each element.
164
for (i = 0; i < val.length; i++) {
165
if (i > 0) {
166
// There are multiple elements, add a comma to separate them.
167
outputBuffer.push(this.delimiters_.propertySeparator);
168
}
169
outputBuffer.push(this.delimiters_.lineBreak);
170
this.printSpaces_(indent + this.delimiters_.indent, outputBuffer);
171
this.printObject_(
172
val[i], outputBuffer, indent + this.delimiters_.indent);
173
}
174
// If there are no properties in this object, don't put a line break
175
// between the beginning "[" and ending "]", so the output of an empty
176
// array looks like <code>[]</code>.
177
if (i > 0) {
178
outputBuffer.push(this.delimiters_.lineBreak);
179
this.printSpaces_(indent, outputBuffer);
180
}
181
outputBuffer.push(this.delimiters_.arrayEnd);
182
break;
183
case 'object':
184
// Example of how an object looks when formatted
185
// (using the default delimiters):
186
// {
187
// "a": 1,
188
// "b": 2,
189
// "c": "3"
190
// }
191
outputBuffer.push(this.delimiters_.objectStart);
192
var propertyCount = 0;
193
// Iterate through the object and display each property.
194
for (var name in val) {
195
if (!val.hasOwnProperty(name)) {
196
continue;
197
}
198
if (propertyCount > 0) {
199
// There are multiple properties, add a comma to separate them.
200
outputBuffer.push(this.delimiters_.propertySeparator);
201
}
202
outputBuffer.push(this.delimiters_.lineBreak);
203
this.printSpaces_(indent + this.delimiters_.indent, outputBuffer);
204
this.printName_(name, outputBuffer);
205
outputBuffer.push(
206
this.delimiters_.nameValueSeparator, this.delimiters_.space);
207
this.printObject_(
208
val[name], outputBuffer, indent + this.delimiters_.indent);
209
propertyCount++;
210
}
211
// If there are no properties in this object, don't put a line break
212
// between the beginning "{" and ending "}", so the output of an empty
213
// object looks like <code>{}</code>.
214
if (propertyCount > 0) {
215
outputBuffer.push(this.delimiters_.lineBreak);
216
this.printSpaces_(indent, outputBuffer);
217
}
218
outputBuffer.push(this.delimiters_.objectEnd);
219
break;
220
// Other types, such as "function", aren't expected in JSON, and their
221
// behavior is undefined. In these cases, just print an empty string to the
222
// output buffer. This allows the pretty printer to continue while still
223
// outputing well-formed JSON.
224
default:
225
this.printValue_('', 'unknown', outputBuffer);
226
}
227
};
228
229
230
/**
231
* Prints a property name to the output.
232
* @param {string} name The property name.
233
* @param {!Array<string|!goog.html.SafeHtml>} outputBuffer The buffer to write
234
* the response to.
235
* @private
236
*/
237
goog.format.JsonPrettyPrinter.prototype.printName_ = function(
238
name, outputBuffer) {
239
outputBuffer.push(
240
this.delimiters_.formatName(this.jsonSerializer_.serialize(name)));
241
};
242
243
244
/**
245
* Prints a property name to the output.
246
* @param {string|boolean|number|null} val The property value.
247
* @param {string} typeOf The type of the value. Used to customize
248
* value-specific css in the display. This allows clients to distinguish
249
* between different types in css. For example, the client may define two
250
* classes: "goog-jsonprettyprinter-propertyvalue-string" and
251
* "goog-jsonprettyprinter-propertyvalue-number" to assign a different color
252
* to string and number values.
253
* @param {!Array<string|!goog.html.SafeHtml>} outputBuffer The buffer to write
254
* the response to.
255
* @private
256
*/
257
goog.format.JsonPrettyPrinter.prototype.printValue_ = function(
258
val, typeOf, outputBuffer) {
259
var value = this.jsonSerializer_.serialize(val);
260
outputBuffer.push(this.delimiters_.formatValue(value, typeOf));
261
};
262
263
264
/**
265
* Print a number of space characters to the output.
266
* @param {number} indent The number of spaces to indent the line.
267
* @param {!Array<string|!goog.html.SafeHtml>} outputBuffer The buffer to write
268
* the response to.
269
* @private
270
*/
271
goog.format.JsonPrettyPrinter.prototype.printSpaces_ = function(
272
indent, outputBuffer) {
273
outputBuffer.push(goog.string.repeat(this.delimiters_.space, indent));
274
};
275
276
277
278
/**
279
* A container for the delimiting characters used to display the JSON string
280
* to a text display. Each delimiter is a publicly accessible property of
281
* the object, which makes it easy to tweak delimiters to specific environments.
282
* @constructor
283
*/
284
goog.format.JsonPrettyPrinter.TextDelimiters = function() {};
285
286
287
/**
288
* Represents a space character in the output. Used to indent properties a
289
* certain number of spaces, and to separate property names from property
290
* values.
291
* @type {string}
292
*/
293
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.space = ' ';
294
295
296
/**
297
* Represents a newline character in the output. Used to begin a new line.
298
* @type {string|!goog.html.SafeHtml}
299
*/
300
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.lineBreak = '\n';
301
302
303
/**
304
* Represents the start of an object in the output.
305
* @type {string}
306
*/
307
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.objectStart = '{';
308
309
310
/**
311
* Represents the end of an object in the output.
312
* @type {string}
313
*/
314
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.objectEnd = '}';
315
316
317
/**
318
* Represents the start of an array in the output.
319
* @type {string}
320
*/
321
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.arrayStart = '[';
322
323
324
/**
325
* Represents the end of an array in the output.
326
* @type {string}
327
*/
328
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.arrayEnd = ']';
329
330
331
/**
332
* Represents the string used to separate properties in the output.
333
* @type {string}
334
*/
335
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.propertySeparator = ',';
336
337
338
/**
339
* Represents the string used to separate property names from property values in
340
* the output.
341
* @type {string|!goog.html.SafeHtml}
342
*/
343
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.nameValueSeparator = ':';
344
345
346
/**
347
* A string that's placed before a property name in the output. Useful for
348
* wrapping a property name in an html tag.
349
* @type {string}
350
*/
351
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.preName = '';
352
353
354
/**
355
* A string that's placed after a property name in the output. Useful for
356
* wrapping a property name in an html tag.
357
* @type {string}
358
*/
359
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.postName = '';
360
361
362
/**
363
* Formats a property name before adding it to the output.
364
* @param {string} name The property name.
365
* @return {string|!goog.html.SafeHtml}
366
*/
367
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.formatName = function(
368
name) {
369
return this.preName + name + this.postName;
370
};
371
372
373
/**
374
* A string that's placed before a property value in the output. Useful for
375
* wrapping a property value in an html tag.
376
* @type {string}
377
*/
378
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.preValue = '';
379
380
381
/**
382
* A string that's placed after a property value in the output. Useful for
383
* wrapping a property value in an html tag.
384
* @type {string}
385
*/
386
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.postValue = '';
387
388
389
/**
390
* Formats a value before adding it to the output.
391
* @param {string} value The value.
392
* @param {string} typeOf The type of the value obtained by goog.typeOf.
393
* @return {string|!goog.html.SafeHtml}
394
*/
395
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.formatValue = function(
396
value, typeOf) {
397
return goog.string.format(this.preValue, typeOf) + value + this.postValue;
398
};
399
400
401
/**
402
* Represents the number of spaces to indent each sub-property of the JSON.
403
* @type {number}
404
*/
405
goog.format.JsonPrettyPrinter.TextDelimiters.prototype.indent = 2;
406
407
408
409
/**
410
* A container for the delimiting characters used to display the JSON string
411
* to an HTML <code>&lt;pre&gt;</code> or <code>&lt;code&gt;</code> element.
412
* It escapes the names and values before they are added to the output.
413
* Use this class together with goog.format.JsonPrettyPrinter#formatSafeHtml.
414
* @constructor
415
* @extends {goog.format.JsonPrettyPrinter.TextDelimiters}
416
*/
417
goog.format.JsonPrettyPrinter.SafeHtmlDelimiters = function() {
418
goog.format.JsonPrettyPrinter.TextDelimiters.call(this);
419
};
420
goog.inherits(
421
goog.format.JsonPrettyPrinter.SafeHtmlDelimiters,
422
goog.format.JsonPrettyPrinter.TextDelimiters);
423
424
425
/** @override */
426
goog.format.JsonPrettyPrinter.SafeHtmlDelimiters.prototype.formatName =
427
function(name) {
428
var classes = goog.getCssName('goog-jsonprettyprinter-propertyname');
429
return goog.html.SafeHtml.create('span', {'class': classes}, name);
430
};
431
432
433
/** @override */
434
goog.format.JsonPrettyPrinter.SafeHtmlDelimiters.prototype.formatValue =
435
function(value, typeOf) {
436
var classes = this.getValueCssName(typeOf);
437
return goog.html.SafeHtml.create('span', {'class': classes}, value);
438
};
439
440
441
/**
442
* Return a class name for the given type.
443
* @param {string} typeOf The type of the value.
444
* @return {string}
445
* @protected
446
*/
447
goog.format.JsonPrettyPrinter.SafeHtmlDelimiters.prototype.getValueCssName =
448
function(typeOf) {
449
// This switch is needed because goog.getCssName requires a constant string.
450
switch (typeOf) {
451
case 'null':
452
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-null');
453
case 'boolean':
454
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-boolean');
455
case 'number':
456
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-number');
457
case 'string':
458
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-string');
459
case 'array':
460
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-array');
461
case 'object':
462
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-object');
463
default:
464
return goog.getCssName('goog-jsonprettyprinter-propertyvalue-unknown');
465
}
466
};
467
468