DebuggerManager.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * Copyright (C) 2013 Apple 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
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. WebInspector.DebuggerManager = function()
  26. {
  27. WebInspector.Object.call(this);
  28. DebuggerAgent.enable();
  29. WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.DisplayLocationDidChange, this._breakpointDisplayLocationDidChange, this);
  30. WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.DisabledStateDidChange, this._breakpointDisabledStateDidChange, this);
  31. WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.ConditionDidChange, this._breakpointConditionDidChange, this);
  32. window.addEventListener("pagehide", this._inspectorClosing.bind(this));
  33. this._allExceptionsBreakpointEnabledSetting = new WebInspector.Setting("break-on-all-exceptions", false);
  34. this._allUncaughtExceptionsBreakpointEnabledSetting = new WebInspector.Setting("break-on-all-uncaught-exceptions", false);
  35. var specialBreakpointLocation = new WebInspector.SourceCodeLocation(null, Infinity, Infinity);
  36. this._allExceptionsBreakpoint = new WebInspector.Breakpoint(specialBreakpointLocation, !this._allExceptionsBreakpointEnabledSetting.value);
  37. this._allExceptionsBreakpoint.resolved = true;
  38. this._allUncaughtExceptionsBreakpoint = new WebInspector.Breakpoint(specialBreakpointLocation, !this._allUncaughtExceptionsBreakpointEnabledSetting.value);
  39. this._breakpoints = [];
  40. this._breakpointURLMap = {};
  41. this._breakpointScriptIdentifierMap = {};
  42. this._breakpointIdMap = {};
  43. this._scriptIdMap = {};
  44. this._scriptURLMap = {};
  45. this._breakpointsSetting = new WebInspector.Setting("breakpoints", []);
  46. this._breakpointsEnabledSetting = new WebInspector.Setting("breakpoints-enabled", true);
  47. DebuggerAgent.setBreakpointsActive(this._breakpointsEnabledSetting.value);
  48. this._updateBreakOnExceptionsState();
  49. var savedBreakpoints = this._breakpointsSetting.value;
  50. for (var i = 0; i < savedBreakpoints.length; ++i) {
  51. var breakpoint = new WebInspector.Breakpoint(savedBreakpoints[i]);
  52. this.addBreakpoint(breakpoint, true);
  53. }
  54. };
  55. WebInspector.DebuggerManager.Event = {
  56. BreakpointAdded: "debugger-manager-breakpoint-added",
  57. BreakpointRemoved: "debugger-manager-breakpoint-removed",
  58. BreakpointMoved: "debugger-manager-breakpoint-moved",
  59. Paused: "debugger-manager-paused",
  60. Resumed: "debugger-manager-resumed",
  61. CallFramesDidChange: "debugger-manager-call-frames-did-change",
  62. ActiveCallFrameDidChange: "debugger-manager-active-call-frame-did-change",
  63. ScriptAdded: "debugger-manager-script-added",
  64. ScriptsCleared: "debugger-manager-scripts-cleared"
  65. };
  66. WebInspector.DebuggerManager.prototype = {
  67. constructor: WebInspector.DebuggerManager,
  68. // Public
  69. get breakpointsEnabled()
  70. {
  71. return this._breakpointsEnabledSetting.value;
  72. },
  73. set breakpointsEnabled(enabled)
  74. {
  75. if (this._breakpointsEnabled === enabled)
  76. return;
  77. this._breakpointsEnabledSetting.value = enabled;
  78. this._allExceptionsBreakpoint.dispatchEventToListeners(WebInspector.Breakpoint.Event.ResolvedStateDidChange);
  79. this._allUncaughtExceptionsBreakpoint.dispatchEventToListeners(WebInspector.Breakpoint.Event.ResolvedStateDidChange);
  80. for (var i = 0; i < this._breakpoints.length; ++i)
  81. this._breakpoints[i].dispatchEventToListeners(WebInspector.Breakpoint.Event.ResolvedStateDidChange);
  82. DebuggerAgent.setBreakpointsActive(enabled);
  83. this._updateBreakOnExceptionsState();
  84. },
  85. get paused()
  86. {
  87. return this._paused;
  88. },
  89. get callFrames()
  90. {
  91. return this._callFrames;
  92. },
  93. get activeCallFrame()
  94. {
  95. return this._activeCallFrame;
  96. },
  97. set activeCallFrame(callFrame)
  98. {
  99. if (callFrame === this._activeCallFrame)
  100. return;
  101. this._activeCallFrame = callFrame || null;
  102. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange);
  103. },
  104. pause: function()
  105. {
  106. DebuggerAgent.pause();
  107. },
  108. resume: function()
  109. {
  110. DebuggerAgent.resume();
  111. },
  112. stepOver: function()
  113. {
  114. DebuggerAgent.stepOver();
  115. },
  116. stepInto: function()
  117. {
  118. DebuggerAgent.stepInto();
  119. },
  120. stepOut: function()
  121. {
  122. DebuggerAgent.stepOut();
  123. },
  124. get allExceptionsBreakpoint()
  125. {
  126. return this._allExceptionsBreakpoint;
  127. },
  128. get allUncaughtExceptionsBreakpoint()
  129. {
  130. return this._allUncaughtExceptionsBreakpoint;
  131. },
  132. get breakpoints()
  133. {
  134. return this._breakpoints;
  135. },
  136. breakpointsForSourceCode: function(sourceCode)
  137. {
  138. console.assert(sourceCode instanceof WebInspector.Resource || sourceCode instanceof WebInspector.Script);
  139. if (sourceCode instanceof WebInspector.SourceMapResource) {
  140. var mappedResourceBreakpoints = [];
  141. var originalSourceCodeBreakpoints = this.breakpointsForSourceCode(sourceCode.sourceMap.originalSourceCode);
  142. return originalSourceCodeBreakpoints.filter(function(breakpoint) {
  143. return breakpoint.sourceCodeLocation.displaySourceCode === sourceCode;
  144. });
  145. }
  146. if (sourceCode.url in this._breakpointURLMap) {
  147. var urlBreakpoint = this._breakpointURLMap[sourceCode.url] || [];
  148. this._associateBreakpointsWithSourceCode(urlBreakpoint, sourceCode);
  149. return urlBreakpoint;
  150. }
  151. if (sourceCode instanceof WebInspector.Script && sourceCode.id in this._breakpointScriptIdentifierMap) {
  152. var scriptIdentifierBreakpoints = this._breakpointScriptIdentifierMap[sourceCode.id] || [];
  153. this._associateBreakpointsWithSourceCode(scriptIdentifierBreakpoints, sourceCode);
  154. return scriptIdentifierBreakpoints;
  155. }
  156. return [];
  157. },
  158. scriptForIdentifier: function(id)
  159. {
  160. return this._scriptIdMap[id] || null;
  161. },
  162. scriptsForURL: function(url)
  163. {
  164. // FIXME: This may not be safe. A Resource's URL may differ from a Script's URL.
  165. return this._scriptURLMap[url] || [];
  166. },
  167. addBreakpoint: function(breakpoint, skipEventDispatch)
  168. {
  169. console.assert(breakpoint);
  170. if (!breakpoint)
  171. return;
  172. if (breakpoint.url) {
  173. var urlBreakpoints = this._breakpointURLMap[breakpoint.url];
  174. if (!urlBreakpoints)
  175. urlBreakpoints = this._breakpointURLMap[breakpoint.url] = [];
  176. urlBreakpoints.push(breakpoint);
  177. }
  178. if (breakpoint.scriptIdentifier) {
  179. var scriptIdentifierBreakpoints = this._breakpointScriptIdentifierMap[breakpoint.scriptIdentifier];
  180. if (!scriptIdentifierBreakpoints)
  181. scriptIdentifierBreakpoints = this._breakpointScriptIdentifierMap[breakpoint.scriptIdentifier] = [];
  182. scriptIdentifierBreakpoints.push(breakpoint);
  183. }
  184. this._breakpoints.push(breakpoint);
  185. if (!breakpoint.disabled)
  186. this._setBreakpoint(breakpoint);
  187. if (!skipEventDispatch)
  188. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.BreakpointAdded, {breakpoint: breakpoint});
  189. },
  190. removeBreakpoint: function(breakpoint)
  191. {
  192. console.assert(breakpoint);
  193. if (!breakpoint)
  194. return;
  195. console.assert(this.isBreakpointRemovable(breakpoint));
  196. if (!this.isBreakpointRemovable(breakpoint))
  197. return;
  198. this._breakpoints.remove(breakpoint);
  199. if (breakpoint.id)
  200. this._removeBreakpoint(breakpoint);
  201. if (breakpoint.url) {
  202. var urlBreakpoints = this._breakpointURLMap[breakpoint.url];
  203. if (urlBreakpoints) {
  204. urlBreakpoints.remove(breakpoint);
  205. if (!urlBreakpoints.length)
  206. delete this._breakpointURLMap[breakpoint.url];
  207. }
  208. }
  209. if (breakpoint.scriptIdentifier) {
  210. var scriptIdentifierBreakpoints = this._breakpointScriptIdentifierMap[breakpoint.scriptIdentifier];
  211. if (scriptIdentifierBreakpoints) {
  212. scriptIdentifierBreakpoints.remove(breakpoint);
  213. if (!scriptIdentifierBreakpoints.length)
  214. delete this._breakpointScriptIdentifierMap[breakpoint.scriptIdentifier];
  215. }
  216. }
  217. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.BreakpointRemoved, {breakpoint: breakpoint});
  218. },
  219. breakpointResolved: function(breakpointIdentifier, location)
  220. {
  221. // Called from WebInspector.DebuggerObserver.
  222. var breakpoint = this._breakpointIdMap[breakpointIdentifier];
  223. console.assert(breakpoint);
  224. if (!breakpoint)
  225. return;
  226. console.assert(breakpoint.id === breakpointIdentifier);
  227. breakpoint.resolved = true;
  228. },
  229. reset: function()
  230. {
  231. // Called from WebInspector.DebuggerObserver.
  232. var wasPaused = this._paused;
  233. WebInspector.Script.resetUniqueDisplayNameNumbers();
  234. this._paused = false;
  235. this._scriptIdMap = {};
  236. this._scriptURLMap = {};
  237. this._ignoreBreakpointDisplayLocationDidChangeEvent = true;
  238. // Mark all the breakpoints as unresolved. They will be reported as resolved when
  239. // breakpointResolved is called as the page loads.
  240. for (var i = 0; i < this._breakpoints.length; ++i) {
  241. var breakpoint = this._breakpoints[i];
  242. breakpoint.resolved = false;
  243. if (breakpoint.sourceCodeLocation.sourceCode)
  244. breakpoint.sourceCodeLocation.sourceCode = null;
  245. }
  246. delete this._ignoreBreakpointDisplayLocationDidChangeEvent;
  247. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.ScriptsCleared);
  248. if (wasPaused)
  249. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.Resumed);
  250. },
  251. debuggerDidPause: function(callFramesPayload)
  252. {
  253. // Called from WebInspector.DebuggerObserver.
  254. if (this._delayedResumeTimeout) {
  255. clearTimeout(this._delayedResumeTimeout);
  256. delete this._delayedResumeTimeout;
  257. }
  258. var wasStillPaused = this._paused;
  259. this._paused = true;
  260. this._callFrames = [];
  261. for (var i = 0; i < callFramesPayload.length; ++i) {
  262. var callFramePayload = callFramesPayload[i];
  263. var sourceCodeLocation = this._sourceCodeLocationFromPayload(callFramePayload.location);
  264. if (!sourceCodeLocation)
  265. continue;
  266. var thisObject = WebInspector.RemoteObject.fromPayload(callFramePayload.this);
  267. var scopeChain = this._scopeChainFromPayload(callFramePayload.scopeChain);
  268. var callFrame = new WebInspector.CallFrame(callFramePayload.callFrameId, sourceCodeLocation, callFramePayload.functionName, thisObject, scopeChain);
  269. this._callFrames.push(callFrame);
  270. }
  271. this._activeCallFrame = this._callFrames[0];
  272. if (!wasStillPaused)
  273. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.Paused);
  274. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.CallFramesDidChange);
  275. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange);
  276. },
  277. debuggerDidResume: function()
  278. {
  279. // Called from WebInspector.DebuggerObserver.
  280. function delayedWork()
  281. {
  282. delete this._delayedResumeTimeout;
  283. this._paused = false;
  284. this._callFrames = null;
  285. this._activeCallFrame = null;
  286. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.Resumed);
  287. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.CallFramesDidChange);
  288. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange);
  289. }
  290. // We delay clearing the state and firing events so the user interface does not flash
  291. // between brief steps or successive breakpoints.
  292. this._delayedResumeTimeout = setTimeout(delayedWork.bind(this), 50);
  293. },
  294. scriptDidParse: function(scriptIdentifier, url, isContentScript, startLine, startColumn, endLine, endColumn, sourceMapURL)
  295. {
  296. // Don't add the script again if it is already known.
  297. if (this._scriptIdMap[scriptIdentifier]) {
  298. console.assert(this._scriptIdMap[scriptIdentifier].url === url);
  299. console.assert(this._scriptIdMap[scriptIdentifier].range.startLine === startLine);
  300. console.assert(this._scriptIdMap[scriptIdentifier].range.startColumn === startColumn);
  301. console.assert(this._scriptIdMap[scriptIdentifier].range.endLine === endLine);
  302. console.assert(this._scriptIdMap[scriptIdentifier].range.endColumn === endColumn);
  303. return;
  304. }
  305. var script = new WebInspector.Script(scriptIdentifier, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn), url, isContentScript, sourceMapURL);
  306. this._scriptIdMap[scriptIdentifier] = script;
  307. if (script.url) {
  308. var scripts = this._scriptURLMap[script.url];
  309. if (!scripts)
  310. scripts = this._scriptURLMap[script.url] = [];
  311. scripts.push(script);
  312. }
  313. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.ScriptAdded, {script: script});
  314. },
  315. isBreakpointRemovable: function(breakpoint)
  316. {
  317. return breakpoint !== this._allExceptionsBreakpoint && breakpoint !== this._allUncaughtExceptionsBreakpoint;
  318. },
  319. isBreakpointEditable: function(breakpoint)
  320. {
  321. return this.isBreakpointRemovable(breakpoint);
  322. },
  323. // Private
  324. _sourceCodeLocationFromPayload: function(payload)
  325. {
  326. var script = this._scriptIdMap[payload.scriptId];
  327. console.assert(script);
  328. if (!script)
  329. return null;
  330. return script.createSourceCodeLocation(payload.lineNumber, payload.columnNumber);
  331. },
  332. _scopeChainFromPayload: function(payload)
  333. {
  334. var scopeChain = [];
  335. for (var i = 0; i < payload.length; ++i)
  336. scopeChain.push(this._scopeChainNodeFromPayload(payload[i]));
  337. return scopeChain;
  338. },
  339. _scopeChainNodeFromPayload: function(payload)
  340. {
  341. var type = null;
  342. switch (payload.type) {
  343. case "local":
  344. type = WebInspector.ScopeChainNode.Type.Local;
  345. break;
  346. case "global":
  347. type = WebInspector.ScopeChainNode.Type.Global;
  348. break;
  349. case "with":
  350. type = WebInspector.ScopeChainNode.Type.With;
  351. break;
  352. case "closure":
  353. type = WebInspector.ScopeChainNode.Type.Closure;
  354. break;
  355. case "catch":
  356. type = WebInspector.ScopeChainNode.Type.Catch;
  357. break;
  358. default:
  359. console.error("Unknown type: " + payload.type);
  360. }
  361. var object = WebInspector.RemoteObject.fromPayload(payload.object);
  362. return new WebInspector.ScopeChainNode(type, object);
  363. },
  364. _setBreakpoint: function(breakpoint, callback)
  365. {
  366. console.assert(!breakpoint.id);
  367. console.assert(!breakpoint.disabled);
  368. if (breakpoint.id || breakpoint.disabled)
  369. return;
  370. function didSetBreakpoint(error, breakpointIdentifier)
  371. {
  372. if (error)
  373. return;
  374. this._breakpointIdMap[breakpointIdentifier] = breakpoint;
  375. breakpoint.id = breakpointIdentifier;
  376. breakpoint.resolved = true;
  377. if (typeof callback === "function")
  378. callback();
  379. }
  380. // The breakpoint will be resolved again by calling DebuggerAgent, so mark it as unresolved.
  381. // If something goes wrong it will stay unresolved and show up as such in the user interface.
  382. breakpoint.resolved = false;
  383. if (breakpoint.url)
  384. DebuggerAgent.setBreakpointByUrl(breakpoint.sourceCodeLocation.lineNumber, breakpoint.url, undefined, breakpoint.sourceCodeLocation.columnNumber, breakpoint.condition, didSetBreakpoint.bind(this));
  385. else if (breakpoint.scriptIdentifier)
  386. DebuggerAgent.setBreakpoint({scriptId: breakpoint.scriptIdentifier, lineNumber: breakpoint.sourceCodeLocation.lineNumber, columnNumber: breakpoint.sourceCodeLocation.columnNumber}, breakpoint.condition, didSetBreakpoint.bind(this));
  387. },
  388. _removeBreakpoint: function(breakpoint, callback)
  389. {
  390. console.assert(breakpoint.id);
  391. if (!breakpoint.id)
  392. return;
  393. function didRemoveBreakpoint(error)
  394. {
  395. delete this._breakpointIdMap[breakpoint.id];
  396. breakpoint.id = null;
  397. // Don't reset resolved here since we want to keep disabled breakpoints looking like they
  398. // are resolved in the user interface. They will get marked as unresolved in reset.
  399. if (typeof callback === "function")
  400. callback();
  401. }
  402. DebuggerAgent.removeBreakpoint(breakpoint.id, didRemoveBreakpoint.bind(this));
  403. },
  404. _breakpointDisplayLocationDidChange: function(event)
  405. {
  406. if (this._ignoreBreakpointDisplayLocationDidChangeEvent)
  407. return;
  408. var breakpoint = event.target;
  409. if (!breakpoint.id || breakpoint.disabled)
  410. return;
  411. // Remove the breakpoint with its old id.
  412. this._removeBreakpoint(breakpoint, breakpointRemoved.bind(this));
  413. function breakpointRemoved()
  414. {
  415. // Add the breakpoint at its new lineNumber and get a new id.
  416. this._setBreakpoint(breakpoint);
  417. this.dispatchEventToListeners(WebInspector.DebuggerManager.Event.BreakpointMoved, {breakpoint: breakpoint});
  418. }
  419. },
  420. _breakpointDisabledStateDidChange: function(event)
  421. {
  422. var breakpoint = event.target;
  423. if (breakpoint === this._allExceptionsBreakpoint) {
  424. this._allExceptionsBreakpointEnabledSetting.value = !breakpoint.disabled;
  425. this._updateBreakOnExceptionsState();
  426. return;
  427. }
  428. if (breakpoint === this._allUncaughtExceptionsBreakpoint) {
  429. this._allUncaughtExceptionsBreakpointEnabledSetting.value = !breakpoint.disabled;
  430. this._updateBreakOnExceptionsState();
  431. return;
  432. }
  433. if (breakpoint.disabled)
  434. this._removeBreakpoint(breakpoint);
  435. else
  436. this._setBreakpoint(breakpoint);
  437. },
  438. _breakpointConditionDidChange: function(event)
  439. {
  440. var breakpoint = event.target;
  441. if (breakpoint.disabled)
  442. return;
  443. console.assert(this.isBreakpointEditable(breakpoint));
  444. if (!this.isBreakpointEditable(breakpoint))
  445. return;
  446. // Remove the breakpoint with its old id.
  447. this._removeBreakpoint(breakpoint, breakpointRemoved.bind(this));
  448. function breakpointRemoved()
  449. {
  450. // Add the breakpoint with its new condition and get a new id.
  451. this._setBreakpoint(breakpoint);
  452. }
  453. },
  454. _updateBreakOnExceptionsState: function()
  455. {
  456. var state = "none";
  457. if (this._breakpointsEnabledSetting.value) {
  458. if (!this._allExceptionsBreakpoint.disabled)
  459. state = "all";
  460. else if (!this._allUncaughtExceptionsBreakpoint.disabled)
  461. state = "uncaught";
  462. }
  463. switch (state) {
  464. case "all":
  465. // Mark the uncaught breakpoint as unresolved since "all" includes "uncaught".
  466. // That way it is clear in the user interface that the breakpoint is ignored.
  467. this._allUncaughtExceptionsBreakpoint.resolved = false;
  468. break;
  469. case "uncaught":
  470. case "none":
  471. // Mark the uncaught breakpoint as resolved again.
  472. this._allUncaughtExceptionsBreakpoint.resolved = true;
  473. break;
  474. }
  475. DebuggerAgent.setPauseOnExceptions(state);
  476. },
  477. _inspectorClosing: function(event)
  478. {
  479. this._saveBreakpoints();
  480. },
  481. _saveBreakpoints: function()
  482. {
  483. var savedBreakpoints = [];
  484. for (var i = 0; i < this._breakpoints.length; ++i) {
  485. var breakpoint = this._breakpoints[i];
  486. // Only breakpoints with URLs can be saved. Breakpoints for transient scripts can't.
  487. if (!breakpoint.url)
  488. continue;
  489. savedBreakpoints.push(breakpoint.info);
  490. }
  491. this._breakpointsSetting.value = savedBreakpoints;
  492. },
  493. _associateBreakpointsWithSourceCode: function(breakpoints, sourceCode)
  494. {
  495. this._ignoreBreakpointDisplayLocationDidChangeEvent = true;
  496. for (var i = 0; i < breakpoints.length; ++i) {
  497. var breakpoint = breakpoints[i];
  498. if (breakpoint.sourceCodeLocation.sourceCode === null)
  499. breakpoint.sourceCodeLocation.sourceCode = sourceCode;
  500. // SourceCodes can be unequal if the SourceCodeLocation is associated with a Script and we are looking at the Resource.
  501. console.assert(breakpoint.sourceCodeLocation.sourceCode === sourceCode || breakpoint.sourceCodeLocation.sourceCode.url === sourceCode.url);
  502. }
  503. delete this._ignoreBreakpointDisplayLocationDidChangeEvent;
  504. }
  505. };
  506. WebInspector.DebuggerManager.prototype.__proto__ = WebInspector.Object.prototype;