code.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. window.Tracker = window.Tracker || {};
  2. /**
  3. * Code
  4. */
  5. Tracker.Code = function(){
  6. var klass;
  7. klass = function( url, content, scriptElementIndex ){
  8. var comboCode, beautifyCode;
  9. this.id = Tracker.Util.id();
  10. this.url = url;
  11. this.type = "";
  12. this.state = "normal";
  13. this.rowsCount = 0;
  14. this.arriveRowsCount = 0;
  15. this.size = content ? Tracker.Util.getByteLength( content ) : -1;
  16. this.fileName = url ? Tracker.Util.fileName( url ) : "-";
  17. this.fullUrl = url ? Tracker.Path.merge( Tracker.Path.getBase(window.document), url ) : null;
  18. this.origContent = content || null;
  19. this.lastModified = Tracker.Util.time();
  20. this.beautifySize = -1;
  21. this.runErrors = [];
  22. this.syntaxErrors = [];
  23. this.props = {};
  24. this.executiveCode = "";
  25. this.linesViewHtml = [];
  26. this.loadConsum =
  27. this.runConsum = -1;
  28. this.onReady = Tracker.Promise.fuze();
  29. if( content ){
  30. comboCode = new Tracker.ComboCode( this );
  31. comboCode.onReady( Tracker.Util.bind( function(){
  32. if( comboCode.errorMessage ){
  33. this.executiveCode = this.origContent;
  34. this.syntaxErrors.push( comboCode );
  35. this.fire( "error", "syntaxErrors" );
  36. }else{
  37. this.executiveCode = comboCode.getExecutiveCode( scriptElementIndex );
  38. beautifyCode = comboCode.getBeautifyCode();
  39. this.beautifySize = Tracker.Util.getByteLength( beautifyCode );
  40. this.rowsCount = Tracker.Util.splitToLines( beautifyCode ).length;
  41. }
  42. this.linesViewHtml = comboCode.getViewHtmlByLines();
  43. this.onReady.fire();
  44. }, this ) );
  45. }else{
  46. this.executiveCode = ";";
  47. this.beautifySize = this.size = 0;
  48. this.rowsCount = 0;
  49. this.linesViewHtml = [];
  50. this.setState( "empty" );
  51. this.onReady.fire();
  52. }
  53. };
  54. klass.prototype = Tracker.Event.bind( {
  55. setType: function( type ){
  56. this.type = type; // embed, link, append
  57. },
  58. setState: function( state ){ // normal, timeout, empty
  59. this.state = state;
  60. },
  61. addError: function( message ){
  62. this.runErrors.push( new Error( message ) );
  63. this.lastModified = Tracker.Util.time();
  64. this.fire( "error", "runErrors" );
  65. },
  66. prop: function( name, value ){
  67. if( arguments.length == 2 )
  68. return this.props[ name ] = value;
  69. else
  70. return this.props[ name ];
  71. }
  72. } );
  73. return klass;
  74. }();
  75. Tracker.ComboCode = function(){
  76. var klass, closeTagRegx, viewHtmlRegx, executiveCodeRegx, comboCodeBoundaryRegx,
  77. lineFirstIdRegx, topLocationToRegx;
  78. closeTagRegx = /<\/(\w{0,10})>/g;
  79. viewHtmlRegx = /\{<\}(<!-- TRACKERINJECTHTML -->.*?)\{>\}/g;
  80. executiveCodeRegx = /\{<\}\/\* TRACKERINJECTJS \*\/.*?\{>\}/g;
  81. comboCodeBoundaryRegx = /\{(?:<|>)\}/g;
  82. lineFirstIdRegx = /id=ckey\-(\d+)/;
  83. topLocationToRegx = /(\s*)(top)(\.location\s*=)(?!=)/g;
  84. klass = function( CodeInstance ){
  85. this.CodeInstance = CodeInstance;
  86. this.code = null;
  87. this.errorMessage = null;
  88. this.onReady = Tracker.Promise.fuze();
  89. try{
  90. this.code = window.document.combocodegen( CodeInstance );
  91. }catch(e){
  92. this.errorMessage = e.message;
  93. }
  94. this.onReady.fire();
  95. };
  96. klass.prototype = Tracker.Event.bind( {
  97. getCode: function(){
  98. return this.code;
  99. },
  100. getBeautifyCode: function(){
  101. var code = this.code;
  102. code = code.replace( viewHtmlRegx, "" );
  103. code = code.replace( executiveCodeRegx, "" );
  104. code = code.replace( comboCodeBoundaryRegx, "" );
  105. return code;
  106. },
  107. getExecutiveCode: function( scriptElementIndex ){
  108. var code, inst, a;
  109. code = this.code;
  110. inst = this.CodeInstance;
  111. code = code.replace( viewHtmlRegx, "" );
  112. code = code.replace( comboCodeBoundaryRegx, "" );
  113. code = code.replace( closeTagRegx, function( s, a ){
  114. return "<\\/" + a + ">";
  115. } );
  116. code = code.replace( topLocationToRegx, function( s, a, b, c ){
  117. return a + "__trackerMockTop__()" + c;
  118. } );
  119. code = "try{" + code +
  120. "}catch(e){__trackerError__('" + inst.id + "',e.message);throw e;}";
  121. a = typeof scriptElementIndex == "undefined" ? "" : "," + scriptElementIndex;
  122. code = "__trackerScriptStart__('" + inst.id + "'" + a + ");" +
  123. code + "; __trackerScriptEnd__('" + inst.id + "');";
  124. return code;
  125. },
  126. getViewHtmlByLines: function(){
  127. var code, lines, firstId;
  128. code = this.code || this.CodeInstance.origContent;
  129. code = code.replace( viewHtmlRegx, function( s, a ){
  130. return a.replace( /</g, "\x00" ).replace( />/g, "\x01" );
  131. } );
  132. code = code.replace( executiveCodeRegx, "" );
  133. code = code.replace( comboCodeBoundaryRegx, "" );
  134. lines = Tracker.Util.splitToLines( code );
  135. // Tracker.Util.forEach( lines, function( line, index ){
  136. // var firstId;
  137. // firstId = line.match( lineFirstIdRegx );
  138. // if( firstId )
  139. // Tracker.StatusPool.beginOfLineSnippetPut( firstId[1] );
  140. // } );
  141. Tracker.Util.forEach( lines, function( line ){
  142. if( firstId = line.match( lineFirstIdRegx ) )
  143. Tracker.StatusPool.snippetGroupCoverLineAdd( firstId[ 1 ] );
  144. } );
  145. return lines;
  146. }
  147. } );
  148. return klass;
  149. }();
  150. Tracker.CodeList = function(){
  151. var single, codes;
  152. codes = [];
  153. single = Tracker.Event.bind( {
  154. add: function(){
  155. var code;
  156. if( arguments.length == 1 ){
  157. code = arguments[ 0 ];
  158. }else if( arguments.length == 2 ){
  159. code = new Tracker.Code( arguments[ 0 ], arguments[ 1 ] );
  160. }else{
  161. return ;
  162. }
  163. codes[ code.id ] = code;
  164. codes.push( code );
  165. },
  166. get: function( idOrIndex ){
  167. return codes[ idOrIndex ];
  168. },
  169. list: function(){
  170. return codes;
  171. },
  172. each: function( fn ){
  173. Tracker.Util.forEach( codes, fn );
  174. },
  175. sort: function(){
  176. for( var i = codes.length - 1, r; i >= 0; i -- ){
  177. r = codes[ i ];
  178. if( r.type == "embed" )
  179. codes.splice( i, 1 ),
  180. codes.push( r );
  181. }
  182. Tracker.Util.forEach( codes, function( code, index ){
  183. code.index = index;
  184. } );
  185. },
  186. count: function(){
  187. return codes.length;
  188. } } );
  189. return single;
  190. }();