1 /* 2 * Copyright (C) 2012 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 * @constructor 33 * @implements {WebInspector.DebuggerSourceMapping} 34 * @param {!WebInspector.DebuggerModel} debuggerModel 35 * @param {!WebInspector.Workspace} workspace 36 * @param {!WebInspector.DebuggerWorkspaceBinding} debuggerWorkspaceBinding 37 */ 38 WebInspector.DefaultScriptMapping = function(debuggerModel, workspace, debuggerWorkspaceBinding) 39 { 40 this._debuggerModel = debuggerModel; 41 this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; 42 this._workspace = workspace; 43 this._projectId = WebInspector.DefaultScriptMapping.projectIdForTarget(debuggerModel.target()); 44 this._projectDelegate = new WebInspector.DebuggerProjectDelegate(this._workspace, this._projectId, WebInspector.projectTypes.Debugger); 45 debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); 46 this._debuggerReset(); 47 } 48 49 WebInspector.DefaultScriptMapping.prototype = { 50 /** 51 * @param {!WebInspector.DebuggerModel.Location} rawLocation 52 * @return {!WebInspector.UILocation} 53 */ 54 rawLocationToUILocation: function(rawLocation) 55 { 56 var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation); 57 var script = debuggerModelLocation.script(); 58 var uiSourceCode = this._uiSourceCodeForScriptId[script.scriptId]; 59 var lineNumber = debuggerModelLocation.lineNumber - (script.isInlineScriptWithSourceURL() ? script.lineOffset : 0); 60 var columnNumber = debuggerModelLocation.columnNumber || 0; 61 if (script.isInlineScriptWithSourceURL() && !lineNumber && columnNumber) 62 columnNumber -= script.columnOffset; 63 return uiSourceCode.uiLocation(lineNumber, columnNumber); 64 }, 65 66 /** 67 * @param {!WebInspector.UISourceCode} uiSourceCode 68 * @param {number} lineNumber 69 * @param {number} columnNumber 70 * @return {?WebInspector.DebuggerModel.Location} 71 */ 72 uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) 73 { 74 var scriptId = this._scriptIdForUISourceCode.get(uiSourceCode); 75 var script = this._debuggerModel.scriptForId(scriptId); 76 if (script.isInlineScriptWithSourceURL()) 77 return this._debuggerModel.createRawLocation(script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset); 78 return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber); 79 }, 80 81 /** 82 * @param {!WebInspector.Script} script 83 */ 84 addScript: function(script) 85 { 86 var path = this._projectDelegate.addScript(script); 87 var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path); 88 if (!uiSourceCode) { 89 console.assert(uiSourceCode); 90 return; 91 } 92 this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode; 93 this._scriptIdForUISourceCode.set(uiSourceCode, script.scriptId); 94 this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel.target(), uiSourceCode, this); 95 this._debuggerWorkspaceBinding.pushSourceMapping(script, this); 96 script.addEventListener(WebInspector.Script.Events.ScriptEdited, this._scriptEdited.bind(this, script.scriptId)); 97 }, 98 99 /** 100 * @return {boolean} 101 */ 102 isIdentity: function() 103 { 104 return true; 105 }, 106 107 /** 108 * @param {!WebInspector.UISourceCode} uiSourceCode 109 * @param {number} lineNumber 110 * @return {boolean} 111 */ 112 uiLineHasMapping: function(uiSourceCode, lineNumber) 113 { 114 return true; 115 }, 116 117 /** 118 * @param {string} scriptId 119 * @param {!WebInspector.Event} event 120 */ 121 _scriptEdited: function(scriptId, event) 122 { 123 var content = /** @type {string} */(event.data); 124 this._uiSourceCodeForScriptId[scriptId].addRevision(content); 125 }, 126 127 _debuggerReset: function() 128 { 129 /** @type {!Object.<string, !WebInspector.UISourceCode>} */ 130 this._uiSourceCodeForScriptId = {}; 131 this._scriptIdForUISourceCode = new Map(); 132 this._projectDelegate.reset(); 133 }, 134 135 dispose: function() 136 { 137 this._workspace.removeProject(this._projectId); 138 } 139 } 140 141 /** 142 * @param {!WebInspector.Target} target 143 * @return {string} 144 */ 145 WebInspector.DefaultScriptMapping.projectIdForTarget = function(target) 146 { 147 return "debugger:" + target.id(); 148 } 149 150 /** 151 * @constructor 152 * @param {!WebInspector.Workspace} workspace 153 * @param {string} id 154 * @param {!WebInspector.projectTypes} type 155 * @extends {WebInspector.ContentProviderBasedProjectDelegate} 156 */ 157 WebInspector.DebuggerProjectDelegate = function(workspace, id, type) 158 { 159 WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, type); 160 } 161 162 WebInspector.DebuggerProjectDelegate.prototype = { 163 /** 164 * @return {string} 165 */ 166 displayName: function() 167 { 168 return ""; 169 }, 170 171 /** 172 * @param {!WebInspector.Script} script 173 * @return {string} 174 */ 175 addScript: function(script) 176 { 177 var contentProvider = script.isInlineScript() && !script.hasSourceURL ? new WebInspector.ConcatenatedScriptsContentProvider([script]) : script; 178 var splitURL = WebInspector.ParsedURL.splitURLIntoPathComponents(script.sourceURL); 179 var name = splitURL[splitURL.length - 1]; 180 name = "VM" + script.scriptId + (name ? " " + name : ""); 181 return this.addContentProvider("", name, script.sourceURL, contentProvider); 182 }, 183 184 __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype 185 } 186