CodeSerializer.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /**
  2. * Development repository: https://github.com/kaisalmen/WWOBJLoader
  3. */
  4. const CodeSerializer = {
  5. /**
  6. * Serialize an object with specific prototype definition.
  7. *
  8. * @param {Object} targetPrototype The object that should be serialized
  9. * @param {Object} targetPrototypeInstance An instance of the oriobject that should be serialized
  10. * @param {String} [basePrototypeName] Name of the prototype
  11. * @param {Object} [overrideFunctions} Array of {@Link CodeSerializationInstruction} allows to replace or remove function with provided content
  12. *
  13. * @returns {String}
  14. */
  15. serializeClass: function ( targetPrototype, targetPrototypeInstance, basePrototypeName, overrideFunctions ) {
  16. let objectPart, constructorString, i, funcInstructions, funcTemp;
  17. const fullObjectName = targetPrototypeInstance.constructor.name;
  18. const prototypeFunctions = [];
  19. const objectProperties = [];
  20. const objectFunctions = [];
  21. const isExtended = ( basePrototypeName !== null && basePrototypeName !== undefined );
  22. if ( ! Array.isArray( overrideFunctions ) ) overrideFunctions = [];
  23. for ( const name in targetPrototype.prototype ) {
  24. objectPart = targetPrototype.prototype[ name ];
  25. funcInstructions = new CodeSerializationInstruction( name, fullObjectName + '.prototype.' + name );
  26. funcInstructions.setCode( objectPart.toString() );
  27. if ( name === 'constructor' ) {
  28. if ( ! funcInstructions.isRemoveCode() ) {
  29. constructorString = fullObjectName + ' = ' + funcInstructions.getCode() + ';\n\n';
  30. }
  31. } else if ( typeof objectPart === 'function' ) {
  32. funcTemp = overrideFunctions[ name ];
  33. if ( funcTemp instanceof CodeSerializationInstruction && funcTemp.getName() === funcInstructions.getName() ) {
  34. funcInstructions = funcTemp;
  35. }
  36. if ( ! funcInstructions.isRemoveCode() ) {
  37. if ( isExtended ) {
  38. prototypeFunctions.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n\n' );
  39. } else {
  40. prototypeFunctions.push( '\t' + funcInstructions.getName() + ': ' + funcInstructions.getCode() + ',\n\n' );
  41. }
  42. }
  43. }
  44. }
  45. for ( const name in targetPrototype ) {
  46. objectPart = targetPrototype[ name ];
  47. funcInstructions = new CodeSerializationInstruction( name, fullObjectName + '.' + name );
  48. if ( typeof objectPart === 'function' ) {
  49. funcTemp = overrideFunctions[ name ];
  50. if ( funcTemp instanceof CodeSerializationInstruction && funcTemp.getName() === funcInstructions.getName() ) {
  51. funcInstructions = funcTemp;
  52. } else {
  53. funcInstructions.setCode( objectPart.toString() );
  54. }
  55. if ( ! funcInstructions.isRemoveCode() ) {
  56. objectFunctions.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n\n' );
  57. }
  58. } else {
  59. if ( typeof ( objectPart ) === 'string' || objectPart instanceof String ) {
  60. funcInstructions.setCode( '\"' + objectPart.toString() + '\"' );
  61. } else if ( typeof objectPart === 'object' ) {
  62. console.log( 'Omitting object "' + funcInstructions.getName() + '" and replace it with empty object.' );
  63. funcInstructions.setCode( '{}' );
  64. } else {
  65. funcInstructions.setCode( objectPart );
  66. }
  67. if ( ! funcInstructions.isRemoveCode() ) {
  68. objectProperties.push( funcInstructions.getFullName() + ' = ' + funcInstructions.getCode() + ';\n' );
  69. }
  70. }
  71. }
  72. let objectString = constructorString + '\n\n';
  73. if ( isExtended ) {
  74. objectString += fullObjectName + '.prototype = Object.create( ' + basePrototypeName + '.prototype );\n';
  75. }
  76. objectString += fullObjectName + '.prototype.constructor = ' + fullObjectName + ';\n';
  77. objectString += '\n\n';
  78. for ( i = 0; i < objectProperties.length; i ++ ) {
  79. objectString += objectProperties[ i ];
  80. }
  81. objectString += '\n\n';
  82. for ( i = 0; i < objectFunctions.length; i ++ ) {
  83. objectString += objectFunctions[ i ];
  84. }
  85. objectString += '\n\n';
  86. if ( isExtended ) {
  87. for ( i = 0; i < prototypeFunctions.length; i ++ ) {
  88. objectString += prototypeFunctions[ i ];
  89. }
  90. } else {
  91. objectString += fullObjectName + '.prototype = {\n\n';
  92. for ( i = 0; i < prototypeFunctions.length; i ++ ) {
  93. objectString += prototypeFunctions[ i ];
  94. }
  95. objectString += '\n};';
  96. }
  97. objectString += '\n\n';
  98. return objectString;
  99. },
  100. };
  101. /**
  102. * Allows to define instructions to override or remove
  103. * @param {String} name Usually the name of a function
  104. * @param {String} fullName The name plus full object description
  105. * @constructor
  106. */
  107. const CodeSerializationInstruction = function ( name, fullName ) {
  108. this.name = name;
  109. this.fullName = fullName;
  110. this.code = null;
  111. this.removeCode = false;
  112. };
  113. CodeSerializationInstruction.prototype = {
  114. constructor: CodeSerializationInstruction,
  115. /**
  116. * Returns the name of the function
  117. * @return {String}
  118. */
  119. getName: function () {
  120. return this.name;
  121. },
  122. /**
  123. * Returns the full name of the function
  124. * @return {String}
  125. */
  126. getFullName: function () {
  127. return this.fullName;
  128. },
  129. /**
  130. * Set the string containing the serialized function
  131. * @param {String} code
  132. * @return {CodeSerializationInstruction}
  133. */
  134. setCode: function ( code ) {
  135. this.code = code;
  136. return this;
  137. },
  138. /**
  139. * Returns the serialized function code
  140. * @return {String}
  141. */
  142. getCode: function () {
  143. return this.code;
  144. },
  145. /**
  146. * Set if function should be removed
  147. * @param {boolean} removeCode
  148. * @return {CodeSerializationInstruction}
  149. */
  150. setRemoveCode: function ( removeCode ) {
  151. this.removeCode = removeCode;
  152. return this;
  153. },
  154. /**
  155. * If function should be completely removed
  156. * @return {boolean}
  157. */
  158. isRemoveCode: function () {
  159. return this.removeCode;
  160. }
  161. };
  162. export {
  163. CodeSerializer,
  164. CodeSerializationInstruction
  165. };