Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 /** | 5 /** |
| 6 * @interface | |
| 7 */ | |
| 8 WebInspector.View = function() | |
| 9 { | |
| 10 } | |
| 11 | |
| 12 WebInspector.View.prototype = { | |
| 13 /** | |
| 14 * @return {string} | |
| 15 */ | |
| 16 viewId: function() { }, | |
| 17 | |
| 18 /** | |
| 19 * @return {string} | |
| 20 */ | |
| 21 title: function() { }, | |
| 22 | |
| 23 /** | |
| 24 * @return {boolean} | |
| 25 */ | |
| 26 isCloseable: function() { }, | |
| 27 | |
| 28 /** | |
| 29 * @return {boolean} | |
| 30 */ | |
| 31 isTransient: function() { }, | |
| 32 | |
| 33 /** | |
| 34 * @return {!Promise<!Array<!WebInspector.ToolbarItem>>} | |
| 35 */ | |
| 36 toolbarItems: function() { }, | |
| 37 | |
| 38 /** | |
| 39 * @return {!Promise<!WebInspector.Widget>} | |
| 40 */ | |
| 41 widget: function() { } | |
| 42 } | |
| 43 | |
| 44 /** | |
| 6 * @constructor | 45 * @constructor |
| 7 * @extends {WebInspector.VBox} | 46 * @extends {WebInspector.VBox} |
| 47 * @implements {WebInspector.View} | |
| 8 * @param {string} title | 48 * @param {string} title |
| 9 * @param {boolean=} isWebComponent | 49 * @param {boolean=} isWebComponent |
| 10 */ | 50 */ |
| 11 WebInspector.View = function(title, isWebComponent) | 51 WebInspector.SimpleView = function(title, isWebComponent) |
| 12 { | 52 { |
| 13 WebInspector.VBox.call(this, isWebComponent); | 53 WebInspector.VBox.call(this, isWebComponent); |
| 14 this._title = title; | 54 this._title = title; |
| 15 /** @type {!Array<!WebInspector.ToolbarItem>} */ | 55 /** @type {!Array<!WebInspector.ToolbarItem>} */ |
| 16 this._toolbarItems = []; | 56 this._toolbarItems = []; |
| 17 } | 57 } |
| 18 | 58 |
| 19 WebInspector.View.prototype = { | 59 WebInspector.SimpleView.prototype = { |
| 20 /** | 60 /** |
| 61 * @override | |
| 62 * @return {string} | |
| 63 */ | |
| 64 viewId: function() | |
| 65 { | |
| 66 return this._title; | |
| 67 }, | |
| 68 | |
| 69 /** | |
| 70 * @override | |
| 21 * @return {string} | 71 * @return {string} |
| 22 */ | 72 */ |
| 23 title: function() | 73 title: function() |
| 24 { | 74 { |
| 25 return this._title; | 75 return this._title; |
| 26 }, | 76 }, |
| 27 | 77 |
| 28 /** | 78 /** |
| 79 * @override | |
| 80 * @return {boolean} | |
| 81 */ | |
| 82 isCloseable: function() | |
| 83 { | |
| 84 return false; | |
| 85 }, | |
| 86 | |
| 87 /** | |
| 88 * @override | |
| 89 * @return {boolean} | |
| 90 */ | |
| 91 isTransient: function() | |
| 92 { | |
| 93 return false; | |
| 94 }, | |
| 95 | |
| 96 /** | |
| 97 * @override | |
| 98 * @return {!Promise<!Array<!WebInspector.ToolbarItem>>} | |
| 99 */ | |
| 100 toolbarItems: function() | |
| 101 { | |
| 102 return Promise.resolve(this.syncToolbarItems()); | |
| 103 }, | |
| 104 | |
| 105 /** | |
| 106 * @return {!Array<!WebInspector.ToolbarItem>} | |
| 107 */ | |
| 108 syncToolbarItems: function() | |
| 109 { | |
| 110 return this._toolbarItems; | |
| 111 }, | |
| 112 | |
| 113 /** | |
| 114 * @override | |
| 115 * @return {!Promise<!WebInspector.Widget>} | |
| 116 */ | |
| 117 widget: function() | |
| 118 { | |
| 119 return /** @type {!Promise<!WebInspector.Widget>} */ (Promise.resolve(th is)); | |
| 120 }, | |
| 121 | |
| 122 /** | |
| 29 * @param {!WebInspector.ToolbarItem} item | 123 * @param {!WebInspector.ToolbarItem} item |
| 30 */ | 124 */ |
| 31 addToolbarItem: function(item) | 125 addToolbarItem: function(item) |
| 32 { | 126 { |
| 33 this._toolbarItems.push(item); | 127 this._toolbarItems.push(item); |
| 34 }, | 128 }, |
| 35 | 129 |
| 36 /** | 130 /** |
| 37 * @return {!Array<!WebInspector.ToolbarItem>} | 131 * @return {!Promise} |
| 132 */ | |
| 133 revealView: function() | |
| 134 { | |
| 135 return WebInspector.viewManager.revealView(this._parentViewToReveal || t his); | |
| 136 }, | |
| 137 | |
| 138 /** | |
| 139 * @param {!WebInspector.View} view | |
| 140 */ | |
| 141 setParentViewForReveal: function(view) | |
| 142 { | |
| 143 this._parentViewToReveal = view; | |
| 144 }, | |
| 145 | |
| 146 __proto__: WebInspector.VBox.prototype | |
| 147 } | |
| 148 | |
| 149 /** | |
| 150 * @constructor | |
| 151 * @implements {WebInspector.View} | |
| 152 * @param {!Runtime.Extension} extension | |
| 153 */ | |
| 154 WebInspector.ProvidedView = function(extension) | |
| 155 { | |
| 156 this._extension = extension; | |
| 157 } | |
| 158 | |
| 159 WebInspector.ProvidedView.prototype = { | |
| 160 /** | |
| 161 * @override | |
| 162 * @return {string} | |
| 163 */ | |
| 164 viewId: function() | |
| 165 { | |
| 166 return this._extension.descriptor()["id"]; | |
| 167 }, | |
| 168 | |
| 169 /** | |
| 170 * @override | |
| 171 * @return {string} | |
| 172 */ | |
| 173 title: function() | |
| 174 { | |
| 175 return this._extension.title(); | |
| 176 }, | |
| 177 | |
| 178 /** | |
| 179 * @override | |
| 180 * @return {boolean} | |
| 181 */ | |
| 182 isCloseable: function() | |
| 183 { | |
| 184 return this._extension.descriptor()["persistence"] === "closeable"; | |
| 185 }, | |
| 186 | |
| 187 /** | |
| 188 * @override | |
| 189 * @return {boolean} | |
| 190 */ | |
| 191 isTransient: function() | |
| 192 { | |
| 193 return this._extension.descriptor()["persistence"] === "transient"; | |
| 194 }, | |
| 195 | |
| 196 /** | |
| 197 * @override | |
| 198 * @return {!Promise<!Array<!WebInspector.ToolbarItem>>} | |
| 38 */ | 199 */ |
| 39 toolbarItems: function() | 200 toolbarItems: function() |
| 40 { | 201 { |
| 41 return this._toolbarItems; | 202 return Promise.resolve([]); |
| 42 }, | 203 }, |
| 43 | 204 |
| 44 __proto__: WebInspector.VBox.prototype | 205 /** |
| 206 * @override | |
| 207 * @return {!Promise<!WebInspector.Widget>} | |
| 208 */ | |
| 209 widget: function() | |
| 210 { | |
| 211 return /** @type {!Promise<!WebInspector.Widget>} */ (this._extension.i nstance()); | |
| 212 } | |
| 45 } | 213 } |
| 46 | 214 |
| 47 /** | 215 /** |
| 48 * @interface | 216 * @interface |
| 49 */ | 217 */ |
| 50 WebInspector.ViewLocation = function() { } | 218 WebInspector.ViewLocation = function() { } |
| 51 | 219 |
| 52 WebInspector.ViewLocation.prototype = { | 220 WebInspector.ViewLocation.prototype = { |
| 53 /** | 221 /** |
| 54 * @param {string} viewId | 222 * @param {!WebInspector.View} view |
| 223 * @param {?WebInspector.View=} insertBefore | |
| 55 */ | 224 */ |
| 56 showView: function(viewId) { }, | 225 appendView: function(view, insertBefore) { }, |
| 226 | |
| 227 /** | |
| 228 * @param {!WebInspector.View} view | |
| 229 * @param {?WebInspector.View=} insertBefore | |
| 230 * @return {!Promise} | |
| 231 */ | |
| 232 showView: function(view, insertBefore) { }, | |
| 57 | 233 |
| 58 /** | 234 /** |
| 59 * @return {!WebInspector.Widget} | 235 * @return {!WebInspector.Widget} |
| 60 */ | 236 */ |
| 61 widget: function() { } | 237 widget: function() { }, |
| 238 | |
| 239 reveal: function() { }, | |
|
dgozman
2016/08/06 00:56:10
Why is this public?
| |
| 62 } | 240 } |
| 63 | 241 |
| 64 /** | 242 /** |
| 65 * @interface | 243 * @interface |
| 66 * @extends {WebInspector.ViewLocation} | 244 * @extends {WebInspector.ViewLocation} |
| 67 */ | 245 */ |
| 68 WebInspector.TabbedViewLocation = function() { } | 246 WebInspector.TabbedViewLocation = function() { } |
| 69 | 247 |
| 70 WebInspector.TabbedViewLocation.prototype = { | 248 WebInspector.TabbedViewLocation.prototype = { |
| 71 /** | 249 /** |
| 72 * @return {!WebInspector.TabbedPane} | 250 * @return {!WebInspector.TabbedPane} |
| 73 */ | 251 */ |
| 74 tabbedPane: function() { }, | 252 tabbedPane: function() { }, |
| 253 | |
| 254 enableMoreTabsButton: function() { } | |
| 75 } | 255 } |
| 76 | 256 |
| 77 /** | 257 /** |
| 78 * @interface | 258 * @interface |
| 79 */ | 259 */ |
| 80 WebInspector.ViewLocationResolver = function() { } | 260 WebInspector.ViewLocationResolver = function() { } |
| 81 | 261 |
| 82 WebInspector.ViewLocationResolver.prototype = { | 262 WebInspector.ViewLocationResolver.prototype = { |
| 83 /** | 263 /** |
| 84 * @param {string} location | 264 * @param {string} location |
| 85 * @return {?WebInspector.ViewLocation} | 265 * @return {?WebInspector.ViewLocation} |
| 86 */ | 266 */ |
| 87 revealLocation: function(location) { } | 267 resolveLocation: function(location) { } |
| 88 } | 268 } |
| 89 | 269 |
| 90 /** | 270 /** |
| 91 * @constructor | 271 * @constructor |
| 92 */ | 272 */ |
| 93 WebInspector.ViewManager = function() | 273 WebInspector.ViewManager = function() |
| 94 { | 274 { |
| 275 /** @type {!Map<string, !WebInspector.View>} */ | |
| 276 this._views = new Map(); | |
| 277 /** @type {!Map<string, string>} */ | |
| 278 this._locationNameByViewId = new Map(); | |
| 279 | |
| 280 for (var extension of self.runtime.extensions("view")) { | |
| 281 var descriptor = extension.descriptor(); | |
| 282 this._views.set(descriptor["id"], new WebInspector.ProvidedView(extensio n)); | |
| 283 this._locationNameByViewId.set(descriptor["id"], descriptor["location"]) ; | |
| 284 } | |
| 95 } | 285 } |
| 96 | 286 |
| 97 WebInspector.ViewManager.prototype = { | 287 WebInspector.ViewManager.prototype = { |
| 98 /** | 288 /** |
| 289 * @param {!WebInspector.View} view | |
| 290 * @return {!Promise} | |
| 291 */ | |
| 292 revealView: function(view) | |
| 293 { | |
| 294 var location = view[WebInspector.ViewManager._Location.symbol]; | |
| 295 if (!location) | |
| 296 return Promise.resolve(); | |
| 297 location.reveal(); | |
| 298 return location.showView(view); | |
| 299 }, | |
| 300 | |
| 301 /** | |
| 99 * @param {string} viewId | 302 * @param {string} viewId |
| 303 * @return {!Promise} | |
| 100 */ | 304 */ |
| 101 showView: function(viewId) | 305 showView: function(viewId) |
| 102 { | 306 { |
| 103 var extensions = self.runtime.extensions("view").filter(extension => ext ension.descriptor()["id"] === viewId); | 307 var view = this._views.get(viewId); |
| 104 if (!extensions.length) { | 308 if (!view) { |
| 105 console.error("Could not find view for id: '" + viewId + "'"); | 309 console.error("Could not find view for id: '" + viewId + "' " + new Error().stack); |
| 106 return; | 310 return Promise.resolve(); |
| 107 } | 311 } |
| 108 var extension = extensions[0]; | 312 var locationName = this._locationNameByViewId.get(viewId); |
| 109 var location = extensions[0].descriptor()["location"]; | 313 if (locationName === "drawer-view") |
| 110 if (location === "drawer-view") | |
| 111 WebInspector.userMetrics.drawerShown(viewId); | 314 WebInspector.userMetrics.drawerShown(viewId); |
| 315 | |
| 316 return this._resolveLocation(locationName).then(location => { | |
| 317 if (!location) | |
| 318 return; | |
| 319 location.reveal(); | |
| 320 return location.showView(view); | |
| 321 }); | |
| 322 }, | |
| 323 | |
| 324 /** | |
| 325 * @param {string=} location | |
| 326 * @return {!Promise<?WebInspector.ViewLocation>} | |
| 327 */ | |
| 328 _resolveLocation: function(location) | |
| 329 { | |
| 330 if (!location) | |
| 331 return /** @type {!Promise<?WebInspector.ViewLocation>} */ (Promise. resolve(null)); | |
| 332 | |
| 112 var resolverExtensions = self.runtime.extensions(WebInspector.ViewLocati onResolver).filter(extension => extension.descriptor()["name"] === location); | 333 var resolverExtensions = self.runtime.extensions(WebInspector.ViewLocati onResolver).filter(extension => extension.descriptor()["name"] === location); |
| 113 if (!resolverExtensions.length) | 334 if (!resolverExtensions.length) |
| 335 return /** @type {!Promise<?WebInspector.ViewLocation>} */ (Promise. resolve(null)); | |
| 336 var resolverExtension = resolverExtensions[0]; | |
| 337 return resolverExtension.instance().then(revealer => revealer.resolveLoc ation(location)); | |
|
dgozman
2016/08/06 00:56:11
nit: revealer -> resolver
| |
| 338 }, | |
| 339 | |
| 340 /** | |
| 341 * @param {function()=} revealCallback | |
| 342 * @param {string=} location | |
| 343 * @param {boolean=} restoreSelection | |
| 344 * @return {!WebInspector.TabbedViewLocation} | |
| 345 */ | |
| 346 createTabbedLocation: function(revealCallback, location, restoreSelection) | |
|
dgozman
2016/08/06 00:56:11
revealCallback should return Promise, since we pla
pfeldman
2016/08/06 01:12:22
All Done, Except for this!
| |
| 347 { | |
| 348 return new WebInspector.ViewManager._TabbedLocation(this, revealCallback , location, restoreSelection); | |
| 349 }, | |
| 350 | |
| 351 /** | |
| 352 * @param {function()=} revealCallback | |
| 353 * @param {string=} location | |
| 354 * @return {!WebInspector.ViewLocation} | |
| 355 */ | |
| 356 createStackLocation: function(revealCallback, location) | |
| 357 { | |
| 358 return new WebInspector.ViewManager._StackLocation(this, revealCallback, location); | |
| 359 }, | |
| 360 | |
| 361 /** | |
| 362 * @param {string} location | |
| 363 * @return {!Array<!WebInspector.View>} | |
| 364 */ | |
| 365 _viewsForLocation: function(location) | |
| 366 { | |
| 367 var result = []; | |
| 368 for (var id of this._views.keys()) { | |
| 369 if (this._locationNameByViewId.get(id) === location) | |
| 370 result.push(this._views.get(id)); | |
| 371 } | |
| 372 return result; | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 | |
| 377 /** | |
| 378 * @param {!Element} element | |
| 379 * @param {!Array<!WebInspector.ToolbarItem>} toolbarItems | |
| 380 */ | |
| 381 WebInspector.ViewManager._populateToolbar = function(element, toolbarItems) | |
| 382 { | |
| 383 if (toolbarItems.length) { | |
|
dgozman
2016/08/06 00:56:10
nit: convert to early return
| |
| 384 var toolbar = new WebInspector.Toolbar(""); | |
| 385 element.insertBefore(toolbar.element, element.firstChild); | |
| 386 for (var item of toolbarItems) | |
| 387 toolbar.appendToolbarItem(item); | |
| 388 } | |
| 389 } | |
| 390 | |
| 391 /** | |
| 392 * @constructor | |
| 393 * @extends {WebInspector.VBox} | |
| 394 * @param {!WebInspector.View} view | |
| 395 */ | |
| 396 WebInspector.ViewManager._ContainerWidget = function(view) | |
| 397 { | |
| 398 WebInspector.VBox.call(this); | |
| 399 this.element.classList.add("flex-auto", "view-container", "overflow-auto"); | |
| 400 this._view = view; | |
| 401 } | |
| 402 | |
| 403 WebInspector.ViewManager._ContainerWidget.prototype = { | |
| 404 /** | |
| 405 * @return {!Promise} | |
| 406 */ | |
| 407 _materialize: function() | |
| 408 { | |
| 409 if (this._materializePromise) | |
| 410 return this._materializePromise; | |
| 411 var promises = []; | |
| 412 promises.push(this._view.toolbarItems().then(WebInspector.ViewManager._p opulateToolbar.bind(WebInspector.ViewManager, this.element))); | |
| 413 promises.push(this._view.widget().then(widget => widget.show(this.elemen t))); | |
| 414 this._materializePromise = Promise.all(promises); | |
| 415 return this._materializePromise; | |
| 416 }, | |
| 417 | |
| 418 __proto__: WebInspector.VBox.prototype | |
| 419 } | |
| 420 | |
| 421 /** | |
| 422 * @constructor | |
| 423 * @extends {WebInspector.VBox} | |
| 424 * @param {!WebInspector.View} view | |
| 425 */ | |
| 426 WebInspector.ViewManager._ExpandableContainerWidget = function(view) | |
| 427 { | |
| 428 WebInspector.VBox.call(this, true); | |
| 429 this.element.classList.add("flex-none"); | |
| 430 this.registerRequiredCSS("ui/viewContainers.css"); | |
| 431 | |
| 432 this._titleElement = createElementWithClass("div", "expandable-view-title"); | |
| 433 this._titleElement.textContent = view.title(); | |
| 434 this._titleElement.tabIndex = 0; | |
| 435 this._titleElement.addEventListener("click", this._toggleExpanded.bind(this) , false); | |
| 436 this._titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(thi s), false); | |
| 437 this.contentElement.insertBefore(this._titleElement, this.contentElement.fir stChild); | |
| 438 | |
| 439 this.contentElement.createChild("content"); | |
| 440 this._view = view; | |
| 441 view[WebInspector.ViewManager._ExpandableContainerWidget._symbol] = this; | |
| 442 } | |
| 443 | |
| 444 WebInspector.ViewManager._ExpandableContainerWidget._symbol = Symbol("container" ); | |
| 445 | |
| 446 WebInspector.ViewManager._ExpandableContainerWidget.prototype = { | |
| 447 /** | |
| 448 * @return {!Promise} | |
| 449 */ | |
| 450 _materialize: function() | |
| 451 { | |
| 452 if (this._materializePromise) | |
| 453 return this._materializePromise; | |
| 454 var promises = []; | |
| 455 promises.push(this._view.toolbarItems().then(WebInspector.ViewManager._p opulateToolbar.bind(WebInspector.ViewManager, this._titleElement))); | |
| 456 promises.push(this._view.widget().then(widget => { | |
| 457 this._widget = widget; | |
| 458 widget.show(this.element); | |
| 459 })); | |
| 460 this._materializePromise = Promise.all(promises); | |
| 461 return this._materializePromise; | |
| 462 }, | |
| 463 | |
| 464 /** | |
| 465 * @return {!Promise} | |
| 466 */ | |
| 467 _expand: function() | |
| 468 { | |
| 469 if (this._titleElement.classList.contains("expanded")) | |
| 470 return this._materialize(); | |
| 471 this._titleElement.classList.add("expanded"); | |
| 472 return this._materialize().then(() => this._widget.show(this.element)); | |
| 473 }, | |
| 474 | |
| 475 _collapse: function() | |
| 476 { | |
| 477 if (!this._titleElement.classList.contains("expanded")) | |
| 114 return; | 478 return; |
| 115 var resolverExtension = resolverExtensions[0]; | 479 this._titleElement.classList.remove("expanded"); |
| 116 resolverExtension.instance().then(this._revealLocation.bind(this, viewId , location)); | 480 this._materialize().then(() => this._widget.detach()); |
| 117 }, | 481 }, |
| 118 | 482 |
| 119 /** | 483 _toggleExpanded: function() |
| 120 * @param {string} location | 484 { |
| 121 * @param {boolean=} restoreSelection | 485 if (this._titleElement.classList.contains("expanded")) |
| 122 * @param {boolean=} enableMoreTabsButton | 486 this._collapse(); |
| 123 * @return {!WebInspector.TabbedViewLocation} | 487 else |
| 124 */ | 488 this._expand(); |
| 125 createTabbedLocation: function(location, restoreSelection, enableMoreTabsBut ton) | 489 }, |
| 126 { | 490 |
| 127 return new WebInspector.ViewManager._TabbedLocation(this, location, rest oreSelection, enableMoreTabsButton); | 491 /** |
| 128 }, | 492 * @param {!Event} event |
| 129 | 493 */ |
| 130 /** | 494 _onTitleKeyDown: function(event) |
| 131 * @param {string} viewId | 495 { |
| 132 * @param {string} location | 496 if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut .Keys.Space.code) |
| 133 * @param {!WebInspector.ViewLocationResolver} resolver | 497 this._toggleExpanded(); |
| 134 */ | 498 }, |
| 135 _revealLocation: function(viewId, location, resolver) | 499 |
| 136 { | 500 __proto__: WebInspector.VBox.prototype |
| 137 var viewLocation = resolver.revealLocation(location); | 501 } |
| 138 if (viewLocation) | 502 |
| 139 viewLocation.showView(viewId); | 503 /** |
| 140 }, | 504 * @constructor |
| 141 | 505 * @param {!WebInspector.ViewManager} manager |
| 142 /** | 506 * @param {!WebInspector.Widget} widget |
| 143 * @param {string} location | 507 * @param {function()=} revealCallback |
| 144 * @return {!Array<!Runtime.Extension>} | 508 * @param {string=} location |
| 145 */ | 509 */ |
| 146 _viewsForLocation: function(location) | 510 WebInspector.ViewManager._Location = function(manager, widget, revealCallback, l ocation) |
| 147 { | 511 { |
| 148 return self.runtime.extensions("view").filter(extension => extension.des criptor()["location"] === location); | 512 this._manager = manager; |
| 149 } | 513 this._revealCallback = revealCallback; |
| 150 } | 514 this._location = location; |
| 151 | 515 this._widget = widget; |
| 152 /** | 516 } |
| 153 * @constructor | 517 |
| 518 WebInspector.ViewManager._Location.symbol = Symbol("location"); | |
| 519 | |
| 520 WebInspector.ViewManager._Location.prototype = { | |
| 521 /** | |
| 522 * @return {!WebInspector.Widget} | |
| 523 */ | |
| 524 widget: function() | |
| 525 { | |
| 526 return this._widget; | |
| 527 }, | |
| 528 | |
| 529 reveal: function() | |
| 530 { | |
| 531 if (this._revealCallback) | |
| 532 this._revealCallback(); | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 /** | |
| 537 * @constructor | |
| 538 * @extends {WebInspector.ViewManager._Location} | |
| 154 * @implements {WebInspector.TabbedViewLocation} | 539 * @implements {WebInspector.TabbedViewLocation} |
| 155 * @param {!WebInspector.ViewManager} manager | 540 * @param {!WebInspector.ViewManager} manager |
| 156 * @param {string} location | 541 * @param {function()=} revealCallback |
| 542 * @param {string=} location | |
| 157 * @param {boolean=} restoreSelection | 543 * @param {boolean=} restoreSelection |
| 158 * @param {boolean=} enableMoreTabsButton | 544 */ |
| 159 */ | 545 WebInspector.ViewManager._TabbedLocation = function(manager, revealCallback, loc ation, restoreSelection) |
| 160 WebInspector.ViewManager._TabbedLocation = function(manager, location, restoreSe lection, enableMoreTabsButton) | 546 { |
| 161 { | |
| 162 this._manager = manager; | |
| 163 this._tabbedPane = new WebInspector.TabbedPane(); | 547 this._tabbedPane = new WebInspector.TabbedPane(); |
| 164 this._location = location; | 548 WebInspector.ViewManager._Location.call(this, manager, this._tabbedPane, rev ealCallback, location); |
| 165 /** @type {!Object.<string, !Promise.<?WebInspector.Widget>>} */ | |
| 166 this._promiseForId = {}; | |
| 167 | 549 |
| 168 this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSele cted, this._tabSelected, this); | 550 this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSele cted, this._tabSelected, this); |
| 169 this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClos ed, this._tabClosed, this); | 551 this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClos ed, this._tabClosed, this); |
| 170 this._closeableTabSetting = WebInspector.settings.createSetting(location + " -closeableTabs", {}); | 552 this._closeableTabSetting = WebInspector.settings.createSetting(location + " -closeableTabs", {}); |
| 171 if (restoreSelection) | 553 if (restoreSelection) |
| 172 this._lastSelectedTabSetting = WebInspector.settings.createSetting(locat ion + "-selectedTab", ""); | 554 this._lastSelectedTabSetting = WebInspector.settings.createSetting(locat ion + "-selectedTab", ""); |
| 173 this._initialize(); | 555 |
| 174 if (enableMoreTabsButton) { | 556 /** @type {!Map.<string, !WebInspector.View>} */ |
| 175 var toolbar = new WebInspector.Toolbar("drawer-toolbar"); | 557 this._views = new Map(); |
| 176 toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton(this._appen dTabsToMenu.bind(this))); | 558 this._populateLocation(); |
| 177 this._tabbedPane.insertBeforeTabStrip(toolbar.element); | |
| 178 this._tabbedPane.disableOverflowMenu(); | |
| 179 } | |
| 180 } | 559 } |
| 181 | 560 |
| 182 WebInspector.ViewManager._TabbedLocation.prototype = { | 561 WebInspector.ViewManager._TabbedLocation.prototype = { |
| 183 /** | 562 /** |
| 184 * @override | 563 * @override |
| 185 * @return {!WebInspector.Widget} | 564 * @return {!WebInspector.Widget} |
| 186 */ | 565 */ |
| 187 widget: function() | 566 widget: function() |
| 188 { | 567 { |
| 189 return this._tabbedPane; | 568 return this._tabbedPane; |
| 190 }, | 569 }, |
| 191 | 570 |
| 192 /** | 571 /** |
| 193 * @override | 572 * @override |
| 194 * @return {!WebInspector.TabbedPane} | 573 * @return {!WebInspector.TabbedPane} |
| 195 */ | 574 */ |
| 196 tabbedPane: function() | 575 tabbedPane: function() |
| 197 { | 576 { |
| 198 return this._tabbedPane; | 577 return this._tabbedPane; |
| 199 }, | 578 }, |
| 200 | 579 |
| 201 _initialize: function() | 580 /** |
| 581 * @override | |
| 582 */ | |
| 583 enableMoreTabsButton: function() | |
| 202 { | 584 { |
| 203 /** @type {!Map.<string, !Runtime.Extension>} */ | 585 var toolbar = new WebInspector.Toolbar("drawer-toolbar"); |
| 204 this._extensions = new Map(); | 586 toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton(this._appen dTabsToMenu.bind(this))); |
| 205 var extensions = this._manager._viewsForLocation(this._location); | 587 this._tabbedPane.insertBeforeTabStrip(toolbar.element); |
| 588 this._tabbedPane.disableOverflowMenu(); | |
| 589 }, | |
| 206 | 590 |
| 207 for (var i = 0; i < extensions.length; ++i) { | 591 _populateLocation: function() |
| 208 var id = extensions[i].descriptor()["id"]; | 592 { |
| 209 this._extensions.set(id, extensions[i]); | 593 if (!this._location) |
| 210 if (this._isPermanentTab(id)) | 594 return; |
| 211 this._appendTab(extensions[i]); | 595 for (var view of this._manager._viewsForLocation(this._location)) { |
| 212 else if (this._isCloseableTab(id) && this._closeableTabSetting.get() [id]) | 596 var id = view.viewId(); |
| 213 this._appendTab(extensions[i]); | 597 this._views.set(id, view); |
| 598 view[WebInspector.ViewManager._Location.symbol] = this; | |
| 599 if (view.isTransient()) | |
| 600 continue; | |
| 601 if (!view.isCloseable()) | |
| 602 this._appendTab(view); | |
| 603 else if (this._closeableTabSetting.get()[id]) | |
| 604 this._appendTab(view); | |
| 214 } | 605 } |
| 215 }, | 606 }, |
| 216 | 607 |
| 217 wasShown: function() | 608 wasShown: function() |
| 218 { | 609 { |
| 219 if (this._wasAlreadyShown || !this._lastSelectedTabSetting) | 610 if (this._wasAlreadyShown || !this._lastSelectedTabSetting) |
| 220 return; | 611 return; |
| 221 this._wasAlreadyShown = true; | 612 this._wasAlreadyShown = true; |
| 222 if (this._tabbedPane.hasTab(this._lastSelectedTabSetting.get())) | 613 if (this._tabbedPane.hasTab(this._lastSelectedTabSetting.get())) |
| 223 this._tabbedPane.selectTab(this._lastSelectedTabSetting.get()); | 614 this._tabbedPane.selectTab(this._lastSelectedTabSetting.get()); |
| 224 }, | 615 }, |
| 225 | 616 |
| 226 /** | 617 /** |
| 227 * @param {string} id | |
| 228 * @return {boolean} | |
| 229 */ | |
| 230 _isPermanentTab: function(id) | |
| 231 { | |
| 232 return this._extensions.get(id).descriptor()["persistence"] === "permane nt" || !this._extensions.get(id).descriptor()["persistence"]; | |
| 233 }, | |
| 234 | |
| 235 /** | |
| 236 * @param {string} id | |
| 237 * @return {boolean} | |
| 238 */ | |
| 239 _isCloseableTab: function(id) | |
| 240 { | |
| 241 return this._extensions.get(id).descriptor()["persistence"] === "closeab le"; | |
| 242 }, | |
| 243 | |
| 244 /** | |
| 245 * @param {!WebInspector.ContextMenu} contextMenu | 618 * @param {!WebInspector.ContextMenu} contextMenu |
| 246 */ | 619 */ |
| 247 _appendTabsToMenu: function(contextMenu) | 620 _appendTabsToMenu: function(contextMenu) |
| 248 { | 621 { |
| 249 var extensions = self.runtime.extensions("view", undefined, true); | 622 for (var view of this._views.values()) { |
| 250 for (var extension of extensions) { | 623 var title = WebInspector.UIString(view.title()); |
| 251 if (extension.descriptor()["location"] !== this._location) | 624 contextMenu.appendItem(title, this.showView.bind(this, view)); |
| 252 continue; | |
| 253 var title = WebInspector.UIString(extension.title()); | |
| 254 contextMenu.appendItem(title, this.showView.bind(this, extension.des criptor()["id"])); | |
| 255 } | 625 } |
| 256 }, | 626 }, |
| 257 | 627 |
| 258 /** | 628 /** |
| 259 * @param {!Runtime.Extension} extension | 629 * @param {!WebInspector.View} view |
| 260 */ | 630 */ |
| 261 _appendTab: function(extension) | 631 _appendTab: function(view) |
| 262 { | 632 { |
| 263 var descriptor = extension.descriptor(); | 633 this._tabbedPane.appendTab(view.viewId(), view.title(), new WebInspector .ViewManager._ContainerWidget(view), undefined, false, view.isCloseable() || vie w.isTransient()); |
| 264 var id = descriptor["id"]; | |
| 265 var title = WebInspector.UIString(extension.title()); | |
| 266 var closeable = descriptor["persistence"] === "closeable" || descriptor[ "persistence"] === "temporary"; | |
| 267 this._tabbedPane.appendTab(id, title, new WebInspector.Widget(), undefin ed, false, closeable); | |
| 268 }, | 634 }, |
| 269 | 635 |
| 270 /** | 636 /** |
| 271 * @override | 637 * @override |
| 272 * @param {string} id | 638 * @param {!WebInspector.View} view |
| 639 * @param {?WebInspector.View=} insertBefore | |
| 273 */ | 640 */ |
| 274 showView: function(id) | 641 appendView: function(view, insertBefore) |
| 275 { | 642 { |
| 276 if (!this._tabbedPane.hasTab(id)) | 643 if (insertBefore) |
| 277 this._appendTab(/** @type {!Runtime.Extension} */(this._extensions.g et(id))); | 644 throw new Error("Insert before in tabbed pane is not supported"); |
| 278 this._tabbedPane.focus(); | 645 if (!this._tabbedPane.hasTab(view.viewId())) { |
| 279 this._tabbedPane.selectTab(id); | 646 view[WebInspector.ViewManager._Location.symbol] = this; |
| 647 this._views.set(view.viewId(), view); | |
| 648 this._appendTab(view); | |
| 649 } | |
| 280 }, | 650 }, |
| 281 | 651 |
| 282 /** | 652 /** |
| 653 * @override | |
| 654 * @param {!WebInspector.View} view | |
| 655 * @param {?WebInspector.View=} insertBefore | |
| 656 * @return {!Promise} | |
| 657 */ | |
| 658 showView: function(view, insertBefore) | |
| 659 { | |
| 660 this.appendView(view, insertBefore); | |
| 661 this._tabbedPane.focus(); | |
| 662 this._tabbedPane.selectTab(view.viewId()); | |
| 663 return this._materializeWidget(view); | |
| 664 }, | |
| 665 | |
| 666 /** | |
| 283 * @param {!WebInspector.Event} event | 667 * @param {!WebInspector.Event} event |
| 284 */ | 668 */ |
| 285 _tabSelected: function(event) | 669 _tabSelected: function(event) |
| 286 { | 670 { |
| 287 var tabId = /** @type {string} */ (event.data.tabId); | 671 var tabId = /** @type {string} */ (event.data.tabId); |
| 288 if (this._lastSelectedTabSetting && event.data["isUserGesture"]) | 672 if (this._lastSelectedTabSetting && event.data["isUserGesture"]) |
| 289 this._lastSelectedTabSetting.set(tabId); | 673 this._lastSelectedTabSetting.set(tabId); |
| 290 if (!this._extensions.has(tabId)) | 674 var view = this._views.get(tabId); |
| 675 if (!view) | |
| 291 return; | 676 return; |
| 292 | 677 |
| 293 this._viewForId(tabId); | 678 this._materializeWidget(view); |
| 294 | 679 |
| 295 var descriptor = this._extensions.get(tabId).descriptor(); | 680 if (view.isCloseable()) { |
| 296 if (descriptor["persistence"] === "closeable") { | |
| 297 var tabs = this._closeableTabSetting.get(); | 681 var tabs = this._closeableTabSetting.get(); |
| 298 if (!tabs[tabId]) { | 682 if (!tabs[tabId]) { |
| 299 tabs[tabId] = true; | 683 tabs[tabId] = true; |
| 300 this._closeableTabSetting.set(tabs); | 684 this._closeableTabSetting.set(tabs); |
| 301 } | 685 } |
| 302 } | 686 } |
| 303 }, | 687 }, |
| 304 | 688 |
| 305 /** | 689 /** |
| 306 * @param {!WebInspector.Event} event | 690 * @param {!WebInspector.Event} event |
| 307 */ | 691 */ |
| 308 _tabClosed: function(event) | 692 _tabClosed: function(event) |
| 309 { | 693 { |
| 310 var id = /** @type {string} */ (event.data["tabId"]); | 694 var id = /** @type {string} */ (event.data["tabId"]); |
| 311 var tabs = this._closeableTabSetting.get(); | 695 var tabs = this._closeableTabSetting.get(); |
| 312 if (tabs[id]) { | 696 if (tabs[id]) { |
| 313 delete tabs[id]; | 697 delete tabs[id]; |
| 314 this._closeableTabSetting.set(tabs); | 698 this._closeableTabSetting.set(tabs); |
| 315 } | 699 } |
| 316 delete this._promiseForId[id]; | |
| 317 }, | 700 }, |
| 318 | 701 |
| 319 /** | 702 /** |
| 320 * @param {string} id | 703 * @param {!WebInspector.View} view |
| 321 * @return {!Promise.<?WebInspector.Widget>} | 704 * @return {!Promise} |
| 322 */ | 705 */ |
| 323 _viewForId: function(id) | 706 _materializeWidget: function(view) |
| 324 { | 707 { |
| 325 if (this._promiseForId[id]) | 708 var widget = /** @type {!WebInspector.ViewManager._ContainerWidget} */ ( this._tabbedPane.tabView(view.viewId())); |
| 326 return this._promiseForId[id]; | 709 return widget._materialize(); |
| 710 }, | |
| 327 | 711 |
| 328 var promise = this._extensions.get(id).instance(); | 712 __proto__: WebInspector.ViewManager._Location.prototype |
| 329 this._promiseForId[id] = /** @type {!Promise.<?WebInspector.Widget>} */ (promise); | |
| 330 return promise.then(cacheView.bind(this)); | |
| 331 | |
| 332 /** | |
| 333 * @param {!Object} object | |
| 334 * @this {WebInspector.ViewManager._TabbedLocation} | |
| 335 */ | |
| 336 function cacheView(object) | |
| 337 { | |
| 338 var view = /** @type {!WebInspector.Widget} */ (object); | |
| 339 this._tabbedPane.changeTabView(id, view); | |
| 340 return view; | |
| 341 } | |
| 342 } | |
| 343 } | 713 } |
| 344 | 714 |
| 345 WebInspector.viewManager = new WebInspector.ViewManager(); | 715 /** |
| 716 * @constructor | |
| 717 * @extends {WebInspector.ViewManager._Location} | |
| 718 * @implements {WebInspector.ViewLocation} | |
| 719 * @param {!WebInspector.ViewManager} manager | |
| 720 * @param {function()=} revealCallback | |
| 721 * @param {string=} location | |
| 722 */ | |
| 723 WebInspector.ViewManager._StackLocation = function(manager, revealCallback, loca tion) | |
| 724 { | |
| 725 this._vbox = new WebInspector.VBox(); | |
| 726 WebInspector.ViewManager._Location.call(this, manager, this._vbox, revealCal lback, location); | |
| 727 | |
| 728 /** @type {!Map<string, !WebInspector.ViewManager._ExpandableContainerWidget >} */ | |
| 729 this._expandableContainers = new Map(); | |
| 730 this._populateLocation(); | |
| 731 } | |
| 732 | |
| 733 WebInspector.ViewManager._StackLocation.prototype = { | |
| 734 | |
| 735 /** | |
| 736 * @override | |
| 737 * @param {!WebInspector.View} view | |
| 738 * @param {?WebInspector.View=} insertBefore | |
| 739 */ | |
| 740 appendView: function(view, insertBefore) | |
| 741 { | |
| 742 var container = this._expandableContainers.get(view.viewId()); | |
| 743 if (!container) { | |
| 744 view[WebInspector.ViewManager._Location.symbol] = this; | |
| 745 container = new WebInspector.ViewManager._ExpandableContainerWidget( view); | |
| 746 var beforeElement = null; | |
| 747 if (insertBefore) { | |
| 748 var beforeContainer = insertBefore[WebInspector.ViewManager._Exp andableContainerWidget._symbol]; | |
| 749 beforeElement = beforeContainer ? beforeContainer.element : null ; | |
| 750 } | |
| 751 container.show(this._vbox.contentElement, beforeElement); | |
| 752 this._expandableContainers.set(view.viewId(), container); | |
| 753 } | |
| 754 }, | |
| 755 | |
| 756 /** | |
| 757 * @override | |
| 758 * @param {!WebInspector.View} view | |
| 759 * @param {?WebInspector.View=} insertBefore | |
| 760 * @return {!Promise} | |
| 761 */ | |
| 762 showView: function(view, insertBefore) | |
| 763 { | |
| 764 this.appendView(view, insertBefore); | |
| 765 var container = this._expandableContainers.get(view.viewId()); | |
| 766 return container._expand(); | |
| 767 }, | |
| 768 | |
| 769 _populateLocation: function() | |
| 770 { | |
| 771 if (!this._location) | |
| 772 return; | |
| 773 for (var view of this._manager._viewsForLocation(this._location)) | |
| 774 this.appendView(view); | |
| 775 }, | |
| 776 | |
| 777 __proto__: WebInspector.ViewManager._Location.prototype | |
| 778 } | |
| 779 | |
| 780 /** | |
| 781 * @type {!WebInspector.ViewManager} | |
| 782 */ | |
| 783 WebInspector.viewManager; | |
| OLD | NEW |