OLD | NEW |
| (Empty) |
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 /** | |
27 * @constructor | |
28 * @extends {WebInspector.SidebarPane} | |
29 * @param {!WebInspector.BreakpointManager} breakpointManager | |
30 * @param {function(!WebInspector.UISourceCode, number=, number=, boolean=)} sho
wSourceLineDelegate | |
31 */ | |
32 WebInspector.JavaScriptBreakpointsSidebarPane = function(breakpointManager, show
SourceLineDelegate) | |
33 { | |
34 WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints")); | |
35 this.registerRequiredCSS("components/breakpointsList.css"); | |
36 | |
37 this._breakpointManager = breakpointManager; | |
38 this._showSourceLineDelegate = showSourceLineDelegate; | |
39 | |
40 this.listElement = createElementWithClass("ol", "breakpoint-list"); | |
41 | |
42 this.emptyElement = this.bodyElement.createChild("div", "info"); | |
43 this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); | |
44 | |
45 this._items = new Map(); | |
46 | |
47 var breakpointLocations = this._breakpointManager.allBreakpointLocations(); | |
48 for (var i = 0; i < breakpointLocations.length; ++i) | |
49 this._addBreakpoint(breakpointLocations[i].breakpoint, breakpointLocatio
ns[i].uiLocation); | |
50 | |
51 this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Even
ts.BreakpointAdded, this._breakpointAdded, this); | |
52 this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Even
ts.BreakpointRemoved, this._breakpointRemoved, this); | |
53 | |
54 this.emptyElement.addEventListener("contextmenu", this._emptyElementContextM
enu.bind(this), true); | |
55 } | |
56 | |
57 WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { | |
58 _emptyElementContextMenu: function(event) | |
59 { | |
60 var contextMenu = new WebInspector.ContextMenu(event); | |
61 this._appendBreakpointActiveItem(contextMenu); | |
62 contextMenu.show(); | |
63 }, | |
64 | |
65 /** | |
66 * @param {!WebInspector.ContextMenu} contextMenu | |
67 */ | |
68 _appendBreakpointActiveItem: function(contextMenu) | |
69 { | |
70 var breakpointActive = this._breakpointManager.breakpointsActive(); | |
71 var breakpointActiveTitle = breakpointActive ? | |
72 WebInspector.UIString.capitalize("Deactivate ^breakpoints") : | |
73 WebInspector.UIString.capitalize("Activate ^breakpoints"); | |
74 contextMenu.appendItem(breakpointActiveTitle, this._breakpointManager.se
tBreakpointsActive.bind(this._breakpointManager, !breakpointActive)); | |
75 }, | |
76 | |
77 /** | |
78 * @param {!WebInspector.Event} event | |
79 */ | |
80 _breakpointAdded: function(event) | |
81 { | |
82 this._breakpointRemoved(event); | |
83 | |
84 var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint}
*/ (event.data.breakpoint); | |
85 var uiLocation = /** @type {!WebInspector.UILocation} */ (event.data.uiL
ocation); | |
86 this._addBreakpoint(breakpoint, uiLocation); | |
87 }, | |
88 | |
89 /** | |
90 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
91 * @param {!WebInspector.UILocation} uiLocation | |
92 */ | |
93 _addBreakpoint: function(breakpoint, uiLocation) | |
94 { | |
95 var element = createElementWithClass("li", "cursor-pointer"); | |
96 element.addEventListener("contextmenu", this._breakpointContextMenu.bind
(this, breakpoint), true); | |
97 element.addEventListener("click", this._breakpointClicked.bind(this, uiL
ocation), false); | |
98 | |
99 var checkbox = element.createChild("input", "checkbox-elem"); | |
100 checkbox.type = "checkbox"; | |
101 checkbox.checked = breakpoint.enabled(); | |
102 checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(
this, breakpoint), false); | |
103 | |
104 element.createTextChild(uiLocation.linkText()); | |
105 | |
106 var snippetElement = element.createChild("div", "source-text monospace")
; | |
107 | |
108 /** | |
109 * @param {?string} content | |
110 */ | |
111 function didRequestContent(content) | |
112 { | |
113 var lineNumber = uiLocation.lineNumber | |
114 var columnNumber = uiLocation.columnNumber; | |
115 var contentString = new String(content); | |
116 if (lineNumber < contentString.lineCount()) { | |
117 var lineText = contentString.lineAt(lineNumber); | |
118 var maxSnippetLength = 200; | |
119 var snippetStartIndex = columnNumber > 100 ? columnNumber : 0; | |
120 snippetElement.textContent = lineText.substr(snippetStartIndex).
trimEnd(maxSnippetLength); | |
121 } | |
122 } | |
123 | |
124 uiLocation.uiSourceCode.requestContent(didRequestContent); | |
125 | |
126 element._data = uiLocation; | |
127 var currentElement = this.listElement.firstChild; | |
128 while (currentElement) { | |
129 if (currentElement._data && this._compareBreakpoints(currentElement.
_data, element._data) > 0) | |
130 break; | |
131 currentElement = currentElement.nextSibling; | |
132 } | |
133 this._addListElement(element, currentElement); | |
134 | |
135 var breakpointItem = { element: element, checkbox: checkbox }; | |
136 this._items.set(breakpoint, breakpointItem); | |
137 | |
138 this.expand(); | |
139 }, | |
140 | |
141 /** | |
142 * @param {!WebInspector.Event} event | |
143 */ | |
144 _breakpointRemoved: function(event) | |
145 { | |
146 var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint}
*/ (event.data.breakpoint); | |
147 var breakpointItem = this._items.get(breakpoint); | |
148 if (!breakpointItem) | |
149 return; | |
150 this._items.remove(breakpoint); | |
151 this._removeListElement(breakpointItem.element); | |
152 }, | |
153 | |
154 /** | |
155 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
156 */ | |
157 highlightBreakpoint: function(breakpoint) | |
158 { | |
159 var breakpointItem = this._items.get(breakpoint); | |
160 if (!breakpointItem) | |
161 return; | |
162 breakpointItem.element.classList.add("breakpoint-hit"); | |
163 this._highlightedBreakpointItem = breakpointItem; | |
164 }, | |
165 | |
166 clearBreakpointHighlight: function() | |
167 { | |
168 if (this._highlightedBreakpointItem) { | |
169 this._highlightedBreakpointItem.element.classList.remove("breakpoint
-hit"); | |
170 delete this._highlightedBreakpointItem; | |
171 } | |
172 }, | |
173 | |
174 _breakpointClicked: function(uiLocation, event) | |
175 { | |
176 this._showSourceLineDelegate(uiLocation.uiSourceCode, uiLocation.lineNum
ber); | |
177 }, | |
178 | |
179 /** | |
180 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
181 * @param {!Event} event | |
182 */ | |
183 _breakpointCheckboxClicked: function(breakpoint, event) | |
184 { | |
185 // Breakpoint element has it's own click handler. | |
186 event.consume(); | |
187 breakpoint.setEnabled(event.target.checked); | |
188 }, | |
189 | |
190 /** | |
191 * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint | |
192 * @param {!Event} event | |
193 */ | |
194 _breakpointContextMenu: function(breakpoint, event) | |
195 { | |
196 var breakpoints = this._items.valuesArray(); | |
197 var contextMenu = new WebInspector.ContextMenu(event); | |
198 contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpo
int"), breakpoint.remove.bind(breakpoint)); | |
199 if (breakpoints.length > 1) { | |
200 var removeAllTitle = WebInspector.UIString.capitalize("Remove ^all ^
breakpoints"); | |
201 contextMenu.appendItem(removeAllTitle, this._breakpointManager.remov
eAllBreakpoints.bind(this._breakpointManager)); | |
202 } | |
203 | |
204 contextMenu.appendSeparator(); | |
205 this._appendBreakpointActiveItem(contextMenu); | |
206 | |
207 function enabledBreakpointCount(breakpoints) | |
208 { | |
209 var count = 0; | |
210 for (var i = 0; i < breakpoints.length; ++i) { | |
211 if (breakpoints[i].checkbox.checked) | |
212 count++; | |
213 } | |
214 return count; | |
215 } | |
216 if (breakpoints.length > 1) { | |
217 var enableBreakpointCount = enabledBreakpointCount(breakpoints); | |
218 var enableTitle = WebInspector.UIString.capitalize("Enable ^all ^bre
akpoints"); | |
219 var disableTitle = WebInspector.UIString.capitalize("Disable ^all ^b
reakpoints"); | |
220 | |
221 contextMenu.appendSeparator(); | |
222 | |
223 contextMenu.appendItem(enableTitle, this._breakpointManager.toggleAl
lBreakpoints.bind(this._breakpointManager, true), !(enableBreakpointCount != bre
akpoints.length)); | |
224 contextMenu.appendItem(disableTitle, this._breakpointManager.toggleA
llBreakpoints.bind(this._breakpointManager, false), !(enableBreakpointCount > 1)
); | |
225 } | |
226 | |
227 contextMenu.show(); | |
228 }, | |
229 | |
230 _addListElement: function(element, beforeElement) | |
231 { | |
232 if (beforeElement) | |
233 this.listElement.insertBefore(element, beforeElement); | |
234 else { | |
235 if (!this.listElement.firstChild) { | |
236 this.bodyElement.removeChild(this.emptyElement); | |
237 this.bodyElement.appendChild(this.listElement); | |
238 } | |
239 this.listElement.appendChild(element); | |
240 } | |
241 }, | |
242 | |
243 _removeListElement: function(element) | |
244 { | |
245 this.listElement.removeChild(element); | |
246 if (!this.listElement.firstChild) { | |
247 this.bodyElement.removeChild(this.listElement); | |
248 this.bodyElement.appendChild(this.emptyElement); | |
249 } | |
250 }, | |
251 | |
252 _compare: function(x, y) | |
253 { | |
254 if (x !== y) | |
255 return x < y ? -1 : 1; | |
256 return 0; | |
257 }, | |
258 | |
259 _compareBreakpoints: function(b1, b2) | |
260 { | |
261 return this._compare(b1.uiSourceCode.originURL(), b2.uiSourceCode.origin
URL()) || this._compare(b1.lineNumber, b2.lineNumber); | |
262 }, | |
263 | |
264 reset: function() | |
265 { | |
266 this.listElement.removeChildren(); | |
267 if (this.listElement.parentElement) { | |
268 this.bodyElement.removeChild(this.listElement); | |
269 this.bodyElement.appendChild(this.emptyElement); | |
270 } | |
271 this._items.clear(); | |
272 }, | |
273 | |
274 __proto__: WebInspector.SidebarPane.prototype | |
275 } | |
276 | |
277 /** | |
278 * @constructor | |
279 * @extends {WebInspector.NativeBreakpointsSidebarPane} | |
280 * @implements {WebInspector.TargetManager.Observer} | |
281 */ | |
282 WebInspector.XHRBreakpointsSidebarPane = function() | |
283 { | |
284 WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("
XHR Breakpoints")); | |
285 | |
286 /** @type {!Map.<string, !Element>} */ | |
287 this._breakpointElements = new Map(); | |
288 | |
289 var addButton = this.titleElement.createChild("button", "pane-title-button a
dd"); | |
290 addButton.title = WebInspector.UIString("Add XHR breakpoint"); | |
291 addButton.addEventListener("click", this._addButtonClicked.bind(this), false
); | |
292 | |
293 this.emptyElement.addEventListener("contextmenu", this._emptyElementContextM
enu.bind(this), true); | |
294 | |
295 WebInspector.targetManager.observeTargets(this); | |
296 } | |
297 | |
298 WebInspector.XHRBreakpointsSidebarPane.prototype = { | |
299 /** | |
300 * @override | |
301 * @param {!WebInspector.Target} target | |
302 */ | |
303 targetAdded: function(target) | |
304 { | |
305 this._restoreBreakpoints(target); | |
306 }, | |
307 | |
308 /** | |
309 * @override | |
310 * @param {!WebInspector.Target} target | |
311 */ | |
312 targetRemoved: function(target) { }, | |
313 | |
314 _emptyElementContextMenu: function(event) | |
315 { | |
316 var contextMenu = new WebInspector.ContextMenu(event); | |
317 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint
"), this._addButtonClicked.bind(this)); | |
318 contextMenu.show(); | |
319 }, | |
320 | |
321 _addButtonClicked: function(event) | |
322 { | |
323 if (event) | |
324 event.consume(); | |
325 | |
326 this.expand(); | |
327 | |
328 var inputElementContainer = createElementWithClass("p", "breakpoint-cond
ition"); | |
329 inputElementContainer.textContent = WebInspector.UIString("Break when UR
L contains:"); | |
330 | |
331 var inputElement = inputElementContainer.createChild("span", "editing"); | |
332 inputElement.id = "breakpoint-condition-input"; | |
333 this.addListElement(inputElementContainer, /** @type {?Element} */ (this
.listElement.firstChild)); | |
334 | |
335 /** | |
336 * @param {boolean} accept | |
337 * @param {!Element} e | |
338 * @param {string} text | |
339 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
340 */ | |
341 function finishEditing(accept, e, text) | |
342 { | |
343 this.removeListElement(inputElementContainer); | |
344 if (accept) { | |
345 this._setBreakpoint(text, true); | |
346 this._saveBreakpoints(); | |
347 } | |
348 } | |
349 | |
350 var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(th
is, true), finishEditing.bind(this, false)); | |
351 WebInspector.InplaceEditor.startEditing(inputElement, config); | |
352 }, | |
353 | |
354 /** | |
355 * @param {string} url | |
356 * @param {boolean} enabled | |
357 * @param {!WebInspector.Target=} target | |
358 */ | |
359 _setBreakpoint: function(url, enabled, target) | |
360 { | |
361 if (enabled) | |
362 this._updateBreakpointOnTarget(url, true, target); | |
363 | |
364 if (this._breakpointElements.has(url)) | |
365 return; | |
366 | |
367 var element = createElement("li"); | |
368 element._url = url; | |
369 element.addEventListener("contextmenu", this._contextMenu.bind(this, url
), true); | |
370 | |
371 var label = createCheckboxLabel(undefined, enabled); | |
372 label.classList.add("checkbox-elem"); | |
373 element.appendChild(label); | |
374 label.checkboxElement.addEventListener("click", this._checkboxClicked.bi
nd(this, url), false); | |
375 element._checkboxElement = label.checkboxElement; | |
376 | |
377 var labelElement = label.createChild("span", "cursor-auto"); | |
378 if (!url) | |
379 labelElement.textContent = WebInspector.UIString("Any XHR"); | |
380 else | |
381 labelElement.textContent = WebInspector.UIString("URL contains \"%s\
"", url); | |
382 labelElement.addEventListener("dblclick", this._labelClicked.bind(this,
url), false); | |
383 | |
384 var currentElement = /** @type {?Element} */ (this.listElement.firstChil
d); | |
385 while (currentElement) { | |
386 if (currentElement._url && currentElement._url < element._url) | |
387 break; | |
388 currentElement = /** @type {?Element} */ (currentElement.nextSibling
); | |
389 } | |
390 this.addListElement(element, currentElement); | |
391 this._breakpointElements.set(url, element); | |
392 }, | |
393 | |
394 /** | |
395 * @param {string} url | |
396 * @param {!WebInspector.Target=} target | |
397 */ | |
398 _removeBreakpoint: function(url, target) | |
399 { | |
400 var element = this._breakpointElements.get(url); | |
401 if (!element) | |
402 return; | |
403 | |
404 this.removeListElement(element); | |
405 this._breakpointElements.delete(url); | |
406 if (element._checkboxElement.checked) | |
407 this._updateBreakpointOnTarget(url, false, target); | |
408 }, | |
409 | |
410 /** | |
411 * @param {string} url | |
412 * @param {boolean} enable | |
413 * @param {!WebInspector.Target=} target | |
414 */ | |
415 _updateBreakpointOnTarget: function(url, enable, target) | |
416 { | |
417 var targets = target ? [target] : WebInspector.targetManager.targets(); | |
418 for (var i = 0; i < targets.length; ++i) { | |
419 if (enable) | |
420 targets[i].domdebuggerAgent().setXHRBreakpoint(url); | |
421 else | |
422 targets[i].domdebuggerAgent().removeXHRBreakpoint(url); | |
423 } | |
424 }, | |
425 | |
426 _contextMenu: function(url, event) | |
427 { | |
428 var contextMenu = new WebInspector.ContextMenu(event); | |
429 | |
430 /** | |
431 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
432 */ | |
433 function removeBreakpoint() | |
434 { | |
435 this._removeBreakpoint(url); | |
436 this._saveBreakpoints(); | |
437 } | |
438 | |
439 /** | |
440 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
441 */ | |
442 function removeAllBreakpoints() | |
443 { | |
444 for (var url of this._breakpointElements.keys()) | |
445 this._removeBreakpoint(url); | |
446 this._saveBreakpoints(); | |
447 } | |
448 var removeAllTitle = WebInspector.UIString.capitalize("Remove ^all ^brea
kpoints"); | |
449 | |
450 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint
"), this._addButtonClicked.bind(this)); | |
451 contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpo
int"), removeBreakpoint.bind(this)); | |
452 contextMenu.appendItem(removeAllTitle, removeAllBreakpoints.bind(this)); | |
453 contextMenu.show(); | |
454 }, | |
455 | |
456 _checkboxClicked: function(url, event) | |
457 { | |
458 this._updateBreakpointOnTarget(url, event.target.checked); | |
459 this._saveBreakpoints(); | |
460 }, | |
461 | |
462 _labelClicked: function(url) | |
463 { | |
464 var element = this._breakpointElements.get(url); | |
465 var inputElement = createElementWithClass("span", "breakpoint-condition
editing"); | |
466 inputElement.textContent = url; | |
467 this.listElement.insertBefore(inputElement, element); | |
468 element.classList.add("hidden"); | |
469 | |
470 /** | |
471 * @param {boolean} accept | |
472 * @param {!Element} e | |
473 * @param {string} text | |
474 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
475 */ | |
476 function finishEditing(accept, e, text) | |
477 { | |
478 this.removeListElement(inputElement); | |
479 if (accept) { | |
480 this._removeBreakpoint(url); | |
481 this._setBreakpoint(text, element._checkboxElement.checked); | |
482 this._saveBreakpoints(); | |
483 } else | |
484 element.classList.remove("hidden"); | |
485 } | |
486 | |
487 WebInspector.InplaceEditor.startEditing(inputElement, new WebInspector.I
nplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, fal
se))); | |
488 }, | |
489 | |
490 highlightBreakpoint: function(url) | |
491 { | |
492 var element = this._breakpointElements.get(url); | |
493 if (!element) | |
494 return; | |
495 this.expand(); | |
496 element.classList.add("breakpoint-hit"); | |
497 this._highlightedElement = element; | |
498 }, | |
499 | |
500 clearBreakpointHighlight: function() | |
501 { | |
502 if (this._highlightedElement) { | |
503 this._highlightedElement.classList.remove("breakpoint-hit"); | |
504 delete this._highlightedElement; | |
505 } | |
506 }, | |
507 | |
508 _saveBreakpoints: function() | |
509 { | |
510 var breakpoints = []; | |
511 for (var url of this._breakpointElements.keys()) | |
512 breakpoints.push({ url: url, enabled: this._breakpointElements.get(u
rl)._checkboxElement.checked }); | |
513 WebInspector.settings.xhrBreakpoints.set(breakpoints); | |
514 }, | |
515 | |
516 /** | |
517 * @param {!WebInspector.Target} target | |
518 */ | |
519 _restoreBreakpoints: function(target) | |
520 { | |
521 var breakpoints = WebInspector.settings.xhrBreakpoints.get(); | |
522 for (var i = 0; i < breakpoints.length; ++i) { | |
523 var breakpoint = breakpoints[i]; | |
524 if (breakpoint && typeof breakpoint.url === "string") | |
525 this._setBreakpoint(breakpoint.url, breakpoint.enabled, target); | |
526 } | |
527 }, | |
528 | |
529 __proto__: WebInspector.NativeBreakpointsSidebarPane.prototype | |
530 } | |
531 | |
532 /** | |
533 * @constructor | |
534 * @extends {WebInspector.SidebarPane} | |
535 * @implements {WebInspector.TargetManager.Observer} | |
536 */ | |
537 WebInspector.EventListenerBreakpointsSidebarPane = function() | |
538 { | |
539 WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Br
eakpoints")); | |
540 this.registerRequiredCSS("components/breakpointsList.css"); | |
541 | |
542 this._categoriesTreeOutline = new TreeOutline(); | |
543 this._categoriesTreeOutline.element.tabIndex = 0; | |
544 this._categoriesTreeOutline.element.classList.add("event-listener-breakpoint
s"); | |
545 this.bodyElement.appendChild(this._categoriesTreeOutline.element); | |
546 | |
547 this._categoryItems = []; | |
548 // FIXME: uncomment following once inspector stops being drop targer in majo
r ports. | |
549 // Otherwise, inspector page reacts on drop event and tries to load the even
t data. | |
550 // this._createCategory(WebInspector.UIString("Drag"), ["drag", "drop", "dra
gstart", "dragend", "dragenter", "dragleave", "dragover"]); | |
551 this._createCategory(WebInspector.UIString("Animation"), ["requestAnimationF
rame", "cancelAnimationFrame", "animationFrameFired"], true); | |
552 this._createCategory(WebInspector.UIString("Control"), ["resize", "scroll",
"zoom", "focus", "blur", "select", "change", "submit", "reset"]); | |
553 this._createCategory(WebInspector.UIString("Clipboard"), ["copy", "cut", "pa
ste", "beforecopy", "beforecut", "beforepaste"]); | |
554 this._createCategory(WebInspector.UIString("DOM Mutation"), ["DOMActivate",
"DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOM
NodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedF
romDocument", "DOMSubtreeModified", "DOMContentLoaded"]); | |
555 this._createCategory(WebInspector.UIString("Device"), ["deviceorientation",
"devicemotion"]); | |
556 this._createCategory(WebInspector.UIString("Drag / drop"), ["dragenter", "dr
agover", "dragleave", "drop"]); | |
557 this._createCategory(WebInspector.UIString("Keyboard"), ["keydown", "keyup",
"keypress", "input"]); | |
558 this._createCategory(WebInspector.UIString("Load"), ["load", "beforeunload",
"unload", "abort", "error", "hashchange", "popstate"]); | |
559 this._createCategory(WebInspector.UIString("Media"), ["play", "pause", "play
ing", "canplay", "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "
ratechange", "durationchange", "volumechange", "loadstart", "progress", "suspend
", "abort", "error", "emptied", "stalled", "loadedmetadata", "loadeddata", "wait
ing"], false, ["audio", "video"]); | |
560 this._createCategory(WebInspector.UIString("Mouse"), ["click", "dblclick", "
mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mouseenter", "mous
eleave", "mousewheel", "wheel", "contextmenu"]); | |
561 this._createCategory(WebInspector.UIString("Promise"), ["newPromise", "promi
seResolved", "promiseRejected"], true); | |
562 this._createCategory(WebInspector.UIString("Script"), ["scriptFirstStatement
"], true); | |
563 this._createCategory(WebInspector.UIString("Timer"), ["setTimer", "clearTime
r", "timerFired"], true); | |
564 this._createCategory(WebInspector.UIString("Touch"), ["touchstart", "touchmo
ve", "touchend", "touchcancel"]); | |
565 this._createCategory(WebInspector.UIString("XHR"), ["readystatechange", "loa
d", "loadstart", "loadend", "abort", "error", "progress", "timeout"], false, ["X
MLHttpRequest", "XMLHttpRequestUpload"]); | |
566 this._createCategory(WebInspector.UIString("WebGL"), ["webglErrorFired", "we
bglWarningFired"], true); | |
567 this._createCategory(WebInspector.UIString("Window"), ["close"], true); | |
568 | |
569 WebInspector.targetManager.observeTargets(this); | |
570 } | |
571 | |
572 WebInspector.EventListenerBreakpointsSidebarPane.categoryListener = "listener:"; | |
573 WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation = "inst
rumentation:"; | |
574 WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny = "*"; | |
575 | |
576 /** | |
577 * @param {string} eventName | |
578 * @param {!Object=} auxData | |
579 * @return {string} | |
580 */ | |
581 WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI = function(event
Name, auxData) | |
582 { | |
583 if (!WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI) { | |
584 WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI = { | |
585 "instrumentation:setTimer": WebInspector.UIString("Set Timer"), | |
586 "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), | |
587 "instrumentation:timerFired": WebInspector.UIString("Timer Fired"), | |
588 "instrumentation:newPromise": WebInspector.UIString("Promise Created
"), | |
589 "instrumentation:promiseResolved": WebInspector.UIString("Promise Re
solved"), | |
590 "instrumentation:promiseRejected": WebInspector.UIString("Promise Re
jected"), | |
591 "instrumentation:scriptFirstStatement": WebInspector.UIString("Scrip
t First Statement"), | |
592 "instrumentation:requestAnimationFrame": WebInspector.UIString("Requ
est Animation Frame"), | |
593 "instrumentation:cancelAnimationFrame": WebInspector.UIString("Cance
l Animation Frame"), | |
594 "instrumentation:animationFrameFired": WebInspector.UIString("Animat
ion Frame Fired"), | |
595 "instrumentation:webglErrorFired": WebInspector.UIString("WebGL Erro
r Fired"), | |
596 "instrumentation:webglWarningFired": WebInspector.UIString("WebGL Wa
rning Fired") | |
597 }; | |
598 } | |
599 if (auxData) { | |
600 if (eventName === "instrumentation:webglErrorFired" && auxData["webglErr
orName"]) { | |
601 var errorName = auxData["webglErrorName"]; | |
602 // If there is a hex code of the error, display only this. | |
603 errorName = errorName.replace(/^.*(0x[0-9a-f]+).*$/i, "$1"); | |
604 return WebInspector.UIString("WebGL Error Fired (%s)", errorName); | |
605 } | |
606 } | |
607 return WebInspector.EventListenerBreakpointsSidebarPane._eventNamesForUI[eve
ntName] || eventName.substring(eventName.indexOf(":") + 1); | |
608 } | |
609 | |
610 WebInspector.EventListenerBreakpointsSidebarPane.prototype = { | |
611 /** | |
612 * @override | |
613 * @param {!WebInspector.Target} target | |
614 */ | |
615 targetAdded: function(target) | |
616 { | |
617 this._restoreBreakpoints(target); | |
618 }, | |
619 | |
620 /** | |
621 * @override | |
622 * @param {!WebInspector.Target} target | |
623 */ | |
624 targetRemoved: function(target) { }, | |
625 | |
626 /** | |
627 * @param {string} name | |
628 * @param {!Array.<string>} eventNames | |
629 * @param {boolean=} isInstrumentationEvent | |
630 * @param {!Array.<string>=} targetNames | |
631 */ | |
632 _createCategory: function(name, eventNames, isInstrumentationEvent, targetNa
mes) | |
633 { | |
634 var labelNode = createCheckboxLabel(name); | |
635 | |
636 var categoryItem = {}; | |
637 categoryItem.element = new TreeElement(labelNode); | |
638 this._categoriesTreeOutline.appendChild(categoryItem.element); | |
639 categoryItem.element.listItemElement.classList.add("event-category"); | |
640 categoryItem.element.selectable = true; | |
641 | |
642 categoryItem.checkbox = labelNode.checkboxElement; | |
643 categoryItem.checkbox.addEventListener("click", this._categoryCheckboxCl
icked.bind(this, categoryItem), true); | |
644 | |
645 categoryItem.targetNames = this._stringArrayToLowerCase(targetNames || [
WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny]); | |
646 categoryItem.children = {}; | |
647 var category = (isInstrumentationEvent ? WebInspector.EventListenerBreak
pointsSidebarPane.categoryInstrumentation : WebInspector.EventListenerBreakpoin
tsSidebarPane.categoryListener); | |
648 for (var i = 0; i < eventNames.length; ++i) { | |
649 var eventName = category + eventNames[i]; | |
650 | |
651 var breakpointItem = {}; | |
652 var title = WebInspector.EventListenerBreakpointsSidebarPane.eventNa
meForUI(eventName); | |
653 | |
654 labelNode = createCheckboxLabel(title); | |
655 labelNode.classList.add("source-code"); | |
656 | |
657 breakpointItem.element = new TreeElement(labelNode); | |
658 categoryItem.element.appendChild(breakpointItem.element); | |
659 | |
660 breakpointItem.element.listItemElement.createChild("div", "breakpoin
t-hit-marker"); | |
661 breakpointItem.element.selectable = false; | |
662 | |
663 breakpointItem.checkbox = labelNode.checkboxElement; | |
664 breakpointItem.checkbox.addEventListener("click", this._breakpointCh
eckboxClicked.bind(this, eventName, categoryItem.targetNames), true); | |
665 breakpointItem.parent = categoryItem; | |
666 | |
667 categoryItem.children[eventName] = breakpointItem; | |
668 } | |
669 this._categoryItems.push(categoryItem); | |
670 }, | |
671 | |
672 /** | |
673 * @param {!Array.<string>} array | |
674 * @return {!Array.<string>} | |
675 */ | |
676 _stringArrayToLowerCase: function(array) | |
677 { | |
678 return array.map(function(value) { | |
679 return value.toLowerCase(); | |
680 }); | |
681 }, | |
682 | |
683 _categoryCheckboxClicked: function(categoryItem) | |
684 { | |
685 var checked = categoryItem.checkbox.checked; | |
686 for (var eventName in categoryItem.children) { | |
687 var breakpointItem = categoryItem.children[eventName]; | |
688 if (breakpointItem.checkbox.checked === checked) | |
689 continue; | |
690 if (checked) | |
691 this._setBreakpoint(eventName, categoryItem.targetNames); | |
692 else | |
693 this._removeBreakpoint(eventName, categoryItem.targetNames); | |
694 } | |
695 this._saveBreakpoints(); | |
696 }, | |
697 | |
698 /** | |
699 * @param {string} eventName | |
700 * @param {!Array.<string>} targetNames | |
701 * @param {!Event} event | |
702 */ | |
703 _breakpointCheckboxClicked: function(eventName, targetNames, event) | |
704 { | |
705 if (event.target.checked) | |
706 this._setBreakpoint(eventName, targetNames); | |
707 else | |
708 this._removeBreakpoint(eventName, targetNames); | |
709 this._saveBreakpoints(); | |
710 }, | |
711 | |
712 /** | |
713 * @param {string} eventName | |
714 * @param {?Array.<string>=} eventTargetNames | |
715 * @param {!WebInspector.Target=} target | |
716 */ | |
717 _setBreakpoint: function(eventName, eventTargetNames, target) | |
718 { | |
719 eventTargetNames = eventTargetNames || [WebInspector.EventListenerBreakp
ointsSidebarPane.eventTargetAny]; | |
720 for (var i = 0; i < eventTargetNames.length; ++i) { | |
721 var eventTargetName = eventTargetNames[i]; | |
722 var breakpointItem = this._findBreakpointItem(eventName, eventTarget
Name); | |
723 if (!breakpointItem) | |
724 continue; | |
725 breakpointItem.checkbox.checked = true; | |
726 breakpointItem.parent.dirtyCheckbox = true; | |
727 this._updateBreakpointOnTarget(eventName, eventTargetName, true, tar
get); | |
728 } | |
729 this._updateCategoryCheckboxes(); | |
730 }, | |
731 | |
732 /** | |
733 * @param {string} eventName | |
734 * @param {?Array.<string>=} eventTargetNames | |
735 * @param {!WebInspector.Target=} target | |
736 */ | |
737 _removeBreakpoint: function(eventName, eventTargetNames, target) | |
738 { | |
739 eventTargetNames = eventTargetNames || [WebInspector.EventListenerBreakp
ointsSidebarPane.eventTargetAny]; | |
740 for (var i = 0; i < eventTargetNames.length; ++i) { | |
741 var eventTargetName = eventTargetNames[i]; | |
742 var breakpointItem = this._findBreakpointItem(eventName, eventTarget
Name); | |
743 if (!breakpointItem) | |
744 continue; | |
745 breakpointItem.checkbox.checked = false; | |
746 breakpointItem.parent.dirtyCheckbox = true; | |
747 this._updateBreakpointOnTarget(eventName, eventTargetName, false, ta
rget); | |
748 } | |
749 this._updateCategoryCheckboxes(); | |
750 }, | |
751 | |
752 /** | |
753 * @param {string} eventName | |
754 * @param {string} eventTargetName | |
755 * @param {boolean} enable | |
756 * @param {!WebInspector.Target=} target | |
757 */ | |
758 _updateBreakpointOnTarget: function(eventName, eventTargetName, enable, targ
et) | |
759 { | |
760 var targets = target ? [target] : WebInspector.targetManager.targets(); | |
761 for (var i = 0; i < targets.length; ++i) { | |
762 if (eventName.startsWith(WebInspector.EventListenerBreakpointsSideba
rPane.categoryListener)) { | |
763 var protocolEventName = eventName.substring(WebInspector.EventLi
stenerBreakpointsSidebarPane.categoryListener.length); | |
764 if (enable) | |
765 targets[i].domdebuggerAgent().setEventListenerBreakpoint(pro
tocolEventName, eventTargetName); | |
766 else | |
767 targets[i].domdebuggerAgent().removeEventListenerBreakpoint(
protocolEventName, eventTargetName); | |
768 } else if (eventName.startsWith(WebInspector.EventListenerBreakpoint
sSidebarPane.categoryInstrumentation)) { | |
769 var protocolEventName = eventName.substring(WebInspector.EventLi
stenerBreakpointsSidebarPane.categoryInstrumentation.length); | |
770 if (enable) | |
771 targets[i].domdebuggerAgent().setInstrumentationBreakpoint(p
rotocolEventName); | |
772 else | |
773 targets[i].domdebuggerAgent().removeInstrumentationBreakpoin
t(protocolEventName); | |
774 } | |
775 } | |
776 }, | |
777 | |
778 _updateCategoryCheckboxes: function() | |
779 { | |
780 for (var i = 0; i < this._categoryItems.length; ++i) { | |
781 var categoryItem = this._categoryItems[i]; | |
782 if (!categoryItem.dirtyCheckbox) | |
783 continue; | |
784 categoryItem.dirtyCheckbox = false; | |
785 var hasEnabled = false; | |
786 var hasDisabled = false; | |
787 for (var eventName in categoryItem.children) { | |
788 var breakpointItem = categoryItem.children[eventName]; | |
789 if (breakpointItem.checkbox.checked) | |
790 hasEnabled = true; | |
791 else | |
792 hasDisabled = true; | |
793 } | |
794 categoryItem.checkbox.checked = hasEnabled; | |
795 categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled; | |
796 } | |
797 }, | |
798 | |
799 /** | |
800 * @param {string} eventName | |
801 * @param {string=} targetName | |
802 * @return {?Object} | |
803 */ | |
804 _findBreakpointItem: function(eventName, targetName) | |
805 { | |
806 targetName = (targetName || WebInspector.EventListenerBreakpointsSidebar
Pane.eventTargetAny).toLowerCase(); | |
807 for (var i = 0; i < this._categoryItems.length; ++i) { | |
808 var categoryItem = this._categoryItems[i]; | |
809 if (categoryItem.targetNames.indexOf(targetName) === -1) | |
810 continue; | |
811 var breakpointItem = categoryItem.children[eventName]; | |
812 if (breakpointItem) | |
813 return breakpointItem; | |
814 } | |
815 return null; | |
816 }, | |
817 | |
818 /** | |
819 * @param {string} eventName | |
820 * @param {string=} targetName | |
821 */ | |
822 highlightBreakpoint: function(eventName, targetName) | |
823 { | |
824 var breakpointItem = this._findBreakpointItem(eventName, targetName); | |
825 if (!breakpointItem || !breakpointItem.checkbox.checked) | |
826 breakpointItem = this._findBreakpointItem(eventName, WebInspector.Ev
entListenerBreakpointsSidebarPane.eventTargetAny); | |
827 if (!breakpointItem) | |
828 return; | |
829 this.expand(); | |
830 breakpointItem.parent.element.expand(); | |
831 breakpointItem.element.listItemElement.classList.add("breakpoint-hit"); | |
832 this._highlightedElement = breakpointItem.element.listItemElement; | |
833 }, | |
834 | |
835 clearBreakpointHighlight: function() | |
836 { | |
837 if (this._highlightedElement) { | |
838 this._highlightedElement.classList.remove("breakpoint-hit"); | |
839 delete this._highlightedElement; | |
840 } | |
841 }, | |
842 | |
843 _saveBreakpoints: function() | |
844 { | |
845 var breakpoints = []; | |
846 for (var i = 0; i < this._categoryItems.length; ++i) { | |
847 var categoryItem = this._categoryItems[i]; | |
848 for (var eventName in categoryItem.children) { | |
849 var breakpointItem = categoryItem.children[eventName]; | |
850 if (breakpointItem.checkbox.checked) | |
851 breakpoints.push({ eventName: eventName, targetNames: catego
ryItem.targetNames }); | |
852 } | |
853 } | |
854 WebInspector.settings.eventListenerBreakpoints.set(breakpoints); | |
855 }, | |
856 | |
857 /** | |
858 * @param {!WebInspector.Target} target | |
859 */ | |
860 _restoreBreakpoints: function(target) | |
861 { | |
862 var breakpoints = WebInspector.settings.eventListenerBreakpoints.get(); | |
863 for (var i = 0; i < breakpoints.length; ++i) { | |
864 var breakpoint = breakpoints[i]; | |
865 if (breakpoint && typeof breakpoint.eventName === "string") | |
866 this._setBreakpoint(breakpoint.eventName, breakpoint.targetNames
, target); | |
867 } | |
868 }, | |
869 | |
870 __proto__: WebInspector.SidebarPane.prototype | |
871 } | |
OLD | NEW |