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