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