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