BreakpointsSidebarPane.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /*
  2. * Copyright (C) 2008 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. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /**
  26. * @constructor
  27. * @param {WebInspector.BreakpointManager} breakpointManager
  28. * @extends {WebInspector.SidebarPane}
  29. */
  30. WebInspector.JavaScriptBreakpointsSidebarPane = function(breakpointManager, showSourceLineDelegate)
  31. {
  32. WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
  33. this.registerRequiredCSS("breakpointsList.css");
  34. this._breakpointManager = breakpointManager;
  35. this._showSourceLineDelegate = showSourceLineDelegate;
  36. this.listElement = document.createElement("ol");
  37. this.listElement.className = "breakpoint-list";
  38. this.emptyElement = document.createElement("div");
  39. this.emptyElement.className = "info";
  40. this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
  41. this.bodyElement.appendChild(this.emptyElement);
  42. this._items = new Map();
  43. var breakpointLocations = this._breakpointManager.allBreakpointLocations();
  44. for (var i = 0; i < breakpointLocations.length; ++i)
  45. this._addBreakpoint(breakpointLocations[i].breakpoint, breakpointLocations[i].uiLocation);
  46. this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
  47. this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
  48. this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true);
  49. }
  50. WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
  51. _emptyElementContextMenu: function(event)
  52. {
  53. var contextMenu = new WebInspector.ContextMenu(event);
  54. var breakpointActive = WebInspector.debuggerModel.breakpointsActive();
  55. var breakpointActiveTitle = breakpointActive ?
  56. WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Deactivate breakpoints" : "Deactivate Breakpoints") :
  57. WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Activate breakpoints" : "Activate Breakpoints");
  58. contextMenu.appendItem(breakpointActiveTitle, WebInspector.debuggerModel.setBreakpointsActive.bind(WebInspector.debuggerModel, !breakpointActive));
  59. contextMenu.show();
  60. },
  61. /**
  62. * @param {WebInspector.Event} event
  63. */
  64. _breakpointAdded: function(event)
  65. {
  66. this._breakpointRemoved(event);
  67. var breakpoint = /** @type {WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
  68. var uiLocation = /** @type {WebInspector.UILocation} */ (event.data.uiLocation);
  69. this._addBreakpoint(breakpoint, uiLocation);
  70. },
  71. /**
  72. * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint
  73. * @param {WebInspector.UILocation} uiLocation
  74. */
  75. _addBreakpoint: function(breakpoint, uiLocation)
  76. {
  77. var element = document.createElement("li");
  78. element.addStyleClass("cursor-pointer");
  79. element.addEventListener("contextmenu", this._breakpointContextMenu.bind(this, breakpoint), true);
  80. element.addEventListener("click", this._breakpointClicked.bind(this, uiLocation), false);
  81. var checkbox = document.createElement("input");
  82. checkbox.className = "checkbox-elem";
  83. checkbox.type = "checkbox";
  84. checkbox.checked = breakpoint.enabled();
  85. checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpoint), false);
  86. element.appendChild(checkbox);
  87. var labelElement = document.createTextNode(WebInspector.formatLinkText(uiLocation.uiSourceCode.originURL(), uiLocation.lineNumber));
  88. element.appendChild(labelElement);
  89. var snippetElement = document.createElement("div");
  90. snippetElement.className = "source-text monospace";
  91. element.appendChild(snippetElement);
  92. /**
  93. * @param {?string} content
  94. * @param {boolean} contentEncoded
  95. * @param {string} mimeType
  96. */
  97. function didRequestContent(content, contentEncoded, mimeType)
  98. {
  99. var lineEndings = content.lineEndings();
  100. if (uiLocation.lineNumber < lineEndings.length)
  101. snippetElement.textContent = content.substring(lineEndings[uiLocation.lineNumber - 1], lineEndings[uiLocation.lineNumber]);
  102. }
  103. uiLocation.uiSourceCode.requestContent(didRequestContent.bind(this));
  104. element._data = uiLocation;
  105. var currentElement = this.listElement.firstChild;
  106. while (currentElement) {
  107. if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0)
  108. break;
  109. currentElement = currentElement.nextSibling;
  110. }
  111. this._addListElement(element, currentElement);
  112. var breakpointItem = {};
  113. breakpointItem.element = element;
  114. breakpointItem.checkbox = checkbox;
  115. this._items.put(breakpoint, breakpointItem);
  116. this.expand();
  117. },
  118. /**
  119. * @param {WebInspector.Event} event
  120. */
  121. _breakpointRemoved: function(event)
  122. {
  123. var breakpoint = /** @type {WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
  124. var uiLocation = /** @type {WebInspector.UILocation} */ (event.data.uiLocation);
  125. var breakpointItem = this._items.get(breakpoint);
  126. if (!breakpointItem)
  127. return;
  128. this._items.remove(breakpoint);
  129. this._removeListElement(breakpointItem.element);
  130. },
  131. /**
  132. * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint
  133. */
  134. highlightBreakpoint: function(breakpoint)
  135. {
  136. var breakpointItem = this._items.get(breakpoint);
  137. if (!breakpointItem)
  138. return;
  139. breakpointItem.element.addStyleClass("breakpoint-hit");
  140. this._highlightedBreakpointItem = breakpointItem;
  141. },
  142. clearBreakpointHighlight: function()
  143. {
  144. if (this._highlightedBreakpointItem) {
  145. this._highlightedBreakpointItem.element.removeStyleClass("breakpoint-hit");
  146. delete this._highlightedBreakpointItem;
  147. }
  148. },
  149. _breakpointClicked: function(uiLocation, event)
  150. {
  151. this._showSourceLineDelegate(uiLocation.uiSourceCode, uiLocation.lineNumber);
  152. },
  153. /**
  154. * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint
  155. */
  156. _breakpointCheckboxClicked: function(breakpoint, event)
  157. {
  158. // Breakpoint element has it's own click handler.
  159. event.consume();
  160. breakpoint.setEnabled(event.target.checked);
  161. },
  162. /**
  163. * @param {WebInspector.BreakpointManager.Breakpoint} breakpoint
  164. */
  165. _breakpointContextMenu: function(breakpoint, event)
  166. {
  167. var breakpoints = this._items.values();
  168. var contextMenu = new WebInspector.ContextMenu(event);
  169. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove breakpoint" : "Remove Breakpoint"), breakpoint.remove.bind(breakpoint));
  170. if (breakpoints.length > 1) {
  171. var removeAllTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all breakpoints" : "Remove All Breakpoints");
  172. contextMenu.appendItem(removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager));
  173. }
  174. contextMenu.appendSeparator();
  175. var breakpointActive = WebInspector.debuggerModel.breakpointsActive();
  176. var breakpointActiveTitle = breakpointActive ?
  177. WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Deactivate breakpoints" : "Deactivate Breakpoints") :
  178. WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Activate breakpoints" : "Activate Breakpoints");
  179. contextMenu.appendItem(breakpointActiveTitle, WebInspector.debuggerModel.setBreakpointsActive.bind(WebInspector.debuggerModel, !breakpointActive));
  180. function enabledBreakpointCount(breakpoints)
  181. {
  182. var count = 0;
  183. for (var i = 0; i < breakpoints.length; ++i) {
  184. if (breakpoints[i].checkbox.checked)
  185. count++;
  186. }
  187. return count;
  188. }
  189. if (breakpoints.length > 1) {
  190. var enableBreakpointCount = enabledBreakpointCount(breakpoints);
  191. var enableTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Enable all breakpoints" : "Enable All Breakpoints");
  192. var disableTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Disable all breakpoints" : "Disable All Breakpoints");
  193. contextMenu.appendSeparator();
  194. contextMenu.appendItem(enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true), !(enableBreakpointCount != breakpoints.length));
  195. contextMenu.appendItem(disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false), !(enableBreakpointCount > 1));
  196. }
  197. contextMenu.show();
  198. },
  199. _addListElement: function(element, beforeElement)
  200. {
  201. if (beforeElement)
  202. this.listElement.insertBefore(element, beforeElement);
  203. else {
  204. if (!this.listElement.firstChild) {
  205. this.bodyElement.removeChild(this.emptyElement);
  206. this.bodyElement.appendChild(this.listElement);
  207. }
  208. this.listElement.appendChild(element);
  209. }
  210. },
  211. _removeListElement: function(element)
  212. {
  213. this.listElement.removeChild(element);
  214. if (!this.listElement.firstChild) {
  215. this.bodyElement.removeChild(this.listElement);
  216. this.bodyElement.appendChild(this.emptyElement);
  217. }
  218. },
  219. _compare: function(x, y)
  220. {
  221. if (x !== y)
  222. return x < y ? -1 : 1;
  223. return 0;
  224. },
  225. _compareBreakpoints: function(b1, b2)
  226. {
  227. return this._compare(b1.uiSourceCode.originURL(), b2.uiSourceCode.originURL()) || this._compare(b1.lineNumber, b2.lineNumber);
  228. },
  229. reset: function()
  230. {
  231. this.listElement.removeChildren();
  232. if (this.listElement.parentElement) {
  233. this.bodyElement.removeChild(this.listElement);
  234. this.bodyElement.appendChild(this.emptyElement);
  235. }
  236. this._items.clear();
  237. },
  238. __proto__: WebInspector.SidebarPane.prototype
  239. }
  240. /**
  241. * @constructor
  242. * @extends {WebInspector.NativeBreakpointsSidebarPane}
  243. */
  244. WebInspector.XHRBreakpointsSidebarPane = function()
  245. {
  246. WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
  247. this._breakpointElements = {};
  248. var addButton = document.createElement("button");
  249. addButton.className = "pane-title-button add";
  250. addButton.addEventListener("click", this._addButtonClicked.bind(this), false);
  251. addButton.title = WebInspector.UIString("Add XHR breakpoint");
  252. this.titleElement.appendChild(addButton);
  253. this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true);
  254. this._restoreBreakpoints();
  255. }
  256. WebInspector.XHRBreakpointsSidebarPane.prototype = {
  257. _emptyElementContextMenu: function(event)
  258. {
  259. var contextMenu = new WebInspector.ContextMenu(event);
  260. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add breakpoint" : "Add Breakpoint"), this._addButtonClicked.bind(this));
  261. contextMenu.show();
  262. },
  263. _addButtonClicked: function(event)
  264. {
  265. if (event)
  266. event.consume();
  267. this.expand();
  268. var inputElementContainer = document.createElement("p");
  269. inputElementContainer.className = "breakpoint-condition";
  270. var inputElement = document.createElement("span");
  271. inputElementContainer.textContent = WebInspector.UIString("Break when URL contains:");
  272. inputElement.className = "editing";
  273. inputElement.id = "breakpoint-condition-input";
  274. inputElementContainer.appendChild(inputElement);
  275. this._addListElement(inputElementContainer, this.listElement.firstChild);
  276. function finishEditing(accept, e, text)
  277. {
  278. this._removeListElement(inputElementContainer);
  279. if (accept) {
  280. this._setBreakpoint(text, true);
  281. this._saveBreakpoints();
  282. }
  283. }
  284. var config = new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false));
  285. WebInspector.startEditing(inputElement, config);
  286. },
  287. _setBreakpoint: function(url, enabled)
  288. {
  289. if (url in this._breakpointElements)
  290. return;
  291. var element = document.createElement("li");
  292. element._url = url;
  293. element.addEventListener("contextmenu", this._contextMenu.bind(this, url), true);
  294. var checkboxElement = document.createElement("input");
  295. checkboxElement.className = "checkbox-elem";
  296. checkboxElement.type = "checkbox";
  297. checkboxElement.checked = enabled;
  298. checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, url), false);
  299. element._checkboxElement = checkboxElement;
  300. element.appendChild(checkboxElement);
  301. var labelElement = document.createElement("span");
  302. if (!url)
  303. labelElement.textContent = WebInspector.UIString("Any XHR");
  304. else
  305. labelElement.textContent = WebInspector.UIString("URL contains \"%s\"", url);
  306. labelElement.addStyleClass("cursor-auto");
  307. labelElement.addEventListener("dblclick", this._labelClicked.bind(this, url), false);
  308. element.appendChild(labelElement);
  309. var currentElement = this.listElement.firstChild;
  310. while (currentElement) {
  311. if (currentElement._url && currentElement._url < element._url)
  312. break;
  313. currentElement = currentElement.nextSibling;
  314. }
  315. this._addListElement(element, currentElement);
  316. this._breakpointElements[url] = element;
  317. if (enabled)
  318. DOMDebuggerAgent.setXHRBreakpoint(url);
  319. },
  320. _removeBreakpoint: function(url)
  321. {
  322. var element = this._breakpointElements[url];
  323. if (!element)
  324. return;
  325. this._removeListElement(element);
  326. delete this._breakpointElements[url];
  327. if (element._checkboxElement.checked)
  328. DOMDebuggerAgent.removeXHRBreakpoint(url);
  329. },
  330. _contextMenu: function(url, event)
  331. {
  332. var contextMenu = new WebInspector.ContextMenu(event);
  333. function removeBreakpoint()
  334. {
  335. this._removeBreakpoint(url);
  336. this._saveBreakpoints();
  337. }
  338. function removeAllBreakpoints()
  339. {
  340. for (var url in this._breakpointElements)
  341. this._removeBreakpoint(url);
  342. this._saveBreakpoints();
  343. }
  344. var removeAllTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all breakpoints" : "Remove All Breakpoints");
  345. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add breakpoint" : "Add Breakpoint"), this._addButtonClicked.bind(this));
  346. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove breakpoint" : "Remove Breakpoint"), removeBreakpoint.bind(this));
  347. contextMenu.appendItem(removeAllTitle, removeAllBreakpoints.bind(this));
  348. contextMenu.show();
  349. },
  350. _checkboxClicked: function(url, event)
  351. {
  352. if (event.target.checked)
  353. DOMDebuggerAgent.setXHRBreakpoint(url);
  354. else
  355. DOMDebuggerAgent.removeXHRBreakpoint(url);
  356. this._saveBreakpoints();
  357. },
  358. _labelClicked: function(url)
  359. {
  360. var element = this._breakpointElements[url];
  361. var inputElement = document.createElement("span");
  362. inputElement.className = "breakpoint-condition editing";
  363. inputElement.textContent = url;
  364. this.listElement.insertBefore(inputElement, element);
  365. element.addStyleClass("hidden");
  366. function finishEditing(accept, e, text)
  367. {
  368. this._removeListElement(inputElement);
  369. if (accept) {
  370. this._removeBreakpoint(url);
  371. this._setBreakpoint(text, element._checkboxElement.checked);
  372. this._saveBreakpoints();
  373. } else
  374. element.removeStyleClass("hidden");
  375. }
  376. WebInspector.startEditing(inputElement, new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false)));
  377. },
  378. highlightBreakpoint: function(url)
  379. {
  380. var element = this._breakpointElements[url];
  381. if (!element)
  382. return;
  383. this.expand();
  384. element.addStyleClass("breakpoint-hit");
  385. this._highlightedElement = element;
  386. },
  387. clearBreakpointHighlight: function()
  388. {
  389. if (this._highlightedElement) {
  390. this._highlightedElement.removeStyleClass("breakpoint-hit");
  391. delete this._highlightedElement;
  392. }
  393. },
  394. _saveBreakpoints: function()
  395. {
  396. var breakpoints = [];
  397. for (var url in this._breakpointElements)
  398. breakpoints.push({ url: url, enabled: this._breakpointElements[url]._checkboxElement.checked });
  399. WebInspector.settings.xhrBreakpoints.set(breakpoints);
  400. },
  401. _restoreBreakpoints: function()
  402. {
  403. var breakpoints = WebInspector.settings.xhrBreakpoints.get();
  404. for (var i = 0; i < breakpoints.length; ++i) {
  405. var breakpoint = breakpoints[i];
  406. if (breakpoint && typeof breakpoint.url === "string")
  407. this._setBreakpoint(breakpoint.url, breakpoint.enabled);
  408. }
  409. },
  410. __proto__: WebInspector.NativeBreakpointsSidebarPane.prototype
  411. }
  412. /**
  413. * @constructor
  414. * @extends {WebInspector.SidebarPane}
  415. */
  416. WebInspector.EventListenerBreakpointsSidebarPane = function()
  417. {
  418. WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints"));
  419. this.registerRequiredCSS("breakpointsList.css");
  420. this.categoriesElement = document.createElement("ol");
  421. this.categoriesElement.tabIndex = 0;
  422. this.categoriesElement.addStyleClass("properties-tree");
  423. this.categoriesElement.addStyleClass("event-listener-breakpoints");
  424. this.categoriesTreeOutline = new TreeOutline(this.categoriesElement);
  425. this.bodyElement.appendChild(this.categoriesElement);
  426. this._breakpointItems = {};
  427. // FIXME: uncomment following once inspector stops being drop targer in major ports.
  428. // Otherwise, inspector page reacts on drop event and tries to load the event data.
  429. // this._createCategory(WebInspector.UIString("Drag"), true, ["drag", "drop", "dragstart", "dragend", "dragenter", "dragleave", "dragover"]);
  430. this._createCategory(WebInspector.UIString("Animation"), false, ["requestAnimationFrame", "cancelAnimationFrame", "animationFrameFired"]);
  431. this._createCategory(WebInspector.UIString("Control"), true, ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]);
  432. this._createCategory(WebInspector.UIString("Clipboard"), true, ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]);
  433. this._createCategory(WebInspector.UIString("DOM Mutation"), true, ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]);
  434. this._createCategory(WebInspector.UIString("Device"), true, ["deviceorientation", "devicemotion"]);
  435. this._createCategory(WebInspector.UIString("Keyboard"), true, ["keydown", "keyup", "keypress", "input"]);
  436. this._createCategory(WebInspector.UIString("Load"), true, ["load", "unload", "abort", "error"]);
  437. this._createCategory(WebInspector.UIString("Mouse"), true, ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"]);
  438. this._createCategory(WebInspector.UIString("Timer"), false, ["setTimer", "clearTimer", "timerFired"]);
  439. this._createCategory(WebInspector.UIString("Touch"), true, ["touchstart", "touchmove", "touchend", "touchcancel"]);
  440. this._restoreBreakpoints();
  441. }
  442. WebInspector.EventListenerBreakpointsSidebarPane.categotyListener = "listener:";
  443. WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation = "instrumentation:";
  444. WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI = function(eventName)
  445. {
  446. if (!WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI) {
  447. WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI = {
  448. "instrumentation:setTimer": WebInspector.UIString("Set Timer"),
  449. "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"),
  450. "instrumentation:timerFired": WebInspector.UIString("Timer Fired"),
  451. "instrumentation:requestAnimationFrame": WebInspector.UIString("Request Animation Frame"),
  452. "instrumentation:cancelAnimationFrame": WebInspector.UIString("Cancel Animation Frame"),
  453. "instrumentation:animationFrameFired": WebInspector.UIString("Animation Frame Fired")
  454. };
  455. }
  456. return WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1);
  457. }
  458. WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
  459. _createCategory: function(name, isDOMEvent, eventNames)
  460. {
  461. var categoryItem = {};
  462. categoryItem.element = new TreeElement(name);
  463. this.categoriesTreeOutline.appendChild(categoryItem.element);
  464. categoryItem.element.listItemElement.addStyleClass("event-category");
  465. categoryItem.element.selectable = true;
  466. categoryItem.checkbox = this._createCheckbox(categoryItem.element);
  467. categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true);
  468. categoryItem.children = {};
  469. for (var i = 0; i < eventNames.length; ++i) {
  470. var eventName = (isDOMEvent ? WebInspector.EventListenerBreakpointsSidebarPane.categotyListener : WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation) + eventNames[i];
  471. var breakpointItem = {};
  472. var title = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
  473. breakpointItem.element = new TreeElement(title);
  474. categoryItem.element.appendChild(breakpointItem.element);
  475. var hitMarker = document.createElement("div");
  476. hitMarker.className = "breakpoint-hit-marker";
  477. breakpointItem.element.listItemElement.appendChild(hitMarker);
  478. breakpointItem.element.listItemElement.addStyleClass("source-code");
  479. breakpointItem.element.selectable = true;
  480. breakpointItem.checkbox = this._createCheckbox(breakpointItem.element);
  481. breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, eventName), true);
  482. breakpointItem.parent = categoryItem;
  483. this._breakpointItems[eventName] = breakpointItem;
  484. categoryItem.children[eventName] = breakpointItem;
  485. }
  486. },
  487. _createCheckbox: function(treeElement)
  488. {
  489. var checkbox = document.createElement("input");
  490. checkbox.className = "checkbox-elem";
  491. checkbox.type = "checkbox";
  492. treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild);
  493. return checkbox;
  494. },
  495. _categoryCheckboxClicked: function(categoryItem)
  496. {
  497. var checked = categoryItem.checkbox.checked;
  498. for (var eventName in categoryItem.children) {
  499. var breakpointItem = categoryItem.children[eventName];
  500. if (breakpointItem.checkbox.checked === checked)
  501. continue;
  502. if (checked)
  503. this._setBreakpoint(eventName);
  504. else
  505. this._removeBreakpoint(eventName);
  506. }
  507. this._saveBreakpoints();
  508. },
  509. _breakpointCheckboxClicked: function(eventName, event)
  510. {
  511. if (event.target.checked)
  512. this._setBreakpoint(eventName);
  513. else
  514. this._removeBreakpoint(eventName);
  515. this._saveBreakpoints();
  516. },
  517. _setBreakpoint: function(eventName)
  518. {
  519. var breakpointItem = this._breakpointItems[eventName];
  520. if (!breakpointItem)
  521. return;
  522. breakpointItem.checkbox.checked = true;
  523. if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener))
  524. DOMDebuggerAgent.setEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener.length));
  525. else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation))
  526. DOMDebuggerAgent.setInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation.length));
  527. this._updateCategoryCheckbox(breakpointItem.parent);
  528. },
  529. _removeBreakpoint: function(eventName)
  530. {
  531. var breakpointItem = this._breakpointItems[eventName];
  532. if (!breakpointItem)
  533. return;
  534. breakpointItem.checkbox.checked = false;
  535. if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener))
  536. DOMDebuggerAgent.removeEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener.length));
  537. else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation))
  538. DOMDebuggerAgent.removeInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation.length));
  539. this._updateCategoryCheckbox(breakpointItem.parent);
  540. },
  541. _updateCategoryCheckbox: function(categoryItem)
  542. {
  543. var hasEnabled = false, hasDisabled = false;
  544. for (var eventName in categoryItem.children) {
  545. var breakpointItem = categoryItem.children[eventName];
  546. if (breakpointItem.checkbox.checked)
  547. hasEnabled = true;
  548. else
  549. hasDisabled = true;
  550. }
  551. categoryItem.checkbox.checked = hasEnabled;
  552. categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled;
  553. },
  554. highlightBreakpoint: function(eventName)
  555. {
  556. var breakpointItem = this._breakpointItems[eventName];
  557. if (!breakpointItem)
  558. return;
  559. this.expand();
  560. breakpointItem.parent.element.expand();
  561. breakpointItem.element.listItemElement.addStyleClass("breakpoint-hit");
  562. this._highlightedElement = breakpointItem.element.listItemElement;
  563. },
  564. clearBreakpointHighlight: function()
  565. {
  566. if (this._highlightedElement) {
  567. this._highlightedElement.removeStyleClass("breakpoint-hit");
  568. delete this._highlightedElement;
  569. }
  570. },
  571. _saveBreakpoints: function()
  572. {
  573. var breakpoints = [];
  574. for (var eventName in this._breakpointItems) {
  575. if (this._breakpointItems[eventName].checkbox.checked)
  576. breakpoints.push({ eventName: eventName });
  577. }
  578. WebInspector.settings.eventListenerBreakpoints.set(breakpoints);
  579. },
  580. _restoreBreakpoints: function()
  581. {
  582. var breakpoints = WebInspector.settings.eventListenerBreakpoints.get();
  583. for (var i = 0; i < breakpoints.length; ++i) {
  584. var breakpoint = breakpoints[i];
  585. if (breakpoint && typeof breakpoint.eventName === "string")
  586. this._setBreakpoint(breakpoint.eventName);
  587. }
  588. },
  589. __proto__: WebInspector.SidebarPane.prototype
  590. }