diff --git a/modules/es/es.JsonSerializer.js b/modules/es/es.JsonSerializer.js new file mode 100644 index 0000000000..9737e77baa --- /dev/null +++ b/modules/es/es.JsonSerializer.js @@ -0,0 +1,100 @@ +/** + * Serializes a WikiDom into JSON. + * + * @class + * @constructor + * @extends {es.Serializer} + * @property options {Object} List of options for serialization + * @property options.indentWith {String} Text to use as indentation, such as \t or 4 spaces + */ +es.JsonSerializer = function( options ) { + es.Serializer.call( this ); + this.options = $.extend( { + 'indentWith': '\t' + }, options || {} ); +}; + +/* Static Methods */ + +es.JsonSerializer.typeOf = function( value ) { + if ( typeof value === 'object' ) { + if ( value === null ) { + return 'null'; + } + switch ( value.constructor ) { + case [].constructor: + return 'array'; + case ( new Date() ).constructor: + return 'date'; + case ( new RegExp() ).constructor: + return 'regex'; + default: + return 'object'; + } + } + return typeof value; +}; + +es.JsonSerializer.prototype.encode = function( data, indention ) { + if ( indention === undefined ) { + indention = ''; + } + var type = es.JsonSerializer.typeOf( data ), + key; + + // Open object/array + var json = ''; + if ( type === 'array' ) { + if (data.length === 0) { + // Empty array + return '[]'; + } + json += '['; + } else { + var empty = true; + for ( key in data ) { + if ( data.hasOwnProperty( key ) ) { + empty = false; + break; + } + } + if ( empty ) { + return '{}'; + } + json += '{'; + } + + // Iterate over items + var comma = false; + for ( key in data ) { + if ( data.hasOwnProperty( key ) ) { + json += ( comma ? ',' : '' ) + '\n' + indention + this.options.indentWith + + ( type === 'array' ? '' : '"' + key + '"' + ': ' ); + switch ( es.JsonSerializer.typeOf( data[key] ) ) { + case 'array': + case 'object': + json += this.encode( data[key], indention + this.options.indentWith ); + break; + case 'boolean': + case 'number': + json += data[key].toString(); + break; + case 'null': + json += 'null'; + break; + case 'string': + json += '"' + data[key] + .replace(/[\n]/g, '\\n') + .replace(/[\t]/g, '\\t') + '"'; + break; + // Skip other types + } + comma = true; + } + } + + // Close object/array + json += '\n' + indention + ( type === 'array' ? ']' : '}' ); + + return json; +};