1/* 2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Joseph Pecoraro 4 * Copyright (C) 2013 Samsung Electronics. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31importScript("ApplicationCacheItemsView.js"); 32importScript("CookieItemsView.js"); 33importScript("DOMStorageItemsView.js"); 34importScript("DatabaseQueryView.js"); 35importScript("DatabaseTableView.js"); 36importScript("DirectoryContentView.js"); 37importScript("IndexedDBViews.js"); 38importScript("FileContentView.js"); 39importScript("FileSystemView.js"); 40 41/** 42 * @constructor 43 * @extends {WebInspector.PanelWithSidebarTree} 44 */ 45WebInspector.ResourcesPanel = function(database) 46{ 47 WebInspector.PanelWithSidebarTree.call(this, "resources"); 48 this.registerRequiredCSS("resourcesPanel.css"); 49 50 WebInspector.settings.resourcesLastSelectedItem = WebInspector.settings.createSetting("resourcesLastSelectedItem", {}); 51 52 this.sidebarElement().classList.add("filter-all", "children", "small", "outline-disclosure"); 53 this.sidebarTree.element.classList.remove("sidebar-tree"); 54 55 this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]); 56 this.sidebarTree.appendChild(this.resourcesListTreeElement); 57 58 this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Web SQL"), "Databases", ["database-storage-tree-item"]); 59 this.sidebarTree.appendChild(this.databasesListTreeElement); 60 61 this.indexedDBListTreeElement = new WebInspector.IndexedDBTreeElement(this); 62 this.sidebarTree.appendChild(this.indexedDBListTreeElement); 63 64 this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", ["domstorage-storage-tree-item", "local-storage"]); 65 this.sidebarTree.appendChild(this.localStorageListTreeElement); 66 67 this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", ["domstorage-storage-tree-item", "session-storage"]); 68 this.sidebarTree.appendChild(this.sessionStorageListTreeElement); 69 70 this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", ["cookie-storage-tree-item"]); 71 this.sidebarTree.appendChild(this.cookieListTreeElement); 72 73 this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", ["application-cache-storage-tree-item"]); 74 this.sidebarTree.appendChild(this.applicationCacheListTreeElement); 75 76 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled()) { 77 this.fileSystemListTreeElement = new WebInspector.FileSystemListTreeElement(this); 78 this.sidebarTree.appendChild(this.fileSystemListTreeElement); 79 } 80 81 var mainView = new WebInspector.VBox(); 82 this.storageViews = mainView.element.createChild("div", "resources-main diff-container"); 83 var statusBarContainer = mainView.element.createChild("div", "resources-status-bar"); 84 this.storageViewStatusBarItemsContainer = statusBarContainer.createChild("div", "status-bar"); 85 mainView.show(this.mainElement()); 86 87 /** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */ 88 this._databaseTableViews = new Map(); 89 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseQueryView>} */ 90 this._databaseQueryViews = new Map(); 91 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseTreeElement>} */ 92 this._databaseTreeElements = new Map(); 93 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageItemsView>} */ 94 this._domStorageViews = new Map(); 95 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageTreeElement>} */ 96 this._domStorageTreeElements = new Map(); 97 /** @type {!Object.<string, !WebInspector.CookieItemsView>} */ 98 this._cookieViews = {}; 99 /** @type {!Object.<string, boolean>} */ 100 this._domains = {}; 101 102 this.sidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false); 103 this.sidebarElement().addEventListener("mouseout", this._onmouseout.bind(this), false); 104 105 /** 106 * @this {WebInspector.ResourcesPanel} 107 * @return {?WebInspector.SourceFrame} 108 */ 109 function sourceFrameGetter() 110 { 111 var view = this.visibleView; 112 if (view && view instanceof WebInspector.SourceFrame) 113 return /** @type {!WebInspector.SourceFrame} */ (view); 114 return null; 115 } 116 WebInspector.GoToLineDialog.install(this, sourceFrameGetter.bind(this)); 117 118 if (WebInspector.resourceTreeModel.cachedResourcesLoaded()) 119 this._cachedResourcesLoaded(); 120 121 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this); 122 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this); 123 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this); 124 125 WebInspector.databaseModel.databases().forEach(this._addDatabase.bind(this)); 126 WebInspector.databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this); 127} 128 129WebInspector.ResourcesPanel.prototype = { 130 /** 131 * @return {boolean} 132 */ 133 canSearch: function() 134 { 135 return false; 136 }, 137 138 wasShown: function() 139 { 140 WebInspector.Panel.prototype.wasShown.call(this); 141 this._initialize(); 142 }, 143 144 _initialize: function() 145 { 146 if (!this._initialized && this.isShowing() && this._cachedResourcesWereLoaded) { 147 var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget()); 148 this._populateResourceTree(); 149 this._populateDOMStorageTree(); 150 this._populateApplicationCacheTree(target); 151 this.indexedDBListTreeElement._initialize(); 152 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled()) 153 this.fileSystemListTreeElement._initialize(); 154 this._initDefaultSelection(); 155 this._initialized = true; 156 } 157 }, 158 159 _loadEventFired: function() 160 { 161 this._initDefaultSelection(); 162 }, 163 164 _initDefaultSelection: function() 165 { 166 if (!this._initialized) 167 return; 168 169 var itemURL = WebInspector.settings.resourcesLastSelectedItem.get(); 170 if (itemURL) { 171 for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) { 172 if (treeElement.itemURL === itemURL) { 173 treeElement.revealAndSelect(true); 174 return; 175 } 176 } 177 } 178 179 var mainResource = WebInspector.resourceTreeModel.inspectedPageURL() && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded 180 ? WebInspector.resourceTreeModel.resourceForURL(WebInspector.resourceTreeModel.inspectedPageURL()) 181 : null; 182 if (mainResource) 183 this.showResource(mainResource); 184 }, 185 186 _resetWithFrames: function() 187 { 188 this.resourcesListTreeElement.removeChildren(); 189 this._treeElementForFrameId = {}; 190 this._reset(); 191 }, 192 193 _reset: function() 194 { 195 this._domains = {}; 196 var queryViews = this._databaseQueryViews.values(); 197 for (var i = 0; i < queryViews.length; ++i) 198 queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this); 199 this._databaseTableViews.clear(); 200 this._databaseQueryViews.clear(); 201 this._databaseTreeElements.clear(); 202 this._domStorageViews.clear(); 203 this._domStorageTreeElements.clear(); 204 this._cookieViews = {}; 205 206 this.databasesListTreeElement.removeChildren(); 207 this.localStorageListTreeElement.removeChildren(); 208 this.sessionStorageListTreeElement.removeChildren(); 209 this.cookieListTreeElement.removeChildren(); 210 211 if (this.visibleView && !(this.visibleView instanceof WebInspector.StorageCategoryView)) 212 this.visibleView.detach(); 213 214 this.storageViewStatusBarItemsContainer.removeChildren(); 215 216 if (this.sidebarTree.selectedTreeElement) 217 this.sidebarTree.selectedTreeElement.deselect(); 218 }, 219 220 _populateResourceTree: function() 221 { 222 this._treeElementForFrameId = {}; 223 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this); 224 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this); 225 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this); 226 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this); 227 228 /** 229 * @param {!WebInspector.ResourceTreeFrame} frame 230 * @this {WebInspector.ResourcesPanel} 231 */ 232 function populateFrame(frame) 233 { 234 this._frameAdded({data:frame}); 235 for (var i = 0; i < frame.childFrames.length; ++i) 236 populateFrame.call(this, frame.childFrames[i]); 237 238 var resources = frame.resources(); 239 for (var i = 0; i < resources.length; ++i) 240 this._resourceAdded({data:resources[i]}); 241 } 242 populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame); 243 }, 244 245 _frameAdded: function(event) 246 { 247 var frame = event.data; 248 var parentFrame = frame.parentFrame; 249 250 var parentTreeElement = parentFrame ? this._treeElementForFrameId[parentFrame.id] : this.resourcesListTreeElement; 251 if (!parentTreeElement) { 252 console.warn("No frame to route " + frame.url + " to.") 253 return; 254 } 255 256 var frameTreeElement = new WebInspector.FrameTreeElement(this, frame); 257 this._treeElementForFrameId[frame.id] = frameTreeElement; 258 parentTreeElement.appendChild(frameTreeElement); 259 }, 260 261 _frameDetached: function(event) 262 { 263 var frame = event.data; 264 var frameTreeElement = this._treeElementForFrameId[frame.id]; 265 if (!frameTreeElement) 266 return; 267 268 delete this._treeElementForFrameId[frame.id]; 269 if (frameTreeElement.parent) 270 frameTreeElement.parent.removeChild(frameTreeElement); 271 }, 272 273 _resourceAdded: function(event) 274 { 275 var resource = event.data; 276 var frameId = resource.frameId; 277 278 if (resource.statusCode >= 301 && resource.statusCode <= 303) 279 return; 280 281 var frameTreeElement = this._treeElementForFrameId[frameId]; 282 if (!frameTreeElement) { 283 // This is a frame's main resource, it will be retained 284 // and re-added by the resource manager; 285 return; 286 } 287 288 frameTreeElement.appendResource(resource); 289 }, 290 291 _frameNavigated: function(event) 292 { 293 var frame = event.data; 294 295 if (!frame.parentFrame) 296 this._reset(); 297 298 var frameId = frame.id; 299 var frameTreeElement = this._treeElementForFrameId[frameId]; 300 if (frameTreeElement) 301 frameTreeElement.frameNavigated(frame); 302 303 var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frameId]; 304 if (applicationCacheFrameTreeElement) 305 applicationCacheFrameTreeElement.frameNavigated(frame); 306 }, 307 308 _cachedResourcesLoaded: function() 309 { 310 this._cachedResourcesWereLoaded = true; 311 this._initialize(); 312 }, 313 314 /** 315 * @param {!WebInspector.Event} event 316 */ 317 _databaseAdded: function(event) 318 { 319 var database = /** @type {!WebInspector.Database} */ (event.data); 320 this._addDatabase(database); 321 }, 322 323 /** 324 * @param {!WebInspector.Database} database 325 */ 326 _addDatabase: function(database) 327 { 328 var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database); 329 this._databaseTreeElements.put(database, databaseTreeElement); 330 this.databasesListTreeElement.appendChild(databaseTreeElement); 331 }, 332 333 addDocumentURL: function(url) 334 { 335 var parsedURL = url.asParsedURL(); 336 if (!parsedURL) 337 return; 338 339 var domain = parsedURL.host; 340 if (!this._domains[domain]) { 341 this._domains[domain] = true; 342 343 var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain); 344 this.cookieListTreeElement.appendChild(cookieDomainTreeElement); 345 } 346 }, 347 348 /** 349 * @param {!WebInspector.Event} event 350 */ 351 _domStorageAdded: function(event) 352 { 353 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data); 354 this._addDOMStorage(domStorage); 355 }, 356 357 /** 358 * @param {!WebInspector.DOMStorage} domStorage 359 */ 360 _addDOMStorage: function(domStorage) 361 { 362 console.assert(!this._domStorageTreeElements.get(domStorage)); 363 364 var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage")); 365 this._domStorageTreeElements.put(domStorage, domStorageTreeElement); 366 if (domStorage.isLocalStorage) 367 this.localStorageListTreeElement.appendChild(domStorageTreeElement); 368 else 369 this.sessionStorageListTreeElement.appendChild(domStorageTreeElement); 370 }, 371 372 /** 373 * @param {!WebInspector.Event} event 374 */ 375 _domStorageRemoved: function(event) 376 { 377 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data); 378 this._removeDOMStorage(domStorage); 379 }, 380 381 /** 382 * @param {!WebInspector.DOMStorage} domStorage 383 */ 384 _removeDOMStorage: function(domStorage) 385 { 386 var treeElement = this._domStorageTreeElements.get(domStorage); 387 if (!treeElement) 388 return; 389 var wasSelected = treeElement.selected; 390 var parentListTreeElement = treeElement.parent; 391 parentListTreeElement.removeChild(treeElement); 392 if (wasSelected) 393 parentListTreeElement.select(); 394 this._domStorageTreeElements.remove(domStorage); 395 this._domStorageViews.remove(domStorage); 396 }, 397 398 /** 399 * @param {!WebInspector.Database} database 400 */ 401 selectDatabase: function(database) 402 { 403 if (database) { 404 this._showDatabase(database); 405 this._databaseTreeElements.get(database).select(); 406 } 407 }, 408 409 /** 410 * @param {!WebInspector.DOMStorage} domStorage 411 */ 412 selectDOMStorage: function(domStorage) 413 { 414 if (domStorage) { 415 this._showDOMStorage(domStorage); 416 this._domStorageTreeElements.get(domStorage).select(); 417 } 418 }, 419 420 /** 421 * @param {!WebInspector.Resource} resource 422 * @param {number=} line 423 * @param {number=} column 424 * @return {boolean} 425 */ 426 showResource: function(resource, line, column) 427 { 428 var resourceTreeElement = this._findTreeElementForResource(resource); 429 if (resourceTreeElement) 430 resourceTreeElement.revealAndSelect(true); 431 432 if (typeof line === "number") { 433 var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource); 434 if (resourceSourceFrame) 435 resourceSourceFrame.revealPosition(line, column, true); 436 } 437 return true; 438 }, 439 440 _showResourceView: function(resource) 441 { 442 var view = this._resourceViewForResource(resource); 443 if (!view) { 444 this.visibleView.detach(); 445 return; 446 } 447 this._innerShowView(view); 448 }, 449 450 /** 451 * @param {!WebInspector.Resource} resource 452 * @return {?WebInspector.View} 453 */ 454 _resourceViewForResource: function(resource) 455 { 456 if (WebInspector.ResourceView.hasTextContent(resource)) { 457 var treeElement = this._findTreeElementForResource(resource); 458 if (!treeElement) 459 return null; 460 return treeElement.sourceView(); 461 } 462 return WebInspector.ResourceView.nonSourceViewForResource(resource); 463 }, 464 465 /** 466 * @param {!WebInspector.Resource} resource 467 * @return {?WebInspector.ResourceSourceFrame} 468 */ 469 _resourceSourceFrameViewForResource: function(resource) 470 { 471 var resourceView = this._resourceViewForResource(resource); 472 if (resourceView && resourceView instanceof WebInspector.ResourceSourceFrame) 473 return /** @type {!WebInspector.ResourceSourceFrame} */ (resourceView); 474 return null; 475 }, 476 477 /** 478 * @param {!WebInspector.Database} database 479 * @param {string=} tableName 480 */ 481 _showDatabase: function(database, tableName) 482 { 483 if (!database) 484 return; 485 486 var view; 487 if (tableName) { 488 var tableViews = this._databaseTableViews.get(database); 489 if (!tableViews) { 490 tableViews = /** @type {!Object.<string, !WebInspector.DatabaseTableView>} */ ({}); 491 this._databaseTableViews.put(database, tableViews); 492 } 493 view = tableViews[tableName]; 494 if (!view) { 495 view = new WebInspector.DatabaseTableView(database, tableName); 496 tableViews[tableName] = view; 497 } 498 } else { 499 view = this._databaseQueryViews.get(database); 500 if (!view) { 501 view = new WebInspector.DatabaseQueryView(database); 502 this._databaseQueryViews.put(database, view); 503 view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this); 504 } 505 } 506 507 this._innerShowView(view); 508 }, 509 510 /** 511 * @param {!WebInspector.View} view 512 */ 513 showIndexedDB: function(view) 514 { 515 this._innerShowView(view); 516 }, 517 518 /** 519 * @param {!WebInspector.DOMStorage} domStorage 520 */ 521 _showDOMStorage: function(domStorage) 522 { 523 if (!domStorage) 524 return; 525 526 var view; 527 view = this._domStorageViews.get(domStorage); 528 if (!view) { 529 view = new WebInspector.DOMStorageItemsView(domStorage); 530 this._domStorageViews.put(domStorage, view); 531 } 532 533 this._innerShowView(view); 534 }, 535 536 /** 537 * @param {!WebInspector.CookieTreeElement} treeElement 538 * @param {string} cookieDomain 539 */ 540 showCookies: function(treeElement, cookieDomain) 541 { 542 var view = this._cookieViews[cookieDomain]; 543 if (!view) { 544 view = new WebInspector.CookieItemsView(treeElement, cookieDomain); 545 this._cookieViews[cookieDomain] = view; 546 } 547 548 this._innerShowView(view); 549 }, 550 551 /** 552 * @param {string} cookieDomain 553 */ 554 clearCookies: function(cookieDomain) 555 { 556 this._cookieViews[cookieDomain].clear(); 557 }, 558 559 showApplicationCache: function(frameId) 560 { 561 if (!this._applicationCacheViews[frameId]) 562 this._applicationCacheViews[frameId] = new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel, frameId); 563 564 this._innerShowView(this._applicationCacheViews[frameId]); 565 }, 566 567 /** 568 * @param {!WebInspector.View} view 569 */ 570 showFileSystem: function(view) 571 { 572 this._innerShowView(view); 573 }, 574 575 showCategoryView: function(categoryName) 576 { 577 if (!this._categoryView) 578 this._categoryView = new WebInspector.StorageCategoryView(); 579 this._categoryView.setText(categoryName); 580 this._innerShowView(this._categoryView); 581 }, 582 583 _innerShowView: function(view) 584 { 585 if (this.visibleView === view) 586 return; 587 588 if (this.visibleView) 589 this.visibleView.detach(); 590 591 view.show(this.storageViews); 592 this.visibleView = view; 593 594 this.storageViewStatusBarItemsContainer.removeChildren(); 595 var statusBarItems = view.statusBarItems || []; 596 for (var i = 0; i < statusBarItems.length; ++i) 597 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]); 598 }, 599 600 closeVisibleView: function() 601 { 602 if (!this.visibleView) 603 return; 604 this.visibleView.detach(); 605 delete this.visibleView; 606 }, 607 608 _updateDatabaseTables: function(event) 609 { 610 var database = event.data; 611 612 if (!database) 613 return; 614 615 var databasesTreeElement = this._databaseTreeElements.get(database); 616 if (!databasesTreeElement) 617 return; 618 619 databasesTreeElement.shouldRefreshChildren = true; 620 var tableViews = this._databaseTableViews.get(database); 621 622 if (!tableViews) 623 return; 624 625 var tableNamesHash = {}; 626 var self = this; 627 function tableNamesCallback(tableNames) 628 { 629 var tableNamesLength = tableNames.length; 630 for (var i = 0; i < tableNamesLength; ++i) 631 tableNamesHash[tableNames[i]] = true; 632 633 for (var tableName in tableViews) { 634 if (!(tableName in tableNamesHash)) { 635 if (self.visibleView === tableViews[tableName]) 636 self.closeVisibleView(); 637 delete tableViews[tableName]; 638 } 639 } 640 } 641 database.getTableNames(tableNamesCallback); 642 }, 643 644 _populateDOMStorageTree: function() 645 { 646 WebInspector.domStorageModel.storages().forEach(this._addDOMStorage.bind(this)); 647 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this); 648 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this); 649 }, 650 651 /** 652 * @param {!WebInspector.Target} target 653 */ 654 _populateApplicationCacheTree: function(target) 655 { 656 this._applicationCacheModel = new WebInspector.ApplicationCacheModel(target); 657 658 this._applicationCacheViews = {}; 659 this._applicationCacheFrameElements = {}; 660 this._applicationCacheManifestElements = {}; 661 662 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this); 663 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this); 664 665 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, this._applicationCacheFrameManifestStatusChanged, this); 666 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this); 667 }, 668 669 _applicationCacheFrameManifestAdded: function(event) 670 { 671 var frameId = event.data; 672 var manifestURL = this._applicationCacheModel.frameManifestURL(frameId); 673 var status = this._applicationCacheModel.frameManifestStatus(frameId) 674 675 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL] 676 if (!manifestTreeElement) { 677 manifestTreeElement = new WebInspector.ApplicationCacheManifestTreeElement(this, manifestURL); 678 this.applicationCacheListTreeElement.appendChild(manifestTreeElement); 679 this._applicationCacheManifestElements[manifestURL] = manifestTreeElement; 680 } 681 682 var frameTreeElement = new WebInspector.ApplicationCacheFrameTreeElement(this, frameId, manifestURL); 683 manifestTreeElement.appendChild(frameTreeElement); 684 manifestTreeElement.expand(); 685 this._applicationCacheFrameElements[frameId] = frameTreeElement; 686 }, 687 688 _applicationCacheFrameManifestRemoved: function(event) 689 { 690 var frameId = event.data; 691 var frameTreeElement = this._applicationCacheFrameElements[frameId]; 692 if (!frameTreeElement) 693 return; 694 695 var manifestURL = frameTreeElement.manifestURL; 696 delete this._applicationCacheFrameElements[frameId]; 697 delete this._applicationCacheViews[frameId]; 698 frameTreeElement.parent.removeChild(frameTreeElement); 699 700 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]; 701 if (manifestTreeElement.children.length !== 0) 702 return; 703 704 delete this._applicationCacheManifestElements[manifestURL]; 705 manifestTreeElement.parent.removeChild(manifestTreeElement); 706 }, 707 708 _applicationCacheFrameManifestStatusChanged: function(event) 709 { 710 var frameId = event.data; 711 var status = this._applicationCacheModel.frameManifestStatus(frameId) 712 713 if (this._applicationCacheViews[frameId]) 714 this._applicationCacheViews[frameId].updateStatus(status); 715 }, 716 717 _applicationCacheNetworkStateChanged: function(event) 718 { 719 var isNowOnline = event.data; 720 721 for (var manifestURL in this._applicationCacheViews) 722 this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline); 723 }, 724 725 _findTreeElementForResource: function(resource) 726 { 727 function getParent(object) 728 { 729 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here. 730 return null; 731 } 732 733 return this.sidebarTree.findTreeElement(resource, getParent); 734 }, 735 736 showView: function(view) 737 { 738 if (view) 739 this.showResource(view.resource); 740 }, 741 742 _onmousemove: function(event) 743 { 744 var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); 745 if (!nodeUnderMouse) 746 return; 747 748 var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li"); 749 if (!listNode) 750 return; 751 752 var element = listNode.treeElement; 753 if (this._previousHoveredElement === element) 754 return; 755 756 if (this._previousHoveredElement) { 757 this._previousHoveredElement.hovered = false; 758 delete this._previousHoveredElement; 759 } 760 761 if (element instanceof WebInspector.FrameTreeElement) { 762 this._previousHoveredElement = element; 763 element.hovered = true; 764 } 765 }, 766 767 _onmouseout: function(event) 768 { 769 if (this._previousHoveredElement) { 770 this._previousHoveredElement.hovered = false; 771 delete this._previousHoveredElement; 772 } 773 }, 774 775 __proto__: WebInspector.PanelWithSidebarTree.prototype 776} 777 778/** 779 * @constructor 780 * @implements {WebInspector.Revealer} 781 */ 782WebInspector.ResourcesPanel.ResourceRevealer = function() 783{ 784} 785 786WebInspector.ResourcesPanel.ResourceRevealer.prototype = { 787 /** 788 * @param {!Object} resource 789 * @param {number=} lineNumber 790 */ 791 reveal: function(resource, lineNumber) 792 { 793 if (resource instanceof WebInspector.Resource) 794 /** @type {!WebInspector.ResourcesPanel} */ (WebInspector.inspectorView.showPanel("resources")).showResource(resource, lineNumber); 795 } 796} 797 798/** 799 * @constructor 800 * @extends {TreeElement} 801 * @param {!WebInspector.ResourcesPanel} storagePanel 802 * @param {?Object} representedObject 803 * @param {string} title 804 * @param {?Array.<string>=} iconClasses 805 * @param {boolean=} hasChildren 806 * @param {boolean=} noIcon 807 */ 808WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren, noIcon) 809{ 810 TreeElement.call(this, "", representedObject, hasChildren); 811 this._storagePanel = storagePanel; 812 this._titleText = title; 813 this._iconClasses = iconClasses; 814 this._noIcon = noIcon; 815} 816 817WebInspector.BaseStorageTreeElement.prototype = { 818 onattach: function() 819 { 820 this.listItemElement.removeChildren(); 821 if (this._iconClasses) { 822 for (var i = 0; i < this._iconClasses.length; ++i) 823 this.listItemElement.classList.add(this._iconClasses[i]); 824 } 825 826 var selectionElement = document.createElement("div"); 827 selectionElement.className = "selection"; 828 this.listItemElement.appendChild(selectionElement); 829 830 if (!this._noIcon) { 831 this.imageElement = document.createElement("img"); 832 this.imageElement.className = "icon"; 833 this.listItemElement.appendChild(this.imageElement); 834 } 835 836 this.titleElement = document.createElement("div"); 837 this.titleElement.className = "base-storage-tree-element-title"; 838 this._titleTextNode = document.createTextNode(""); 839 this.titleElement.appendChild(this._titleTextNode); 840 this._updateTitle(); 841 this._updateSubtitle(); 842 this.listItemElement.appendChild(this.titleElement); 843 }, 844 845 get displayName() 846 { 847 return this._displayName; 848 }, 849 850 _updateDisplayName: function() 851 { 852 this._displayName = this._titleText || ""; 853 if (this._subtitleText) 854 this._displayName += " (" + this._subtitleText + ")"; 855 }, 856 857 _updateTitle: function() 858 { 859 this._updateDisplayName(); 860 861 if (!this.titleElement) 862 return; 863 864 this._titleTextNode.textContent = this._titleText || ""; 865 }, 866 867 _updateSubtitle: function() 868 { 869 this._updateDisplayName(); 870 871 if (!this.titleElement) 872 return; 873 874 if (this._subtitleText) { 875 if (!this._subtitleElement) { 876 this._subtitleElement = document.createElement("span"); 877 this._subtitleElement.className = "base-storage-tree-element-subtitle"; 878 this.titleElement.appendChild(this._subtitleElement); 879 } 880 this._subtitleElement.textContent = "(" + this._subtitleText + ")"; 881 } else if (this._subtitleElement) { 882 this.titleElement.removeChild(this._subtitleElement); 883 delete this._subtitleElement; 884 } 885 }, 886 887 /** 888 * @override 889 * @return {boolean} 890 */ 891 onselect: function(selectedByUser) 892 { 893 if (!selectedByUser) 894 return false; 895 var itemURL = this.itemURL; 896 if (itemURL) 897 WebInspector.settings.resourcesLastSelectedItem.set(itemURL); 898 return false; 899 }, 900 901 /** 902 * @override 903 */ 904 onreveal: function() 905 { 906 if (this.listItemElement) 907 this.listItemElement.scrollIntoViewIfNeeded(false); 908 }, 909 910 get titleText() 911 { 912 return this._titleText; 913 }, 914 915 set titleText(titleText) 916 { 917 this._titleText = titleText; 918 this._updateTitle(); 919 }, 920 921 get subtitleText() 922 { 923 return this._subtitleText; 924 }, 925 926 set subtitleText(subtitleText) 927 { 928 this._subtitleText = subtitleText; 929 this._updateSubtitle(); 930 }, 931 932 __proto__: TreeElement.prototype 933} 934 935/** 936 * @constructor 937 * @extends {WebInspector.BaseStorageTreeElement} 938 * @param {!WebInspector.ResourcesPanel} storagePanel 939 * @param {string} categoryName 940 * @param {string} settingsKey 941 * @param {?Array.<string>=} iconClasses 942 * @param {boolean=} noIcon 943 */ 944WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon) 945{ 946 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, false, noIcon); 947 this._expandedSettingKey = "resources" + settingsKey + "Expanded"; 948 WebInspector.settings[this._expandedSettingKey] = WebInspector.settings.createSetting(this._expandedSettingKey, settingsKey === "Frames"); 949 this._categoryName = categoryName; 950 this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget()); 951} 952 953WebInspector.StorageCategoryTreeElement.prototype = { 954 /** 955 * @return {!WebInspector.Target} 956 */ 957 target: function() 958 { 959 return this._target; 960 }, 961 962 get itemURL() 963 { 964 return "category://" + this._categoryName; 965 }, 966 967 /** 968 * @override 969 * @return {boolean} 970 */ 971 onselect: function(selectedByUser) 972 { 973 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 974 this._storagePanel.showCategoryView(this._categoryName); 975 return false; 976 }, 977 978 /** 979 * @override 980 */ 981 onattach: function() 982 { 983 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); 984 if (WebInspector.settings[this._expandedSettingKey].get()) 985 this.expand(); 986 }, 987 988 /** 989 * @override 990 */ 991 onexpand: function() 992 { 993 WebInspector.settings[this._expandedSettingKey].set(true); 994 }, 995 996 /** 997 * @override 998 */ 999 oncollapse: function() 1000 { 1001 WebInspector.settings[this._expandedSettingKey].set(false); 1002 }, 1003 1004 __proto__: WebInspector.BaseStorageTreeElement.prototype 1005} 1006 1007/** 1008 * @constructor 1009 * @extends {WebInspector.BaseStorageTreeElement} 1010 */ 1011WebInspector.FrameTreeElement = function(storagePanel, frame) 1012{ 1013 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]); 1014 this._frame = frame; 1015 this.frameNavigated(frame); 1016} 1017 1018WebInspector.FrameTreeElement.prototype = { 1019 frameNavigated: function(frame) 1020 { 1021 this.removeChildren(); 1022 this._frameId = frame.id; 1023 1024 this.titleText = frame.name; 1025 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName; 1026 1027 this._categoryElements = {}; 1028 this._treeElementForResource = {}; 1029 1030 this._storagePanel.addDocumentURL(frame.url); 1031 }, 1032 1033 get itemURL() 1034 { 1035 return "frame://" + encodeURI(this.displayName); 1036 }, 1037 1038 /** 1039 * @override 1040 * @return {boolean} 1041 */ 1042 onselect: function(selectedByUser) 1043 { 1044 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1045 this._storagePanel.showCategoryView(this.displayName); 1046 1047 this.listItemElement.classList.remove("hovered"); 1048 DOMAgent.hideHighlight(); 1049 return false; 1050 }, 1051 1052 set hovered(hovered) 1053 { 1054 if (hovered) { 1055 this.listItemElement.classList.add("hovered"); 1056 DOMAgent.highlightFrame(this._frameId, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA()); 1057 } else { 1058 this.listItemElement.classList.remove("hovered"); 1059 DOMAgent.hideHighlight(); 1060 } 1061 }, 1062 1063 appendResource: function(resource) 1064 { 1065 if (resource.isHidden()) 1066 return; 1067 var categoryName = resource.type.name(); 1068 var categoryElement = resource.type === WebInspector.resourceTypes.Document ? this : this._categoryElements[categoryName]; 1069 if (!categoryElement) { 1070 categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.type.categoryTitle(), categoryName, null, true); 1071 this._categoryElements[resource.type.name()] = categoryElement; 1072 this._insertInPresentationOrder(this, categoryElement); 1073 } 1074 var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource); 1075 this._insertInPresentationOrder(categoryElement, resourceTreeElement); 1076 this._treeElementForResource[resource.url] = resourceTreeElement; 1077 }, 1078 1079 /** 1080 * @param {string} url 1081 * @return {?WebInspector.Resource} 1082 */ 1083 resourceByURL: function(url) 1084 { 1085 var treeElement = this._treeElementForResource[url]; 1086 return treeElement ? treeElement.representedObject : null; 1087 }, 1088 1089 appendChild: function(treeElement) 1090 { 1091 this._insertInPresentationOrder(this, treeElement); 1092 }, 1093 1094 _insertInPresentationOrder: function(parentTreeElement, childTreeElement) 1095 { 1096 // Insert in the alphabetical order, first frames, then resources. Document resource goes last. 1097 function typeWeight(treeElement) 1098 { 1099 if (treeElement instanceof WebInspector.StorageCategoryTreeElement) 1100 return 2; 1101 if (treeElement instanceof WebInspector.FrameTreeElement) 1102 return 1; 1103 return 3; 1104 } 1105 1106 function compare(treeElement1, treeElement2) 1107 { 1108 var typeWeight1 = typeWeight(treeElement1); 1109 var typeWeight2 = typeWeight(treeElement2); 1110 1111 var result; 1112 if (typeWeight1 > typeWeight2) 1113 result = 1; 1114 else if (typeWeight1 < typeWeight2) 1115 result = -1; 1116 else { 1117 var title1 = treeElement1.displayName || treeElement1.titleText; 1118 var title2 = treeElement2.displayName || treeElement2.titleText; 1119 result = title1.localeCompare(title2); 1120 } 1121 return result; 1122 } 1123 1124 var children = parentTreeElement.children; 1125 var i; 1126 for (i = 0; i < children.length; ++i) { 1127 if (compare(childTreeElement, children[i]) < 0) 1128 break; 1129 } 1130 parentTreeElement.insertChild(childTreeElement, i); 1131 }, 1132 1133 __proto__: WebInspector.BaseStorageTreeElement.prototype 1134} 1135 1136/** 1137 * @constructor 1138 * @extends {WebInspector.BaseStorageTreeElement} 1139 */ 1140WebInspector.FrameResourceTreeElement = function(storagePanel, resource) 1141{ 1142 WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, ["resource-sidebar-tree-item", "resources-type-" + resource.type.name()]); 1143 this._resource = resource; 1144 this._resource.addEventListener(WebInspector.Resource.Events.MessageAdded, this._consoleMessageAdded, this); 1145 this._resource.addEventListener(WebInspector.Resource.Events.MessagesCleared, this._consoleMessagesCleared, this); 1146 this.tooltip = resource.url; 1147} 1148 1149WebInspector.FrameResourceTreeElement.prototype = { 1150 get itemURL() 1151 { 1152 return this._resource.url; 1153 }, 1154 1155 /** 1156 * @override 1157 * @return {boolean} 1158 */ 1159 onselect: function(selectedByUser) 1160 { 1161 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1162 this._storagePanel._showResourceView(this._resource); 1163 return false; 1164 }, 1165 1166 /** 1167 * @override 1168 * @return {boolean} 1169 */ 1170 ondblclick: function(event) 1171 { 1172 InspectorFrontendHost.openInNewTab(this._resource.url); 1173 return false; 1174 }, 1175 1176 /** 1177 * @override 1178 */ 1179 onattach: function() 1180 { 1181 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); 1182 1183 if (this._resource.type === WebInspector.resourceTypes.Image) { 1184 var previewImage = document.createElement("img"); 1185 previewImage.className = "image-resource-icon-preview"; 1186 this._resource.populateImageSource(previewImage); 1187 1188 var iconElement = document.createElement("div"); 1189 iconElement.className = "icon"; 1190 iconElement.appendChild(previewImage); 1191 this.listItemElement.replaceChild(iconElement, this.imageElement); 1192 } 1193 1194 this._statusElement = document.createElement("div"); 1195 this._statusElement.className = "status"; 1196 this.listItemElement.insertBefore(this._statusElement, this.titleElement); 1197 1198 this.listItemElement.draggable = true; 1199 this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false); 1200 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); 1201 1202 this._updateErrorsAndWarningsBubbles(); 1203 }, 1204 1205 /** 1206 * @param {!MouseEvent} event 1207 * @return {boolean} 1208 */ 1209 _ondragstart: function(event) 1210 { 1211 event.dataTransfer.setData("text/plain", this._resource.content); 1212 event.dataTransfer.effectAllowed = "copy"; 1213 return true; 1214 }, 1215 1216 _handleContextMenuEvent: function(event) 1217 { 1218 var contextMenu = new WebInspector.ContextMenu(event); 1219 contextMenu.appendApplicableItems(this._resource); 1220 contextMenu.show(); 1221 }, 1222 1223 _setBubbleText: function(x) 1224 { 1225 if (!this._bubbleElement) { 1226 this._bubbleElement = document.createElement("div"); 1227 this._bubbleElement.className = "bubble"; 1228 this._statusElement.appendChild(this._bubbleElement); 1229 } 1230 1231 this._bubbleElement.textContent = x; 1232 }, 1233 1234 _resetBubble: function() 1235 { 1236 if (this._bubbleElement) { 1237 this._bubbleElement.textContent = ""; 1238 this._bubbleElement.classList.remove("warning"); 1239 this._bubbleElement.classList.remove("error"); 1240 } 1241 }, 1242 1243 _updateErrorsAndWarningsBubbles: function() 1244 { 1245 if (this._storagePanel.currentQuery) 1246 return; 1247 1248 this._resetBubble(); 1249 1250 if (this._resource.warnings || this._resource.errors) 1251 this._setBubbleText(this._resource.warnings + this._resource.errors); 1252 1253 if (this._resource.warnings) 1254 this._bubbleElement.classList.add("warning"); 1255 1256 if (this._resource.errors) 1257 this._bubbleElement.classList.add("error"); 1258 }, 1259 1260 _consoleMessagesCleared: function() 1261 { 1262 // FIXME: move to the SourceFrame. 1263 if (this._sourceView) 1264 this._sourceView.clearMessages(); 1265 1266 this._updateErrorsAndWarningsBubbles(); 1267 }, 1268 1269 _consoleMessageAdded: function(event) 1270 { 1271 var msg = event.data; 1272 if (this._sourceView) 1273 this._sourceView.addMessage(msg); 1274 this._updateErrorsAndWarningsBubbles(); 1275 }, 1276 1277 /** 1278 * @return {!WebInspector.ResourceSourceFrame} 1279 */ 1280 sourceView: function() 1281 { 1282 if (!this._sourceView) { 1283 var sourceFrame = new WebInspector.ResourceSourceFrame(this._resource); 1284 sourceFrame.setHighlighterType(this._resource.canonicalMimeType()); 1285 this._sourceView = sourceFrame; 1286 if (this._resource.messages) { 1287 for (var i = 0; i < this._resource.messages.length; i++) 1288 this._sourceView.addMessage(this._resource.messages[i]); 1289 } 1290 } 1291 return this._sourceView; 1292 }, 1293 1294 __proto__: WebInspector.BaseStorageTreeElement.prototype 1295} 1296 1297/** 1298 * @constructor 1299 * @extends {WebInspector.BaseStorageTreeElement} 1300 * @param {!WebInspector.ResourcesPanel} storagePanel 1301 * @param {!WebInspector.Database} database 1302 */ 1303WebInspector.DatabaseTreeElement = function(storagePanel, database) 1304{ 1305 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, ["database-storage-tree-item"], true); 1306 this._database = database; 1307} 1308 1309WebInspector.DatabaseTreeElement.prototype = { 1310 get itemURL() 1311 { 1312 return "database://" + encodeURI(this._database.name); 1313 }, 1314 1315 /** 1316 * @override 1317 * @return {boolean} 1318 */ 1319 onselect: function(selectedByUser) 1320 { 1321 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1322 this._storagePanel._showDatabase(this._database); 1323 return false; 1324 }, 1325 1326 /** 1327 * @override 1328 */ 1329 onexpand: function() 1330 { 1331 this._updateChildren(); 1332 }, 1333 1334 _updateChildren: function() 1335 { 1336 this.removeChildren(); 1337 1338 /** 1339 * @param {!Array.<string>} tableNames 1340 * @this {WebInspector.DatabaseTreeElement} 1341 */ 1342 function tableNamesCallback(tableNames) 1343 { 1344 var tableNamesLength = tableNames.length; 1345 for (var i = 0; i < tableNamesLength; ++i) 1346 this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i])); 1347 } 1348 this._database.getTableNames(tableNamesCallback.bind(this)); 1349 }, 1350 1351 __proto__: WebInspector.BaseStorageTreeElement.prototype 1352} 1353 1354/** 1355 * @constructor 1356 * @extends {WebInspector.BaseStorageTreeElement} 1357 */ 1358WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName) 1359{ 1360 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, ["database-storage-tree-item"]); 1361 this._database = database; 1362 this._tableName = tableName; 1363} 1364 1365WebInspector.DatabaseTableTreeElement.prototype = { 1366 get itemURL() 1367 { 1368 return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName); 1369 }, 1370 1371 /** 1372 * @override 1373 * @return {boolean} 1374 */ 1375 onselect: function(selectedByUser) 1376 { 1377 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1378 this._storagePanel._showDatabase(this._database, this._tableName); 1379 return false; 1380 }, 1381 1382 __proto__: WebInspector.BaseStorageTreeElement.prototype 1383} 1384 1385/** 1386 * @constructor 1387 * @extends {WebInspector.StorageCategoryTreeElement} 1388 * @param {!WebInspector.ResourcesPanel} storagePanel 1389 */ 1390WebInspector.IndexedDBTreeElement = function(storagePanel) 1391{ 1392 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("IndexedDB"), "IndexedDB", ["indexed-db-storage-tree-item"]); 1393} 1394 1395WebInspector.IndexedDBTreeElement.prototype = { 1396 _initialize: function() 1397 { 1398 this._createIndexedDBModel(); 1399 }, 1400 1401 onattach: function() 1402 { 1403 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this); 1404 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); 1405 }, 1406 1407 _handleContextMenuEvent: function(event) 1408 { 1409 var contextMenu = new WebInspector.ContextMenu(event); 1410 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this.refreshIndexedDB.bind(this)); 1411 contextMenu.show(); 1412 }, 1413 1414 _createIndexedDBModel: function() 1415 { 1416 this._indexedDBModel = new WebInspector.IndexedDBModel(this.target()); 1417 this._idbDatabaseTreeElements = []; 1418 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this); 1419 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this); 1420 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, this._indexedDBLoaded, this); 1421 }, 1422 1423 refreshIndexedDB: function() 1424 { 1425 if (!this._indexedDBModel) { 1426 this._createIndexedDBModel(); 1427 return; 1428 } 1429 1430 this._indexedDBModel.refreshDatabaseNames(); 1431 }, 1432 1433 /** 1434 * @param {!WebInspector.Event} event 1435 */ 1436 _indexedDBAdded: function(event) 1437 { 1438 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data); 1439 1440 var idbDatabaseTreeElement = new WebInspector.IDBDatabaseTreeElement(this._storagePanel, this._indexedDBModel, databaseId); 1441 this._idbDatabaseTreeElements.push(idbDatabaseTreeElement); 1442 this.appendChild(idbDatabaseTreeElement); 1443 1444 this._indexedDBModel.refreshDatabase(databaseId); 1445 }, 1446 1447 /** 1448 * @param {!WebInspector.Event} event 1449 */ 1450 _indexedDBRemoved: function(event) 1451 { 1452 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data); 1453 1454 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(databaseId) 1455 if (!idbDatabaseTreeElement) 1456 return; 1457 1458 idbDatabaseTreeElement.clear(); 1459 this.removeChild(idbDatabaseTreeElement); 1460 this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement); 1461 }, 1462 1463 /** 1464 * @param {!WebInspector.Event} event 1465 */ 1466 _indexedDBLoaded: function(event) 1467 { 1468 var database = /** @type {!WebInspector.IndexedDBModel.Database} */ (event.data); 1469 1470 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(database.databaseId) 1471 if (!idbDatabaseTreeElement) 1472 return; 1473 1474 idbDatabaseTreeElement.update(database); 1475 }, 1476 1477 /** 1478 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId 1479 * @return {?WebInspector.IDBDatabaseTreeElement} 1480 */ 1481 _idbDatabaseTreeElement: function(databaseId) 1482 { 1483 var index = -1; 1484 for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) { 1485 if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId)) { 1486 index = i; 1487 break; 1488 } 1489 } 1490 if (index !== -1) 1491 return this._idbDatabaseTreeElements[i]; 1492 return null; 1493 }, 1494 1495 __proto__: WebInspector.StorageCategoryTreeElement.prototype 1496} 1497 1498/** 1499 * @constructor 1500 * @extends {WebInspector.StorageCategoryTreeElement} 1501 * @param {!WebInspector.ResourcesPanel} storagePanel 1502 */ 1503WebInspector.FileSystemListTreeElement = function(storagePanel) 1504{ 1505 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("FileSystem"), "FileSystem", ["file-system-storage-tree-item"]); 1506} 1507 1508WebInspector.FileSystemListTreeElement.prototype = { 1509 _initialize: function() 1510 { 1511 this._refreshFileSystem(); 1512 }, 1513 1514 onattach: function() 1515 { 1516 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this); 1517 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); 1518 }, 1519 1520 _handleContextMenuEvent: function(event) 1521 { 1522 var contextMenu = new WebInspector.ContextMenu(event); 1523 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Refresh FileSystem list" : "Refresh FileSystem List"), this._refreshFileSystem.bind(this)); 1524 contextMenu.show(); 1525 }, 1526 1527 _fileSystemAdded: function(event) 1528 { 1529 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data); 1530 var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this._storagePanel, fileSystem); 1531 this.appendChild(fileSystemTreeElement); 1532 }, 1533 1534 _fileSystemRemoved: function(event) 1535 { 1536 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data); 1537 var fileSystemTreeElement = this._fileSystemTreeElementByName(fileSystem.name); 1538 if (!fileSystemTreeElement) 1539 return; 1540 fileSystemTreeElement.clear(); 1541 this.removeChild(fileSystemTreeElement); 1542 }, 1543 1544 _fileSystemTreeElementByName: function(fileSystemName) 1545 { 1546 for (var i = 0; i < this.children.length; ++i) { 1547 var child = /** @type {!WebInspector.FileSystemTreeElement} */ (this.children[i]); 1548 if (child.fileSystemName === fileSystemName) 1549 return this.children[i]; 1550 } 1551 return null; 1552 }, 1553 1554 _refreshFileSystem: function() 1555 { 1556 if (!this._fileSystemModel) { 1557 this._fileSystemModel = new WebInspector.FileSystemModel(this.target()); 1558 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, this._fileSystemAdded, this); 1559 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, this._fileSystemRemoved, this); 1560 } 1561 1562 this._fileSystemModel.refreshFileSystemList(); 1563 }, 1564 1565 __proto__: WebInspector.StorageCategoryTreeElement.prototype 1566} 1567 1568/** 1569 * @constructor 1570 * @extends {WebInspector.BaseStorageTreeElement} 1571 * @param {!WebInspector.ResourcesPanel} storagePanel 1572 * @param {!WebInspector.IndexedDBModel} model 1573 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId 1574 */ 1575WebInspector.IDBDatabaseTreeElement = function(storagePanel, model, databaseId) 1576{ 1577 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, databaseId.name + " - " + databaseId.securityOrigin, ["indexed-db-storage-tree-item"]); 1578 this._model = model; 1579 this._databaseId = databaseId; 1580 this._idbObjectStoreTreeElements = {}; 1581} 1582 1583WebInspector.IDBDatabaseTreeElement.prototype = { 1584 get itemURL() 1585 { 1586 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name; 1587 }, 1588 1589 onattach: function() 1590 { 1591 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); 1592 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); 1593 }, 1594 1595 _handleContextMenuEvent: function(event) 1596 { 1597 var contextMenu = new WebInspector.ContextMenu(event); 1598 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this._refreshIndexedDB.bind(this)); 1599 contextMenu.show(); 1600 }, 1601 1602 _refreshIndexedDB: function() 1603 { 1604 this._model.refreshDatabaseNames(); 1605 }, 1606 1607 /** 1608 * @param {!WebInspector.IndexedDBModel.Database} database 1609 */ 1610 update: function(database) 1611 { 1612 this._database = database; 1613 var objectStoreNames = {}; 1614 for (var objectStoreName in this._database.objectStores) { 1615 var objectStore = this._database.objectStores[objectStoreName]; 1616 objectStoreNames[objectStore.name] = true; 1617 if (!this._idbObjectStoreTreeElements[objectStore.name]) { 1618 var idbObjectStoreTreeElement = new WebInspector.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore); 1619 this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement; 1620 this.appendChild(idbObjectStoreTreeElement); 1621 } 1622 this._idbObjectStoreTreeElements[objectStore.name].update(objectStore); 1623 } 1624 for (var objectStoreName in this._idbObjectStoreTreeElements) { 1625 if (!objectStoreNames[objectStoreName]) 1626 this._objectStoreRemoved(objectStoreName); 1627 } 1628 1629 if (this.children.length) { 1630 this.hasChildren = true; 1631 this.expand(); 1632 } 1633 1634 if (this._view) 1635 this._view.update(database); 1636 1637 this._updateTooltip(); 1638 }, 1639 1640 _updateTooltip: function() 1641 { 1642 this.tooltip = WebInspector.UIString("Version") + ": " + this._database.version; 1643 }, 1644 1645 /** 1646 * @override 1647 * @return {boolean} 1648 */ 1649 onselect: function(selectedByUser) 1650 { 1651 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1652 if (!this._view) 1653 this._view = new WebInspector.IDBDatabaseView(this._database); 1654 1655 this._storagePanel.showIndexedDB(this._view); 1656 return false; 1657 }, 1658 1659 /** 1660 * @param {string} objectStoreName 1661 */ 1662 _objectStoreRemoved: function(objectStoreName) 1663 { 1664 var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName]; 1665 objectStoreTreeElement.clear(); 1666 this.removeChild(objectStoreTreeElement); 1667 delete this._idbObjectStoreTreeElements[objectStoreName]; 1668 }, 1669 1670 clear: function() 1671 { 1672 for (var objectStoreName in this._idbObjectStoreTreeElements) 1673 this._objectStoreRemoved(objectStoreName); 1674 }, 1675 1676 __proto__: WebInspector.BaseStorageTreeElement.prototype 1677} 1678 1679/** 1680 * @constructor 1681 * @extends {WebInspector.BaseStorageTreeElement} 1682 * @param {!WebInspector.ResourcesPanel} storagePanel 1683 * @param {!WebInspector.IndexedDBModel} model 1684 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId 1685 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore 1686 */ 1687WebInspector.IDBObjectStoreTreeElement = function(storagePanel, model, databaseId, objectStore) 1688{ 1689 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, objectStore.name, ["indexed-db-object-store-storage-tree-item"]); 1690 this._model = model; 1691 this._databaseId = databaseId; 1692 this._idbIndexTreeElements = {}; 1693} 1694 1695WebInspector.IDBObjectStoreTreeElement.prototype = { 1696 get itemURL() 1697 { 1698 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name; 1699 }, 1700 1701 onattach: function() 1702 { 1703 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); 1704 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); 1705 }, 1706 1707 _handleContextMenuEvent: function(event) 1708 { 1709 var contextMenu = new WebInspector.ContextMenu(event); 1710 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearObjectStore.bind(this)); 1711 contextMenu.show(); 1712 }, 1713 1714 _clearObjectStore: function() 1715 { 1716 /** 1717 * @this {WebInspector.IDBObjectStoreTreeElement} 1718 */ 1719 function callback() { 1720 this.update(this._objectStore); 1721 } 1722 this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this)); 1723 }, 1724 1725 /** 1726 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore 1727 */ 1728 update: function(objectStore) 1729 { 1730 this._objectStore = objectStore; 1731 1732 var indexNames = {}; 1733 for (var indexName in this._objectStore.indexes) { 1734 var index = this._objectStore.indexes[indexName]; 1735 indexNames[index.name] = true; 1736 if (!this._idbIndexTreeElements[index.name]) { 1737 var idbIndexTreeElement = new WebInspector.IDBIndexTreeElement(this._storagePanel, this._model, this._databaseId, this._objectStore, index); 1738 this._idbIndexTreeElements[index.name] = idbIndexTreeElement; 1739 this.appendChild(idbIndexTreeElement); 1740 } 1741 this._idbIndexTreeElements[index.name].update(index); 1742 } 1743 for (var indexName in this._idbIndexTreeElements) { 1744 if (!indexNames[indexName]) 1745 this._indexRemoved(indexName); 1746 } 1747 for (var indexName in this._idbIndexTreeElements) { 1748 if (!indexNames[indexName]) { 1749 this.removeChild(this._idbIndexTreeElements[indexName]); 1750 delete this._idbIndexTreeElements[indexName]; 1751 } 1752 } 1753 1754 if (this.children.length) { 1755 this.hasChildren = true; 1756 this.expand(); 1757 } 1758 1759 if (this._view) 1760 this._view.update(this._objectStore); 1761 1762 this._updateTooltip(); 1763 }, 1764 1765 _updateTooltip: function() 1766 { 1767 1768 var keyPathString = this._objectStore.keyPathString; 1769 var tooltipString = keyPathString !== null ? (WebInspector.UIString("Key path: ") + keyPathString) : ""; 1770 if (this._objectStore.autoIncrement) 1771 tooltipString += "\n" + WebInspector.UIString("autoIncrement"); 1772 this.tooltip = tooltipString 1773 }, 1774 1775 /** 1776 * @override 1777 * @return {boolean} 1778 */ 1779 onselect: function(selectedByUser) 1780 { 1781 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1782 if (!this._view) 1783 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, null); 1784 1785 this._storagePanel.showIndexedDB(this._view); 1786 return false; 1787 }, 1788 1789 /** 1790 * @param {string} indexName 1791 */ 1792 _indexRemoved: function(indexName) 1793 { 1794 var indexTreeElement = this._idbIndexTreeElements[indexName]; 1795 indexTreeElement.clear(); 1796 this.removeChild(indexTreeElement); 1797 delete this._idbIndexTreeElements[indexName]; 1798 }, 1799 1800 clear: function() 1801 { 1802 for (var indexName in this._idbIndexTreeElements) 1803 this._indexRemoved(indexName); 1804 if (this._view) 1805 this._view.clear(); 1806 }, 1807 1808 __proto__: WebInspector.BaseStorageTreeElement.prototype 1809} 1810 1811/** 1812 * @constructor 1813 * @extends {WebInspector.BaseStorageTreeElement} 1814 * @param {!WebInspector.ResourcesPanel} storagePanel 1815 * @param {!WebInspector.IndexedDBModel} model 1816 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId 1817 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore 1818 * @param {!WebInspector.IndexedDBModel.Index} index 1819 */ 1820WebInspector.IDBIndexTreeElement = function(storagePanel, model, databaseId, objectStore, index) 1821{ 1822 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, index.name, ["indexed-db-index-storage-tree-item"]); 1823 this._model = model; 1824 this._databaseId = databaseId; 1825 this._objectStore = objectStore; 1826 this._index = index; 1827} 1828 1829WebInspector.IDBIndexTreeElement.prototype = { 1830 get itemURL() 1831 { 1832 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name + "/" + this._index.name; 1833 }, 1834 1835 /** 1836 * @param {!WebInspector.IndexedDBModel.Index} index 1837 */ 1838 update: function(index) 1839 { 1840 this._index = index; 1841 1842 if (this._view) 1843 this._view.update(this._index); 1844 1845 this._updateTooltip(); 1846 }, 1847 1848 _updateTooltip: function() 1849 { 1850 var tooltipLines = []; 1851 var keyPathString = this._index.keyPathString; 1852 tooltipLines.push(WebInspector.UIString("Key path: ") + keyPathString); 1853 if (this._index.unique) 1854 tooltipLines.push(WebInspector.UIString("unique")); 1855 if (this._index.multiEntry) 1856 tooltipLines.push(WebInspector.UIString("multiEntry")); 1857 this.tooltip = tooltipLines.join("\n"); 1858 }, 1859 1860 /** 1861 * @override 1862 * @return {boolean} 1863 */ 1864 onselect: function(selectedByUser) 1865 { 1866 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1867 if (!this._view) 1868 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, this._index); 1869 1870 this._storagePanel.showIndexedDB(this._view); 1871 return false; 1872 }, 1873 1874 clear: function() 1875 { 1876 if (this._view) 1877 this._view.clear(); 1878 }, 1879 1880 __proto__: WebInspector.BaseStorageTreeElement.prototype 1881} 1882 1883/** 1884 * @constructor 1885 * @extends {WebInspector.BaseStorageTreeElement} 1886 */ 1887WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className) 1888{ 1889 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.securityOrigin ? domStorage.securityOrigin : WebInspector.UIString("Local Files"), ["domstorage-storage-tree-item", className]); 1890 this._domStorage = domStorage; 1891} 1892 1893WebInspector.DOMStorageTreeElement.prototype = { 1894 get itemURL() 1895 { 1896 return "storage://" + this._domStorage.securityOrigin + "/" + (this._domStorage.isLocalStorage ? "local" : "session"); 1897 }, 1898 1899 /** 1900 * @override 1901 * @return {boolean} 1902 */ 1903 onselect: function(selectedByUser) 1904 { 1905 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1906 this._storagePanel._showDOMStorage(this._domStorage); 1907 return false; 1908 }, 1909 1910 __proto__: WebInspector.BaseStorageTreeElement.prototype 1911} 1912 1913/** 1914 * @constructor 1915 * @extends {WebInspector.BaseStorageTreeElement} 1916 */ 1917WebInspector.CookieTreeElement = function(storagePanel, cookieDomain) 1918{ 1919 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), ["cookie-storage-tree-item"]); 1920 this._cookieDomain = cookieDomain; 1921} 1922 1923WebInspector.CookieTreeElement.prototype = { 1924 get itemURL() 1925 { 1926 return "cookies://" + this._cookieDomain; 1927 }, 1928 1929 onattach: function() 1930 { 1931 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this); 1932 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); 1933 }, 1934 1935 /** 1936 * @param {!Event} event 1937 */ 1938 _handleContextMenuEvent: function(event) 1939 { 1940 var contextMenu = new WebInspector.ContextMenu(event); 1941 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearCookies.bind(this)); 1942 contextMenu.show(); 1943 }, 1944 1945 /** 1946 * @param {string} domain 1947 */ 1948 _clearCookies: function(domain) 1949 { 1950 this._storagePanel.clearCookies(this._cookieDomain); 1951 }, 1952 1953 /** 1954 * @override 1955 * @return {boolean} 1956 */ 1957 onselect: function(selectedByUser) 1958 { 1959 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1960 this._storagePanel.showCookies(this, this._cookieDomain); 1961 return false; 1962 }, 1963 1964 __proto__: WebInspector.BaseStorageTreeElement.prototype 1965} 1966 1967/** 1968 * @constructor 1969 * @extends {WebInspector.BaseStorageTreeElement} 1970 */ 1971WebInspector.ApplicationCacheManifestTreeElement = function(storagePanel, manifestURL) 1972{ 1973 var title = new WebInspector.ParsedURL(manifestURL).displayName; 1974 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["application-cache-storage-tree-item"]); 1975 this.tooltip = manifestURL; 1976 this._manifestURL = manifestURL; 1977} 1978 1979WebInspector.ApplicationCacheManifestTreeElement.prototype = { 1980 get itemURL() 1981 { 1982 return "appcache://" + this._manifestURL; 1983 }, 1984 1985 get manifestURL() 1986 { 1987 return this._manifestURL; 1988 }, 1989 1990 /** 1991 * @override 1992 * @return {boolean} 1993 */ 1994 onselect: function(selectedByUser) 1995 { 1996 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 1997 this._storagePanel.showCategoryView(this._manifestURL); 1998 return false; 1999 }, 2000 2001 __proto__: WebInspector.BaseStorageTreeElement.prototype 2002} 2003 2004/** 2005 * @constructor 2006 * @extends {WebInspector.BaseStorageTreeElement} 2007 */ 2008WebInspector.ApplicationCacheFrameTreeElement = function(storagePanel, frameId, manifestURL) 2009{ 2010 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]); 2011 this._frameId = frameId; 2012 this._manifestURL = manifestURL; 2013 this._refreshTitles(); 2014} 2015 2016WebInspector.ApplicationCacheFrameTreeElement.prototype = { 2017 get itemURL() 2018 { 2019 return "appcache://" + this._manifestURL + "/" + encodeURI(this.displayName); 2020 }, 2021 2022 get frameId() 2023 { 2024 return this._frameId; 2025 }, 2026 2027 get manifestURL() 2028 { 2029 return this._manifestURL; 2030 }, 2031 2032 _refreshTitles: function() 2033 { 2034 var frame = WebInspector.resourceTreeModel.frameForId(this._frameId); 2035 if (!frame) { 2036 this.subtitleText = WebInspector.UIString("new frame"); 2037 return; 2038 } 2039 this.titleText = frame.name; 2040 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName; 2041 }, 2042 2043 frameNavigated: function() 2044 { 2045 this._refreshTitles(); 2046 }, 2047 2048 /** 2049 * @override 2050 * @return {boolean} 2051 */ 2052 onselect: function(selectedByUser) 2053 { 2054 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 2055 this._storagePanel.showApplicationCache(this._frameId); 2056 return false; 2057 }, 2058 2059 __proto__: WebInspector.BaseStorageTreeElement.prototype 2060} 2061 2062/** 2063 * @constructor 2064 * @extends {WebInspector.BaseStorageTreeElement} 2065 * @param {!WebInspector.ResourcesPanel} storagePanel 2066 * @param {!WebInspector.FileSystemModel.FileSystem} fileSystem 2067 */ 2068WebInspector.FileSystemTreeElement = function(storagePanel, fileSystem) 2069{ 2070 var displayName = fileSystem.type + " - " + fileSystem.origin; 2071 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, ["file-system-storage-tree-item"]); 2072 this._fileSystem = fileSystem; 2073} 2074 2075WebInspector.FileSystemTreeElement.prototype = { 2076 get fileSystemName() 2077 { 2078 return this._fileSystem.name; 2079 }, 2080 2081 get itemURL() 2082 { 2083 return "filesystem://" + this._fileSystem.name; 2084 }, 2085 2086 /** 2087 * @override 2088 * @return {boolean} 2089 */ 2090 onselect: function(selectedByUser) 2091 { 2092 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser); 2093 this._fileSystemView = new WebInspector.FileSystemView(this._fileSystem); 2094 this._storagePanel.showFileSystem(this._fileSystemView); 2095 return false; 2096 }, 2097 2098 clear: function() 2099 { 2100 if (this.fileSystemView && this._storagePanel.visibleView === this.fileSystemView) 2101 this._storagePanel.closeVisibleView(); 2102 }, 2103 2104 __proto__: WebInspector.BaseStorageTreeElement.prototype 2105} 2106 2107/** 2108 * @constructor 2109 * @extends {WebInspector.VBox} 2110 */ 2111WebInspector.StorageCategoryView = function() 2112{ 2113 WebInspector.VBox.call(this); 2114 2115 this.element.classList.add("storage-view"); 2116 this._emptyView = new WebInspector.EmptyView(""); 2117 this._emptyView.show(this.element); 2118} 2119 2120WebInspector.StorageCategoryView.prototype = { 2121 setText: function(text) 2122 { 2123 this._emptyView.text = text; 2124 }, 2125 2126 __proto__: WebInspector.VBox.prototype 2127} 2128