OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | |
5 /** | 4 /** |
6 * @constructor | |
7 * @extends {WebInspector.BreakpointsSidebarPaneBase} | |
8 * @implements {WebInspector.ContextFlavorListener} | 5 * @implements {WebInspector.ContextFlavorListener} |
9 * @implements {WebInspector.TargetManager.Observer} | 6 * @implements {WebInspector.TargetManager.Observer} |
10 * @implements {WebInspector.ToolbarItem.ItemsProvider} | 7 * @implements {WebInspector.ToolbarItem.ItemsProvider} |
| 8 * @unrestricted |
11 */ | 9 */ |
12 WebInspector.XHRBreakpointsSidebarPane = function() | 10 WebInspector.XHRBreakpointsSidebarPane = class extends WebInspector.BreakpointsS
idebarPaneBase { |
13 { | 11 constructor() { |
14 WebInspector.BreakpointsSidebarPaneBase.call(this); | 12 super(); |
15 this._xhrBreakpointsSetting = WebInspector.settings.createLocalSetting("xhrB
reakpoints", []); | 13 this._xhrBreakpointsSetting = WebInspector.settings.createLocalSetting('xhrB
reakpoints', []); |
16 | 14 |
17 /** @type {!Map.<string, !Element>} */ | 15 /** @type {!Map.<string, !Element>} */ |
18 this._breakpointElements = new Map(); | 16 this._breakpointElements = new Map(); |
19 | 17 |
20 this._addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add
breakpoint"), "add-toolbar-item"); | 18 this._addButton = new WebInspector.ToolbarButton(WebInspector.UIString('Add
breakpoint'), 'add-toolbar-item'); |
21 this._addButton.addEventListener("click", this._addButtonClicked.bind(this))
; | 19 this._addButton.addEventListener('click', this._addButtonClicked.bind(this))
; |
22 | 20 |
23 this.emptyElement.addEventListener("contextmenu", this._emptyElementContextM
enu.bind(this), true); | 21 this.emptyElement.addEventListener('contextmenu', this._emptyElementContextM
enu.bind(this), true); |
24 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili
ty.Browser); | 22 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili
ty.Browser); |
25 this._update(); | 23 this._update(); |
| 24 } |
| 25 |
| 26 /** |
| 27 * @override |
| 28 * @param {!WebInspector.Target} target |
| 29 */ |
| 30 targetAdded(target) { |
| 31 this._restoreBreakpoints(target); |
| 32 } |
| 33 |
| 34 /** |
| 35 * @override |
| 36 * @param {!WebInspector.Target} target |
| 37 */ |
| 38 targetRemoved(target) { |
| 39 } |
| 40 |
| 41 /** |
| 42 * @override |
| 43 * @return {!Array<!WebInspector.ToolbarItem>} |
| 44 */ |
| 45 toolbarItems() { |
| 46 return [this._addButton]; |
| 47 } |
| 48 |
| 49 _emptyElementContextMenu(event) { |
| 50 var contextMenu = new WebInspector.ContextMenu(event); |
| 51 contextMenu.appendItem(WebInspector.UIString.capitalize('Add ^breakpoint'),
this._addButtonClicked.bind(this)); |
| 52 contextMenu.show(); |
| 53 } |
| 54 |
| 55 _addButtonClicked(event) { |
| 56 if (event) |
| 57 event.consume(); |
| 58 |
| 59 WebInspector.viewManager.showView('sources.xhrBreakpoints'); |
| 60 |
| 61 var inputElementContainer = createElementWithClass('p', 'breakpoint-conditio
n'); |
| 62 inputElementContainer.textContent = WebInspector.UIString('Break when URL co
ntains:'); |
| 63 |
| 64 var inputElement = inputElementContainer.createChild('span', 'editing'); |
| 65 inputElement.id = 'breakpoint-condition-input'; |
| 66 this.addListElement(inputElementContainer, /** @type {?Element} */ (this.lis
tElement.firstChild)); |
| 67 |
| 68 /** |
| 69 * @param {boolean} accept |
| 70 * @param {!Element} e |
| 71 * @param {string} text |
| 72 * @this {WebInspector.XHRBreakpointsSidebarPane} |
| 73 */ |
| 74 function finishEditing(accept, e, text) { |
| 75 this.removeListElement(inputElementContainer); |
| 76 if (accept) { |
| 77 this._setBreakpoint(text, true); |
| 78 this._saveBreakpoints(); |
| 79 } |
| 80 } |
| 81 |
| 82 var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this,
true), finishEditing.bind(this, false)); |
| 83 WebInspector.InplaceEditor.startEditing(inputElement, config); |
| 84 } |
| 85 |
| 86 /** |
| 87 * @param {string} url |
| 88 * @param {boolean} enabled |
| 89 * @param {!WebInspector.Target=} target |
| 90 */ |
| 91 _setBreakpoint(url, enabled, target) { |
| 92 if (enabled) |
| 93 this._updateBreakpointOnTarget(url, true, target); |
| 94 |
| 95 if (this._breakpointElements.has(url)) { |
| 96 this._breakpointElements.get(url)._checkboxElement.checked = enabled; |
| 97 return; |
| 98 } |
| 99 |
| 100 var element = createElement('li'); |
| 101 element._url = url; |
| 102 element.addEventListener('contextmenu', this._contextMenu.bind(this, url), t
rue); |
| 103 |
| 104 var title = url ? WebInspector.UIString('URL contains "%s"', url) : WebInspe
ctor.UIString('Any XHR'); |
| 105 var label = createCheckboxLabel(title, enabled); |
| 106 element.appendChild(label); |
| 107 label.checkboxElement.addEventListener('click', this._checkboxClicked.bind(t
his, url), false); |
| 108 element._checkboxElement = label.checkboxElement; |
| 109 |
| 110 label.textElement.classList.add('cursor-auto'); |
| 111 label.textElement.addEventListener('dblclick', this._labelClicked.bind(this,
url), false); |
| 112 |
| 113 var currentElement = /** @type {?Element} */ (this.listElement.firstChild); |
| 114 while (currentElement) { |
| 115 if (currentElement._url && currentElement._url < element._url) |
| 116 break; |
| 117 currentElement = /** @type {?Element} */ (currentElement.nextSibling); |
| 118 } |
| 119 this.addListElement(element, currentElement); |
| 120 this._breakpointElements.set(url, element); |
| 121 } |
| 122 |
| 123 /** |
| 124 * @param {string} url |
| 125 * @param {!WebInspector.Target=} target |
| 126 */ |
| 127 _removeBreakpoint(url, target) { |
| 128 var element = this._breakpointElements.get(url); |
| 129 if (!element) |
| 130 return; |
| 131 |
| 132 this.removeListElement(element); |
| 133 this._breakpointElements.delete(url); |
| 134 if (element._checkboxElement.checked) |
| 135 this._updateBreakpointOnTarget(url, false, target); |
| 136 } |
| 137 |
| 138 /** |
| 139 * @param {string} url |
| 140 * @param {boolean} enable |
| 141 * @param {!WebInspector.Target=} target |
| 142 */ |
| 143 _updateBreakpointOnTarget(url, enable, target) { |
| 144 var targets = target ? [target] : WebInspector.targetManager.targets(WebInsp
ector.Target.Capability.Browser); |
| 145 for (target of targets) { |
| 146 if (enable) |
| 147 target.domdebuggerAgent().setXHRBreakpoint(url); |
| 148 else |
| 149 target.domdebuggerAgent().removeXHRBreakpoint(url); |
| 150 } |
| 151 } |
| 152 |
| 153 _contextMenu(url, event) { |
| 154 var contextMenu = new WebInspector.ContextMenu(event); |
| 155 |
| 156 /** |
| 157 * @this {WebInspector.XHRBreakpointsSidebarPane} |
| 158 */ |
| 159 function removeBreakpoint() { |
| 160 this._removeBreakpoint(url); |
| 161 this._saveBreakpoints(); |
| 162 } |
| 163 |
| 164 /** |
| 165 * @this {WebInspector.XHRBreakpointsSidebarPane} |
| 166 */ |
| 167 function removeAllBreakpoints() { |
| 168 for (var url of this._breakpointElements.keys()) |
| 169 this._removeBreakpoint(url); |
| 170 this._saveBreakpoints(); |
| 171 } |
| 172 var removeAllTitle = WebInspector.UIString.capitalize('Remove ^all ^breakpoi
nts'); |
| 173 |
| 174 contextMenu.appendItem(WebInspector.UIString.capitalize('Add ^breakpoint'),
this._addButtonClicked.bind(this)); |
| 175 contextMenu.appendItem(WebInspector.UIString.capitalize('Remove ^breakpoint'
), removeBreakpoint.bind(this)); |
| 176 contextMenu.appendItem(removeAllTitle, removeAllBreakpoints.bind(this)); |
| 177 contextMenu.show(); |
| 178 } |
| 179 |
| 180 _checkboxClicked(url, event) { |
| 181 this._updateBreakpointOnTarget(url, event.target.checked); |
| 182 this._saveBreakpoints(); |
| 183 } |
| 184 |
| 185 _labelClicked(url) { |
| 186 var element = this._breakpointElements.get(url) || null; |
| 187 var inputElement = createElementWithClass('span', 'breakpoint-condition edit
ing'); |
| 188 inputElement.textContent = url; |
| 189 this.listElement.insertBefore(inputElement, element); |
| 190 element.classList.add('hidden'); |
| 191 |
| 192 /** |
| 193 * @param {boolean} accept |
| 194 * @param {!Element} e |
| 195 * @param {string} text |
| 196 * @this {WebInspector.XHRBreakpointsSidebarPane} |
| 197 */ |
| 198 function finishEditing(accept, e, text) { |
| 199 this.removeListElement(inputElement); |
| 200 if (accept) { |
| 201 this._removeBreakpoint(url); |
| 202 this._setBreakpoint(text, element._checkboxElement.checked); |
| 203 this._saveBreakpoints(); |
| 204 } else |
| 205 element.classList.remove('hidden'); |
| 206 } |
| 207 |
| 208 WebInspector.InplaceEditor.startEditing( |
| 209 inputElement, |
| 210 new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), fi
nishEditing.bind(this, false))); |
| 211 } |
| 212 |
| 213 /** |
| 214 * @override |
| 215 * @param {?Object} object |
| 216 */ |
| 217 flavorChanged(object) { |
| 218 this._update(); |
| 219 } |
| 220 |
| 221 _update() { |
| 222 var details = WebInspector.context.flavor(WebInspector.DebuggerPausedDetails
); |
| 223 if (!details || details.reason !== WebInspector.DebuggerModel.BreakReason.XH
R) { |
| 224 if (this._highlightedElement) { |
| 225 this._highlightedElement.classList.remove('breakpoint-hit'); |
| 226 delete this._highlightedElement; |
| 227 } |
| 228 return; |
| 229 } |
| 230 var url = details.auxData['breakpointURL']; |
| 231 var element = this._breakpointElements.get(url); |
| 232 if (!element) |
| 233 return; |
| 234 WebInspector.viewManager.showView('sources.xhrBreakpoints'); |
| 235 element.classList.add('breakpoint-hit'); |
| 236 this._highlightedElement = element; |
| 237 } |
| 238 |
| 239 _saveBreakpoints() { |
| 240 var breakpoints = []; |
| 241 for (var url of this._breakpointElements.keys()) |
| 242 breakpoints.push({url: url, enabled: this._breakpointElements.get(url)._ch
eckboxElement.checked}); |
| 243 this._xhrBreakpointsSetting.set(breakpoints); |
| 244 } |
| 245 |
| 246 /** |
| 247 * @param {!WebInspector.Target} target |
| 248 */ |
| 249 _restoreBreakpoints(target) { |
| 250 var breakpoints = this._xhrBreakpointsSetting.get(); |
| 251 for (var i = 0; i < breakpoints.length; ++i) { |
| 252 var breakpoint = breakpoints[i]; |
| 253 if (breakpoint && typeof breakpoint.url === 'string') |
| 254 this._setBreakpoint(breakpoint.url, breakpoint.enabled, target); |
| 255 } |
| 256 } |
26 }; | 257 }; |
27 | |
28 WebInspector.XHRBreakpointsSidebarPane.prototype = { | |
29 /** | |
30 * @override | |
31 * @param {!WebInspector.Target} target | |
32 */ | |
33 targetAdded: function(target) | |
34 { | |
35 this._restoreBreakpoints(target); | |
36 }, | |
37 | |
38 /** | |
39 * @override | |
40 * @param {!WebInspector.Target} target | |
41 */ | |
42 targetRemoved: function(target) { }, | |
43 | |
44 /** | |
45 * @override | |
46 * @return {!Array<!WebInspector.ToolbarItem>} | |
47 */ | |
48 toolbarItems: function() | |
49 { | |
50 return [this._addButton]; | |
51 }, | |
52 | |
53 _emptyElementContextMenu: function(event) | |
54 { | |
55 var contextMenu = new WebInspector.ContextMenu(event); | |
56 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint
"), this._addButtonClicked.bind(this)); | |
57 contextMenu.show(); | |
58 }, | |
59 | |
60 _addButtonClicked: function(event) | |
61 { | |
62 if (event) | |
63 event.consume(); | |
64 | |
65 WebInspector.viewManager.showView("sources.xhrBreakpoints"); | |
66 | |
67 var inputElementContainer = createElementWithClass("p", "breakpoint-cond
ition"); | |
68 inputElementContainer.textContent = WebInspector.UIString("Break when UR
L contains:"); | |
69 | |
70 var inputElement = inputElementContainer.createChild("span", "editing"); | |
71 inputElement.id = "breakpoint-condition-input"; | |
72 this.addListElement(inputElementContainer, /** @type {?Element} */ (this
.listElement.firstChild)); | |
73 | |
74 /** | |
75 * @param {boolean} accept | |
76 * @param {!Element} e | |
77 * @param {string} text | |
78 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
79 */ | |
80 function finishEditing(accept, e, text) | |
81 { | |
82 this.removeListElement(inputElementContainer); | |
83 if (accept) { | |
84 this._setBreakpoint(text, true); | |
85 this._saveBreakpoints(); | |
86 } | |
87 } | |
88 | |
89 var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(th
is, true), finishEditing.bind(this, false)); | |
90 WebInspector.InplaceEditor.startEditing(inputElement, config); | |
91 }, | |
92 | |
93 /** | |
94 * @param {string} url | |
95 * @param {boolean} enabled | |
96 * @param {!WebInspector.Target=} target | |
97 */ | |
98 _setBreakpoint: function(url, enabled, target) | |
99 { | |
100 if (enabled) | |
101 this._updateBreakpointOnTarget(url, true, target); | |
102 | |
103 if (this._breakpointElements.has(url)) { | |
104 this._breakpointElements.get(url)._checkboxElement.checked = enabled
; | |
105 return; | |
106 } | |
107 | |
108 var element = createElement("li"); | |
109 element._url = url; | |
110 element.addEventListener("contextmenu", this._contextMenu.bind(this, url
), true); | |
111 | |
112 var title = url ? WebInspector.UIString("URL contains \"%s\"", url) : We
bInspector.UIString("Any XHR"); | |
113 var label = createCheckboxLabel(title, enabled); | |
114 element.appendChild(label); | |
115 label.checkboxElement.addEventListener("click", this._checkboxClicked.bi
nd(this, url), false); | |
116 element._checkboxElement = label.checkboxElement; | |
117 | |
118 label.textElement.classList.add("cursor-auto"); | |
119 label.textElement.addEventListener("dblclick", this._labelClicked.bind(t
his, url), false); | |
120 | |
121 var currentElement = /** @type {?Element} */ (this.listElement.firstChil
d); | |
122 while (currentElement) { | |
123 if (currentElement._url && currentElement._url < element._url) | |
124 break; | |
125 currentElement = /** @type {?Element} */ (currentElement.nextSibling
); | |
126 } | |
127 this.addListElement(element, currentElement); | |
128 this._breakpointElements.set(url, element); | |
129 }, | |
130 | |
131 /** | |
132 * @param {string} url | |
133 * @param {!WebInspector.Target=} target | |
134 */ | |
135 _removeBreakpoint: function(url, target) | |
136 { | |
137 var element = this._breakpointElements.get(url); | |
138 if (!element) | |
139 return; | |
140 | |
141 this.removeListElement(element); | |
142 this._breakpointElements.delete(url); | |
143 if (element._checkboxElement.checked) | |
144 this._updateBreakpointOnTarget(url, false, target); | |
145 }, | |
146 | |
147 /** | |
148 * @param {string} url | |
149 * @param {boolean} enable | |
150 * @param {!WebInspector.Target=} target | |
151 */ | |
152 _updateBreakpointOnTarget: function(url, enable, target) | |
153 { | |
154 var targets = target ? [target] : WebInspector.targetManager.targets(Web
Inspector.Target.Capability.Browser); | |
155 for (target of targets) { | |
156 if (enable) | |
157 target.domdebuggerAgent().setXHRBreakpoint(url); | |
158 else | |
159 target.domdebuggerAgent().removeXHRBreakpoint(url); | |
160 } | |
161 }, | |
162 | |
163 _contextMenu: function(url, event) | |
164 { | |
165 var contextMenu = new WebInspector.ContextMenu(event); | |
166 | |
167 /** | |
168 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
169 */ | |
170 function removeBreakpoint() | |
171 { | |
172 this._removeBreakpoint(url); | |
173 this._saveBreakpoints(); | |
174 } | |
175 | |
176 /** | |
177 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
178 */ | |
179 function removeAllBreakpoints() | |
180 { | |
181 for (var url of this._breakpointElements.keys()) | |
182 this._removeBreakpoint(url); | |
183 this._saveBreakpoints(); | |
184 } | |
185 var removeAllTitle = WebInspector.UIString.capitalize("Remove ^all ^brea
kpoints"); | |
186 | |
187 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^breakpoint
"), this._addButtonClicked.bind(this)); | |
188 contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^breakpo
int"), removeBreakpoint.bind(this)); | |
189 contextMenu.appendItem(removeAllTitle, removeAllBreakpoints.bind(this)); | |
190 contextMenu.show(); | |
191 }, | |
192 | |
193 _checkboxClicked: function(url, event) | |
194 { | |
195 this._updateBreakpointOnTarget(url, event.target.checked); | |
196 this._saveBreakpoints(); | |
197 }, | |
198 | |
199 _labelClicked: function(url) | |
200 { | |
201 var element = this._breakpointElements.get(url) || null; | |
202 var inputElement = createElementWithClass("span", "breakpoint-condition
editing"); | |
203 inputElement.textContent = url; | |
204 this.listElement.insertBefore(inputElement, element); | |
205 element.classList.add("hidden"); | |
206 | |
207 /** | |
208 * @param {boolean} accept | |
209 * @param {!Element} e | |
210 * @param {string} text | |
211 * @this {WebInspector.XHRBreakpointsSidebarPane} | |
212 */ | |
213 function finishEditing(accept, e, text) | |
214 { | |
215 this.removeListElement(inputElement); | |
216 if (accept) { | |
217 this._removeBreakpoint(url); | |
218 this._setBreakpoint(text, element._checkboxElement.checked); | |
219 this._saveBreakpoints(); | |
220 } else | |
221 element.classList.remove("hidden"); | |
222 } | |
223 | |
224 WebInspector.InplaceEditor.startEditing(inputElement, new WebInspector.I
nplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, fal
se))); | |
225 }, | |
226 | |
227 /** | |
228 * @override | |
229 * @param {?Object} object | |
230 */ | |
231 flavorChanged: function(object) | |
232 { | |
233 this._update(); | |
234 }, | |
235 | |
236 _update: function() | |
237 { | |
238 var details = WebInspector.context.flavor(WebInspector.DebuggerPausedDet
ails); | |
239 if (!details || details.reason !== WebInspector.DebuggerModel.BreakReaso
n.XHR) { | |
240 if (this._highlightedElement) { | |
241 this._highlightedElement.classList.remove("breakpoint-hit"); | |
242 delete this._highlightedElement; | |
243 } | |
244 return; | |
245 } | |
246 var url = details.auxData["breakpointURL"]; | |
247 var element = this._breakpointElements.get(url); | |
248 if (!element) | |
249 return; | |
250 WebInspector.viewManager.showView("sources.xhrBreakpoints"); | |
251 element.classList.add("breakpoint-hit"); | |
252 this._highlightedElement = element; | |
253 }, | |
254 | |
255 _saveBreakpoints: function() | |
256 { | |
257 var breakpoints = []; | |
258 for (var url of this._breakpointElements.keys()) | |
259 breakpoints.push({ url: url, enabled: this._breakpointElements.get(u
rl)._checkboxElement.checked }); | |
260 this._xhrBreakpointsSetting.set(breakpoints); | |
261 }, | |
262 | |
263 /** | |
264 * @param {!WebInspector.Target} target | |
265 */ | |
266 _restoreBreakpoints: function(target) | |
267 { | |
268 var breakpoints = this._xhrBreakpointsSetting.get(); | |
269 for (var i = 0; i < breakpoints.length; ++i) { | |
270 var breakpoint = breakpoints[i]; | |
271 if (breakpoint && typeof breakpoint.url === "string") | |
272 this._setBreakpoint(breakpoint.url, breakpoint.enabled, target); | |
273 } | |
274 }, | |
275 | |
276 __proto__: WebInspector.BreakpointsSidebarPaneBase.prototype | |
277 }; | |
OLD | NEW |