1 (function(global){ // BEGIN CLOSURE 2 3 var Joint = global.Joint; 4 5 Joint.Mixin(Joint.prototype, /** @lends Joint.prototype */ { 6 /** 7 * Returns compact object representation of joint. Used for serialization. 8 * @return {Object} Compact representation of the joint. 9 */ 10 compact: function(){ 11 var start = this.startObject(), end = this.endObject(), 12 regs = this._registeredObjects, iRegs = regs.length, reg, 13 j = { 14 object: "joint", 15 euid: this.euid(), 16 opt: this._opt, 17 from: undefined, 18 to: undefined, 19 registered: { 20 start: [], 21 end: [], 22 both: [] 23 } 24 }; 25 // @todo Ugly!!! Joint shouldn't know anything about Joint.dia! Remove! 26 27 // from/to 28 if (start.wholeShape) 29 j.from = start.wholeShape.euid(); 30 if (end.wholeShape) 31 j.to = end.wholeShape.euid(); 32 33 if (this.isStartDummy()) 34 j.from = start.attrs.cx + "@" + start.attrs.cy; 35 if (this.isEndDummy()) 36 j.to = end.attrs.cx + "@" + end.attrs.cy; 37 38 // registered objects processing 39 while(iRegs--){ 40 reg = regs[iRegs]; 41 j.registered[reg._capToStick || "both"].push(reg.euid()); 42 } 43 return j; 44 }, 45 /** 46 * @return {String} JSON representation of joint. 47 */ 48 stringify: function(){ 49 return JSON.stringify(this.compact()); 50 } 51 }); 52 53 Joint.Mixin(Joint.dia, /** @lends Joint.dia */ { 54 /** 55 * Clones diagram in the current paper. 56 * @return {Array} Array of the constructed elements. 57 */ 58 clone: function(){ 59 return this.parse(this.stringify(Joint.paper())); 60 }, 61 /** 62 * Construct a diagram from the JSON representation. 63 * @param {String} JSON 64 * @return {Array} Array of the constructed elements. 65 */ 66 parse: function(json){ 67 var arr = JSON.parse(json), o, m, e, 68 element, joints = [], i, len, elements = {}, 69 objects = []; 70 71 if (!(arr instanceof Array)) arr = [arr]; 72 73 // for all elements 74 for (i = 0, len = arr.length; i < len; i++){ 75 o = arr[i]; 76 77 m = o.module; 78 e = o.object; 79 80 // create joints separatly, after all elements are created 81 // so that they can connect them 82 if (e === "joint"){ 83 joints.push(o); 84 objects.push(o); 85 continue; 86 } 87 // construct the element 88 if (this[m]){ 89 if (this[m][e]){ 90 element = this[m][e].create(o); 91 } else { 92 console.error("Object " + e + " of module " + m + " is missing."); 93 return; 94 } 95 } else { 96 console.error("Module " + m + " is missing."); 97 return; 98 } 99 if (o.euid) elements[o.euid] = element; 100 101 // translate, @todo rotate, scale 102 element.translate(o.dx, o.dy); 103 // element.rotate(o.rot); 104 element.scale(o.sx, o.sy); 105 objects.push(element); 106 } 107 this.hierarchize(elements); 108 this.createJoints(joints, elements); 109 return objects; 110 }, 111 /** 112 * @private 113 */ 114 hierarchize: function(elements){ 115 var euid, element; 116 for (euid in elements){ 117 if (!elements.hasOwnProperty(euid)) continue; 118 element = elements[euid]; 119 if (element.properties.parent && elements[element.properties.parent]) 120 elements[element.properties.parent].addInner(element); 121 } 122 }, 123 /** 124 * Create joints. 125 * @private 126 * @param {Array} joints Matrix of joints for each element. 127 * @param {Object} elements Hash table of elements (key: euid, value: element). 128 */ 129 createJoints: function(joints, elements){ 130 var iJoints = joints.length, 131 joint, from, to, realFrom, realTo, 132 newJoint, toRegister, toRegisterElement, iRegister, cap, 133 sides = ["start", "end", "both"], iSides = sides.length; 134 // for all joints of all elements 135 while (iJoints--){ 136 joint = joints[iJoints]; 137 from = elements[joint.from]; 138 to = elements[joint.to]; 139 140 // point or element wrapper 141 realFrom = (from) ? from.wrapper : {x: joint.from.split("@")[0], y: joint.from.split("@")[1]}; 142 realTo = (to) ? to.wrapper : {x: joint.to.split("@")[0], y: joint.to.split("@")[1]}; 143 144 // create joint 145 newJoint = this.Joint(realFrom, realTo, joint.opt); 146 // register caps - elements 147 toRegister = []; 148 iSides = sides.length; 149 while (iSides--){ 150 cap = sides[iSides]; 151 iRegister = joint.registered[cap].length; 152 while (iRegister--){ 153 if (elements[joint.registered[cap][iRegister]]){ 154 toRegisterElement = elements[joint.registered[cap][iRegister]]; 155 toRegisterElement._capToStick = cap; 156 toRegister.push(toRegisterElement); 157 } 158 } 159 } 160 newJoint.registerForever(toRegister); 161 }//endwhile (iJoints--) 162 }, 163 /** 164 * Stringify the whole diagram (occupying a paper). 165 * @param {RaphaelPaper} paper Raphael paper the diagram belongs to. 166 * @return {String} JSON representation of the diagram. 167 */ 168 stringify: function(paper){ 169 var objs, iObjs, o, str = [], 170 registeredObjects = this._registeredObjects, registeredJoints = this._registeredJoints, 171 paperEuid = paper.euid(); 172 // elements 173 if (registeredObjects[paperEuid]){ 174 objs = registeredObjects[paperEuid]; 175 iObjs = objs.length; 176 while (iObjs--){ 177 o = objs[iObjs]; 178 if (o.object) 179 str.push(o.stringify()); 180 } 181 } 182 // joints 183 if (registeredJoints[paperEuid]){ 184 objs = registeredJoints[paperEuid]; 185 iObjs = objs.length; 186 while (iObjs--){ 187 o = objs[iObjs]; 188 str.push(o.stringify()); 189 } 190 } 191 return "[" + str.join(",") + "]"; 192 } 193 }); 194 195 Joint.Mixin(Joint.dia.Element.prototype, /** @lends Joint.dia.Element.prototype */ { 196 /** 197 * @return JSON representation of the element. 198 */ 199 stringify: function(){ 200 return JSON.stringify(Joint.Mixin(this.properties, { euid: this.euid() })); 201 }, 202 /** 203 * Clone element. 204 * @return {Element} Cloned element. 205 */ 206 clone: function(){ 207 return Joint.dia.parse(this.stringify())[0]; 208 } 209 }); 210 211 })(this); // END CLOSURE 212