1 /* 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2007 Matt Lilek (pewtermoose (at) gmail.com). 4 * Copyright (C) 2009 Joseph Pecoraro 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /** 32 * @constructor 33 * @implements {InspectorAgent.Dispatcher} 34 * @implements {WebInspector.Console.UIDelegate} 35 */ 36 WebInspector.Main = function() 37 { 38 var boundListener = windowLoaded.bind(this); 39 WebInspector.console.setUIDelegate(this); 40 41 /** 42 * @this {WebInspector.Main} 43 */ 44 function windowLoaded() 45 { 46 this._loaded(); 47 window.removeEventListener("DOMContentLoaded", boundListener, false); 48 } 49 window.addEventListener("DOMContentLoaded", boundListener, false); 50 } 51 52 WebInspector.Main.prototype = { 53 showConsole: function() 54 { 55 WebInspector.Revealer.reveal(WebInspector.console); 56 }, 57 58 _createGlobalStatusBarItems: function() 59 { 60 var extensions = self.runtime.extensions(WebInspector.StatusBarItem.Provider); 61 62 /** 63 * @param {!Runtime.Extension} left 64 * @param {!Runtime.Extension} right 65 */ 66 function orderComparator(left, right) 67 { 68 return left.descriptor()["order"] - right.descriptor()["order"]; 69 } 70 extensions.sort(orderComparator); 71 extensions.forEach(function(extension) { 72 var item; 73 switch (extension.descriptor()["location"]) { 74 case "toolbar-left": 75 item = createItem(extension); 76 if (item) 77 WebInspector.inspectorView.appendToLeftToolbar(item); 78 break; 79 case "toolbar-right": 80 item = createItem(extension); 81 if (item) 82 WebInspector.inspectorView.appendToRightToolbar(item); 83 break; 84 } 85 if (item && extension.descriptor()["actionId"]) { 86 item.addEventListener("click", function() { 87 WebInspector.actionRegistry.execute(extension.descriptor()["actionId"]); 88 }); 89 } 90 }); 91 92 function createItem(extension) 93 { 94 var descriptor = extension.descriptor(); 95 if (descriptor.className) 96 return extension.instance().item(); 97 return new WebInspector.StatusBarButton(WebInspector.UIString(descriptor["title"]), descriptor["elementClass"]); 98 } 99 }, 100 101 _calculateWorkerInspectorTitle: function() 102 { 103 var expression = "location.href"; 104 if (Runtime.queryParam("isSharedWorker")) 105 expression += " + (this.name ? ' (' + this.name + ')' : '')"; 106 RuntimeAgent.invoke_evaluate({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback); 107 108 /** 109 * @param {?Protocol.Error} error 110 * @param {!RuntimeAgent.RemoteObject} result 111 * @param {boolean=} wasThrown 112 */ 113 function evalCallback(error, result, wasThrown) 114 { 115 if (error || wasThrown) { 116 console.error(error); 117 return; 118 } 119 InspectorFrontendHost.inspectedURLChanged(String(result.value)); 120 } 121 }, 122 123 _loadCompletedForWorkers: function() 124 { 125 // Make sure script execution of dedicated worker or service worker is 126 // resumed and then paused on the first script statement in case we 127 // autoattached to it. 128 if (Runtime.queryParam("workerPaused")) { 129 pauseAndResume.call(this); 130 } else{ 131 RuntimeAgent.isRunRequired(isRunRequiredCallback.bind(this)); 132 } 133 134 /** 135 * @this {WebInspector.Main} 136 */ 137 function isRunRequiredCallback(error, result) 138 { 139 if (result) { 140 pauseAndResume.call(this); 141 } else if (WebInspector.isWorkerFrontend()) { 142 calculateTitle.call(this); 143 } 144 } 145 146 /** 147 * @this {WebInspector.Main} 148 */ 149 function pauseAndResume() 150 { 151 DebuggerAgent.pause(); 152 RuntimeAgent.run(calculateTitle.bind(this)); 153 } 154 155 /** 156 * @this {WebInspector.Main} 157 */ 158 function calculateTitle() 159 { 160 this._calculateWorkerInspectorTitle(); 161 } 162 }, 163 164 _loaded: function() 165 { 166 console.timeStamp("Main._loaded"); 167 168 this._createSettings(); 169 this._createAppUI(); 170 }, 171 172 _createSettings: function() 173 { 174 WebInspector.settings = new WebInspector.Settings(); 175 this._initializeExperiments(); 176 // This setting is needed for backwards compatibility with Devtools CodeSchool extension. DO NOT REMOVE 177 WebInspector.settings.pauseOnExceptionStateString = new WebInspector.PauseOnExceptionStateSetting(); 178 new WebInspector.VersionController().updateVersion(); 179 }, 180 181 _initializeExperiments: function() 182 { 183 Runtime.experiments.register("applyCustomStylesheet", "Allow custom UI themes"); 184 Runtime.experiments.register("canvasInspection", "Canvas inspection"); 185 Runtime.experiments.register("devicesPanel", "Devices panel"); 186 Runtime.experiments.register("disableAgentsWhenProfile", "Disable other agents and UI when profiler is active", true); 187 Runtime.experiments.register("dockToLeft", "Dock to left", true); 188 Runtime.experiments.register("documentation", "JavaScript documentation", true); 189 Runtime.experiments.register("fileSystemInspection", "FileSystem inspection"); 190 Runtime.experiments.register("gpuTimeline", "GPU data on timeline", true); 191 Runtime.experiments.register("layersPanel", "Layers panel"); 192 Runtime.experiments.register("promiseTracker", "Enable Promise inspection", true); 193 Runtime.experiments.register("suggestUsingWorkspace", "Suggest using workspace", true); 194 Runtime.experiments.register("timelineOnTraceEvents", "Timeline on trace events"); 195 Runtime.experiments.register("timelinePowerProfiler", "Timeline power profiler"); 196 Runtime.experiments.register("timelineJSCPUProfile", "Timeline with JS sampling"); 197 Runtime.experiments.cleanUpStaleExperiments(); 198 }, 199 200 _createAppUI: function() 201 { 202 console.timeStamp("Main._createApp"); 203 204 WebInspector.installPortStyles(); 205 if (Runtime.queryParam("toolbarColor") && Runtime.queryParam("textColor")) 206 WebInspector.setToolbarColors(Runtime.queryParam("toolbarColor"), Runtime.queryParam("textColor")); 207 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetToolbarColors, updateToolbarColors); 208 /** 209 * @param {!WebInspector.Event} event 210 */ 211 function updateToolbarColors(event) 212 { 213 WebInspector.setToolbarColors(/** @type {string} */ (event.data["backgroundColor"]), /** @type {string} */ (event.data["color"])); 214 } 215 216 this._addMainEventListeners(document); 217 218 var canDock = !!Runtime.queryParam("can_dock"); 219 WebInspector.zoomManager = new WebInspector.ZoomManager(InspectorFrontendHost); 220 WebInspector.inspectorView = new WebInspector.InspectorView(); 221 WebInspector.ContextMenu.initialize(); 222 WebInspector.dockController = new WebInspector.DockController(canDock); 223 WebInspector.overridesSupport = new WebInspector.OverridesSupport(canDock); 224 WebInspector.multitargetConsoleModel = new WebInspector.MultitargetConsoleModel(); 225 226 WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen(); 227 // set order of some sections explicitly 228 WebInspector.shortcutsScreen.section(WebInspector.UIString("Console")); 229 WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel")); 230 231 WebInspector.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager(); 232 WebInspector.workspace = new WebInspector.Workspace(WebInspector.isolatedFileSystemManager.mapping()); 233 WebInspector.networkWorkspaceBinding = new WebInspector.NetworkWorkspaceBinding(WebInspector.workspace); 234 new WebInspector.NetworkUISourceCodeProvider(WebInspector.networkWorkspaceBinding, WebInspector.workspace); 235 WebInspector.presentationConsoleMessageHelper = new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace); 236 WebInspector.cssWorkspaceBinding = new WebInspector.CSSWorkspaceBinding(); 237 WebInspector.debuggerWorkspaceBinding = new WebInspector.DebuggerWorkspaceBinding(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkWorkspaceBinding); 238 WebInspector.fileSystemWorkspaceBinding = new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager, WebInspector.workspace); 239 WebInspector.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, WebInspector.workspace, WebInspector.targetManager, WebInspector.debuggerWorkspaceBinding); 240 WebInspector.scriptSnippetModel = new WebInspector.ScriptSnippetModel(WebInspector.workspace); 241 new WebInspector.ContentScriptProjectDecorator(); 242 new WebInspector.ExecutionContextSelector(); 243 244 var autoselectPanel = WebInspector.UIString("a panel chosen automatically"); 245 var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel); 246 WebInspector.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting); 247 WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; }); 248 WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler()); 249 250 new WebInspector.WorkspaceController(WebInspector.workspace); 251 new WebInspector.RenderingOptions(); 252 new WebInspector.Main.PauseListener(); 253 new WebInspector.Main.InspectedNodeRevealer(); 254 WebInspector.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane(); 255 256 WebInspector.actionRegistry = new WebInspector.ActionRegistry(); 257 WebInspector.shortcutRegistry = new WebInspector.ShortcutRegistry(WebInspector.actionRegistry); 258 WebInspector.ShortcutsScreen.registerShortcuts(); 259 this._registerForwardedShortcuts(); 260 this._registerMessageSinkListener(); 261 262 if (canDock) 263 WebInspector.app = new WebInspector.AdvancedApp(); 264 else if (Runtime.queryParam("remoteFrontend")) 265 WebInspector.app = new WebInspector.ScreencastApp(); 266 else 267 WebInspector.app = new WebInspector.SimpleApp(); 268 269 // It is important to kick controller lifetime after apps are instantiated. 270 WebInspector.dockController.initialize(); 271 console.timeStamp("Main._presentUI"); 272 WebInspector.app.presentUI(); 273 274 if (!WebInspector.isWorkerFrontend()) 275 WebInspector.inspectElementModeController = new WebInspector.InspectElementModeController(); 276 this._createGlobalStatusBarItems(); 277 278 WebInspector.extensionServerProxy.setFrontendReady(); 279 InspectorFrontendAPI.loadCompleted(); 280 281 // Give UI cycles to repaint, then proceed with creating connection. 282 setTimeout(this._createConnection.bind(this), 0); 283 }, 284 285 _createConnection: function() 286 { 287 console.timeStamp("Main._createConnection"); 288 InspectorBackend.loadFromJSONIfNeeded("../protocol.json"); 289 290 var workerId = Runtime.queryParam("dedicatedWorkerId"); 291 if (workerId) { 292 this._connectionEstablished(new WebInspector.ExternalWorkerConnection(workerId)); 293 return; 294 } 295 296 if (Runtime.queryParam("ws")) { 297 var ws = "ws://" + Runtime.queryParam("ws"); 298 InspectorBackendClass.WebSocketConnection.Create(ws, this._connectionEstablished.bind(this)); 299 return; 300 } 301 302 if (!InspectorFrontendHost.isHostedMode()) { 303 this._connectionEstablished(new InspectorBackendClass.MainConnection()); 304 return; 305 } 306 307 this._connectionEstablished(new InspectorBackendClass.StubConnection()); 308 }, 309 310 /** 311 * @param {!InspectorBackendClass.Connection} connection 312 */ 313 _connectionEstablished: function(connection) 314 { 315 console.timeStamp("Main._connectionEstablished"); 316 connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, onDisconnected); 317 318 /** 319 * @param {!WebInspector.Event} event 320 */ 321 function onDisconnected(event) 322 { 323 if (WebInspector._disconnectedScreenWithReasonWasShown) 324 return; 325 new WebInspector.RemoteDebuggingTerminatedScreen(event.data.reason).showModal(); 326 } 327 328 InspectorBackend.setConnection(connection); 329 WebInspector.targetManager.createTarget(WebInspector.UIString("Main"), connection, this._mainTargetCreated.bind(this)); 330 }, 331 332 /** 333 * @param {?WebInspector.Target} target 334 */ 335 _mainTargetCreated: function(target) 336 { 337 console.timeStamp("Main._mainTargetCreated"); 338 339 var mainTarget = /** @type {!WebInspector.Target} */(target); 340 this._registerShortcuts(); 341 342 WebInspector.workerTargetManager = new WebInspector.WorkerTargetManager(mainTarget, WebInspector.targetManager); 343 344 mainTarget.registerInspectorDispatcher(this); 345 346 if (WebInspector.isWorkerFrontend()) { 347 mainTarget.runtimeAgent().run(); 348 mainTarget.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerDisconnected, onWorkerDisconnected); 349 } 350 351 function onWorkerDisconnected() 352 { 353 var screen = new WebInspector.WorkerTerminatedScreen(); 354 var listener = hideScreen.bind(null, screen); 355 mainTarget.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener); 356 357 /** 358 * @param {!WebInspector.WorkerTerminatedScreen} screen 359 */ 360 function hideScreen(screen) 361 { 362 mainTarget.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener); 363 screen.hide(); 364 } 365 366 screen.showModal(); 367 } 368 369 InspectorAgent.enable(inspectorAgentEnableCallback); 370 371 function inspectorAgentEnableCallback() 372 { 373 console.timeStamp("Main.inspectorAgentEnableCallback"); 374 WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.InspectorAgentEnabledForTests); 375 } 376 377 WebInspector.overridesSupport.applyInitialOverrides(); 378 if (!WebInspector.overridesSupport.responsiveDesignAvailable() && WebInspector.overridesSupport.emulationEnabled()) 379 WebInspector.inspectorView.showViewInDrawer("emulation", true); 380 381 this._loadCompletedForWorkers(); 382 }, 383 384 _registerForwardedShortcuts: function() 385 { 386 /** @const */ var forwardedActions = ["main.reload", "main.hard-reload"]; 387 var actionKeys = WebInspector.shortcutRegistry.keysForActions(forwardedActions).map(WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey); 388 389 actionKeys.push({keyCode: WebInspector.KeyboardShortcut.Keys.F8.code}); 390 InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys)); 391 }, 392 393 _registerMessageSinkListener: function() 394 { 395 WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded, messageAdded); 396 397 /** 398 * @param {!WebInspector.Event} event 399 */ 400 function messageAdded(event) 401 { 402 var message = /** @type {!WebInspector.Console.Message} */ (event.data); 403 if (message.show) 404 WebInspector.console.show(); 405 } 406 }, 407 408 _documentClick: function(event) 409 { 410 var anchor = event.target.enclosingNodeOrSelfWithNodeName("a"); 411 if (!anchor || !anchor.href) 412 return; 413 414 // Prevent the link from navigating, since we don't do any navigation by following links normally. 415 event.consume(true); 416 417 if (anchor.target === "_blank") { 418 InspectorFrontendHost.openInNewTab(anchor.href); 419 return; 420 } 421 422 function followLink() 423 { 424 if (WebInspector.isBeingEdited(event.target)) 425 return; 426 if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber})) 427 return; 428 429 var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href); 430 if (uiSourceCode) { 431 WebInspector.Revealer.reveal(uiSourceCode.uiLocation(anchor.lineNumber || 0, anchor.columnNumber || 0)); 432 return; 433 } 434 435 var resource = WebInspector.resourceForURL(anchor.href); 436 if (resource) { 437 WebInspector.Revealer.reveal(resource); 438 return; 439 } 440 441 var request = WebInspector.networkLog.requestForURL(anchor.href); 442 if (request) { 443 WebInspector.Revealer.reveal(request); 444 return; 445 } 446 InspectorFrontendHost.openInNewTab(anchor.href); 447 } 448 449 if (WebInspector.followLinkTimeout) 450 clearTimeout(WebInspector.followLinkTimeout); 451 452 if (anchor.preventFollowOnDoubleClick) { 453 // Start a timeout if this is the first click, if the timeout is canceled 454 // before it fires, then a double clicked happened or another link was clicked. 455 if (event.detail === 1) 456 WebInspector.followLinkTimeout = setTimeout(followLink, 333); 457 return; 458 } 459 460 followLink(); 461 }, 462 463 _registerShortcuts: function() 464 { 465 var shortcut = WebInspector.KeyboardShortcut; 466 var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels")); 467 var keys = [ 468 shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta), 469 shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta) 470 ]; 471 section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right")); 472 473 keys = [ 474 shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt), 475 shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt) 476 ]; 477 section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history")); 478 479 var toggleConsoleLabel = WebInspector.UIString("Show console"); 480 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel); 481 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), WebInspector.UIString("Toggle drawer")); 482 if (WebInspector.overridesSupport.responsiveDesignAvailable()) 483 section.addKey(shortcut.makeDescriptor("M", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift), WebInspector.UIString("Toggle device mode")); 484 section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search")); 485 486 var advancedSearchShortcutModifier = WebInspector.isMac() 487 ? WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt 488 : WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift; 489 var advancedSearchShortcut = shortcut.makeDescriptor("f", advancedSearchShortcutModifier); 490 section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources")); 491 492 var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut(); 493 section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect")); 494 495 var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("p", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta); 496 section.addKey(openResourceShortcut, WebInspector.UIString("Go to source")); 497 498 if (WebInspector.isMac()) { 499 keys = [ 500 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta), 501 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift) 502 ]; 503 section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous")); 504 } 505 }, 506 507 _postDocumentKeyDown: function(event) 508 { 509 if (event.handled) 510 return; 511 512 if (!WebInspector.Dialog.currentInstance() && WebInspector.inspectorView.currentPanel()) { 513 WebInspector.inspectorView.currentPanel().handleShortcut(event); 514 if (event.handled) { 515 event.consume(true); 516 return; 517 } 518 } 519 520 WebInspector.shortcutRegistry.handleShortcut(event); 521 }, 522 523 _documentCanCopy: function(event) 524 { 525 var panel = WebInspector.inspectorView.currentPanel(); 526 if (panel && panel["handleCopyEvent"]) 527 event.preventDefault(); 528 }, 529 530 _documentCopy: function(event) 531 { 532 var panel = WebInspector.inspectorView.currentPanel(); 533 if (panel && panel["handleCopyEvent"]) 534 panel["handleCopyEvent"](event); 535 }, 536 537 _documentCut: function(event) 538 { 539 var panel = WebInspector.inspectorView.currentPanel(); 540 if (panel && panel["handleCutEvent"]) 541 panel["handleCutEvent"](event); 542 }, 543 544 _documentPaste: function(event) 545 { 546 var panel = WebInspector.inspectorView.currentPanel(); 547 if (panel && panel["handlePasteEvent"]) 548 panel["handlePasteEvent"](event); 549 }, 550 551 _contextMenuEventFired: function(event) 552 { 553 if (event.handled || event.target.classList.contains("popup-glasspane")) 554 event.preventDefault(); 555 }, 556 557 _addMainEventListeners: function(doc) 558 { 559 doc.addEventListener("keydown", this._postDocumentKeyDown.bind(this), false); 560 doc.addEventListener("beforecopy", this._documentCanCopy.bind(this), true); 561 doc.addEventListener("copy", this._documentCopy.bind(this), false); 562 doc.addEventListener("cut", this._documentCut.bind(this), false); 563 doc.addEventListener("paste", this._documentPaste.bind(this), false); 564 doc.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); 565 doc.addEventListener("click", this._documentClick.bind(this), false); 566 }, 567 568 /** 569 * @override 570 * @param {!RuntimeAgent.RemoteObject} payload 571 * @param {!Object=} hints 572 */ 573 inspect: function(payload, hints) 574 { 575 var object = WebInspector.runtimeModel.createRemoteObject(payload); 576 if (object.isNode()) { 577 var nodeObjectInspector = runtime.instance(WebInspector.NodeRemoteObjectInspector, object); 578 if (nodeObjectInspector) 579 nodeObjectInspector.inspectNodeObject(object); 580 return; 581 } 582 583 if (object.type === "function") { 584 object.functionDetails(didGetDetails); 585 return; 586 } 587 588 /** 589 * @param {?WebInspector.DebuggerModel.FunctionDetails} response 590 */ 591 function didGetDetails(response) 592 { 593 object.release(); 594 595 if (!response || !response.location) 596 return; 597 598 WebInspector.Revealer.reveal(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(response.location)); 599 } 600 601 if (hints.copyToClipboard) 602 InspectorFrontendHost.copyText(object.value); 603 object.release(); 604 }, 605 606 /** 607 * @override 608 * @param {string} reason 609 */ 610 detached: function(reason) 611 { 612 WebInspector._disconnectedScreenWithReasonWasShown = true; 613 new WebInspector.RemoteDebuggingTerminatedScreen(reason).showModal(); 614 }, 615 616 /** 617 * @override 618 */ 619 targetCrashed: function() 620 { 621 (new WebInspector.HelpScreenUntilReload( 622 WebInspector.UIString("Inspected target crashed"), 623 WebInspector.UIString("Inspected target has crashed. Once it reloads we will attach to it automatically."))).showModal(); 624 }, 625 626 /** 627 * @override 628 * @param {number} callId 629 * @param {string} script 630 */ 631 evaluateForTestInFrontend: function(callId, script) 632 { 633 WebInspector.evaluateForTestInFrontend(callId, script); 634 } 635 } 636 637 WebInspector.reload = function() 638 { 639 InspectorAgent.reset(); 640 window.location.reload(); 641 } 642 643 /** 644 * @constructor 645 * @implements {WebInspector.ActionDelegate} 646 */ 647 WebInspector.Main.ReloadActionDelegate = function() 648 { 649 } 650 651 WebInspector.Main.ReloadActionDelegate.prototype = { 652 /** 653 * @return {boolean} 654 */ 655 handleAction: function() 656 { 657 return WebInspector.Main._reloadPage(false); 658 } 659 } 660 661 /** 662 * @constructor 663 * @implements {WebInspector.ActionDelegate} 664 */ 665 WebInspector.Main.HardReloadActionDelegate = function() 666 { 667 } 668 669 WebInspector.Main.HardReloadActionDelegate.prototype = { 670 /** 671 * @return {boolean} 672 */ 673 handleAction: function() 674 { 675 return WebInspector.Main._reloadPage(true); 676 } 677 } 678 679 /** 680 * @constructor 681 * @implements {WebInspector.ActionDelegate} 682 */ 683 WebInspector.Main.DebugReloadActionDelegate = function() 684 { 685 } 686 687 WebInspector.Main.DebugReloadActionDelegate.prototype = { 688 /** 689 * @return {boolean} 690 */ 691 handleAction: function() 692 { 693 WebInspector.reload(); 694 return true; 695 } 696 } 697 698 /** 699 * @constructor 700 * @implements {WebInspector.ActionDelegate} 701 */ 702 WebInspector.Main.ZoomInActionDelegate = function() 703 { 704 } 705 706 WebInspector.Main.ZoomInActionDelegate.prototype = { 707 /** 708 * @return {boolean} 709 */ 710 handleAction: function() 711 { 712 if (InspectorFrontendHost.isHostedMode()) 713 return false; 714 715 InspectorFrontendHost.zoomIn(); 716 return true; 717 } 718 } 719 720 /** 721 * @constructor 722 * @implements {WebInspector.ActionDelegate} 723 */ 724 WebInspector.Main.ZoomOutActionDelegate = function() 725 { 726 } 727 728 WebInspector.Main.ZoomOutActionDelegate.prototype = { 729 /** 730 * @return {boolean} 731 */ 732 handleAction: function() 733 { 734 if (InspectorFrontendHost.isHostedMode()) 735 return false; 736 737 InspectorFrontendHost.zoomOut(); 738 return true; 739 } 740 } 741 742 /** 743 * @constructor 744 * @implements {WebInspector.ActionDelegate} 745 */ 746 WebInspector.Main.ZoomResetActionDelegate = function() 747 { 748 } 749 750 WebInspector.Main.ZoomResetActionDelegate.prototype = { 751 /** 752 * @return {boolean} 753 */ 754 handleAction: function() 755 { 756 if (InspectorFrontendHost.isHostedMode()) 757 return false; 758 759 InspectorFrontendHost.resetZoom(); 760 return true; 761 } 762 } 763 764 /** 765 * @constructor 766 * @extends {WebInspector.UISettingDelegate} 767 */ 768 WebInspector.Main.ShortcutPanelSwitchSettingDelegate = function() 769 { 770 WebInspector.UISettingDelegate.call(this); 771 } 772 773 WebInspector.Main.ShortcutPanelSwitchSettingDelegate.prototype = { 774 /** 775 * @override 776 * @return {!Element} 777 */ 778 settingElement: function() 779 { 780 var modifier = WebInspector.platform() === "mac" ? "Cmd" : "Ctrl"; 781 return WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Enable %s + 1-9 shortcut to switch panels", modifier), WebInspector.settings.shortcutPanelSwitch); 782 }, 783 784 __proto__: WebInspector.UISettingDelegate.prototype 785 } 786 787 /** 788 * @param {boolean} hard 789 * @return {boolean} 790 */ 791 WebInspector.Main._reloadPage = function(hard) 792 { 793 if (!WebInspector.targetManager.hasTargets()) 794 return false; 795 796 var targets = WebInspector.targetManager.targets(); 797 for (var i = 0; i < targets.length; ++i) 798 targets[i].debuggerModel.skipAllPauses(true, true); 799 WebInspector.targetManager.reloadPage(hard); 800 return true; 801 } 802 803 /** 804 * @param {string} ws 805 */ 806 WebInspector.Main._addWebSocketTarget = function(ws) 807 { 808 /** 809 * @param {!InspectorBackendClass.Connection} connection 810 */ 811 function callback(connection) 812 { 813 WebInspector.targetManager.createTarget(ws, connection); 814 } 815 new InspectorBackendClass.WebSocketConnection(ws, callback); 816 } 817 818 new WebInspector.Main(); 819 820 // These methods are added for backwards compatibility with Devtools CodeSchool extension. 821 // DO NOT REMOVE 822 823 WebInspector.__defineGetter__("inspectedPageURL", function() 824 { 825 return WebInspector.targetManager.inspectedPageURL(); 826 }); 827 828 /** 829 * @param {string} name 830 * @return {?WebInspector.Panel} 831 */ 832 WebInspector.panel = function(name) 833 { 834 return WebInspector.inspectorView.panel(name); 835 } 836 837 /** 838 * @constructor 839 * @implements {WebInspector.StatusBarItem.Provider} 840 */ 841 WebInspector.Main.WarningErrorCounter = function() 842 { 843 this._counter = new WebInspector.StatusBarCounter(["error-icon-small", "warning-icon-small"]); 844 this._counter.addEventListener("click", showConsole); 845 846 function showConsole() 847 { 848 WebInspector.console.show(); 849 } 850 851 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this); 852 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this); 853 } 854 855 WebInspector.Main.WarningErrorCounter.prototype = { 856 _updateErrorAndWarningCounts: function() 857 { 858 var errors = 0; 859 var warnings = 0; 860 var targets = WebInspector.targetManager.targets(); 861 for (var i = 0; i < targets.length; ++i) { 862 errors = errors + targets[i].consoleModel.errors; 863 warnings = warnings + targets[i].consoleModel.warnings; 864 } 865 this._counter.setCounter("error-icon-small", errors, WebInspector.UIString(errors > 1 ? "%d errors" : "%d error", errors)); 866 this._counter.setCounter("warning-icon-small", warnings, WebInspector.UIString(warnings > 1 ? "%d warnings" : "%d warning", warnings)); 867 WebInspector.inspectorView.toolbarItemResized(); 868 }, 869 870 /** 871 * @return {?WebInspector.StatusBarItem} 872 */ 873 item: function() 874 { 875 return this._counter; 876 } 877 } 878 879 /** 880 * @constructor 881 */ 882 WebInspector.Main.PauseListener = function() 883 { 884 WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); 885 } 886 887 WebInspector.Main.PauseListener.prototype = { 888 /** 889 * @param {!WebInspector.Event} event 890 */ 891 _debuggerPaused: function(event) 892 { 893 WebInspector.targetManager.removeModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); 894 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target); 895 WebInspector.context.setFlavor(WebInspector.Target, debuggerModel.target()); 896 WebInspector.inspectorView.showPanel("sources"); 897 } 898 } 899 900 /** 901 * @constructor 902 */ 903 WebInspector.Main.InspectedNodeRevealer = function() 904 { 905 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeInspected, this._inspectNode, this); 906 } 907 908 WebInspector.Main.InspectedNodeRevealer.prototype = { 909 /** 910 * @param {!WebInspector.Event} event 911 */ 912 _inspectNode: function(event) 913 { 914 WebInspector.Revealer.reveal(/** @type {!WebInspector.DOMNode} */ (event.data)); 915 } 916 } 917