/** * Durandal 2.1.0 Copyright (c) 2012 Blue Spire Consulting, Inc. All Rights Reserved. * Available via the MIT license. * see: http://durandaljs.com or https://github.com/BlueSpire/Durandal for details. */ /** * Serializes and deserializes data to/from JSON. * @module serializer * @requires system */ define(['durandal/system'], function(system) { /** * @class SerializerModule * @static */ return { /** * The name of the attribute that the serializer should use to identify an object's type. * @property {string} typeAttribute * @default type */ typeAttribute: 'type', /** * The amount of space to use for indentation when writing out JSON. * @property {string|number} space * @default undefined */ space:undefined, /** * The default replacer function used during serialization. By default properties starting with '_' or '$' are removed from the serialized object. * @method replacer * @param {string} key The object key to check. * @param {object} value The object value to check. * @return {object} The value to serialize. */ replacer: function(key, value) { if(key){ var first = key[0]; if(first === '_' || first === '$'){ return undefined; } } return value; }, /** * Serializes the object. * @method serialize * @param {object} object The object to serialize. * @param {object} [settings] Settings can specify a replacer or space to override the serializer defaults. * @return {string} The JSON string. */ serialize: function(object, settings) { settings = (settings === undefined) ? {} : settings; if(system.isString(settings) || system.isNumber(settings)) { settings = { space: settings }; } return JSON.stringify(object, settings.replacer || this.replacer, settings.space || this.space); }, /** * Gets the type id for an object instance, using the configured `typeAttribute`. * @method getTypeId * @param {object} object The object to serialize. * @return {string} The type. */ getTypeId: function(object) { if (object) { return object[this.typeAttribute]; } return undefined; }, /** * Maps type ids to object constructor functions. Keys are type ids and values are functions. * @property {object} typeMap. */ typeMap: {}, /** * Adds a type id/constructor function mampping to the `typeMap`. * @method registerType * @param {string} typeId The type id. * @param {function} constructor The constructor. */ registerType: function() { var first = arguments[0]; if (arguments.length == 1) { var id = first[this.typeAttribute] || system.getModuleId(first); this.typeMap[id] = first; } else { this.typeMap[first] = arguments[1]; } }, /** * The default reviver function used during deserialization. By default is detects type properties on objects and uses them to re-construct the correct object using the provided constructor mapping. * @method reviver * @param {string} key The attribute key. * @param {object} value The object value associated with the key. * @param {function} getTypeId A custom function used to get the type id from a value. * @param {object} getConstructor A custom function used to get the constructor function associated with a type id. * @return {object} The value. */ reviver: function(key, value, getTypeId, getConstructor) { var typeId = getTypeId(value); if (typeId) { var ctor = getConstructor(typeId); if (ctor) { if (ctor.fromJSON) { return ctor.fromJSON(value); } return new ctor(value); } } return value; }, /** * Deserialize the JSON. * @method deserialize * @param {string} text The JSON string. * @param {object} [settings] Settings can specify a reviver, getTypeId function or getConstructor function. * @return {object} The deserialized object. */ deserialize: function(text, settings) { var that = this; settings = settings || {}; var getTypeId = settings.getTypeId || function(object) { return that.getTypeId(object); }; var getConstructor = settings.getConstructor || function(id) { return that.typeMap[id]; }; var reviver = settings.reviver || function(key, value) { return that.reviver(key, value, getTypeId, getConstructor); }; return JSON.parse(text, reviver); }, /** * Clone the object. * @method clone * @param {object} obj The object to clone. * @param {object} [settings] Settings can specify any of the options allowed by the serialize or deserialize methods. * @return {object} The new clone. */ clone:function(obj, settings) { return this.deserialize(this.serialize(obj, settings), settings); } }; });