| 35 | | var extended = {}; |
|---|
| 36 | | var parent; |
|---|
| | 36 | |
|---|
| | 37 | // All instances of OpenLayers classes inherit from the extended prototype. |
|---|
| | 38 | var extended = { |
|---|
| | 39 | /** |
|---|
| | 40 | * APIMethod: Class.prototype.serialize |
|---|
| | 41 | * This is an instance method that returns a data structure representing |
|---|
| | 42 | * the instance. This data structure can be passed to the |
|---|
| | 43 | * appropriate deserialize class method to return a new instance |
|---|
| | 44 | * which is the equivalent of a clone of this instance. |
|---|
| | 45 | * |
|---|
| | 46 | * Returns: |
|---|
| | 47 | * {Object} A data structure representing the instance. |
|---|
| | 48 | */ |
|---|
| | 49 | serialize: function() { |
|---|
| | 50 | var data = {}; |
|---|
| | 51 | var olClass = eval(this.CLASS_NAME); |
|---|
| | 52 | var obj = olClass.prototype.serializable; |
|---|
| | 53 | // serialize the args and props |
|---|
| | 54 | var index; |
|---|
| | 55 | var args = obj.args; |
|---|
| | 56 | if(args) { |
|---|
| | 57 | for(index=0; index<args.length; ++index) { |
|---|
| | 58 | data[args[index]] = OpenLayers.Class.serialize( |
|---|
| | 59 | this[args[index]] |
|---|
| | 60 | ); |
|---|
| | 61 | } |
|---|
| | 62 | } |
|---|
| | 63 | var props = obj.props; |
|---|
| | 64 | for(index=0; index<props.length; ++index) { |
|---|
| | 65 | data[props[index]] = OpenLayers.Class.serialize( |
|---|
| | 66 | this[props[index]] |
|---|
| | 67 | ); |
|---|
| | 68 | } |
|---|
| | 69 | // add in the class name |
|---|
| | 70 | data.CLASS_NAME = this.CLASS_NAME; |
|---|
| | 71 | return data; |
|---|
| | 72 | } |
|---|
| | 73 | }; |
|---|
| | 74 | |
|---|
| | 75 | // get the serializable object on the prototype |
|---|
| | 76 | var proto = arguments[arguments.length - 1]; |
|---|
| | 77 | var serializable; |
|---|
| | 78 | if(proto.serializable) { |
|---|
| | 79 | /** |
|---|
| | 80 | * Property: Class.prototype.serializable |
|---|
| | 81 | * {Object} Object that maps serializalble properties of an instance |
|---|
| | 82 | * of this class. By default, instances will not be serialized. |
|---|
| | 83 | * To allow an instance to be serialized, add a serializable |
|---|
| | 84 | * property to the prototype. Subclasses will inherit this |
|---|
| | 85 | * property in the manor described below. The simplest way to make |
|---|
| | 86 | * an instance serializable is to set the serializable property |
|---|
| | 87 | * to an empty object ({}). |
|---|
| | 88 | * |
|---|
| | 89 | * The serializable object has three properties: |
|---|
| | 90 | * args - {Array} Property names to be applied to the constructor. |
|---|
| | 91 | * All required argument names must be supplied here. If args |
|---|
| | 92 | * is undefined, args will be inherited from the parent. |
|---|
| | 93 | * props - {Array} All additional properties to set on the new |
|---|
| | 94 | * instance. These will be set by direct assignment. The props |
|---|
| | 95 | * array inherits from its parent by merging arrays. Any new |
|---|
| | 96 | * properties specified in a child props array will be added |
|---|
| | 97 | * to the properties inherited from a parent class. |
|---|
| | 98 | * except - {Array} List of properties from a parent class' props |
|---|
| | 99 | * array that will not be merged with the props array of a child |
|---|
| | 100 | * class. There is no inheritance of the except array. |
|---|
| | 101 | */ |
|---|
| | 102 | serializable = { |
|---|
| | 103 | "args": (proto.serializable.args) ? |
|---|
| | 104 | proto.serializable.args : undefined, |
|---|
| | 105 | "props": (proto.serializable.props) ? |
|---|
| | 106 | proto.serializable.props : [], |
|---|
| | 107 | "except": (proto.serializable.except) ? |
|---|
| | 108 | proto.serializable.except : [] |
|---|
| | 109 | }; |
|---|
| | 110 | }; |
|---|
| | 111 | |
|---|
| | 112 | // inherit from all arguments |
|---|
| | 113 | var parent = {}; |
|---|
| | 118 | // All OpenLayers classes are serializable. |
|---|
| | 119 | // Inheriting from others still works. |
|---|
| | 120 | if(parent.serializable) { |
|---|
| | 121 | // prototype may not have serializable property |
|---|
| | 122 | serializable = (serializable) ? |
|---|
| | 123 | serializable : {"props": [], "except": []}; |
|---|
| | 124 | // props are merged with the parent |
|---|
| | 125 | var prop; |
|---|
| | 126 | var indexOf = OpenLayers.Util.indexOf; |
|---|
| | 127 | for(var j=0; j<parent.serializable.props.length; ++j) { |
|---|
| | 128 | prop = parent.serializable.props[j]; |
|---|
| | 129 | if(indexOf(serializable.except, prop) == -1) { |
|---|
| | 130 | if(indexOf(serializable.props, prop) == -1) { |
|---|
| | 131 | serializable.props.push(prop); |
|---|
| | 132 | } |
|---|
| | 133 | } |
|---|
| | 134 | } |
|---|
| | 135 | // args are inherited only if not specified in the prototype |
|---|
| | 136 | if(!serializable.args) { |
|---|
| | 137 | serializable.args = parent.serializable.args; |
|---|
| | 138 | } |
|---|
| | 139 | } |
|---|
| | 151 | |
|---|
| | 152 | /* |
|---|
| | 153 | * APIProperty: OpenLayers.Class.recursionDepth |
|---|
| | 154 | * Class property that limits the recursion depth for serializing instances |
|---|
| | 155 | * of OpenLayers classes. Defaults to 20. |
|---|
| | 156 | */ |
|---|
| | 157 | OpenLayers.Class.recursionDepth = 20; |
|---|
| | 158 | |
|---|
| | 159 | /** |
|---|
| | 160 | * APIFunction: OpenLayers.Class.serialize |
|---|
| | 161 | * Recursively serialize an object. Stops recursion at a depth of |
|---|
| | 162 | * <OpenLayers.Class.recursionDepth>. |
|---|
| | 163 | * |
|---|
| | 164 | * Parameters: |
|---|
| | 165 | * obj - {Object} An object to be serialized. |
|---|
| | 166 | * |
|---|
| | 167 | * Returns: |
|---|
| | 168 | * {Object} An object without circular references or methods. |
|---|
| | 169 | */ |
|---|
| | 170 | OpenLayers.Class.serialize = function(obj, depth) { |
|---|
| | 171 | var data; |
|---|
| | 172 | depth = (depth != undefined) ? depth + 1 : 0; |
|---|
| | 173 | if(!(obj instanceof Function)) { |
|---|
| | 174 | if(depth <= OpenLayers.Class.recursionDepth) { |
|---|
| | 175 | if(obj && obj.serialize instanceof Function) { |
|---|
| | 176 | data = obj.serialize(); |
|---|
| | 177 | } else { |
|---|
| | 178 | if(obj instanceof Array) { |
|---|
| | 179 | data = new Array(obj.length); |
|---|
| | 180 | for(var i=0; i<obj.length; ++i) { |
|---|
| | 181 | data[i] = OpenLayers.Class.serialize(obj[i], depth); |
|---|
| | 182 | } |
|---|
| | 183 | } else if(obj instanceof Object) { |
|---|
| | 184 | data = {}; |
|---|
| | 185 | var value; |
|---|
| | 186 | for(var key in obj) { |
|---|
| | 187 | value = OpenLayers.Class.serialize(obj[key], depth); |
|---|
| | 188 | if(value !== undefined) { |
|---|
| | 189 | data[key] = OpenLayers.Class.serialize( |
|---|
| | 190 | obj[key], depth |
|---|
| | 191 | ); |
|---|
| | 192 | } |
|---|
| | 193 | } |
|---|
| | 194 | } else { |
|---|
| | 195 | data = obj; |
|---|
| | 196 | } |
|---|
| | 197 | } |
|---|
| | 198 | } |
|---|
| | 199 | } |
|---|
| | 200 | return data; |
|---|
| | 201 | }; |
|---|
| | 202 | |
|---|
| | 203 | /** |
|---|
| | 204 | * APIFunction: OpenLayers.Class.deserialize |
|---|
| | 205 | * Class method that deserializes any data structure into an instance of |
|---|
| | 206 | * an OpenLayers class. In the case of arrays and objects, an object |
|---|
| | 207 | * with the same data structure is returned, with each item or proerty |
|---|
| | 208 | * value deserialized. |
|---|
| | 209 | * |
|---|
| | 210 | * Parameters: |
|---|
| | 211 | * struct - {Object} Data structure representing an object. |
|---|
| | 212 | * |
|---|
| | 213 | * Returns: |
|---|
| | 214 | * {Object} An instance of an OpenLayers class based on the data structure. |
|---|
| | 215 | */ |
|---|
| | 216 | OpenLayers.Class.deserialize = function(struct, depth) { |
|---|
| | 217 | var instance, index, key; |
|---|
| | 218 | depth = (depth != undefined) ? depth + 1 : 1; |
|---|
| | 219 | if(struct instanceof Function) { |
|---|
| | 220 | var msg = "Cannot serialize functions"; |
|---|
| | 221 | OpenLayers.Console.error(msg); |
|---|
| | 222 | } else if(depth <= OpenLayers.Class.recursionDepth) { |
|---|
| | 223 | if(!struct) { |
|---|
| | 224 | // deal with null and all else that evaluates to false |
|---|
| | 225 | instance = struct; |
|---|
| | 226 | } else if(!struct.CLASS_NAME || |
|---|
| | 227 | struct.CLASS_NAME.indexOf("OpenLayers") != 0) { |
|---|
| | 228 | if(struct instanceof Array) { |
|---|
| | 229 | // deserialize items in an array |
|---|
| | 230 | instance = new Array(struct.length); |
|---|
| | 231 | for(index=0; index<struct.length; ++index) { |
|---|
| | 232 | instance[index] = OpenLayers.Class.deserialize( |
|---|
| | 233 | struct[index], depth |
|---|
| | 234 | ); |
|---|
| | 235 | } |
|---|
| | 236 | } else if(struct instanceof Object) { |
|---|
| | 237 | // deserialize properties of an object |
|---|
| | 238 | instance = {}; |
|---|
| | 239 | for(key in struct) { |
|---|
| | 240 | instance[key] = OpenLayers.Class.deserialize( |
|---|
| | 241 | struct[key], depth |
|---|
| | 242 | ); |
|---|
| | 243 | } |
|---|
| | 244 | } else { |
|---|
| | 245 | // all other literals |
|---|
| | 246 | instance = struct; |
|---|
| | 247 | } |
|---|
| | 248 | } else { |
|---|
| | 249 | // deal with instances of OpenLayers classes |
|---|
| | 250 | var olClass = eval(struct.CLASS_NAME); |
|---|
| | 251 | if(!olClass.prototype.serializable) { |
|---|
| | 252 | var msg = "Unable to deserialize. CLASS_NAME: " + |
|---|
| | 253 | struct.CLASS_NAME; |
|---|
| | 254 | throw Error(msg); |
|---|
| | 255 | } |
|---|
| | 256 | // deserialize the args |
|---|
| | 257 | var argArray = olClass.prototype.serializable.args; |
|---|
| | 258 | var args = []; |
|---|
| | 259 | if(argArray) { |
|---|
| | 260 | for(index=0; index<argArray.length; ++index) { |
|---|
| | 261 | key = argArray[index]; |
|---|
| | 262 | if(struct[key] === undefined) { |
|---|
| | 263 | var msg = "Deserializing failed. " + |
|---|
| | 264 | struct.CLASS_NAME + " requires argument: " + key; |
|---|
| | 265 | throw Error(msg); |
|---|
| | 266 | } |
|---|
| | 267 | args.push(OpenLayers.Class.deserialize(struct[key], depth)); |
|---|
| | 268 | } |
|---|
| | 269 | } |
|---|
| | 270 | // create prototype with properties deserialized from the structure |
|---|
| | 271 | var proto = {}; |
|---|
| | 272 | var propArray = olClass.prototype.serializable.props; |
|---|
| | 273 | if(propArray) { |
|---|
| | 274 | for(index=0; index<propArray.length; ++index) { |
|---|
| | 275 | key = propArray[index]; |
|---|
| | 276 | proto[key] = OpenLayers.Class.deserialize( |
|---|
| | 277 | struct[key], depth |
|---|
| | 278 | ); |
|---|
| | 279 | } |
|---|
| | 280 | } |
|---|
| | 281 | // construct our instance (except for maps at this point) |
|---|
| | 282 | if(struct.CLASS_NAME == "OpenLayers.Map") { |
|---|
| | 283 | instance = proto; |
|---|
| | 284 | } else { |
|---|
| | 285 | OpenLayers.Util.applyDefaults(proto, olClass.prototype); |
|---|
| | 286 | instance = olClass.apply(proto, args); |
|---|
| | 287 | } |
|---|
| | 288 | } |
|---|
| | 289 | } |
|---|
| | 290 | return instance; |
|---|
| | 291 | }; |
|---|
| | 292 | |
|---|
| | 293 | ///////////////////////////////////////////////////////////////////// |
|---|
| | 294 | // Deprecated methods below. Remove everything below here in 3.0. // |
|---|
| | 295 | ///////////////////////////////////////////////////////////////////// |
|---|