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