1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /** 32 * @fileoverview These stubs emulate backend functionality and allows 33 * DevTools frontend to function as a standalone web app. 34 */ 35 36 if (!window["RemoteDebuggerAgent"]) { 37 38 /** 39 * FIXME: change field naming style to use trailing underscore. 40 * @constructor 41 */ 42 RemoteDebuggerAgentStub = function() 43 { 44 }; 45 46 47 RemoteDebuggerAgentStub.prototype.getContextId = function() 48 { 49 RemoteDebuggerAgent.setContextId(3); 50 }; 51 52 53 RemoteDebuggerAgentStub.prototype.processDebugCommands = function() 54 { 55 }; 56 57 58 /** 59 * @constructor 60 */ 61 RemoteProfilerAgentStub = function() 62 { 63 }; 64 65 66 RemoteProfilerAgentStub.prototype.getActiveProfilerModules = function() 67 { 68 ProfilerStubHelper.GetInstance().getActiveProfilerModules(); 69 }; 70 71 72 RemoteProfilerAgentStub.prototype.getLogLines = function(pos) 73 { 74 ProfilerStubHelper.GetInstance().getLogLines(pos); 75 }; 76 77 78 /** 79 * @constructor 80 */ 81 RemoteToolsAgentStub = function() 82 { 83 }; 84 85 86 RemoteToolsAgentStub.prototype.dispatchOnInjectedScript = function() 87 { 88 }; 89 90 91 RemoteToolsAgentStub.prototype.dispatchOnInspectorController = function() 92 { 93 }; 94 95 96 /** 97 * @constructor 98 */ 99 ProfilerStubHelper = function() 100 { 101 this.activeProfilerModules_ = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; 102 this.heapProfSample_ = 0; 103 this.log_ = ''; 104 }; 105 106 107 ProfilerStubHelper.GetInstance = function() 108 { 109 if (!ProfilerStubHelper.instance_) 110 ProfilerStubHelper.instance_ = new ProfilerStubHelper(); 111 return ProfilerStubHelper.instance_; 112 }; 113 114 115 ProfilerStubHelper.prototype.StopProfiling = function(modules) 116 { 117 this.activeProfilerModules_ &= ~modules; 118 }; 119 120 121 ProfilerStubHelper.prototype.StartProfiling = function(modules) 122 { 123 var profModules = devtools.ProfilerAgent.ProfilerModules; 124 if (modules & profModules.PROFILER_MODULE_HEAP_SNAPSHOT) { 125 if (modules & profModules.PROFILER_MODULE_HEAP_STATS) { 126 this.log_ += 127 'heap-sample-begin,"Heap","allocated",' + 128 (new Date()).getTime() + '\n' + 129 'heap-sample-stats,"Heap","allocated",10000,1000\n'; 130 this.log_ += 131 'heap-sample-item,STRING_TYPE,100,1000\n' + 132 'heap-sample-item,CODE_TYPE,10,200\n' + 133 'heap-sample-item,MAP_TYPE,20,350\n'; 134 this.log_ += ProfilerStubHelper.HeapSamples[this.heapProfSample_++]; 135 this.heapProfSample_ %= ProfilerStubHelper.HeapSamples.length; 136 this.log_ += 'heap-sample-end,"Heap","allocated"\n'; 137 } 138 } else { 139 if (modules & profModules.PROFILER_MODULE_CPU) 140 this.log_ += ProfilerStubHelper.ProfilerLogBuffer; 141 this.activeProfilerModules_ |= modules; 142 } 143 }; 144 145 146 ProfilerStubHelper.prototype.getActiveProfilerModules = function() 147 { 148 var self = this; 149 setTimeout(function() { 150 RemoteProfilerAgent.didGetActiveProfilerModules(self.activeProfilerModules_); 151 }, 100); 152 }; 153 154 155 ProfilerStubHelper.prototype.getLogLines = function(pos) 156 { 157 var profModules = devtools.ProfilerAgent.ProfilerModules; 158 var logLines = this.log_.substr(pos); 159 setTimeout(function() { 160 RemoteProfilerAgent.didGetLogLines(pos + logLines.length, logLines); 161 }, 100); 162 }; 163 164 165 ProfilerStubHelper.ProfilerLogBuffer = 166 'profiler,begin,1\n' + 167 'profiler,resume\n' + 168 'code-creation,LazyCompile,0x1000,256,"test1 http://aaa.js:1"\n' + 169 'code-creation,LazyCompile,0x2000,256,"test2 http://bbb.js:2"\n' + 170 'code-creation,LazyCompile,0x3000,256,"test3 http://ccc.js:3"\n' + 171 'tick,0x1010,0x0,3\n' + 172 'tick,0x2020,0x0,3,0x1010\n' + 173 'tick,0x2020,0x0,3,0x1010\n' + 174 'tick,0x3010,0x0,3,0x2020, 0x1010\n' + 175 'tick,0x2020,0x0,3,0x1010\n' + 176 'tick,0x2030,0x0,3,0x2020, 0x1010\n' + 177 'tick,0x2020,0x0,3,0x1010\n' + 178 'tick,0x1010,0x0,3\n' + 179 'profiler,pause\n'; 180 181 182 ProfilerStubHelper.HeapSamples = [ 183 'heap-js-cons-item,foo,1,100\n' + 184 'heap-js-cons-item,bar,20,2000\n' + 185 'heap-js-cons-item,Object,5,100\n' + 186 'heap-js-ret-item,foo,bar;3\n' + 187 'heap-js-ret-item,bar,foo;5\n' + 188 'heap-js-ret-item,Object:0x1234,(roots);1\n', 189 190 'heap-js-cons-item,foo,2000,200000\n' + 191 'heap-js-cons-item,bar,10,1000\n' + 192 'heap-js-cons-item,Object,6,120\n' + 193 'heap-js-ret-item,foo,bar;7,Object:0x1234;10\n' + 194 'heap-js-ret-item,bar,foo;10,Object:0x1234;10\n' + 195 'heap-js-ret-item,Object:0x1234,(roots);1\n', 196 197 'heap-js-cons-item,foo,15,1500\n' + 198 'heap-js-cons-item,bar,15,1500\n' + 199 'heap-js-cons-item,Object,5,100\n' + 200 'heap-js-cons-item,Array,3,1000\n' + 201 'heap-js-ret-item,foo,bar;3,Array:0x5678;1\n' + 202 'heap-js-ret-item,bar,foo;5,Object:0x1234;8,Object:0x5678;2\n' + 203 'heap-js-ret-item,Object:0x1234,(roots);1,Object:0x5678;2\n' + 204 'heap-js-ret-item,Object:0x5678,(global property);3,Object:0x1234;5\n' + 205 'heap-js-ret-item,Array:0x5678,(global property);3,Array:0x5678;2\n', 206 207 'heap-js-cons-item,bar,20,2000\n' + 208 'heap-js-cons-item,Object,6,120\n' + 209 'heap-js-ret-item,bar,foo;5,Object:0x1234;1,Object:0x1235;3\n' + 210 'heap-js-ret-item,Object:0x1234,(global property);3\n' + 211 'heap-js-ret-item,Object:0x1235,(global property);5\n', 212 213 'heap-js-cons-item,foo,15,1500\n' + 214 'heap-js-cons-item,bar,15,1500\n' + 215 'heap-js-cons-item,Array,10,1000\n' + 216 'heap-js-ret-item,foo,bar;1,Array:0x5678;1\n' + 217 'heap-js-ret-item,bar,foo;5\n' + 218 'heap-js-ret-item,Array:0x5678,(roots);3\n', 219 220 'heap-js-cons-item,bar,20,2000\n' + 221 'heap-js-cons-item,baz,15,1500\n' + 222 'heap-js-ret-item,bar,baz;3\n' + 223 'heap-js-ret-item,baz,bar;3\n' 224 ]; 225 226 227 /** 228 * @constructor 229 */ 230 RemoteDebuggerCommandExecutorStub = function() 231 { 232 }; 233 234 235 RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function(cmd) 236 { 237 if ('{"seq":2,"type":"request","command":"scripts","arguments":{"includeSource":false}}' === cmd) { 238 var response1 = 239 '{"seq":5,"request_seq":2,"type":"response","command":"scripts","' + 240 'success":true,"body":[{"handle":61,"type":"script","name":"' + 241 'http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + 242 '"lineCount":1,"sourceStart":"function fib(n) {","sourceLength":300,' + 243 '"scriptType":2,"compilationType":0,"context":{"ref":60}}],"refs":[{' + 244 '"handle":60,"type":"context","data":"page,3"}],"running":false}'; 245 this.sendResponse_(response1); 246 } else if ('{"seq":3,"type":"request","command":"scripts","arguments":{"ids":[59],"includeSource":true}}' === cmd) { 247 this.sendResponse_( 248 '{"seq":8,"request_seq":3,"type":"response","command":"scripts",' + 249 '"success":true,"body":[{"handle":1,"type":"script","name":' + 250 '"http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + 251 '"lineCount":1,"source":"function fib(n) {return n+1;}",' + 252 '"sourceLength":244,"scriptType":2,"compilationType":0,"context":{' + 253 '"ref":0}}],"refs":[{"handle":0,"type":"context","data":"page,3}],"' + 254 '"running":false}'); 255 } else if (cmd.indexOf('"command":"profile"') !== -1) { 256 var cmdObj = JSON.parse(cmd); 257 if (cmdObj.arguments.command === "resume") 258 ProfilerStubHelper.GetInstance().StartProfiling(parseInt(cmdObj.arguments.modules)); 259 else if (cmdObj.arguments.command === "pause") 260 ProfilerStubHelper.GetInstance().StopProfiling(parseInt(cmdObj.arguments.modules)); 261 else 262 debugPrint("Unexpected profile command: " + cmdObj.arguments.command); 263 } else 264 debugPrint("Unexpected command: " + cmd); 265 }; 266 267 268 RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript = function() 269 { 270 }; 271 272 273 RemoteDebuggerCommandExecutorStub.prototype.sendResponse_ = function(response) 274 { 275 setTimeout(function() { 276 RemoteDebuggerAgent.debuggerOutput(response); 277 }, 0); 278 }; 279 280 281 DevToolsHostStub = function() 282 { 283 this.isStub = true; 284 }; 285 DevToolsHostStub.prototype.__proto__ = WebInspector.InspectorFrontendHostStub.prototype; 286 287 288 DevToolsHostStub.prototype.reset = function() 289 { 290 }; 291 292 293 DevToolsHostStub.prototype.setting = function() 294 { 295 }; 296 297 298 DevToolsHostStub.prototype.setSetting = function() 299 { 300 }; 301 302 303 window["RemoteDebuggerAgent"] = new RemoteDebuggerAgentStub(); 304 window["RemoteDebuggerCommandExecutor"] = new RemoteDebuggerCommandExecutorStub(); 305 window["RemoteProfilerAgent"] = new RemoteProfilerAgentStub(); 306 window["RemoteToolsAgent"] = new RemoteToolsAgentStub(); 307 InspectorFrontendHost = new DevToolsHostStub(); 308 309 } 310