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 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._shouldHideOnMouseUp = false; | |
| 35 this._toolbarItem.element.addEventListener('mousedown', event => { | |
| 36 if (this._shouldHideOnMouseUp) | |
| 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._shouldHideOnMouseUp) | |
| 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._shouldHideOnMouseUp = 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._shouldHideOnMouseUp = 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 this._updateDisabledState(); |
| 93 this._select(newOption); | 279 if (executionContext === UI.context.flavor(SDK.ExecutionContext)) { |
| 94 this._updateOptionDisabledState(newOption); | 280 this._list.selectItem(executionContext); |
| 95 | 281 this._updateSelectedContext(); |
| 96 /** | |
| 97 * @param {!Element} option | |
| 98 * @return {!SDK.ExecutionContext} | |
| 99 */ | |
| 100 function mapping(option) { | |
| 101 return option.__executionContext; | |
| 102 } | 282 } |
| 103 } | 283 } |
| 104 | 284 |
| 105 /** | 285 /** |
| 106 * @param {!Common.Event} event | 286 * @param {!Common.Event} event |
| 107 */ | 287 */ |
| 108 _onExecutionContextCreated(event) { | 288 _onExecutionContextCreated(event) { |
| 109 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); | 289 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); |
| 110 this._executionContextCreated(executionContext); | 290 this._executionContextCreated(executionContext); |
| 111 this._updateSelectionWarning(); | 291 this._updateSelectionWarning(); |
| 292 this._updateGlasspaneSize(); | |
| 112 } | 293 } |
| 113 | 294 |
| 114 /** | 295 /** |
| 115 * @param {!Common.Event} event | 296 * @param {!Common.Event} event |
| 116 */ | 297 */ |
| 117 _onExecutionContextChanged(event) { | 298 _onExecutionContextChanged(event) { |
| 118 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); | 299 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); |
| 119 var option = this._optionByExecutionContext.get(executionContext); | 300 if (this._list.indexOfItem(executionContext) === -1) |
| 120 if (option) | 301 return; |
| 121 option.text = this._titleFor(executionContext); | 302 this._executionContextDestroyed(executionContext); |
| 303 this._executionContextCreated(executionContext); | |
| 122 this._updateSelectionWarning(); | 304 this._updateSelectionWarning(); |
| 123 } | 305 } |
| 124 | 306 |
| 125 /** | 307 /** |
| 126 * @param {!SDK.ExecutionContext} executionContext | 308 * @param {!SDK.ExecutionContext} executionContext |
| 127 */ | 309 */ |
| 128 _executionContextDestroyed(executionContext) { | 310 _executionContextDestroyed(executionContext) { |
| 129 var option = this._optionByExecutionContext.remove(executionContext); | 311 if (this._list.indexOfItem(executionContext) === -1) |
| 130 option.remove(); | 312 return; |
| 313 this._list.removeItem(executionContext); | |
| 314 this._updateDisabledState(); | |
| 315 this._updateGlasspaneSize(); | |
| 316 } | |
| 317 | |
| 318 _updateDisabledState() { | |
| 319 this._toolbarItem.element.disabled = (this._list.length() <= 1); | |
|
dgozman
2017/05/11 21:14:52
Let's land this in a separate patch.
einbinder
2017/05/11 21:47:22
Done.
| |
| 131 } | 320 } |
| 132 | 321 |
| 133 /** | 322 /** |
| 134 * @param {!Common.Event} event | 323 * @param {!Common.Event} event |
| 135 */ | 324 */ |
| 136 _onExecutionContextDestroyed(event) { | 325 _onExecutionContextDestroyed(event) { |
| 137 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); | 326 var executionContext = /** @type {!SDK.ExecutionContext} */ (event.data); |
| 138 this._executionContextDestroyed(executionContext); | 327 this._executionContextDestroyed(executionContext); |
| 139 this._updateSelectionWarning(); | 328 this._updateSelectionWarning(); |
| 140 } | 329 } |
| 141 | 330 |
| 142 /** | 331 /** |
| 143 * @param {!Common.Event} event | 332 * @param {!Common.Event} event |
| 144 */ | 333 */ |
| 145 _executionContextChangedExternally(event) { | 334 _executionContextChangedExternally(event) { |
| 146 var executionContext = /** @type {?SDK.ExecutionContext} */ (event.data); | 335 var executionContext = /** @type {?SDK.ExecutionContext} */ (event.data); |
| 147 if (!executionContext) | 336 if (!executionContext || this._list.indexOfItem(executionContext) === -1) |
| 148 return; | 337 return; |
| 149 | 338 this._list.selectItem(executionContext); |
| 150 var options = this._selectElement.options; | 339 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 } | 340 } |
| 163 | 341 |
| 164 _updateSelectionWarning() { | 342 _updateSelectionWarning() { |
| 165 var executionContext = UI.context.flavor(SDK.ExecutionContext); | 343 var executionContext = UI.context.flavor(SDK.ExecutionContext); |
| 166 this._selectElement.parentElement.classList.toggle( | 344 this._toolbarItem.element.classList.toggle( |
| 167 'warning', !this._isTopContext(executionContext) && this._hasTopContext( )); | 345 'warning', !this._isTopContext(executionContext) && this._hasTopContext( )); |
| 168 } | 346 } |
| 169 | 347 |
| 170 /** | 348 /** |
| 171 * @param {?SDK.ExecutionContext} executionContext | 349 * @param {?SDK.ExecutionContext} executionContext |
| 172 * @return {boolean} | 350 * @return {boolean} |
| 173 */ | 351 */ |
| 174 _isTopContext(executionContext) { | 352 _isTopContext(executionContext) { |
| 175 if (!executionContext || !executionContext.isDefault) | 353 if (!executionContext || !executionContext.isDefault) |
| 176 return false; | 354 return false; |
| 177 var resourceTreeModel = executionContext.target().model(SDK.ResourceTreeMode l); | 355 var resourceTreeModel = executionContext.target().model(SDK.ResourceTreeMode l); |
| 178 var frame = executionContext.frameId && resourceTreeModel && resourceTreeMod el.frameForId(executionContext.frameId); | 356 var frame = executionContext.frameId && resourceTreeModel && resourceTreeMod el.frameForId(executionContext.frameId); |
| 179 if (!frame) | 357 if (!frame) |
| 180 return false; | 358 return false; |
| 181 return frame.isMainFrame(); | 359 return frame.isMainFrame(); |
| 182 } | 360 } |
| 183 | 361 |
| 184 /** | 362 /** |
| 185 * @return {boolean} | 363 * @return {boolean} |
| 186 */ | 364 */ |
| 187 _hasTopContext() { | 365 _hasTopContext() { |
| 188 var options = this._selectElement.options; | 366 for (var i = 0; i < this._list.length(); i++) { |
| 189 for (var i = 0; i < options.length; i++) { | 367 if (this._isTopContext(this._list.itemAtIndex(i))) |
| 190 if (this._isTopContext(options[i].__executionContext)) | |
| 191 return true; | 368 return true; |
| 192 } | 369 } |
| 193 return false; | 370 return false; |
| 194 } | 371 } |
| 195 | 372 |
| 196 /** | 373 /** |
| 197 * @override | 374 * @override |
| 198 * @param {!SDK.RuntimeModel} runtimeModel | 375 * @param {!SDK.RuntimeModel} runtimeModel |
| 199 */ | 376 */ |
| 200 modelAdded(runtimeModel) { | 377 modelAdded(runtimeModel) { |
| 201 runtimeModel.executionContexts().forEach(this._executionContextCreated, this ); | 378 runtimeModel.executionContexts().forEach(this._executionContextCreated, this ); |
| 202 } | 379 } |
| 203 | 380 |
| 204 /** | 381 /** |
| 205 * @override | 382 * @override |
| 206 * @param {!SDK.RuntimeModel} runtimeModel | 383 * @param {!SDK.RuntimeModel} runtimeModel |
| 207 */ | 384 */ |
| 208 modelRemoved(runtimeModel) { | 385 modelRemoved(runtimeModel) { |
| 209 var executionContexts = this._optionByExecutionContext.keysArray(); | 386 for (var i = 0; i < this._list.length(); i++) { |
| 210 for (var i = 0; i < executionContexts.length; ++i) { | 387 if (this._list.itemAtIndex(i).runtimeModel === runtimeModel) |
| 211 if (executionContexts[i].runtimeModel === runtimeModel) | 388 this._executionContextDestroyed(this._list.itemAtIndex(i)); |
| 212 this._executionContextDestroyed(executionContexts[i]); | |
| 213 } | 389 } |
| 214 } | 390 } |
| 215 | 391 |
| 216 /** | 392 /** |
| 217 * @param {!Element} option | 393 * @override |
| 394 * @param {!SDK.ExecutionContext} item | |
| 395 * @return {!Element} | |
| 218 */ | 396 */ |
| 219 _select(option) { | 397 createElementForItem(item) { |
| 220 this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type { ?} */ (this._selectElement), option); | 398 var element = createElementWithClass('div', 'context'); |
| 399 element.style.paddingLeft = (8 + this._depthFor(item) * 15) + 'px'; | |
| 400 element.createChild('div', 'title').textContent = this._titleFor(item).trimE nd(100); | |
| 401 element.createChild('div', 'subtitle').textContent = this._subtitleFor(item) ; | |
| 402 element.addEventListener('mousemove', e => { | |
| 403 if ((e.movementX || e.movementY) && this.isItemSelectable(item)) | |
| 404 this._list.selectItem(item, false, /* Don't scroll */ true); | |
| 405 }); | |
| 406 element.classList.toggle('disabled', !this.isItemSelectable(item)); | |
| 407 return element; | |
| 408 } | |
| 409 | |
| 410 /** | |
| 411 * @param {!SDK.ExecutionContext} executionContext | |
| 412 * @return {string} | |
| 413 */ | |
| 414 _subtitleFor(executionContext) { | |
| 415 var target = executionContext.target(); | |
| 416 if (executionContext.frameId) { | |
| 417 var resourceTreeModel = target.model(SDK.ResourceTreeModel); | |
| 418 var frame = resourceTreeModel && resourceTreeModel.frameForId(executionCon text.frameId); | |
| 419 } | |
| 420 if (executionContext.origin.startsWith('chrome-extension://')) | |
| 421 return Common.UIString('Extension'); | |
| 422 if (!frame || !frame.parentFrame || frame.parentFrame.securityOrigin !== exe cutionContext.origin) { | |
| 423 var url = executionContext.origin.asParsedURL(); | |
| 424 if (url) { | |
| 425 if (this._productRegistry) { | |
| 426 var product = this._productRegistry.nameForUrl(url); | |
| 427 if (product) | |
| 428 return product; | |
| 429 } | |
| 430 return url.domain(); | |
| 431 } | |
| 432 } | |
| 433 | |
| 434 if (frame) { | |
| 435 var stackTrace = frame.creationStackTrace(); | |
| 436 while (stackTrace) { | |
| 437 for (var stack of stackTrace.callFrames) { | |
| 438 if (stack.url) { | |
| 439 var url = new Common.ParsedURL(stack.url); | |
| 440 if (this._productRegistry) { | |
| 441 var product = this._productRegistry.nameForUrl(url); | |
| 442 if (product) | |
| 443 return product; | |
| 444 } | |
| 445 return url.domain(); | |
| 446 } | |
| 447 } | |
| 448 stackTrace = frame.parent; | |
| 449 } | |
| 450 } | |
| 451 return ''; | |
| 452 } | |
| 453 | |
| 454 /** | |
| 455 * @override | |
| 456 * @param {!SDK.ExecutionContext} item | |
| 457 * @return {number} | |
| 458 */ | |
| 459 heightForItem(item) { | |
| 460 return 0; | |
| 461 } | |
| 462 | |
| 463 /** | |
| 464 * @override | |
| 465 * @param {!SDK.ExecutionContext} item | |
| 466 * @return {boolean} | |
| 467 */ | |
| 468 isItemSelectable(item) { | |
| 469 var callFrame = item.debuggerModel.selectedCallFrame(); | |
| 470 var callFrameContext = callFrame && callFrame.script.executionContext(); | |
| 471 return !callFrameContext || item === callFrameContext; | |
| 472 } | |
| 473 | |
| 474 /** | |
| 475 * @override | |
| 476 * @param {?SDK.ExecutionContext} from | |
| 477 * @param {?SDK.ExecutionContext} to | |
| 478 * @param {?Element} fromElement | |
| 479 * @param {?Element} toElement | |
| 480 */ | |
| 481 selectedItemChanged(from, to, fromElement, toElement) { | |
| 482 if (fromElement) | |
| 483 fromElement.classList.remove('selected'); | |
| 484 if (toElement) | |
| 485 toElement.classList.add('selected'); | |
| 486 SDK.OverlayModel.hideDOMNodeHighlight(); | |
| 487 if (to && to.frameId) { | |
| 488 var resourceTreeModel = to.target().model(SDK.ResourceTreeModel); | |
| 489 if (resourceTreeModel) | |
| 490 resourceTreeModel.domModel().overlayModel().highlightFrame(to.frameId); | |
| 491 } | |
| 492 } | |
| 493 | |
| 494 _updateSelectedContext() { | |
| 495 var context = this._list.selectedItem(); | |
| 496 if (context) | |
| 497 this._titleElement.textContent = this._titleFor(context); | |
| 498 else | |
| 499 this._titleElement.textContent = ''; | |
| 500 UI.context.setFlavor(SDK.ExecutionContext, context); | |
| 221 this._updateSelectionWarning(); | 501 this._updateSelectionWarning(); |
| 222 } | 502 } |
| 223 | 503 |
| 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() { | 504 _callFrameSelectedInUI() { |
| 256 var callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); | 505 var callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); |
| 257 var callFrameContext = callFrame && callFrame.script.executionContext(); | 506 var callFrameContext = callFrame && callFrame.script.executionContext(); |
| 258 if (callFrameContext) | 507 if (callFrameContext) |
| 259 UI.context.setFlavor(SDK.ExecutionContext, callFrameContext); | 508 UI.context.setFlavor(SDK.ExecutionContext, callFrameContext); |
| 260 } | 509 } |
| 510 | |
| 511 /** | |
| 512 * @param {!Common.Event} event | |
| 513 */ | |
| 514 _callFrameSelectedInModel(event) { | |
| 515 var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data); | |
| 516 for (var i = 0; i < this._list.length(); i++) { | |
| 517 if (this._list.itemAtIndex(i).debuggerModel === debuggerModel) | |
| 518 this._list.refreshItemsInRange(i, i + 1); | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 /** | |
| 523 * @param {!Common.Event} event | |
| 524 */ | |
| 525 _frameNavigated(event) { | |
| 526 var frameId = event.data.id; | |
| 527 for (var i = 0; i < this._list.length(); i++) { | |
| 528 if (frameId === this._list.itemAtIndex(i).frameId) | |
| 529 this._list.refreshItemsInRange(i, i + 1); | |
| 530 } | |
| 531 } | |
| 261 }; | 532 }; |
| OLD | NEW |