blob: dfe0d55a1906aadd5e8d027956263235c7c24fe5 [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel='import' href='/base/polymer_utils.html'>
9<link rel="import" href="/base/range.html">
10<link rel="import" href="/core/side_panel/side_panel.html">
11
12<polymer-element name='tv-c-side-panel-container' is='HTMLUnknownElement'>
13 <template>
14 <style>
15 :host {
16 align-items: stretch;
17 display: -webkit-flex;
18 }
19
Chris Craikbeca7ae2015-04-07 13:29:55 -070020 :host([expanded]) > active-panel-container {
Chris Craikb122baf2015-03-05 13:58:42 -080021 -webkit-flex: 1 1 auto;
22 border-left: 1px solid black;
23 display: -webkit-flex;
24 }
25
Chris Craikbeca7ae2015-04-07 13:29:55 -070026 :host(:not([expanded])) > active-panel-container {
Chris Craikb122baf2015-03-05 13:58:42 -080027 display: none;
28 }
29
Chris Craik19832152015-04-16 15:43:38 -070030 active-panel-container {
31 display: flex;
32 }
33
Chris Craikb122baf2015-03-05 13:58:42 -080034 tab-strip {
35 -webkit-flex: 0 0 auto;
36 -webkit-flex-direction: column;
37 -webkit-user-select: none;
38 background-color: rgb(236, 236, 236);
39 border-left: 1px solid black;
40 cursor: default;
41 display: -webkit-flex;
42 min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
43 padding: 10px 0 10px 0;
44 font-size: 12px;
45 }
46
47 tab-strip > tab-strip-label {
48 -webkit-writing-mode: vertical-rl;
49 display: inline;
50 margin-right: 1px;
51 min-height: 20px;
52 padding: 15px 3px 15px 1px;
53 }
54
55 tab-strip >
56 tab-strip-label:not([enabled]) {
57 color: rgb(128, 128, 128);
58 }
59
60 tab-strip > tab-strip-label[selected] {
61 background-color: white;
62 border: 1px solid rgb(163, 163, 163);
63 border-left: none;
64 padding: 14px 2px 14px 1px;
65 }
66 </style>
67
68 <active-panel-container id='active_panel_container'>
69 </active-panel-container>
70 <tab-strip id='tab_strip'></tab-strip>
71 </template>
72
73 <script>
74 'use strict';
75 Polymer({
76 ready: function() {
77 this.activePanelContainer_ = this.$.active_panel_container;
78 this.tabStrip_ = this.$.tab_strip;
79
Chris Craikb122baf2015-03-05 13:58:42 -080080 this.rangeOfInterest_ = new tv.b.Range();
Chris Craik44c28202015-05-12 17:25:16 -070081 this.selectionController_ = undefined;
82 this.onSelectionChanged_ = this.onSelectionChanged_.bind(this);
83 this.onModelChanged_ = this.onModelChanged_.bind(this);
84 },
85
86 get selectionController() {
87 return this.selectionController_;
88 },
89
90 set selectionController(selectionController) {
91 if (this.selectionController) {
92 this.selectionController_.removeEventListener(
93 'change', this.onSelectionChanged_);
94 this.selectionController_.removeEventListener(
95 'model-changed', this.onModelChanged_);
96 }
97 this.selectionController_ = selectionController;
98 if (this.selectionController) {
99 this.selectionController_.addEventListener(
100 'change', this.onSelectionChanged_);
101 this.selectionController_.addEventListener(
102 'model-changed', this.onModelChanged_);
103 }
104 },
105
106 get selection() {
107 return this.selectionController_.selection;
108 },
109
110 onSelectionChanged_: function() {
111 if (this.activePanel)
112 this.activePanel.selection = this.selection;
Chris Craikb122baf2015-03-05 13:58:42 -0800113 },
114
115 get model() {
Chris Craik44c28202015-05-12 17:25:16 -0700116 return this.selectionController_.model;
Chris Craikb122baf2015-03-05 13:58:42 -0800117 },
118
Chris Craik44c28202015-05-12 17:25:16 -0700119 onModelChanged_: function() {
Chris Craikb122baf2015-03-05 13:58:42 -0800120 this.activePanelType_ = undefined;
121 this.updateContents_();
122 },
123
124 get expanded() {
125 this.hasAttribute('expanded');
126 },
127
128 get activePanel() {
129 if (this.activePanelContainer_.children.length === 0)
130 return undefined;
131 return this.activePanelContainer_.children[0];
132 },
133
134 get activePanelType() {
135 return this.activePanelType_;
136 },
137
138 set activePanelType(panelType) {
Chris Craik44c28202015-05-12 17:25:16 -0700139 if (this.model === undefined)
Chris Craikb122baf2015-03-05 13:58:42 -0800140 throw new Error('Cannot activate panel without a model');
141
142 var panel = undefined;
143 if (panelType)
144 panel = document.createElement(panelType);
145
Chris Craik44c28202015-05-12 17:25:16 -0700146 if (panel !== undefined && !panel.supportsModel(this.model))
Chris Craikb122baf2015-03-05 13:58:42 -0800147 throw new Error('Cannot activate panel: does not support this model');
148
149 if (this.activePanelType) {
150 this.getLabelElementForPanelType_(
151 this.activePanelType).removeAttribute('selected');
152 }
153 this.activePanelContainer_.textContent = '';
154
155 if (panelType === undefined) {
156 this.removeAttribute('expanded');
157 this.activePanelType_ = undefined;
158 return;
159 }
160
161 this.getLabelElementForPanelType_(panelType).
162 setAttribute('selected', true);
163 this.setAttribute('expanded', true);
164
165 this.activePanelContainer_.appendChild(panel);
166 panel.rangeOfInterest = this.rangeOfInterest_;
167 panel.selection = this.selection_;
Chris Craik44c28202015-05-12 17:25:16 -0700168 panel.model = this.model;
Chris Craikb122baf2015-03-05 13:58:42 -0800169
170 this.activePanelType_ = panelType;
171 },
172
173 getPanelTypeForConstructor_: function(constructor) {
174 for (var i = 0; i < this.tabStrip_.children.length; i++) {
175 if (this.tabStrip_.children[i].panelType.constructor == constructor)
176 return this.tabStrip_.children[i].panelType;
177 }
178 },
179
180 getLabelElementForPanelType_: function(panelType) {
181 for (var i = 0; i < this.tabStrip_.children.length; i++) {
182 if (this.tabStrip_.children[i].panelType == panelType)
183 return this.tabStrip_.children[i];
184 }
185 return undefined;
186 },
187
188 updateContents_: function() {
189 var previouslyActivePanelType = this.activePanelType;
190
191 this.tabStrip_.textContent = '';
192 var supportedPanelTypes = [];
193
194 var panelTypes = tv.b.getPolymerElementsThatSubclass('tv-c-side-panel');
195 panelTypes.forEach(function(panelType) {
196 var labelEl = document.createElement('tab-strip-label');
197 var panel = document.createElement(panelType);
198
199 labelEl.textContent = panel.textLabel;
200 labelEl.panelType = panelType;
201
Chris Craik44c28202015-05-12 17:25:16 -0700202 var supported = panel.supportsModel(this.model);
203 if (this.model && supported.supported) {
Chris Craikb122baf2015-03-05 13:58:42 -0800204 supportedPanelTypes.push(panelType);
205 labelEl.setAttribute('enabled', true);
206 labelEl.addEventListener('click', function() {
207 this.activePanelType =
208 this.activePanelType === panelType ? undefined : panelType;
209 }.bind(this));
210 } else {
211 labelEl.title = 'Not supported for the current trace: ' +
212 supported.reason;
Chris Craik19832152015-04-16 15:43:38 -0700213 labelEl.style.display = 'none';
Chris Craikb122baf2015-03-05 13:58:42 -0800214 }
215 this.tabStrip_.appendChild(labelEl);
216 }, this);
217
218 // Restore the active panel, or collapse
219 if (previouslyActivePanelType &&
220 supportedPanelTypes.indexOf(previouslyActivePanelType) != -1) {
221 this.activePanelType = previouslyActivePanelType;
222 this.setAttribute('expanded', true);
223 } else {
224 this.activePanelContainer_.textContent = '';
225 this.removeAttribute('expanded');
226 }
227 },
228
Chris Craikb122baf2015-03-05 13:58:42 -0800229 get rangeOfInterest() {
230 return this.rangeOfInterest_;
231 },
232
233 set rangeOfInterest(range) {
234 if (range == undefined)
235 throw new Error('Must not be undefined');
236 this.rangeOfInterest_ = range;
237 if (this.activePanel)
238 this.activePanel.rangeOfInterest = range;
239 }
240 });
241 </script>
242</polymer-element>
243