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

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: for landing 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() { }
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;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698