OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 Resources.FrameMenu = class extends Common.Object { | |
6 constructor() { | |
7 super(); | |
8 this._button = createElement('button'); | |
9 this._button.className = 'frame-selector'; | |
10 this._button.appendChild(UI.Icon.create('largeicon-navigator-frame')); | |
11 this._nameLabel = this._button.createChild('span', 'frame-name'); | |
12 this._button.appendChild(UI.Icon.create('smallicon-triangle-down')); | |
13 | |
14 this._button.addEventListener('click', () => this._showPopup()); | |
15 | |
16 /** @type {?SDK.ResourceTreeFrame} */ | |
17 this._selectedFrame = null; | |
18 | |
19 this.selectFrame(null); | |
20 } | |
21 | |
22 /** | |
23 * @param {number} depth | |
24 * @param {?string} parentId | |
25 * @param {!Map<?string, !Array<!SDK.ResourceTreeFrame>>} framesTree | |
26 * @param {!Array<!Resources.FrameMenu._ListItem>} array | |
27 * @return {!Array<!Resources.FrameMenu._ListItem>} | |
dgozman
2017/04/05 20:52:56
Let's not return since this function actually popu
eostroukhov
2017/05/03 00:33:47
Done.
| |
28 */ | |
29 static _flatten(depth, parentId, framesTree, array) { | |
30 var frames = framesTree.get(parentId); | |
dgozman
2017/04/05 20:52:56
Looks like you call this with |null| parentId firs
eostroukhov
2017/05/03 00:33:46
Not sure I understand. Can you elaborate?
| |
31 if (!frames) | |
32 return array; | |
33 for (var frame of frames) { | |
34 array.push(new Resources.FrameMenu._ListItem(frame, depth)); | |
35 Resources.FrameMenu._flatten(depth + 1, frame.id, framesTree, array); | |
36 } | |
37 return array; | |
38 } | |
39 | |
40 /** | |
41 * @param {?SDK.Target} target | |
42 * @param {!Map<?string, !Array<!SDK.ResourceTreeFrame>>} framesTree | |
dgozman
2017/04/05 20:52:56
Why frame id is nullable? I don't see where you us
eostroukhov
2017/05/03 00:33:47
It is for frames with null parent, e.g. for the ro
| |
43 * @param {!Set<!SDK.Target>} visitedTargets | |
44 * @return {?string} main frame ID | |
45 */ | |
46 static _collectFrames(target, framesTree, visitedTargets) { | |
47 if (!target) | |
48 return null; | |
49 var model = target.model(SDK.ResourceTreeModel); | |
50 if (!model || !model.mainFrame) | |
51 return null; | |
52 if (visitedTargets.has(target)) | |
53 return model.mainFrame.id; | |
54 visitedTargets.add(target); | |
55 var parentId = Resources.FrameMenu._collectFrames(target.parentTarget(), fra mesTree, visitedTargets); | |
56 framesTree.get(parentId).push(model.mainFrame); | |
57 Resources.FrameMenu._addChildFrames(model.mainFrame, framesTree); | |
58 return model.mainFrame.id; | |
59 } | |
60 | |
61 /** | |
62 * @param {!SDK.ResourceTreeFrame} frame | |
63 * @param {!Map<?string, !Array<!SDK.ResourceTreeFrame>>} framesTree | |
64 */ | |
65 static _addChildFrames(frame, framesTree) { | |
66 framesTree.set(frame.id, frame.childFrames); | |
67 for (var childFrame of frame.childFrames) | |
68 Resources.FrameMenu._addChildFrames(childFrame, framesTree); | |
69 } | |
70 | |
71 /** | |
72 * @returns {!Element} | |
73 */ | |
74 get element() { | |
dgozman
2017/04/05 20:52:56
No getters.
eostroukhov
2017/05/03 00:33:46
Done.
| |
75 return this._button; | |
76 } | |
77 | |
78 /** | |
79 * @return {?SDK.ResourceTreeFrame} frame | |
80 */ | |
81 selectedFrame() { | |
82 return this._selectedFrame; | |
83 } | |
84 | |
85 selectRootFrame() { | |
86 var target = SDK.targetManager.mainTarget(); | |
87 var model = target && target.model(SDK.ResourceTreeModel); | |
88 var frame = model && model.mainFrame; | |
89 this.selectFrame(frame); | |
90 } | |
91 | |
92 _showPopup() { | |
93 /** @type {!Map<?string, !Array<!SDK.ResourceTreeFrame>>} */ | |
94 var framesTree = new Map(); | |
95 framesTree.set(null, []); | |
96 /** @type {!Set<!SDK.Target>} */ | |
97 var visitedTargets = new Set(); | |
98 for (var target of SDK.targetManager.targets()) | |
99 Resources.FrameMenu._collectFrames(target, framesTree, visitedTargets); | |
100 | |
101 var items = Resources.FrameMenu._flatten(0, null, framesTree, []); | |
102 var provider = new Resources.FrameMenu._ListProvider(this, items); | |
103 var list = new QuickOpen.FilteredListWidget(provider); | |
104 var selectedItem = null; | |
105 if (this._selectedFrame) { | |
106 for (var i = 0; i < items.length; i++) { | |
107 if (items[i].frame === this._selectedFrame) { | |
108 selectedItem = i; | |
109 break; | |
110 } | |
111 } | |
112 } | |
113 if (selectedItem !== null) | |
114 list.selectItem(selectedItem); | |
115 list.setInputIcon('mediumicon-search'); | |
116 var anchorBox = this._button.firstElementChild.boxInWindow(); | |
117 list.showAsDialog(anchorBox, UI.GlassPane.AnchorBehavior.PreferBottom); | |
118 } | |
119 | |
120 reset() { | |
dgozman
2017/04/05 20:52:56
Inline this one.
eostroukhov
2017/05/03 00:33:46
It was not used anywhere anyways :)
| |
121 this.selectFrame(null); | |
122 } | |
123 | |
124 /** | |
125 * @param {?SDK.ResourceTreeFrame} frame | |
126 */ | |
127 selectFrame(frame) { | |
128 this._selectedFrame = frame; | |
129 | |
130 var displayName = frame ? frame.displayName() : ''; | |
131 var frameName = frame ? frame.name : ''; | |
132 | |
133 this._nameLabel.textContent = frameName || displayName; | |
134 this._button.title = displayName; | |
135 } | |
136 }; | |
137 | |
138 Resources.FrameMenu._ListItem = class { | |
139 /** | |
140 * @param {!SDK.ResourceTreeFrame} frame | |
141 * @param {number} depth | |
142 */ | |
143 constructor(frame, depth) { | |
144 this.frame = frame; | |
145 this.depth = depth; | |
146 } | |
147 }; | |
148 | |
149 Resources.FrameMenu._ListProvider = class extends QuickOpen.FilteredListWidget.P rovider { | |
dgozman
2017/04/05 20:52:56
Why not merge with FrameMenu itself?
eostroukhov
2017/05/03 00:33:47
I felt like it was more natural as it ties frames
| |
150 /** | |
151 * @param {!Resources.FrameMenu} menu | |
152 * @param {!Array<!Resources.FrameMenu._ListItem>} items | |
153 */ | |
154 constructor(menu, items) { | |
155 super(); | |
156 this._menu = menu; | |
157 this._items = items; | |
158 } | |
159 | |
160 /** | |
161 * @override | |
162 * @return {number} | |
163 */ | |
164 itemCount() { | |
165 return this._items.length; | |
166 } | |
167 | |
168 /** | |
169 * @override | |
170 * @param {number} itemIndex | |
171 * @return {string} | |
172 */ | |
173 itemKeyAt(itemIndex) { | |
174 var frame = this._items[itemIndex].frame; | |
175 return frame.displayName() + frame.securityOrigin; | |
176 } | |
177 | |
178 /** | |
179 * @override | |
180 * @param {?number} itemIndex | |
181 */ | |
182 hoverItem(itemIndex) { | |
183 SDK.DOMModel.hideDOMNodeHighlight(); | |
184 if (itemIndex === null) | |
185 return; | |
186 var frame = this._items[itemIndex].frame; | |
187 var domModel = frame && frame.target().model(SDK.DOMModel); | |
dgozman
2017/04/05 20:52:56
How there could be no frame?
eostroukhov
2017/05/03 00:33:46
Done.
| |
188 if (!domModel) | |
189 return; | |
190 domModel.highlightFrame(frame.id); | |
191 } | |
192 | |
193 /** | |
194 * @override | |
195 * @param {number} itemIndex | |
196 * @param {string} query | |
197 * @param {!Element} titleElement | |
198 * @param {!Element} subtitleElement | |
199 */ | |
200 renderItem(itemIndex, query, titleElement, subtitleElement) { | |
201 var frame = this._items[itemIndex].frame; | |
202 var indent = query ? 0 : (this._items[itemIndex].depth * 16); | |
203 var padding = 24 + indent + 'px'; | |
204 titleElement.textContent = frame.displayName(); | |
205 subtitleElement.textContent = frame.securityOrigin; | |
206 titleElement.style.paddingLeft = padding; | |
207 subtitleElement.style.paddingLeft = padding; | |
208 QuickOpen.FilteredListWidget.highlightRanges(titleElement, query, true); | |
209 QuickOpen.FilteredListWidget.highlightRanges(subtitleElement, query, true); | |
210 } | |
211 | |
212 /** | |
213 * @override | |
214 * @param {?number} itemIndex | |
215 * @param {string} promptValue | |
216 */ | |
217 selectItem(itemIndex, promptValue) { | |
218 if (itemIndex === null) | |
219 return; | |
220 var frame = this._items[itemIndex].frame; | |
221 this._menu.selectFrame(frame); | |
222 this._menu.dispatchEventToListeners(Resources.FrameMenu.Events.FrameSelected , frame); | |
223 } | |
224 | |
225 /** | |
226 * @override | |
227 * @return {boolean} | |
228 */ | |
229 renderAsTwoRows() { | |
230 return true; | |
231 } | |
232 }; | |
233 | |
234 /** | |
235 * @enum {symbol} | |
236 */ | |
237 Resources.FrameMenu.Events = { | |
238 FrameSelected: Symbol('FrameSelected') | |
239 }; | |
OLD | NEW |