Skip to content

Commit 60ed504

Browse files
committed
Initial checkin of source files
1 parent eba9667 commit 60ed504

File tree

3 files changed

+614
-0
lines changed

3 files changed

+614
-0
lines changed

dist/Serializer.js

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
// Nico Westerdale - 1/2004-7 - www.iconico.com
2+
3+
// Serializer.js
4+
5+
// TODO: error trapping
6+
// TODO: Internt Explorer 4 doesn't support try-catch statements!
7+
8+
9+
//Serializer object
10+
function JSSerializer() {
11+
//properties
12+
this.Data = null; //this is the root for the internal SerialData object
13+
//methods
14+
this.Serialize = mtdSerialize;
15+
this.HasData = function() {return this.Data?true:false}; //whether Data has been loaded into the Serializer
16+
this.MaxDepth = null;
17+
this.CheckInfiniteLoops = true;
18+
//locals
19+
var theSerializer = this; //easier to reference later on
20+
var currDepth = 0;
21+
22+
//TODO: Unchanged Prototype Data Exclusion
23+
// Would be really nice to have an option to exclude the data that's in the prototype.
24+
// This is a little tricky to accomplish so I'm going to leave it for v2.0
25+
// You have to check prototype inheritance situations like this one:
26+
// Monkey.prototype = new Ape();
27+
// Monkey.prototype.constructor = Monkey;
28+
// And to compund the problem, Ape could also inherit, so it needs to be recursive.
29+
// This is further confused by properties being set in the prototypes too.
30+
31+
//TODO:
32+
//this.GetJSDataSerialString <- this should be a JSON string - then write a method to seed data back in!
33+
// also do this from XML, should be easy to write a simple parser etc.
34+
//TODO: also make this into a Javascript HTML code colorizer = use CSS for the display
35+
36+
37+
//serializes any Javascript object and returns a string
38+
function mtdSerialize(obj) {
39+
if (IsSerializable('SrliZe', obj)) {
40+
//Set root SerialData object to be the root object passed in to be serialized
41+
// We give it the default name 'SrliZe'
42+
this.Data = new SerialData('SrliZe', obj, null);
43+
//Start serializing entire tree
44+
SerializeAll(obj, this.Data);
45+
//Return true because we could serialize something
46+
return true;
47+
//TODO: Should keep track of whether we could serialize the entire tree.
48+
} else {
49+
//Couldn't serialize anything
50+
return false;
51+
}
52+
}
53+
54+
//Private functions
55+
56+
57+
//recursive serialization function
58+
function SerializeAll(obj, objParent) {
59+
60+
currDepth++;
61+
//depth check
62+
if ((theSerializer.MaxDepth==null) || (theSerializer.MaxDepth=='') || (theSerializer.MaxDepth < 0) || (currDepth <= theSerializer.MaxDepth)) {
63+
var i;
64+
var objSerial;
65+
var blnDidForIn = false;
66+
//loop through items
67+
try {
68+
for (i in obj) {
69+
SerializeItem(i, obj, objParent);
70+
blnDidForIn = true;
71+
}
72+
} catch (e) {
73+
//some DOM container objects throw enumeration errors here, i.e. the extrnal object
74+
}
75+
//alternate enumeration for objects.
76+
// Objects like the 'arguments' object need this type of enumeration
77+
if (!blnDidForIn) {
78+
if (obj) {
79+
if (obj.length && (GetExactType(obj) == 'Object')) {
80+
for (var i = 0; i < obj.length; i++) {
81+
SerializeItem(i, obj, objParent);
82+
}
83+
}
84+
}
85+
}
86+
87+
}
88+
currDepth--;
89+
}
90+
91+
//serializes an individual item
92+
function SerializeItem(i, obj, objParent) {
93+
//for now we're going to ignore non-serializable objects
94+
if (IsSerializable(i, obj[i])) {
95+
//build the SerialData object to encapsulate this item
96+
objSerial = new SerialData(i, obj[i], objParent);
97+
//assign this item to it's parent's Kids array
98+
objParent.Kids[objParent.Kids.length] = objSerial;
99+
//check infinite loops
100+
if (theSerializer.CheckInfiniteLoops) {
101+
//save the actual object, this is used to check links
102+
objSerial.RealObject = obj[i];
103+
//TODO: Might want to delete these after serializing object is complete
104+
//Add any links to ancestors
105+
objSerial.Link = findSerialLink(objSerial);
106+
}
107+
//recurse down the object tree if container object and not a linked object
108+
if ((IsContainerType(obj[i])) && (objSerial.Link == null)) {
109+
SerializeAll(obj[i], objSerial)
110+
}
111+
}
112+
}
113+
114+
//returns an ancestor object if it's identical to this one
115+
function findSerialLink(objSerial) {
116+
//check parents to see if they are the same object as this
117+
var obj = objSerial;
118+
blnDidCheck = false;
119+
try {
120+
while ((obj.Parent != null) && (obj.Parent.RealObject != objSerial.RealObject)) {
121+
blnDidCheck = true;
122+
obj = obj.Parent;
123+
}
124+
} catch (e) {
125+
return null; //Some DOM objects throw errors when trying to equate obj.Parent.RealObject!
126+
}
127+
//return object
128+
if (blnDidCheck) {
129+
return obj.Parent;
130+
} else {
131+
return null;
132+
}
133+
}
134+
135+
//Returns the type of an object from the constructor as a string
136+
function GetExactType(obj) {
137+
try {
138+
if (obj.constructor) {
139+
var strType;
140+
strType = obj.constructor.toString().match(/function (\w*)/)[1];
141+
if (strType.replace(' ','') == '') strType = 'n/a'; //Mozilla needs this
142+
if (theSerializer.Types.UseObjectsForUserDefined && ! (strType in oc(['Array','Boolean','Date','Enumerator','Error','Function','Number','RegExp','String','VBArray'])) ) {
143+
strType = 'Object';
144+
}
145+
return strType;
146+
} else {
147+
return 'n/a';
148+
}
149+
} catch(e) {
150+
return 'n/a';
151+
}
152+
}
153+
154+
//Object converter function
155+
function oc(a) {
156+
var o = {};
157+
for(var i=0;i<a.length;i++) {
158+
o[a[i]]='';
159+
}
160+
return o;
161+
}
162+
163+
//Returns true if the javascript object can be expanded.
164+
function IsContainerType(obj) {
165+
try {
166+
//return (GetExactType(obj) != 'Boolean' && GetExactType(obj) != 'Date' && GetExactType(obj) != 'Enumerator' && GetExactType(obj) != 'Function' && GetExactType(obj) != 'Number' && GetExactType(obj) != 'RegExp' && GetExactType(obj) != 'String' && GetExactType(obj) != 'VBArray' && GetExactType(obj) != null && GetExactType(obj) !== undefined && GetExactType(obj) != 'n/a')
167+
return (GetExactType(obj) != 'Boolean' && GetExactType(obj) != 'Date' && GetExactType(obj) != 'Enumerator' && GetExactType(obj) != 'Function' && GetExactType(obj) != 'Number' && GetExactType(obj) != 'RegExp' && GetExactType(obj) != 'String' && GetExactType(obj) != 'VBArray' && GetExactType(obj) != null && GetExactType(obj) !== undefined)
168+
} catch(e) {
169+
return false;
170+
}
171+
}
172+
173+
//Returns true if the object can be serialized.
174+
//Returns false if the object cannot
175+
function IsSerializable(strName, obj) {
176+
try {
177+
//check Types to see what we should serialize
178+
switch (GetExactType(obj)) {
179+
case 'n/a':
180+
if (obj == undefined) {
181+
return theSerializer.Types.UseUndefined;
182+
} else {
183+
return theSerializer.Types.UseNull;
184+
}
185+
break;
186+
case 'Array': return theSerializer.Types.UseArray; break;
187+
case 'Object': return theSerializer.Types.UseObject; break;
188+
case 'Boolean': return theSerializer.Types.UseBoolean; break;
189+
case 'Date': return theSerializer.Types.UseDate; break;
190+
case 'Enumerator': return false; break; // - this can't ever be serialized!
191+
case 'Error': return theSerializer.Types.UseError; break;
192+
case 'Function':
193+
if (strName=='constructor') {
194+
//Check that this isn't the object's constructor, which we never serialize.
195+
//This is only neccesary in Mozilla.
196+
return false;
197+
} else {
198+
return theSerializer.Types.UseFunction;
199+
}
200+
break;
201+
case 'Number': return theSerializer.Types.UseNumber; break;
202+
case 'RegExp': return theSerializer.Types.UseRegExp; break;
203+
case 'String': return theSerializer.Types.UseString; break;
204+
case 'VBArray': return false; break; // - this can't ever be serialized!
205+
default: return theSerializer.Types.UseUserDefined; break;
206+
}
207+
208+
} catch(e) {
209+
return false;
210+
}
211+
}
212+
213+
//Constructor
214+
//The SerialData object is used internally by the serializer to maintain the object in it's hierarchy
215+
//This object's properties (apart from Kids) are all meant to be read-only after it's constructed.
216+
function SerialData(strName, obj, objParent) {
217+
//properties
218+
this.Name = strName; //This is the name of the object or property or method.
219+
//This is the value of the property. This can be of any type.
220+
if (obj != null) {
221+
try {
222+
if (obj.toString) { //If we use a DOM object some nodes fail here, e.g. the namespaces collection
223+
this.Value = obj.toString(); //We save the string representation of the object
224+
}
225+
} catch (e) {} //Some DOM objects throw errors on obj.toString!
226+
} else {
227+
this.Value = obj; //This could be either null or undefined
228+
}
229+
//Used for checking infinite loops
230+
this.RealObject = null;
231+
//the type of the object retrieved from using typeof()
232+
this.Type = typeof(obj);
233+
//the name of the constructor of the object
234+
this.ExactType = GetExactType(obj);
235+
//Whether the object is of a type that has kids
236+
this.IsContainer = IsContainerType(obj);
237+
//points to the parent SerialData object. Top level SerialData object will have null parent
238+
this.Parent = objParent;
239+
//array of child SerialData objects
240+
this.Kids = new Array;
241+
//link to an ancestor SerialData object, where appropriate
242+
this.Link = null;
243+
}
244+
245+
246+
}
247+
248+
JSSerializer.prototype.Prefs = new SerialPrefs();
249+
250+
//Constructor
251+
//The SerialPrefs object is used for output rendering preferences
252+
// Different formatter objects may add properties to the SerialPrefs object
253+
function SerialPrefs() {
254+
//properties
255+
this.ShowLineBreaks = false; //Whether to render line breaks in formatter output
256+
this.SmartIndent = false; //Whether to insert tabs in output based on hierarchy. Used by XML formatters mainly.
257+
this.ShowTypes = false; //Whether to show the data types in the output. Used by XML formatters mainly.
258+
//TODO: this.ShowErrors = false; //Whether to show javascript errors or fail gracefully
259+
}
260+
261+
JSSerializer.prototype.Types = new SerialTypes();
262+
263+
//Constructor
264+
//The SerialTypes object is used for runtime choices of which types of objects should be serialized
265+
function SerialTypes() {
266+
//properties
267+
this.UseNull = true;
268+
this.UseUndefined = true;
269+
this.UseArray = true;
270+
this.UseObject = true;
271+
this.UseBoolean = true;
272+
this.UseDate = true;
273+
this.UseError = true;
274+
this.UseFunction = true;
275+
this.UseNumber = true;
276+
this.UseRegExp = true;
277+
this.UseString = true;
278+
this.UseUserDefined = true; //this will be for user defined objects
279+
this.UseObjectsForUserDefined = false;
280+
}

0 commit comments

Comments
 (0)