Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(919)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui/View.js

Issue 2217783002: DevTools: use view locations in the elements and sources sidebars. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ready for review Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698