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 * @param {WebInspector.Workspace} workspace 34 */ 35 WebInspector.LiveEditSupport = function(workspace) 36 { 37 this._workspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.LiveEdit); 38 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); 39 this._debuggerReset(); 40 } 41 42 WebInspector.LiveEditSupport.prototype = { 43 /** 44 * @param {WebInspector.UISourceCode} uiSourceCode 45 * @return {WebInspector.UISourceCode} 46 */ 47 uiSourceCodeForLiveEdit: function(uiSourceCode) 48 { 49 var rawLocation = uiSourceCode.uiLocationToRawLocation(0, 0); 50 var debuggerModelLocation = /** @type {WebInspector.DebuggerModel.Location} */ (rawLocation); 51 var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId); 52 var uiLocation = script.rawLocationToUILocation(0, 0); 53 54 // FIXME: Support live editing of scripts mapped to some file. 55 if (uiLocation.uiSourceCode !== uiSourceCode) 56 return uiLocation.uiSourceCode; 57 if (this._uiSourceCodeForScriptId[script.scriptId]) 58 return this._uiSourceCodeForScriptId[script.scriptId]; 59 60 console.assert(!script.isInlineScript()); 61 var liveEditUISourceCode = this._workspaceProvider.addUniqueFileForURL(script.sourceURL, script, true, script.isContentScript); 62 63 liveEditUISourceCode.setScriptFile(new WebInspector.LiveEditScriptFile(uiSourceCode, liveEditUISourceCode, script.scriptId)); 64 this._uiSourceCodeForScriptId[script.scriptId] = liveEditUISourceCode; 65 this._scriptIdForUISourceCode.put(liveEditUISourceCode, script.scriptId); 66 return liveEditUISourceCode; 67 }, 68 69 _debuggerReset: function() 70 { 71 /** @type {!Object.<string, WebInspector.UISourceCode>} */ 72 this._uiSourceCodeForScriptId = {}; 73 /** @type {!Map.<WebInspector.UISourceCode, string>} */ 74 this._scriptIdForUISourceCode = new Map(); 75 this._workspaceProvider.reset(); 76 }, 77 } 78 79 /** 80 * @param {?string} error 81 * @param {DebuggerAgent.SetScriptSourceError=} errorData 82 * @param {WebInspector.Script=} contextScript 83 */ 84 WebInspector.LiveEditSupport.logDetailedError = function(error, errorData, contextScript) 85 { 86 if (!errorData) { 87 WebInspector.showErrorMessage(error); 88 return; 89 } 90 var compileError = errorData.compileError; 91 if (compileError) { 92 var message = compileError.message; 93 if (contextScript) 94 message += " at " + contextScript.sourceURL + ":" + compileError.lineNumber + ":" + compileError.columnNumber; 95 WebInspector.showErrorMessage(message); 96 } else { 97 WebInspector.showErrorMessage("Unknown LiveEdit error: " + JSON.stringify(errorData) + "; " + error); 98 } 99 } 100 101 /** 102 * @constructor 103 * @implements {WebInspector.ScriptFile} 104 * @extends {WebInspector.Object} 105 * @param {WebInspector.UISourceCode} uiSourceCode 106 * @param {WebInspector.UISourceCode} liveEditUISourceCode 107 * @param {string} scriptId 108 */ 109 WebInspector.LiveEditScriptFile = function(uiSourceCode, liveEditUISourceCode, scriptId) 110 { 111 WebInspector.ScriptFile.call(this); 112 this._uiSourceCode = uiSourceCode; 113 this._liveEditUISourceCode = liveEditUISourceCode; 114 this._scriptId = scriptId; 115 this._liveEditUISourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this); 116 } 117 118 WebInspector.LiveEditScriptFile.prototype = { 119 _workingCopyCommitted: function(event) 120 { 121 /** 122 * @param {?string} error 123 * @param {DebuggerAgent.SetScriptSourceError=} errorData 124 */ 125 function innerCallback(error, errorData) 126 { 127 if (error) { 128 var script = WebInspector.debuggerModel.scriptForId(this._scriptId); 129 WebInspector.LiveEditSupport.logDetailedError(error, errorData, script); 130 return; 131 } 132 } 133 134 var script = WebInspector.debuggerModel.scriptForId(this._scriptId); 135 WebInspector.debuggerModel.setScriptSource(script.scriptId, this._liveEditUISourceCode.workingCopy(), innerCallback.bind(this)); 136 }, 137 138 /** 139 * @return {boolean} 140 */ 141 hasDivergedFromVM: function() 142 { 143 return true; 144 }, 145 146 /** 147 * @return {boolean} 148 */ 149 isDivergingFromVM: function() 150 { 151 return false; 152 }, 153 154 /** 155 * @return {boolean} 156 */ 157 isMergingToVM: function() 158 { 159 return false; 160 }, 161 162 checkMapping: function() 163 { 164 }, 165 166 __proto__: WebInspector.Object.prototype 167 } 168 169 /** @type {WebInspector.LiveEditSupport} */ 170 WebInspector.liveEditSupport = null; 171