Chromium Code Reviews| 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.ResourcesSection = class { | |
| 6 /** | |
| 7 * @param {!Resources.ResourcesPanel} storagePanel | |
| 8 * @param {!UI.TreeElement} treeElement | |
| 9 */ | |
| 10 constructor(storagePanel, treeElement) { | |
| 11 this._panel = storagePanel; | |
| 12 this._treeElement = treeElement; | |
| 13 /** @type {!Map<string, !Resources.FrameTreeElement>} */ | |
| 14 this._treeElementForFrameId = new Map(); | |
| 15 | |
| 16 function addListener(eventType, handler, target) { | |
| 17 SDK.targetManager.addModelListener(SDK.ResourceTreeModel, eventType, event => handler.call(target, event.data)); | |
| 18 } | |
| 19 addListener(SDK.ResourceTreeModel.Events.FrameAdded, this.frameAdded, this); | |
|
caseq
2017/03/03 21:59:54
let's keep listeners private.
eostroukhov
2017/03/04 00:16:36
Done.
| |
| 20 addListener(SDK.ResourceTreeModel.Events.FrameNavigated, this.frameNavigated , this); | |
| 21 addListener(SDK.ResourceTreeModel.Events.FrameDetached, this.frameDetached, this); | |
| 22 addListener(SDK.ResourceTreeModel.Events.ResourceAdded, this.resourceAdded, this); | |
| 23 | |
| 24 var mainTarget = SDK.targetManager.mainTarget(); | |
| 25 var resourceTreeModel = mainTarget && mainTarget.hasDOMCapability() && SDK.R esourceTreeModel.fromTarget(mainTarget); | |
| 26 var mainFrame = resourceTreeModel && resourceTreeModel.mainFrame; | |
| 27 if (mainFrame) | |
| 28 this.populateFrame(mainFrame); | |
|
dgozman
2017/02/25 00:54:42
Why populate with main frame?
eostroukhov
2017/02/25 01:00:22
It is the root node.
| |
| 29 } | |
| 30 | |
| 31 /** | |
| 32 * @param {!SDK.ResourceTreeFrame} frame | |
| 33 * @returns {?SDK.ResourceTreeFrame} | |
| 34 */ | |
| 35 static _getParentFrame(frame) { | |
| 36 var parentFrame = frame.parentFrame; | |
| 37 if (parentFrame) | |
| 38 return parentFrame; | |
| 39 var parentTarget = frame.target().parentTarget(); | |
| 40 while (parentTarget && !parentTarget.hasDOMCapability()) | |
|
caseq
2017/03/03 21:59:54
Does it ever happen?
eostroukhov
2017/03/04 00:16:36
Changed to console.assert, as per offline discussi
| |
| 41 parentTarget = parentTarget.parentTarget(); | |
| 42 if (!parentTarget) | |
| 43 return null; | |
| 44 var model = SDK.ResourceTreeModel.fromTarget(parentTarget); | |
| 45 return model.mainFrame; | |
| 46 } | |
| 47 | |
| 48 /** | |
| 49 * @param {!SDK.ResourceTreeFrame} frame | |
| 50 */ | |
| 51 frameAdded(frame) { | |
| 52 var parentFrame = Resources.ResourcesSection._getParentFrame(frame); | |
| 53 var parentTreeElement = parentFrame ? this._treeElementForFrameId.get(parent Frame.id) : this._treeElement; | |
| 54 if (!parentTreeElement) { | |
| 55 console.warn('No frame to route ' + frame.url + ' to.'); | |
|
caseq
2017/03/03 21:59:54
nit: `No frame to route ${frame.url} to.`
eostroukhov
2017/03/04 00:16:36
Done.
| |
| 56 return; | |
| 57 } | |
| 58 | |
| 59 var frameTreeElement = new Resources.FrameTreeElement(this._panel, frame); | |
| 60 this._treeElementForFrameId.set(frame.id, frameTreeElement); | |
| 61 parentTreeElement.appendChild(frameTreeElement); | |
| 62 } | |
| 63 | |
| 64 /** | |
| 65 * @param {!SDK.ResourceTreeFrame} frame | |
| 66 */ | |
| 67 frameDetached(frame) { | |
| 68 var frameTreeElement = this._treeElementForFrameId.get(frame.id); | |
| 69 if (!frameTreeElement) | |
| 70 return; | |
| 71 | |
| 72 this._treeElementForFrameId.remove(frame.id); | |
| 73 if (frameTreeElement.parent) | |
| 74 frameTreeElement.parent.removeChild(frameTreeElement); | |
| 75 } | |
| 76 | |
| 77 /** | |
| 78 * @param {!SDK.ResourceTreeFrame} frame | |
| 79 */ | |
| 80 frameNavigated(frame) { | |
| 81 if (!Resources.ResourcesSection._getParentFrame(frame)) | |
| 82 return; | |
| 83 var frameTreeElement = this._treeElementForFrameId.get(frame.id); | |
| 84 if (frameTreeElement) | |
| 85 frameTreeElement.frameNavigated(frame); | |
| 86 } | |
| 87 | |
| 88 /** | |
| 89 * @param {!SDK.Resource} resource | |
| 90 */ | |
| 91 resourceAdded(resource) { | |
| 92 var statusCode = resource['statusCode']; | |
| 93 if (statusCode >= 301 && statusCode <= 303) | |
| 94 return; | |
| 95 | |
| 96 var frameTreeElement = this._treeElementForFrameId.get(resource.frameId); | |
| 97 if (!frameTreeElement) { | |
| 98 // This is a frame's main resource, it will be retained | |
| 99 // and re-added by the resource manager; | |
| 100 return; | |
| 101 } | |
| 102 | |
| 103 frameTreeElement.appendResource(resource); | |
| 104 } | |
| 105 | |
| 106 reset() { | |
| 107 this._treeElement.removeChildren(); | |
| 108 this._treeElementForFrameId.clear(); | |
| 109 } | |
| 110 | |
| 111 /** | |
| 112 * @param {!SDK.ResourceTreeFrame} frame | |
| 113 */ | |
| 114 populateFrame(frame) { | |
| 115 this.frameAdded(frame); | |
| 116 for (var child of frame.childFrames) | |
| 117 this.populateFrame(child); | |
| 118 for (var resource of frame.resources()) | |
| 119 this.resourceAdded(resource); | |
| 120 } | |
| 121 }; | |
| 122 | |
| 123 Resources.FrameTreeElement = class extends Resources.BaseStorageTreeElement { | |
|
dgozman
2017/02/25 00:54:42
Didn't we agree on the frame picker? Why is there
eostroukhov
2017/02/25 01:00:22
This is a refactoring change, functionality remain
caseq
2017/03/03 21:59:55
Mind re-uploading with --similarity=<something-sma
eostroukhov
2017/03/04 00:16:36
I tried that.
| |
| 124 /** | |
| 125 * @param {!Resources.ResourcesPanel} storagePanel | |
| 126 * @param {!SDK.ResourceTreeFrame} frame | |
| 127 */ | |
| 128 constructor(storagePanel, frame) { | |
| 129 super(storagePanel, '', false); | |
| 130 this._panel = storagePanel; | |
| 131 this._frame = frame; | |
| 132 this._frameId = frame.id; | |
| 133 this._categoryElements = {}; | |
| 134 this._treeElementForResource = {}; | |
| 135 this.frameNavigated(frame); | |
| 136 | |
| 137 var icon = UI.Icon.create('largeicon-navigator-frame', 'navigator-tree-item' ); | |
| 138 icon.classList.add('navigator-frame-tree-item'); | |
| 139 this.setLeadingIcons([icon]); | |
| 140 } | |
| 141 | |
| 142 frameNavigated(frame) { | |
| 143 this.removeChildren(); | |
| 144 this._frameId = frame.id; | |
| 145 this.title = frame.displayName(); | |
| 146 this._categoryElements = {}; | |
| 147 this._treeElementForResource = {}; | |
| 148 } | |
| 149 | |
| 150 get itemURL() { | |
| 151 return 'frame://' + encodeURI(this.titleAsText()); | |
| 152 } | |
| 153 | |
| 154 /** | |
| 155 * @override | |
| 156 * @return {boolean} | |
| 157 */ | |
| 158 onselect(selectedByUser) { | |
| 159 super.onselect(selectedByUser); | |
| 160 this._panel.showCategoryView(this.titleAsText()); | |
| 161 | |
| 162 this.listItemElement.classList.remove('hovered'); | |
| 163 SDK.DOMModel.hideDOMNodeHighlight(); | |
| 164 return false; | |
| 165 } | |
| 166 | |
| 167 set hovered(hovered) { | |
| 168 if (hovered) { | |
| 169 this.listItemElement.classList.add('hovered'); | |
| 170 var domModel = SDK.DOMModel.fromTarget(this._frame.target()); | |
| 171 if (domModel) | |
| 172 domModel.highlightFrame(this._frameId); | |
| 173 } else { | |
| 174 this.listItemElement.classList.remove('hovered'); | |
| 175 SDK.DOMModel.hideDOMNodeHighlight(); | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 /** | |
| 180 * @param {!SDK.Resource} resource | |
| 181 */ | |
| 182 appendResource(resource) { | |
| 183 var resourceType = resource.resourceType(); | |
| 184 var categoryName = resourceType.name(); | |
| 185 var categoryElement = resourceType === Common.resourceTypes.Document ? this : this._categoryElements[categoryName]; | |
| 186 if (!categoryElement) { | |
| 187 categoryElement = | |
| 188 new Resources.StorageCategoryTreeElement(this._panel, resource.resourc eType().category().title, categoryName); | |
| 189 this._categoryElements[resourceType.name()] = categoryElement; | |
| 190 this._insertInPresentationOrder(this, categoryElement); | |
| 191 } | |
| 192 var resourceTreeElement = new Resources.FrameResourceTreeElement(this._panel , resource); | |
| 193 this._insertInPresentationOrder(categoryElement, resourceTreeElement); | |
| 194 this._treeElementForResource[resource.url] = resourceTreeElement; | |
| 195 } | |
| 196 | |
| 197 /** | |
| 198 * @param {string} url | |
| 199 * @return {?SDK.Resource} | |
| 200 */ | |
| 201 resourceByURL(url) { | |
| 202 var treeElement = this._treeElementForResource[url]; | |
| 203 return treeElement ? treeElement._resource : null; | |
| 204 } | |
| 205 | |
| 206 /** | |
| 207 * @override | |
| 208 */ | |
| 209 appendChild(treeElement) { | |
| 210 this._insertInPresentationOrder(this, treeElement); | |
| 211 } | |
| 212 | |
| 213 _insertInPresentationOrder(parentTreeElement, childTreeElement) { | |
| 214 // Insert in the alphabetical order, first frames, then resources. Document resource goes last. | |
| 215 function typeWeight(treeElement) { | |
| 216 if (treeElement instanceof Resources.StorageCategoryTreeElement) | |
| 217 return 2; | |
| 218 if (treeElement instanceof Resources.FrameTreeElement) | |
| 219 return 1; | |
| 220 return 3; | |
| 221 } | |
| 222 | |
| 223 function compare(treeElement1, treeElement2) { | |
| 224 var typeWeight1 = typeWeight(treeElement1); | |
| 225 var typeWeight2 = typeWeight(treeElement2); | |
| 226 | |
| 227 var result; | |
| 228 if (typeWeight1 > typeWeight2) | |
| 229 result = 1; | |
| 230 else if (typeWeight1 < typeWeight2) | |
| 231 result = -1; | |
| 232 else | |
| 233 result = treeElement1.titleAsText().localeCompare(treeElement2.titleAsTe xt()); | |
| 234 return result; | |
| 235 } | |
| 236 | |
| 237 var childCount = parentTreeElement.childCount(); | |
| 238 var i; | |
| 239 for (i = 0; i < childCount; ++i) { | |
| 240 if (compare(childTreeElement, parentTreeElement.childAt(i)) < 0) | |
| 241 break; | |
| 242 } | |
| 243 parentTreeElement.insertChild(childTreeElement, i); | |
| 244 } | |
| 245 }; | |
| 246 | |
| 247 Resources.FrameResourceTreeElement = class extends Resources.BaseStorageTreeElem ent { | |
| 248 /** | |
| 249 * @param {!Resources.ResourcesPanel} storagePanel | |
| 250 * @param {!SDK.Resource} resource | |
| 251 */ | |
| 252 constructor(storagePanel, resource) { | |
| 253 super(storagePanel, resource.displayName, false); | |
| 254 this._panel = storagePanel; | |
| 255 /** @type {!SDK.Resource} */ | |
| 256 this._resource = resource; | |
| 257 /** @type {?SourceFrame.ResourceSourceFrame} */ | |
| 258 this._sourceFrame = null; | |
| 259 this.tooltip = resource.url; | |
| 260 this._resource[Resources.FrameResourceTreeElement._symbol] = this; | |
| 261 | |
| 262 var icon = UI.Icon.create('largeicon-navigator-file', 'navigator-tree-item') ; | |
| 263 icon.classList.add('navigator-file-tree-item'); | |
| 264 icon.classList.add('navigator-' + resource.resourceType().name() + '-tree-it em'); | |
| 265 this.setLeadingIcons([icon]); | |
| 266 } | |
| 267 | |
| 268 /** | |
| 269 * @param {!SDK.Resource} resource | |
| 270 */ | |
| 271 static forResource(resource) { | |
| 272 return resource[Resources.FrameResourceTreeElement._symbol]; | |
| 273 } | |
| 274 | |
| 275 /** | |
| 276 * @param {!SDK.Resource} resource | |
| 277 * @return {?UI.Widget} | |
| 278 */ | |
| 279 static resourceViewForResource(resource) { | |
| 280 if (resource.hasTextContent()) { | |
| 281 var treeElement = Resources.FrameResourceTreeElement.forResource(resource) ; | |
| 282 if (!treeElement) | |
| 283 return null; | |
| 284 return treeElement._sourceView(); | |
| 285 } | |
| 286 | |
| 287 switch (resource.resourceType()) { | |
| 288 case Common.resourceTypes.Image: | |
| 289 return new SourceFrame.ImageView(resource.mimeType, resource); | |
| 290 case Common.resourceTypes.Font: | |
| 291 return new SourceFrame.FontView(resource.mimeType, resource); | |
| 292 default: | |
| 293 return new UI.EmptyWidget(resource.url); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 get itemURL() { | |
| 298 return this._resource.url; | |
| 299 } | |
| 300 | |
| 301 /** | |
| 302 * @override | |
| 303 * @return {boolean} | |
| 304 */ | |
| 305 onselect(selectedByUser) { | |
| 306 super.onselect(selectedByUser); | |
| 307 this.showView(Resources.FrameResourceTreeElement.resourceViewForResource(thi s._resource)); | |
| 308 return false; | |
| 309 } | |
| 310 | |
| 311 /** | |
| 312 * @override | |
| 313 * @return {boolean} | |
| 314 */ | |
| 315 ondblclick(event) { | |
| 316 InspectorFrontendHost.openInNewTab(this._resource.url); | |
| 317 return false; | |
| 318 } | |
| 319 | |
| 320 /** | |
| 321 * @override | |
| 322 */ | |
| 323 onattach() { | |
| 324 super.onattach(); | |
| 325 this.listItemElement.draggable = true; | |
| 326 this.listItemElement.addEventListener('dragstart', this._ondragstart.bind(th is), false); | |
| 327 this.listItemElement.addEventListener('contextmenu', this._handleContextMenu Event.bind(this), true); | |
| 328 } | |
| 329 | |
| 330 /** | |
| 331 * @param {!MouseEvent} event | |
| 332 * @return {boolean} | |
| 333 */ | |
| 334 _ondragstart(event) { | |
| 335 event.dataTransfer.setData('text/plain', this._resource.content || ''); | |
| 336 event.dataTransfer.effectAllowed = 'copy'; | |
| 337 return true; | |
| 338 } | |
| 339 | |
| 340 _handleContextMenuEvent(event) { | |
| 341 var contextMenu = new UI.ContextMenu(event); | |
| 342 contextMenu.appendApplicableItems(this._resource); | |
| 343 contextMenu.show(); | |
| 344 } | |
| 345 | |
| 346 /** | |
| 347 * @return {!SourceFrame.ResourceSourceFrame} | |
| 348 */ | |
| 349 _sourceView() { | |
| 350 if (!this._sourceFrame) { | |
| 351 this._sourceFrame = new SourceFrame.ResourceSourceFrame(this._resource); | |
| 352 this._sourceFrame.setHighlighterType(this._resource.canonicalMimeType()); | |
| 353 } | |
| 354 return this._sourceFrame; | |
| 355 } | |
| 356 }; | |
| 357 | |
| 358 Resources.FrameResourceTreeElement._symbol = Symbol('treeElement'); | |
| OLD | NEW |