| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 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 /** | 4 /** |
| 5 * @implements {SDK.SDKModelObserver<!SDK.RuntimeModel>} | 5 * @implements {SDK.SDKModelObserver<!SDK.RuntimeModel>} |
| 6 * @unrestricted | 6 * @implements {UI.ListDelegate<!SDK.ExecutionContext>} |
| 7 */ | 7 */ |
| 8 Console.ConsoleContextSelector = class { | 8 Console.ConsoleContextSelector = class { |
| 9 /** | 9 constructor() { |
| 10 * @param {!Element} selectElement | 10 this._toolbarItem = new UI.ToolbarItem(createElementWithClass('button', 'con
sole-context')); |
| 11 */ | 11 var shadowRoot = |
| 12 constructor(selectElement) { | 12 UI.createShadowRootWithCoreStyles(this._toolbarItem.element, 'console/co
nsoleContextSelectorButton.css'); |
| 13 this._selectElement = selectElement; | 13 this._titleElement = shadowRoot.createChild('span', 'title'); |
| 14 /** | 14 this._productRegistry = null; |
| 15 * @type {!Map.<!SDK.ExecutionContext, !Element>} | 15 |
| 16 */ | 16 ProductRegistry.instance().then(registry => { |
| 17 this._optionByExecutionContext = new Map(); | 17 this._productRegistry = registry; |
| 18 this._list.refreshAllItems(); |
| 19 }); |
| 20 this._toolbarItem.element.classList.add('toolbar-has-dropdown'); |
| 21 this._toolbarItem.element.tabIndex = 0; |
| 22 this._glassPane = new UI.GlassPane(); |
| 23 this._glassPane.setMarginBehavior(UI.GlassPane.MarginBehavior.NoMargin); |
| 24 this._glassPane.setAnchorBehavior(UI.GlassPane.AnchorBehavior.PreferBottom); |
| 25 this._glassPane.setOutsideClickCallback(this._hide.bind(this)); |
| 26 this._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.
BlockedByGlassPane); |
| 27 this._list = new UI.ListControl(this, UI.ListMode.EqualHeightItems); |
| 28 this._list.element.classList.add('context-list'); |
| 29 this._list.element.tabIndex = -1; |
| 30 this._rowHeight = 34; |
| 31 UI.createShadowRootWithCoreStyles(this._glassPane.contentElement, 'console/c
onsoleContextSelector.css') |
| 32 .appendChild(this._list.element); |
| 33 |
| 34 this._listWasShowing200msAgo = false; |
| 35 this._toolbarItem.element.addEventListener('mousedown', event => { |
| 36 if (this._listWasShowing200msAgo) |
| 37 this._hide(event); |
| 38 else |
| 39 this._show(event); |
| 40 }, false); |
| 41 this._toolbarItem.element.addEventListener('keydown', this._onKeyDown.bind(t
his), false); |
| 42 this._toolbarItem.element.addEventListener('focusout', this._hide.bind(this)
, false); |
| 43 this._list.element.addEventListener('mousedown', event => { |
| 44 event.consume(true); |
| 45 }, false); |
| 46 this._list.element.addEventListener('mouseup', event => { |
| 47 if (event.target === this._list.element) |
| 48 return; |
| 49 |
| 50 if (!this._listWasShowing200msAgo) |
| 51 return; |
| 52 this._updateSelectedContext(); |
| 53 this._hide(event); |
| 54 }, false); |
| 55 |
| 56 var dropdownArrowIcon = UI.Icon.create('smallicon-triangle-down'); |
| 57 shadowRoot.appendChild(dropdownArrowIcon); |
| 18 | 58 |
| 19 SDK.targetManager.addModelListener( | 59 SDK.targetManager.addModelListener( |
| 20 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this.
_onExecutionContextCreated, this); | 60 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this.
_onExecutionContextCreated, this); |
| 21 SDK.targetManager.addModelListener( | 61 SDK.targetManager.addModelListener( |
| 22 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextChanged, this.
_onExecutionContextChanged, this); | 62 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextChanged, this.
_onExecutionContextChanged, this); |
| 23 SDK.targetManager.addModelListener( | 63 SDK.targetManager.addModelListener( |
| 24 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, thi
s._onExecutionContextDestroyed, this); | 64 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, thi
s._onExecutionContextDestroyed, this); |
| 65 SDK.targetManager.addModelListener( |
| 66 SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.FrameNavigated, this
._frameNavigated, this); |
| 25 | 67 |
| 26 this._selectElement.addEventListener('change', this._executionContextChanged
.bind(this), false); | |
| 27 UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._executionCont
extChangedExternally, this); | 68 UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._executionCont
extChangedExternally, this); |
| 28 UI.context.addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this._callFr
ameSelectedInUI, this); | 69 UI.context.addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this._callFr
ameSelectedInUI, this); |
| 29 SDK.targetManager.observeModels(SDK.RuntimeModel, this); | 70 SDK.targetManager.observeModels(SDK.RuntimeModel, this); |
| 30 SDK.targetManager.addModelListener( | 71 SDK.targetManager.addModelListener( |
| 31 SDK.DebuggerModel, SDK.DebuggerModel.Events.CallFrameSelected, this._cal
lFrameSelectedInModel, this); | 72 SDK.DebuggerModel, SDK.DebuggerModel.Events.CallFrameSelected, this._cal
lFrameSelectedInModel, this); |
| 32 } | 73 } |
| 33 | 74 |
| 34 /** | 75 /** |
| 76 * @return {!UI.ToolbarItem} |
| 77 */ |
| 78 toolbarItem() { |
| 79 return this._toolbarItem; |
| 80 } |
| 81 |
| 82 /** |
| 83 * @param {!Event} event |
| 84 */ |
| 85 _show(event) { |
| 86 if (this._glassPane.isShowing()) |
| 87 return; |
| 88 this._glassPane.setContentAnchorBox(this._toolbarItem.element.boxInWindow())
; |
| 89 this._glassPane.show(/** @type {!Document} **/ (this._toolbarItem.element.ow
nerDocument)); |
| 90 this._updateGlasspaneSize(); |
| 91 var selectedItem = this._list.selectedItem(); |
| 92 if (selectedItem) |
| 93 this._list.scrollItemIntoView(selectedItem, true); |
| 94 this._toolbarItem.element.focus(); |
| 95 event.consume(true); |
| 96 setTimeout(() => this._listWasShowing200msAgo = true, 200); |
| 97 } |
| 98 |
| 99 _updateGlasspaneSize() { |
| 100 var maxHeight = this._rowHeight * (Math.min(this._list.length(), 9)); |
| 101 this._glassPane.setMaxContentSize(new UI.Size(315, maxHeight)); |
| 102 this._list.viewportResized(); |
| 103 } |
| 104 |
| 105 /** |
| 106 * @param {!Event} event |
| 107 */ |
| 108 _hide(event) { |
| 109 setTimeout(() => this._listWasShowing200msAgo = false, 200); |
| 110 this._glassPane.hide(); |
| 111 SDK.OverlayModel.hideDOMNodeHighlight(); |
| 112 var selectedContext = UI.context.flavor(SDK.ExecutionContext); |
| 113 if (selectedContext) |
| 114 this._list.selectItem(selectedContext); |
| 115 event.consume(true); |
| 116 } |
| 117 |
| 118 /** |
| 119 * @param {!Event} event |
| 120 */ |
| 121 _onKeyDown(event) { |
| 122 var handled = false; |
| 123 switch (event.key) { |
| 124 case 'ArrowUp': |
| 125 handled = this._list.selectPreviousItem(false, false); |
| 126 break; |
| 127 case 'ArrowDown': |
| 128 handled = this._list.selectNextItem(false, false); |
| 129 break; |
| 130 case 'ArrowRight': |
| 131 var currentExecutionContext = this._list.selectedItem(); |
| 132 if (!currentExecutionContext) |
| 133 break; |
| 134 var nextExecutionContext = this._list.itemAtIndex(this._list.selectedInd
ex() + 1); |
| 135 if (nextExecutionContext && this._depthFor(currentExecutionContext) < th
is._depthFor(nextExecutionContext)) |
| 136 handled = this._list.selectNextItem(false, false); |
| 137 break; |
| 138 case 'ArrowLeft': |
| 139 var currentExecutionContext = this._list.selectedItem(); |
| 140 if (!currentExecutionContext) |
| 141 break; |
| 142 var depth = this._depthFor(currentExecutionContext); |
| 143 for (var i = this._list.selectedIndex() - 1; i >= 0; i--) { |
| 144 if (this._depthFor(this._list.itemAtIndex(i)) < depth) { |
| 145 handled = true; |
| 146 this._list.selectItem(this._list.itemAtIndex(i), false); |
| 147 break; |
| 148 } |
| 149 } |
| 150 break; |
| 151 case 'PageUp': |
| 152 handled = this._list.selectItemPreviousPage(false); |
| 153 break; |
| 154 case 'PageDown': |
| 155 handled = this._list.selectItemNextPage(false); |
| 156 break; |
| 157 case 'Home': |
| 158 for (var i = 0; i < this._list.length(); i++) { |
| 159 if (this.isItemSelectable(this._list.itemAtIndex(i))) { |
| 160 this._list.selectItem(this._list.itemAtIndex(i)); |
| 161 handled = true; |
| 162 break; |
| 163 } |
| 164 } |
| 165 break; |
| 166 case 'End': |
| 167 for (var i = this._list.length() - 1; i >= 0; i--) { |
| 168 if (this.isItemSelectable(this._list.itemAtIndex(i))) { |
| 169 this._list.selectItem(this._list.itemAtIndex(i)); |
| 170 handled = true; |
| 171 break; |
| 172 } |
| 173 } |
| 174 break; |
| 175 case 'Escape': |
| 176 this._hide(event); |
| 177 break; |
| 178 case 'Tab': |
| 179 if (!this._glassPane.isShowing()) |
| 180 break; |
| 181 this._updateSelectedContext(); |
| 182 this._hide(event); |
| 183 break; |
| 184 case 'Enter': |
| 185 if (!this._glassPane.isShowing()) { |
| 186 this._show(event); |
| 187 break; |
| 188 } |
| 189 this._updateSelectedContext(); |
| 190 this._hide(event); |
| 191 break; |
| 192 case ' ': |
| 193 this._show(event); |
| 194 break; |
| 195 default: |
| 196 if (event.key.length === 1) { |
| 197 var selectedIndex = this._list.selectedIndex(); |
| 198 var letter = event.key.toUpperCase(); |
| 199 for (var i = 0; i < this._list.length(); i++) { |
| 200 var context = this._list.itemAtIndex((selectedIndex + i + 1) % this.
_list.length()); |
| 201 if (this._titleFor(context).toUpperCase().startsWith(letter)) { |
| 202 this._list.selectItem(context); |
| 203 break; |
| 204 } |
| 205 } |
| 206 handled = true; |
| 207 } |
| 208 break; |
| 209 } |
| 210 |
| 211 if (handled) { |
| 212 event.consume(true); |
| 213 this._updateSelectedContext(); |
| 214 } |
| 215 } |
| 216 |
| 217 /** |
| 35 * @param {!SDK.ExecutionContext} executionContext | 218 * @param {!SDK.ExecutionContext} executionContext |
| 36 * @return {string} | 219 * @return {string} |
| 37 */ | 220 */ |
| 38 _titleFor(executionContext) { | 221 _titleFor(executionContext) { |
| 39 var target = executionContext.target(); | 222 var target = executionContext.target(); |
| 223 var label = executionContext.label() ? target.decorateLabel(executionContext
.label()) : ''; |
| 224 if (executionContext.frameId) { |
| 225 var resourceTreeModel = target.model(SDK.ResourceTreeModel); |
| 226 var frame = resourceTreeModel && resourceTreeModel.frameForId(executionCon
text.frameId); |
| 227 if (frame) |
| 228 label = label || frame.displayName(); |
| 229 } |
| 230 label = label || executionContext.origin; |
| 231 |
| 232 return label; |
| 233 } |
| 234 |
| 235 /** |
| 236 * @param {!SDK.ExecutionContext} executionContext |
| 237 * @return {number} |
| 238 */ |
| 239 _depthFor(executionContext) { |
| 240 var target = executionContext.target(); |
| 40 var depth = 0; | 241 var depth = 0; |
| 41 var label = executionContext.label() ? target.decorateLabel(executionContext
.label()) : ''; | |
| 42 if (!executionContext.isDefault) | 242 if (!executionContext.isDefault) |
| 43 depth++; | 243 depth++; |
| 44 if (executionContext.frameId) { | 244 if (executionContext.frameId) { |
| 45 var resourceTreeModel = target.model(SDK.ResourceTreeModel); | 245 var resourceTreeModel = target.model(SDK.ResourceTreeModel); |
| 46 var frame = resourceTreeModel && resourceTreeModel.frameForId(executionCon
text.frameId); | 246 var frame = resourceTreeModel && resourceTreeModel.frameForId(executionCon
text.frameId); |
| 47 if (frame) { | 247 while (frame && frame.parentFrame) { |
| 48 label = label || frame.displayName(); | 248 depth++; |
| 49 while (frame.parentFrame) { | 249 frame = frame.parentFrame; |
| 50 depth++; | |
| 51 frame = frame.parentFrame; | |
| 52 } | |
| 53 } | 250 } |
| 54 } | 251 } |
| 55 label = label || executionContext.origin; | |
| 56 var targetDepth = 0; | 252 var targetDepth = 0; |
| 57 while (target.parentTarget()) { | 253 while (target.parentTarget()) { |
| 58 if (target.parentTarget().hasJSCapability()) { | 254 if (target.parentTarget().hasJSCapability()) { |
| 59 targetDepth++; | 255 targetDepth++; |
| 60 } else { | 256 } else { |
| 61 // Special casing service workers to be top-level. | 257 // Special casing service workers to be top-level. |
| 62 targetDepth = 0; | 258 targetDepth = 0; |
| 63 break; | 259 break; |
| 64 } | 260 } |
| 65 target = target.parentTarget(); | 261 target = target.parentTarget(); |
| 66 } | 262 } |
| 67 | |
| 68 depth += targetDepth; | 263 depth += targetDepth; |
| 69 var prefix = new Array(4 * depth + 1).join('\u00a0'); | 264 return depth; |
| 70 var maxLength = 50; | |
| 71 return (prefix + label).trimMiddle(maxLength); | |
| 72 } | 265 } |
| 73 | 266 |
| 74 /** | 267 /** |
| 75 * @param {!SDK.ExecutionContext} executionContext | 268 * @param {!SDK.ExecutionContext} executionContext |
| 76 */ | 269 */ |
| 77 _executionContextCreated(executionContext) { | 270 _executionContextCreated(executionContext) { |
| 78 // FIXME(413886): We never want to show execution context for the main threa
d of shadow page in service/shared worker frontend. | 271 // FIXME(413886): We never want to show execution context for the main threa
d of shadow page in service/shared worker frontend. |
| 79 // This check could be removed once we do not send this context to frontend. | 272 // This check could be removed once we do not send this context to frontend. |
| 80 if (!executionContext.target().hasJSCapability()) | 273 if (!executionContext.target().hasJSCapability()) |
| 81 return; | 274 return; |
| 82 | 275 |
| 83 var newOption = createElement('option'); | 276 this._list.insertItemWithComparator(executionContext, executionContext.runti
meModel.executionContextComparator()); |
| 84 newOption.__executionContext = executionContext; | |
| 85 newOption.text = this._titleFor(executionContext); | |
| 86 this._optionByExecutionContext.set(executionContext, newOption); | |
| 87 var options = this._selectElement.options; | |
| 88 var contexts = Array.prototype.map.call(options, mapping); | |
| 89 var index = contexts.lowerBound(executionContext, executionContext.runtimeMo
del.executionContextComparator()); | |
| 90 this._selectElement.insertBefore(newOption, options[index]); | |
| 91 | 277 |
| 92 if (executionContext === UI.context.flavor(SDK.ExecutionContext)) | 278 if (executionContext === UI.context.flavor(SDK.ExecutionContext)) { |
| 93 this._select(newOption); | 279 this._list.selectItem(executionContext); |
| 94 this._updateOptionDisabledState(newOption); | 280 this._updateSelectedContext(); |
| 95 | |
| 96 /** | |
| 97 * @param {!Element} option | |
| 98 * @return {!SDK.ExecutionContext} | |
| 99 */ | |
| 100 function mapping(option) { | |
| 101 return option.__executionContext; | |
| 102 } | 281 } |
| 103 } | 282 } |
| 104 | 283 |
| 105 /** | 284 /** |
| 106 * @param {!Common.Event} event | 285 * @param {!Common.Event} event |
| 107 */ | 286 */ |
| 108 _onExecutionContextCreated(event) { | 287 _onExecutionContextCreated(event) { |
| 109 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); | 288 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); |
| 110 this._executionContextCreated(executionContext); | 289 this._executionContextCreated(executionContext); |
| 111 this._updateSelectionWarning(); | 290 this._updateSelectionWarning(); |
| 291 this._updateGlasspaneSize(); |
| 112 } | 292 } |
| 113 | 293 |
| 114 /** | 294 /** |
| 115 * @param {!Common.Event} event | 295 * @param {!Common.Event} event |
| 116 */ | 296 */ |
| 117 _onExecutionContextChanged(event) { | 297 _onExecutionContextChanged(event) { |
| 118 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); | 298 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); |
| 119 var option = this._optionByExecutionContext.get(executionContext); | 299 if (this._list.indexOfItem(executionContext) === -1) |
| 120 if (option) | 300 return; |
| 121 option.text = this._titleFor(executionContext); | 301 this._executionContextDestroyed(executionContext); |
| 302 this._executionContextCreated(executionContext); |
| 122 this._updateSelectionWarning(); | 303 this._updateSelectionWarning(); |
| 123 } | 304 } |
| 124 | 305 |
| 125 /** | 306 /** |
| 126 * @param {!SDK.ExecutionContext} executionContext | 307 * @param {!SDK.ExecutionContext} executionContext |
| 127 */ | 308 */ |
| 128 _executionContextDestroyed(executionContext) { | 309 _executionContextDestroyed(executionContext) { |
| 129 var option = this._optionByExecutionContext.remove(executionContext); | 310 if (this._list.indexOfItem(executionContext) === -1) |
| 130 option.remove(); | 311 return; |
| 312 this._list.removeItem(executionContext); |
| 313 this._updateGlasspaneSize(); |
| 131 } | 314 } |
| 132 | 315 |
| 133 /** | 316 /** |
| 134 * @param {!Common.Event} event | 317 * @param {!Common.Event} event |
| 135 */ | 318 */ |
| 136 _onExecutionContextDestroyed(event) { | 319 _onExecutionContextDestroyed(event) { |
| 137 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); | 320 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); |
| 138 this._executionContextDestroyed(executionContext); | 321 this._executionContextDestroyed(executionContext); |
| 139 this._updateSelectionWarning(); | 322 this._updateSelectionWarning(); |
| 140 } | 323 } |
| 141 | 324 |
| 142 /** | 325 /** |
| 143 * @param {!Common.Event} event | 326 * @param {!Common.Event} event |
| 144 */ | 327 */ |
| 145 _executionContextChangedExternally(event) { | 328 _executionContextChangedExternally(event) { |
| 146 var executionContext = /** @type {?SDK.ExecutionContext} */ (event.data); | 329 var executionContext = /** @type {?SDK.ExecutionContext} */ (event.data); |
| 147 if (!executionContext) | 330 if (!executionContext || this._list.indexOfItem(executionContext) === -1) |
| 148 return; | 331 return; |
| 149 | 332 this._list.selectItem(executionContext); |
| 150 var options = this._selectElement.options; | 333 this._updateSelectedContext(); |
| 151 for (var i = 0; i < options.length; ++i) { | |
| 152 if (options[i].__executionContext === executionContext) | |
| 153 this._select(options[i]); | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 _executionContextChanged() { | |
| 158 var option = this._selectedOption(); | |
| 159 var newContext = option ? option.__executionContext : null; | |
| 160 UI.context.setFlavor(SDK.ExecutionContext, newContext); | |
| 161 this._updateSelectionWarning(); | |
| 162 } | 334 } |
| 163 | 335 |
| 164 _updateSelectionWarning() { | 336 _updateSelectionWarning() { |
| 165 var executionContext = UI.context.flavor(SDK.ExecutionContext); | 337 var executionContext = UI.context.flavor(SDK.ExecutionContext); |
| 166 this._selectElement.parentElement.classList.toggle( | 338 this._toolbarItem.element.classList.toggle( |
| 167 'warning', !this._isTopContext(executionContext) && this._hasTopContext(
)); | 339 'warning', !this._isTopContext(executionContext) && this._hasTopContext(
)); |
| 168 } | 340 } |
| 169 | 341 |
| 170 /** | 342 /** |
| 171 * @param {?SDK.ExecutionContext} executionContext | 343 * @param {?SDK.ExecutionContext} executionContext |
| 172 * @return {boolean} | 344 * @return {boolean} |
| 173 */ | 345 */ |
| 174 _isTopContext(executionContext) { | 346 _isTopContext(executionContext) { |
| 175 if (!executionContext || !executionContext.isDefault) | 347 if (!executionContext || !executionContext.isDefault) |
| 176 return false; | 348 return false; |
| 177 var resourceTreeModel = executionContext.target().model(SDK.ResourceTreeMode
l); | 349 var resourceTreeModel = executionContext.target().model(SDK.ResourceTreeMode
l); |
| 178 var frame = executionContext.frameId && resourceTreeModel && resourceTreeMod
el.frameForId(executionContext.frameId); | 350 var frame = executionContext.frameId && resourceTreeModel && resourceTreeMod
el.frameForId(executionContext.frameId); |
| 179 if (!frame) | 351 if (!frame) |
| 180 return false; | 352 return false; |
| 181 return frame.isMainFrame(); | 353 return frame.isMainFrame(); |
| 182 } | 354 } |
| 183 | 355 |
| 184 /** | 356 /** |
| 185 * @return {boolean} | 357 * @return {boolean} |
| 186 */ | 358 */ |
| 187 _hasTopContext() { | 359 _hasTopContext() { |
| 188 var options = this._selectElement.options; | 360 for (var i = 0; i < this._list.length(); i++) { |
| 189 for (var i = 0; i < options.length; i++) { | 361 if (this._isTopContext(this._list.itemAtIndex(i))) |
| 190 if (this._isTopContext(options[i].__executionContext)) | |
| 191 return true; | 362 return true; |
| 192 } | 363 } |
| 193 return false; | 364 return false; |
| 194 } | 365 } |
| 195 | 366 |
| 196 /** | 367 /** |
| 197 * @override | 368 * @override |
| 198 * @param {!SDK.RuntimeModel} runtimeModel | 369 * @param {!SDK.RuntimeModel} runtimeModel |
| 199 */ | 370 */ |
| 200 modelAdded(runtimeModel) { | 371 modelAdded(runtimeModel) { |
| 201 runtimeModel.executionContexts().forEach(this._executionContextCreated, this
); | 372 runtimeModel.executionContexts().forEach(this._executionContextCreated, this
); |
| 202 } | 373 } |
| 203 | 374 |
| 204 /** | 375 /** |
| 205 * @override | 376 * @override |
| 206 * @param {!SDK.RuntimeModel} runtimeModel | 377 * @param {!SDK.RuntimeModel} runtimeModel |
| 207 */ | 378 */ |
| 208 modelRemoved(runtimeModel) { | 379 modelRemoved(runtimeModel) { |
| 209 var executionContexts = this._optionByExecutionContext.keysArray(); | 380 for (var i = 0; i < this._list.length(); i++) { |
| 210 for (var i = 0; i < executionContexts.length; ++i) { | 381 if (this._list.itemAtIndex(i).runtimeModel === runtimeModel) |
| 211 if (executionContexts[i].runtimeModel === runtimeModel) | 382 this._executionContextDestroyed(this._list.itemAtIndex(i)); |
| 212 this._executionContextDestroyed(executionContexts[i]); | |
| 213 } | 383 } |
| 214 } | 384 } |
| 215 | 385 |
| 216 /** | 386 /** |
| 217 * @param {!Element} option | 387 * @override |
| 388 * @param {!SDK.ExecutionContext} item |
| 389 * @return {!Element} |
| 218 */ | 390 */ |
| 219 _select(option) { | 391 createElementForItem(item) { |
| 220 this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {
?} */ (this._selectElement), option); | 392 var element = createElementWithClass('div', 'context'); |
| 393 element.style.paddingLeft = (8 + this._depthFor(item) * 15) + 'px'; |
| 394 element.createChild('div', 'title').textContent = this._titleFor(item).trimE
nd(100); |
| 395 element.createChild('div', 'subtitle').textContent = this._subtitleFor(item)
; |
| 396 element.addEventListener('mousemove', e => { |
| 397 if ((e.movementX || e.movementY) && this.isItemSelectable(item)) |
| 398 this._list.selectItem(item, false, /* Don't scroll */ true); |
| 399 }); |
| 400 element.classList.toggle('disabled', !this.isItemSelectable(item)); |
| 401 return element; |
| 402 } |
| 403 |
| 404 /** |
| 405 * @param {!SDK.ExecutionContext} executionContext |
| 406 * @return {string} |
| 407 */ |
| 408 _subtitleFor(executionContext) { |
| 409 var target = executionContext.target(); |
| 410 if (executionContext.frameId) { |
| 411 var resourceTreeModel = target.model(SDK.ResourceTreeModel); |
| 412 var frame = resourceTreeModel && resourceTreeModel.frameForId(executionCon
text.frameId); |
| 413 } |
| 414 if (executionContext.origin.startsWith('chrome-extension://')) |
| 415 return Common.UIString('Extension'); |
| 416 if (!frame || !frame.parentFrame || frame.parentFrame.securityOrigin !== exe
cutionContext.origin) { |
| 417 var url = executionContext.origin.asParsedURL(); |
| 418 if (url) { |
| 419 if (this._productRegistry) { |
| 420 var product = this._productRegistry.nameForUrl(url); |
| 421 if (product) |
| 422 return product; |
| 423 } |
| 424 return url.domain(); |
| 425 } |
| 426 } |
| 427 |
| 428 if (frame) { |
| 429 var callFrame = frame.findCreationCallFrame(callFrame => !!callFrame.url); |
| 430 if (callFrame) { |
| 431 var url = new Common.ParsedURL(callFrame.url); |
| 432 if (this._productRegistry) { |
| 433 var product = this._productRegistry.nameForUrl(url); |
| 434 if (product) |
| 435 return product; |
| 436 } |
| 437 return url.domain(); |
| 438 } |
| 439 } |
| 440 return ''; |
| 441 } |
| 442 |
| 443 /** |
| 444 * @override |
| 445 * @param {!SDK.ExecutionContext} item |
| 446 * @return {number} |
| 447 */ |
| 448 heightForItem(item) { |
| 449 return 0; |
| 450 } |
| 451 |
| 452 /** |
| 453 * @override |
| 454 * @param {!SDK.ExecutionContext} item |
| 455 * @return {boolean} |
| 456 */ |
| 457 isItemSelectable(item) { |
| 458 var callFrame = item.debuggerModel.selectedCallFrame(); |
| 459 var callFrameContext = callFrame && callFrame.script.executionContext(); |
| 460 return !callFrameContext || item === callFrameContext; |
| 461 } |
| 462 |
| 463 /** |
| 464 * @override |
| 465 * @param {?SDK.ExecutionContext} from |
| 466 * @param {?SDK.ExecutionContext} to |
| 467 * @param {?Element} fromElement |
| 468 * @param {?Element} toElement |
| 469 */ |
| 470 selectedItemChanged(from, to, fromElement, toElement) { |
| 471 if (fromElement) |
| 472 fromElement.classList.remove('selected'); |
| 473 if (toElement) |
| 474 toElement.classList.add('selected'); |
| 475 SDK.OverlayModel.hideDOMNodeHighlight(); |
| 476 if (to && to.frameId) { |
| 477 var resourceTreeModel = to.target().model(SDK.ResourceTreeModel); |
| 478 if (resourceTreeModel) |
| 479 resourceTreeModel.domModel().overlayModel().highlightFrame(to.frameId); |
| 480 } |
| 481 } |
| 482 |
| 483 _updateSelectedContext() { |
| 484 var context = this._list.selectedItem(); |
| 485 if (context) |
| 486 this._titleElement.textContent = this._titleFor(context); |
| 487 else |
| 488 this._titleElement.textContent = ''; |
| 489 UI.context.setFlavor(SDK.ExecutionContext, context); |
| 221 this._updateSelectionWarning(); | 490 this._updateSelectionWarning(); |
| 222 } | 491 } |
| 223 | 492 |
| 224 /** | |
| 225 * @return {?Element} | |
| 226 */ | |
| 227 _selectedOption() { | |
| 228 if (this._selectElement.selectedIndex >= 0) | |
| 229 return this._selectElement[this._selectElement.selectedIndex]; | |
| 230 return null; | |
| 231 } | |
| 232 | |
| 233 /** | |
| 234 * @param {!Common.Event} event | |
| 235 */ | |
| 236 _callFrameSelectedInModel(event) { | |
| 237 var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data); | |
| 238 var options = this._selectElement.options; | |
| 239 for (var i = 0; i < options.length; i++) { | |
| 240 if (options[i].__executionContext.debuggerModel === debuggerModel) | |
| 241 this._updateOptionDisabledState(options[i]); | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 /** | |
| 246 * @param {!Element} option | |
| 247 */ | |
| 248 _updateOptionDisabledState(option) { | |
| 249 var executionContext = option.__executionContext; | |
| 250 var callFrame = executionContext.debuggerModel.selectedCallFrame(); | |
| 251 var callFrameContext = callFrame && callFrame.script.executionContext(); | |
| 252 option.disabled = callFrameContext && executionContext !== callFrameContext; | |
| 253 } | |
| 254 | |
| 255 _callFrameSelectedInUI() { | 493 _callFrameSelectedInUI() { |
| 256 var callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); | 494 var callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); |
| 257 var callFrameContext = callFrame && callFrame.script.executionContext(); | 495 var callFrameContext = callFrame && callFrame.script.executionContext(); |
| 258 if (callFrameContext) | 496 if (callFrameContext) |
| 259 UI.context.setFlavor(SDK.ExecutionContext, callFrameContext); | 497 UI.context.setFlavor(SDK.ExecutionContext, callFrameContext); |
| 260 } | 498 } |
| 499 |
| 500 /** |
| 501 * @param {!Common.Event} event |
| 502 */ |
| 503 _callFrameSelectedInModel(event) { |
| 504 var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data); |
| 505 for (var i = 0; i < this._list.length(); i++) { |
| 506 if (this._list.itemAtIndex(i).debuggerModel === debuggerModel) |
| 507 this._list.refreshItemsInRange(i, i + 1); |
| 508 } |
| 509 } |
| 510 |
| 511 /** |
| 512 * @param {!Common.Event} event |
| 513 */ |
| 514 _frameNavigated(event) { |
| 515 var frameId = event.data.id; |
| 516 for (var i = 0; i < this._list.length(); i++) { |
| 517 if (frameId === this._list.itemAtIndex(i).frameId) |
| 518 this._list.refreshItemsInRange(i, i + 1); |
| 519 } |
| 520 } |
| 261 }; | 521 }; |
| OLD | NEW |