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.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
31 importScript("ApplicationCacheItemsView.js");
32 importScript("DOMStorageItemsView.js");
33 importScript("DatabaseQueryView.js");
34 importScript("DatabaseTableView.js");
35 importScript("DirectoryContentView.js");
36 importScript("IndexedDBViews.js");
37 importScript("FileContentView.js");
38 importScript("FileSystemView.js");
42 * @extends {WebInspector.PanelWithSidebarTree}
44 WebInspector.ResourcesPanel = function(database)
46 WebInspector.PanelWithSidebarTree.call(this, "resources");
47 this.registerRequiredCSS("resourcesPanel.css");
49 WebInspector.settings.resourcesLastSelectedItem = WebInspector.settings.createSetting("resourcesLastSelectedItem", {});
51 this.sidebarElement().classList.add("filter-all", "children", "small", "outline-disclosure");
52 this.sidebarTree.element.classList.remove("sidebar-tree");
54 this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]);
55 this.sidebarTree.appendChild(this.resourcesListTreeElement);
57 this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Web SQL"), "Databases", ["database-storage-tree-item"]);
58 this.sidebarTree.appendChild(this.databasesListTreeElement);
60 this.indexedDBListTreeElement = new WebInspector.IndexedDBTreeElement(this);
61 this.sidebarTree.appendChild(this.indexedDBListTreeElement);
63 this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", ["domstorage-storage-tree-item", "local-storage"]);
64 this.sidebarTree.appendChild(this.localStorageListTreeElement);
66 this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", ["domstorage-storage-tree-item", "session-storage"]);
67 this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
69 this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", ["cookie-storage-tree-item"]);
70 this.sidebarTree.appendChild(this.cookieListTreeElement);
72 this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", ["application-cache-storage-tree-item"]);
73 this.sidebarTree.appendChild(this.applicationCacheListTreeElement);
75 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled()) {
76 this.fileSystemListTreeElement = new WebInspector.FileSystemListTreeElement(this);
77 this.sidebarTree.appendChild(this.fileSystemListTreeElement);
80 var mainView = new WebInspector.View();
81 this.storageViews = mainView.element.createChild("div", "resources-main diff-container");
82 var statusBarContainer = mainView.element.createChild("div", "resources-status-bar");
83 this.storageViewStatusBarItemsContainer = statusBarContainer.createChild("div", "status-bar");
84 mainView.show(this.mainElement());
86 /** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */
87 this._databaseTableViews = new Map();
88 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseQueryView>} */
89 this._databaseQueryViews = new Map();
90 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseTreeElement>} */
91 this._databaseTreeElements = new Map();
92 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageItemsView>} */
93 this._domStorageViews = new Map();
94 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageTreeElement>} */
95 this._domStorageTreeElements = new Map();
96 /** @type {!Object.<string, !WebInspector.CookieItemsView>} */
97 this._cookieViews = {};
98 /** @type {!Object.<string, boolean>} */
101 this.sidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false);
102 this.sidebarElement().addEventListener("mouseout", this._onmouseout.bind(this), false);
105 * @return {!WebInspector.View}
106 * @this {WebInspector.ResourcesPanel}
108 function viewGetter()
110 return this.visibleView;
112 WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
114 if (WebInspector.resourceTreeModel.cachedResourcesLoaded())
115 this._cachedResourcesLoaded();
117 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
118 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this);
119 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
121 WebInspector.databaseModel.databases().forEach(this._addDatabase.bind(this));
122 WebInspector.databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
125 WebInspector.ResourcesPanel.prototype = {
129 canSearch: function()
136 WebInspector.Panel.prototype.wasShown.call(this);
140 _initialize: function()
142 if (!this._initialized && this.isShowing() && this._cachedResourcesWereLoaded) {
143 this._populateResourceTree();
144 this._populateDOMStorageTree();
145 this._populateApplicationCacheTree();
146 this.indexedDBListTreeElement._initialize();
147 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled())
148 this.fileSystemListTreeElement._initialize();
149 this._initDefaultSelection();
150 this._initialized = true;
154 _loadEventFired: function()
156 this._initDefaultSelection();
159 _initDefaultSelection: function()
161 if (!this._initialized)
164 var itemURL = WebInspector.settings.resourcesLastSelectedItem.get();
166 for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) {
167 if (treeElement.itemURL === itemURL) {
168 treeElement.revealAndSelect(true);
174 var mainResource = WebInspector.inspectedPageURL && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded && WebInspector.resourceTreeModel.resourceForURL(WebInspector.inspectedPageURL);
176 this.showResource(mainResource);
179 _resetWithFrames: function()
181 this.resourcesListTreeElement.removeChildren();
182 this._treeElementForFrameId = {};
189 var queryViews = this._databaseQueryViews.values();
190 for (var i = 0; i < queryViews.length; ++i)
191 queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
192 this._databaseTableViews.clear();
193 this._databaseQueryViews.clear();
194 this._databaseTreeElements.clear();
195 this._domStorageViews.clear();
196 this._domStorageTreeElements.clear();
197 this._cookieViews = {};
199 this.databasesListTreeElement.removeChildren();
200 this.localStorageListTreeElement.removeChildren();
201 this.sessionStorageListTreeElement.removeChildren();
202 this.cookieListTreeElement.removeChildren();
204 if (this.visibleView && !(this.visibleView instanceof WebInspector.StorageCategoryView))
205 this.visibleView.detach();
207 this.storageViewStatusBarItemsContainer.removeChildren();
209 if (this.sidebarTree.selectedTreeElement)
210 this.sidebarTree.selectedTreeElement.deselect();
213 _populateResourceTree: function()
215 this._treeElementForFrameId = {};
216 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
217 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
218 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
219 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
222 * @param {!WebInspector.ResourceTreeFrame} frame
223 * @this {WebInspector.ResourcesPanel}
225 function populateFrame(frame)
227 this._frameAdded({data:frame});
228 for (var i = 0; i < frame.childFrames.length; ++i)
229 populateFrame.call(this, frame.childFrames[i]);
231 var resources = frame.resources();
232 for (var i = 0; i < resources.length; ++i)
233 this._resourceAdded({data:resources[i]});
235 populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
238 _frameAdded: function(event)
240 var frame = event.data;
241 var parentFrame = frame.parentFrame;
243 var parentTreeElement = parentFrame ? this._treeElementForFrameId[parentFrame.id] : this.resourcesListTreeElement;
244 if (!parentTreeElement) {
245 console.warn("No frame to route " + frame.url + " to.")
249 var frameTreeElement = new WebInspector.FrameTreeElement(this, frame);
250 this._treeElementForFrameId[frame.id] = frameTreeElement;
251 parentTreeElement.appendChild(frameTreeElement);
254 _frameDetached: function(event)
256 var frame = event.data;
257 var frameTreeElement = this._treeElementForFrameId[frame.id];
258 if (!frameTreeElement)
261 delete this._treeElementForFrameId[frame.id];
262 if (frameTreeElement.parent)
263 frameTreeElement.parent.removeChild(frameTreeElement);
266 _resourceAdded: function(event)
268 var resource = event.data;
269 var frameId = resource.frameId;
271 if (resource.statusCode >= 301 && resource.statusCode <= 303)
274 var frameTreeElement = this._treeElementForFrameId[frameId];
275 if (!frameTreeElement) {
276 // This is a frame's main resource, it will be retained
277 // and re-added by the resource manager;
281 frameTreeElement.appendResource(resource);
284 _frameNavigated: function(event)
286 var frame = event.data;
288 if (!frame.parentFrame)
291 var frameId = frame.id;
292 var frameTreeElement = this._treeElementForFrameId[frameId];
293 if (frameTreeElement)
294 frameTreeElement.frameNavigated(frame);
296 var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frameId];
297 if (applicationCacheFrameTreeElement)
298 applicationCacheFrameTreeElement.frameNavigated(frame);
301 _cachedResourcesLoaded: function()
303 this._cachedResourcesWereLoaded = true;
308 * @param {!WebInspector.Event} event
310 _databaseAdded: function(event)
312 var database = /** @type {!WebInspector.Database} */ (event.data);
313 this._addDatabase(database);
317 * @param {!WebInspector.Database} database
319 _addDatabase: function(database)
321 var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database);
322 this._databaseTreeElements.put(database, databaseTreeElement);
323 this.databasesListTreeElement.appendChild(databaseTreeElement);
326 addDocumentURL: function(url)
328 var parsedURL = url.asParsedURL();
332 var domain = parsedURL.host;
333 if (!this._domains[domain]) {
334 this._domains[domain] = true;
336 var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain);
337 this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
342 * @param {!WebInspector.Event} event
344 _domStorageAdded: function(event)
346 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
347 this._addDOMStorage(domStorage);
351 * @param {!WebInspector.DOMStorage} domStorage
353 _addDOMStorage: function(domStorage)
355 console.assert(!this._domStorageTreeElements.get(domStorage));
357 var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
358 this._domStorageTreeElements.put(domStorage, domStorageTreeElement);
359 if (domStorage.isLocalStorage)
360 this.localStorageListTreeElement.appendChild(domStorageTreeElement);
362 this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
366 * @param {!WebInspector.Event} event
368 _domStorageRemoved: function(event)
370 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
371 this._removeDOMStorage(domStorage);
375 * @param {!WebInspector.DOMStorage} domStorage
377 _removeDOMStorage: function(domStorage)
379 var treeElement = this._domStorageTreeElements.get(domStorage);
382 var wasSelected = treeElement.selected;
383 var parentListTreeElement = treeElement.parent;
384 parentListTreeElement.removeChild(treeElement);
386 parentListTreeElement.select();
387 this._domStorageTreeElements.remove(treeElement);
388 this._domStorageViews.remove(domStorage);
392 * @param {!WebInspector.Database} database
394 selectDatabase: function(database)
397 this._showDatabase(database);
398 this._databaseTreeElements.get(database).select();
403 * @param {!WebInspector.DOMStorage} domStorage
405 selectDOMStorage: function(domStorage)
408 this._showDOMStorage(domStorage);
409 this._domStorageTreeElements.get(domStorage).select();
414 * @param {!WebInspector.Resource} resource
415 * @param {number=} line
416 * @param {number=} column
419 showResource: function(resource, line, column)
421 var resourceTreeElement = this._findTreeElementForResource(resource);
422 if (resourceTreeElement)
423 resourceTreeElement.revealAndSelect(true);
425 if (typeof line === "number") {
426 var view = this._resourceViewForResource(resource);
427 if (view.canHighlightPosition())
428 view.highlightPosition(line, column);
433 _showResourceView: function(resource)
435 var view = this._resourceViewForResource(resource);
437 this.visibleView.detach();
440 this._innerShowView(view);
443 _resourceViewForResource: function(resource)
445 if (WebInspector.ResourceView.hasTextContent(resource)) {
446 var treeElement = this._findTreeElementForResource(resource);
449 return treeElement.sourceView();
451 return WebInspector.ResourceView.nonSourceViewForResource(resource);
455 * @param {!WebInspector.Database} database
456 * @param {string=} tableName
458 _showDatabase: function(database, tableName)
465 var tableViews = this._databaseTableViews.get(database);
467 tableViews = /** @type {!Object.<string, !WebInspector.DatabaseTableView>} */ ({});
468 this._databaseTableViews.put(database, tableViews);
470 view = tableViews[tableName];
472 view = new WebInspector.DatabaseTableView(database, tableName);
473 tableViews[tableName] = view;
476 view = this._databaseQueryViews.get(database);
478 view = new WebInspector.DatabaseQueryView(database);
479 this._databaseQueryViews.put(database, view);
480 view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
484 this._innerShowView(view);
488 * @param {!WebInspector.View} view
490 showIndexedDB: function(view)
492 this._innerShowView(view);
496 * @param {!WebInspector.DOMStorage} domStorage
498 _showDOMStorage: function(domStorage)
504 view = this._domStorageViews.get(domStorage);
506 view = new WebInspector.DOMStorageItemsView(domStorage);
507 this._domStorageViews.put(domStorage, view);
510 this._innerShowView(view);
514 * @param {!WebInspector.CookieTreeElement} treeElement
515 * @param {string} cookieDomain
517 showCookies: function(treeElement, cookieDomain)
519 var view = this._cookieViews[cookieDomain];
521 view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
522 this._cookieViews[cookieDomain] = view;
525 this._innerShowView(view);
529 * @param {string} cookieDomain
531 clearCookies: function(cookieDomain)
533 this._cookieViews[cookieDomain].clear();
536 showApplicationCache: function(frameId)
538 if (!this._applicationCacheViews[frameId])
539 this._applicationCacheViews[frameId] = new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
541 this._innerShowView(this._applicationCacheViews[frameId]);
545 * @param {!WebInspector.View} view
547 showFileSystem: function(view)
549 this._innerShowView(view);
552 showCategoryView: function(categoryName)
554 if (!this._categoryView)
555 this._categoryView = new WebInspector.StorageCategoryView();
556 this._categoryView.setText(categoryName);
557 this._innerShowView(this._categoryView);
560 _innerShowView: function(view)
562 if (this.visibleView === view)
565 if (this.visibleView)
566 this.visibleView.detach();
568 view.show(this.storageViews);
569 this.visibleView = view;
571 this.storageViewStatusBarItemsContainer.removeChildren();
572 var statusBarItems = view.statusBarItems || [];
573 for (var i = 0; i < statusBarItems.length; ++i)
574 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
577 closeVisibleView: function()
579 if (!this.visibleView)
581 this.visibleView.detach();
582 delete this.visibleView;
585 _updateDatabaseTables: function(event)
587 var database = event.data;
592 var databasesTreeElement = this._databaseTreeElements.get(database);
593 if (!databasesTreeElement)
596 databasesTreeElement.shouldRefreshChildren = true;
597 var tableViews = this._databaseTableViews.get(database);
602 var tableNamesHash = {};
604 function tableNamesCallback(tableNames)
606 var tableNamesLength = tableNames.length;
607 for (var i = 0; i < tableNamesLength; ++i)
608 tableNamesHash[tableNames[i]] = true;
610 for (var tableName in tableViews) {
611 if (!(tableName in tableNamesHash)) {
612 if (self.visibleView === tableViews[tableName])
613 self.closeVisibleView();
614 delete tableViews[tableName];
618 database.getTableNames(tableNamesCallback);
621 _populateDOMStorageTree: function()
623 WebInspector.domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
624 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
625 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
628 _populateApplicationCacheTree: function()
630 this._applicationCacheModel = new WebInspector.ApplicationCacheModel();
632 this._applicationCacheViews = {};
633 this._applicationCacheFrameElements = {};
634 this._applicationCacheManifestElements = {};
636 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
637 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
639 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, this._applicationCacheFrameManifestStatusChanged, this);
640 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
643 _applicationCacheFrameManifestAdded: function(event)
645 var frameId = event.data;
646 var manifestURL = this._applicationCacheModel.frameManifestURL(frameId);
647 var status = this._applicationCacheModel.frameManifestStatus(frameId)
649 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]
650 if (!manifestTreeElement) {
651 manifestTreeElement = new WebInspector.ApplicationCacheManifestTreeElement(this, manifestURL);
652 this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
653 this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
656 var frameTreeElement = new WebInspector.ApplicationCacheFrameTreeElement(this, frameId, manifestURL);
657 manifestTreeElement.appendChild(frameTreeElement);
658 manifestTreeElement.expand();
659 this._applicationCacheFrameElements[frameId] = frameTreeElement;
662 _applicationCacheFrameManifestRemoved: function(event)
664 var frameId = event.data;
665 var frameTreeElement = this._applicationCacheFrameElements[frameId];
666 if (!frameTreeElement)
669 var manifestURL = frameTreeElement.manifestURL;
670 delete this._applicationCacheFrameElements[frameId];
671 delete this._applicationCacheViews[frameId];
672 frameTreeElement.parent.removeChild(frameTreeElement);
674 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
675 if (manifestTreeElement.children.length !== 0)
678 delete this._applicationCacheManifestElements[manifestURL];
679 manifestTreeElement.parent.removeChild(manifestTreeElement);
682 _applicationCacheFrameManifestStatusChanged: function(event)
684 var frameId = event.data;
685 var status = this._applicationCacheModel.frameManifestStatus(frameId)
687 if (this._applicationCacheViews[frameId])
688 this._applicationCacheViews[frameId].updateStatus(status);
691 _applicationCacheNetworkStateChanged: function(event)
693 var isNowOnline = event.data;
695 for (var manifestURL in this._applicationCacheViews)
696 this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
699 _forAllResourceTreeElements: function(callback)
702 for (var treeElement = this.resourcesListTreeElement; !stop && treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.resourcesListTreeElement, true)) {
703 if (treeElement instanceof WebInspector.FrameResourceTreeElement)
704 stop = callback(treeElement);
708 _findTreeElementForResource: function(resource)
710 function isAncestor(ancestor, object)
712 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
716 function getParent(object)
718 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
722 return this.sidebarTree.findTreeElement(resource, isAncestor, getParent);
725 showView: function(view)
728 this.showResource(view.resource);
731 _onmousemove: function(event)
733 var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
737 var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");
741 var element = listNode.treeElement;
742 if (this._previousHoveredElement === element)
745 if (this._previousHoveredElement) {
746 this._previousHoveredElement.hovered = false;
747 delete this._previousHoveredElement;
750 if (element instanceof WebInspector.FrameTreeElement) {
751 this._previousHoveredElement = element;
752 element.hovered = true;
756 _onmouseout: function(event)
758 if (this._previousHoveredElement) {
759 this._previousHoveredElement.hovered = false;
760 delete this._previousHoveredElement;
764 __proto__: WebInspector.PanelWithSidebarTree.prototype
769 * @implements {WebInspector.Revealer}
771 WebInspector.ResourcesPanel.ResourceRevealer = function()
775 WebInspector.ResourcesPanel.ResourceRevealer.prototype = {
777 * @param {!Object} resource
778 * @param {number=} lineNumber
780 reveal: function(resource, lineNumber)
782 if (resource instanceof WebInspector.Resource)
783 /** @type {!WebInspector.ResourcesPanel} */ (WebInspector.showPanel("resources")).showResource(resource, lineNumber);
789 * @extends {TreeElement}
790 * @param {boolean=} hasChildren
791 * @param {boolean=} noIcon
793 WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren, noIcon)
795 TreeElement.call(this, "", representedObject, hasChildren);
796 this._storagePanel = storagePanel;
797 this._titleText = title;
798 this._iconClasses = iconClasses;
799 this._noIcon = noIcon;
802 WebInspector.BaseStorageTreeElement.prototype = {
805 this.listItemElement.removeChildren();
806 if (this._iconClasses) {
807 for (var i = 0; i < this._iconClasses.length; ++i)
808 this.listItemElement.classList.add(this._iconClasses[i]);
811 var selectionElement = document.createElement("div");
812 selectionElement.className = "selection";
813 this.listItemElement.appendChild(selectionElement);
816 this.imageElement = document.createElement("img");
817 this.imageElement.className = "icon";
818 this.listItemElement.appendChild(this.imageElement);
821 this.titleElement = document.createElement("div");
822 this.titleElement.className = "base-storage-tree-element-title";
823 this._titleTextNode = document.createTextNode("");
824 this.titleElement.appendChild(this._titleTextNode);
826 this._updateSubtitle();
827 this.listItemElement.appendChild(this.titleElement);
832 return this._displayName;
835 _updateDisplayName: function()
837 this._displayName = this._titleText || "";
838 if (this._subtitleText)
839 this._displayName += " (" + this._subtitleText + ")";
842 _updateTitle: function()
844 this._updateDisplayName();
846 if (!this.titleElement)
849 this._titleTextNode.textContent = this._titleText || "";
852 _updateSubtitle: function()
854 this._updateDisplayName();
856 if (!this.titleElement)
859 if (this._subtitleText) {
860 if (!this._subtitleElement) {
861 this._subtitleElement = document.createElement("span");
862 this._subtitleElement.className = "base-storage-tree-element-subtitle";
863 this.titleElement.appendChild(this._subtitleElement);
865 this._subtitleElement.textContent = "(" + this._subtitleText + ")";
866 } else if (this._subtitleElement) {
867 this.titleElement.removeChild(this._subtitleElement);
868 delete this._subtitleElement;
876 onselect: function(selectedByUser)
880 var itemURL = this.itemURL;
882 WebInspector.settings.resourcesLastSelectedItem.set(itemURL);
891 if (this.listItemElement)
892 this.listItemElement.scrollIntoViewIfNeeded(false);
897 return this._titleText;
900 set titleText(titleText)
902 this._titleText = titleText;
908 return this._subtitleText;
911 set subtitleText(subtitleText)
913 this._subtitleText = subtitleText;
914 this._updateSubtitle();
917 __proto__: TreeElement.prototype
922 * @extends {WebInspector.BaseStorageTreeElement}
923 * @param {boolean=} noIcon
925 WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
927 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, false, noIcon);
928 this._expandedSettingKey = "resources" + settingsKey + "Expanded";
929 WebInspector.settings[this._expandedSettingKey] = WebInspector.settings.createSetting(this._expandedSettingKey, settingsKey === "Frames");
930 this._categoryName = categoryName;
933 WebInspector.StorageCategoryTreeElement.prototype = {
936 return "category://" + this._categoryName;
943 onselect: function(selectedByUser)
945 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
946 this._storagePanel.showCategoryView(this._categoryName);
955 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
956 if (WebInspector.settings[this._expandedSettingKey].get())
965 WebInspector.settings[this._expandedSettingKey].set(true);
971 oncollapse: function()
973 WebInspector.settings[this._expandedSettingKey].set(false);
976 __proto__: WebInspector.BaseStorageTreeElement.prototype
981 * @extends {WebInspector.BaseStorageTreeElement}
983 WebInspector.FrameTreeElement = function(storagePanel, frame)
985 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
987 this.frameNavigated(frame);
990 WebInspector.FrameTreeElement.prototype = {
991 frameNavigated: function(frame)
993 this.removeChildren();
994 this._frameId = frame.id;
996 this.titleText = frame.name;
997 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
999 this._categoryElements = {};
1000 this._treeElementForResource = {};
1002 this._storagePanel.addDocumentURL(frame.url);
1007 return "frame://" + encodeURI(this.displayName);
1014 onselect: function(selectedByUser)
1016 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1017 this._storagePanel.showCategoryView(this.displayName);
1019 this.listItemElement.classList.remove("hovered");
1020 DOMAgent.hideHighlight();
1024 set hovered(hovered)
1027 this.listItemElement.classList.add("hovered");
1028 DOMAgent.highlightFrame(this._frameId, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
1030 this.listItemElement.classList.remove("hovered");
1031 DOMAgent.hideHighlight();
1035 appendResource: function(resource)
1037 if (resource.isHidden())
1039 var categoryName = resource.type.name();
1040 var categoryElement = resource.type === WebInspector.resourceTypes.Document ? this : this._categoryElements[categoryName];
1041 if (!categoryElement) {
1042 categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.type.categoryTitle(), categoryName, null, true);
1043 this._categoryElements[resource.type.name()] = categoryElement;
1044 this._insertInPresentationOrder(this, categoryElement);
1046 var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource);
1047 this._insertInPresentationOrder(categoryElement, resourceTreeElement);
1048 this._treeElementForResource[resource.url] = resourceTreeElement;
1052 * @param {string} url
1053 * @return {?WebInspector.Resource}
1055 resourceByURL: function(url)
1057 var treeElement = this._treeElementForResource[url];
1058 return treeElement ? treeElement.representedObject : null;
1061 appendChild: function(treeElement)
1063 this._insertInPresentationOrder(this, treeElement);
1066 _insertInPresentationOrder: function(parentTreeElement, childTreeElement)
1068 // Insert in the alphabetical order, first frames, then resources. Document resource goes last.
1069 function typeWeight(treeElement)
1071 if (treeElement instanceof WebInspector.StorageCategoryTreeElement)
1073 if (treeElement instanceof WebInspector.FrameTreeElement)
1078 function compare(treeElement1, treeElement2)
1080 var typeWeight1 = typeWeight(treeElement1);
1081 var typeWeight2 = typeWeight(treeElement2);
1084 if (typeWeight1 > typeWeight2)
1086 else if (typeWeight1 < typeWeight2)
1089 var title1 = treeElement1.displayName || treeElement1.titleText;
1090 var title2 = treeElement2.displayName || treeElement2.titleText;
1091 result = title1.localeCompare(title2);
1096 var children = parentTreeElement.children;
1098 for (i = 0; i < children.length; ++i) {
1099 if (compare(childTreeElement, children[i]) < 0)
1102 parentTreeElement.insertChild(childTreeElement, i);
1105 __proto__: WebInspector.BaseStorageTreeElement.prototype
1110 * @extends {WebInspector.BaseStorageTreeElement}
1112 WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
1114 WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, ["resource-sidebar-tree-item", "resources-type-" + resource.type.name()]);
1115 this._resource = resource;
1116 this._resource.addEventListener(WebInspector.Resource.Events.MessageAdded, this._consoleMessageAdded, this);
1117 this._resource.addEventListener(WebInspector.Resource.Events.MessagesCleared, this._consoleMessagesCleared, this);
1118 this.tooltip = resource.url;
1121 WebInspector.FrameResourceTreeElement.prototype = {
1124 return this._resource.url;
1131 onselect: function(selectedByUser)
1133 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1134 this._storagePanel._showResourceView(this._resource);
1142 ondblclick: function(event)
1144 InspectorFrontendHost.openInNewTab(this._resource.url);
1151 onattach: function()
1153 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1155 if (this._resource.type === WebInspector.resourceTypes.Image) {
1156 var previewImage = document.createElement("img");
1157 previewImage.className = "image-resource-icon-preview";
1158 this._resource.populateImageSource(previewImage);
1160 var iconElement = document.createElement("div");
1161 iconElement.className = "icon";
1162 iconElement.appendChild(previewImage);
1163 this.listItemElement.replaceChild(iconElement, this.imageElement);
1166 this._statusElement = document.createElement("div");
1167 this._statusElement.className = "status";
1168 this.listItemElement.insertBefore(this._statusElement, this.titleElement);
1170 this.listItemElement.draggable = true;
1171 this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
1172 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1174 this._updateErrorsAndWarningsBubbles();
1178 * @param {!MouseEvent} event
1181 _ondragstart: function(event)
1183 event.dataTransfer.setData("text/plain", this._resource.content);
1184 event.dataTransfer.effectAllowed = "copy";
1188 _handleContextMenuEvent: function(event)
1190 var contextMenu = new WebInspector.ContextMenu(event);
1191 contextMenu.appendApplicableItems(this._resource);
1195 _setBubbleText: function(x)
1197 if (!this._bubbleElement) {
1198 this._bubbleElement = document.createElement("div");
1199 this._bubbleElement.className = "bubble";
1200 this._statusElement.appendChild(this._bubbleElement);
1203 this._bubbleElement.textContent = x;
1206 _resetBubble: function()
1208 if (this._bubbleElement) {
1209 this._bubbleElement.textContent = "";
1210 this._bubbleElement.classList.remove("warning");
1211 this._bubbleElement.classList.remove("error");
1215 _updateErrorsAndWarningsBubbles: function()
1217 if (this._storagePanel.currentQuery)
1220 this._resetBubble();
1222 if (this._resource.warnings || this._resource.errors)
1223 this._setBubbleText(this._resource.warnings + this._resource.errors);
1225 if (this._resource.warnings)
1226 this._bubbleElement.classList.add("warning");
1228 if (this._resource.errors)
1229 this._bubbleElement.classList.add("error");
1232 _consoleMessagesCleared: function()
1234 // FIXME: move to the SourceFrame.
1235 if (this._sourceView)
1236 this._sourceView.clearMessages();
1238 this._updateErrorsAndWarningsBubbles();
1241 _consoleMessageAdded: function(event)
1243 var msg = event.data;
1244 if (this._sourceView)
1245 this._sourceView.addMessage(msg);
1246 this._updateErrorsAndWarningsBubbles();
1250 * @return {!WebInspector.ResourceSourceFrame}
1252 sourceView: function()
1254 if (!this._sourceView) {
1255 var sourceFrame = new WebInspector.ResourceSourceFrame(this._resource);
1256 sourceFrame.setHighlighterType(this._resource.canonicalMimeType());
1257 this._sourceView = sourceFrame;
1258 if (this._resource.messages) {
1259 for (var i = 0; i < this._resource.messages.length; i++)
1260 this._sourceView.addMessage(this._resource.messages[i]);
1263 return this._sourceView;
1266 __proto__: WebInspector.BaseStorageTreeElement.prototype
1271 * @extends {WebInspector.BaseStorageTreeElement}
1272 * @param {!WebInspector.Database} database
1274 WebInspector.DatabaseTreeElement = function(storagePanel, database)
1276 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, ["database-storage-tree-item"], true);
1277 this._database = database;
1280 WebInspector.DatabaseTreeElement.prototype = {
1283 return "database://" + encodeURI(this._database.name);
1290 onselect: function(selectedByUser)
1292 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1293 this._storagePanel._showDatabase(this._database);
1300 onexpand: function()
1302 this._updateChildren();
1305 _updateChildren: function()
1307 this.removeChildren();
1310 * @param {!Array.<string>} tableNames
1311 * @this {WebInspector.DatabaseTreeElement}
1313 function tableNamesCallback(tableNames)
1315 var tableNamesLength = tableNames.length;
1316 for (var i = 0; i < tableNamesLength; ++i)
1317 this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i]));
1319 this._database.getTableNames(tableNamesCallback.bind(this));
1322 __proto__: WebInspector.BaseStorageTreeElement.prototype
1327 * @extends {WebInspector.BaseStorageTreeElement}
1329 WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName)
1331 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, ["database-storage-tree-item"]);
1332 this._database = database;
1333 this._tableName = tableName;
1336 WebInspector.DatabaseTableTreeElement.prototype = {
1339 return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName);
1346 onselect: function(selectedByUser)
1348 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1349 this._storagePanel._showDatabase(this._database, this._tableName);
1353 __proto__: WebInspector.BaseStorageTreeElement.prototype
1358 * @extends {WebInspector.StorageCategoryTreeElement}
1359 * @param {!WebInspector.ResourcesPanel} storagePanel
1361 WebInspector.IndexedDBTreeElement = function(storagePanel)
1363 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("IndexedDB"), "IndexedDB", ["indexed-db-storage-tree-item"]);
1366 WebInspector.IndexedDBTreeElement.prototype = {
1367 _initialize: function()
1369 this._createIndexedDBModel();
1372 onattach: function()
1374 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1375 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1378 _handleContextMenuEvent: function(event)
1380 var contextMenu = new WebInspector.ContextMenu(event);
1381 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this.refreshIndexedDB.bind(this));
1385 _createIndexedDBModel: function()
1387 this._indexedDBModel = new WebInspector.IndexedDBModel();
1388 this._idbDatabaseTreeElements = [];
1389 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this);
1390 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this);
1391 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, this._indexedDBLoaded, this);
1394 refreshIndexedDB: function()
1396 if (!this._indexedDBModel) {
1397 this._createIndexedDBModel();
1401 this._indexedDBModel.refreshDatabaseNames();
1405 * @param {!WebInspector.Event} event
1407 _indexedDBAdded: function(event)
1409 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1411 var idbDatabaseTreeElement = new WebInspector.IDBDatabaseTreeElement(this._storagePanel, this._indexedDBModel, databaseId);
1412 this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
1413 this.appendChild(idbDatabaseTreeElement);
1415 this._indexedDBModel.refreshDatabase(databaseId);
1419 * @param {!WebInspector.Event} event
1421 _indexedDBRemoved: function(event)
1423 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1425 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(databaseId)
1426 if (!idbDatabaseTreeElement)
1429 idbDatabaseTreeElement.clear();
1430 this.removeChild(idbDatabaseTreeElement);
1431 this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
1435 * @param {!WebInspector.Event} event
1437 _indexedDBLoaded: function(event)
1439 var database = /** @type {!WebInspector.IndexedDBModel.Database} */ (event.data);
1441 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(database.databaseId)
1442 if (!idbDatabaseTreeElement)
1445 idbDatabaseTreeElement.update(database);
1449 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1450 * @return {?WebInspector.IDBDatabaseTreeElement}
1452 _idbDatabaseTreeElement: function(databaseId)
1455 for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
1456 if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId)) {
1462 return this._idbDatabaseTreeElements[i];
1466 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1471 * @extends {WebInspector.StorageCategoryTreeElement}
1472 * @param {!WebInspector.ResourcesPanel} storagePanel
1474 WebInspector.FileSystemListTreeElement = function(storagePanel)
1476 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("FileSystem"), "FileSystem", ["file-system-storage-tree-item"]);
1479 WebInspector.FileSystemListTreeElement.prototype = {
1480 _initialize: function()
1482 this._refreshFileSystem();
1485 onattach: function()
1487 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1488 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1491 _handleContextMenuEvent: function(event)
1493 var contextMenu = new WebInspector.ContextMenu(event);
1494 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Refresh FileSystem list" : "Refresh FileSystem List"), this._refreshFileSystem.bind(this));
1498 _fileSystemAdded: function(event)
1500 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1501 var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this._storagePanel, fileSystem);
1502 this.appendChild(fileSystemTreeElement);
1505 _fileSystemRemoved: function(event)
1507 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1508 var fileSystemTreeElement = this._fileSystemTreeElementByName(fileSystem.name);
1509 if (!fileSystemTreeElement)
1511 fileSystemTreeElement.clear();
1512 this.removeChild(fileSystemTreeElement);
1515 _fileSystemTreeElementByName: function(fileSystemName)
1517 for (var i = 0; i < this.children.length; ++i) {
1518 var child = /** @type {!WebInspector.FileSystemTreeElement} */ (this.children[i]);
1519 if (child.fileSystemName === fileSystemName)
1520 return this.children[i];
1525 _refreshFileSystem: function()
1527 if (!this._fileSystemModel) {
1528 this._fileSystemModel = new WebInspector.FileSystemModel();
1529 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, this._fileSystemAdded, this);
1530 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, this._fileSystemRemoved, this);
1533 this._fileSystemModel.refreshFileSystemList();
1536 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1541 * @extends {WebInspector.BaseStorageTreeElement}
1542 * @param {!WebInspector.ResourcesPanel} storagePanel
1543 * @param {!WebInspector.IndexedDBModel} model
1544 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1546 WebInspector.IDBDatabaseTreeElement = function(storagePanel, model, databaseId)
1548 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, databaseId.name + " - " + databaseId.securityOrigin, ["indexed-db-storage-tree-item"]);
1549 this._model = model;
1550 this._databaseId = databaseId;
1551 this._idbObjectStoreTreeElements = {};
1554 WebInspector.IDBDatabaseTreeElement.prototype = {
1557 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name;
1560 onattach: function()
1562 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1563 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1566 _handleContextMenuEvent: function(event)
1568 var contextMenu = new WebInspector.ContextMenu(event);
1569 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this._refreshIndexedDB.bind(this));
1573 _refreshIndexedDB: function()
1575 this._model.refreshDatabaseNames();
1579 * @param {!WebInspector.IndexedDBModel.Database} database
1581 update: function(database)
1583 this._database = database;
1584 var objectStoreNames = {};
1585 for (var objectStoreName in this._database.objectStores) {
1586 var objectStore = this._database.objectStores[objectStoreName];
1587 objectStoreNames[objectStore.name] = true;
1588 if (!this._idbObjectStoreTreeElements[objectStore.name]) {
1589 var idbObjectStoreTreeElement = new WebInspector.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
1590 this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
1591 this.appendChild(idbObjectStoreTreeElement);
1593 this._idbObjectStoreTreeElements[objectStore.name].update(objectStore);
1595 for (var objectStoreName in this._idbObjectStoreTreeElements) {
1596 if (!objectStoreNames[objectStoreName])
1597 this._objectStoreRemoved(objectStoreName);
1600 if (this.children.length) {
1601 this.hasChildren = true;
1606 this._view.update(database);
1608 this._updateTooltip();
1611 _updateTooltip: function()
1613 this.tooltip = WebInspector.UIString("Version") + ": " + this._database.version;
1620 onselect: function(selectedByUser)
1622 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1624 this._view = new WebInspector.IDBDatabaseView(this._database);
1626 this._storagePanel.showIndexedDB(this._view);
1631 * @param {string} objectStoreName
1633 _objectStoreRemoved: function(objectStoreName)
1635 var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
1636 objectStoreTreeElement.clear();
1637 this.removeChild(objectStoreTreeElement);
1638 delete this._idbObjectStoreTreeElements[objectStoreName];
1643 for (var objectStoreName in this._idbObjectStoreTreeElements)
1644 this._objectStoreRemoved(objectStoreName);
1647 __proto__: WebInspector.BaseStorageTreeElement.prototype
1652 * @extends {WebInspector.BaseStorageTreeElement}
1653 * @param {!WebInspector.ResourcesPanel} storagePanel
1654 * @param {!WebInspector.IndexedDBModel} model
1655 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1656 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1658 WebInspector.IDBObjectStoreTreeElement = function(storagePanel, model, databaseId, objectStore)
1660 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, objectStore.name, ["indexed-db-object-store-storage-tree-item"]);
1661 this._model = model;
1662 this._databaseId = databaseId;
1663 this._idbIndexTreeElements = {};
1666 WebInspector.IDBObjectStoreTreeElement.prototype = {
1669 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name;
1672 onattach: function()
1674 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1675 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1678 _handleContextMenuEvent: function(event)
1680 var contextMenu = new WebInspector.ContextMenu(event);
1681 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearObjectStore.bind(this));
1685 _clearObjectStore: function()
1688 * @this {WebInspector.IDBObjectStoreTreeElement}
1690 function callback() {
1691 this.update(this._objectStore);
1693 this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this));
1697 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1699 update: function(objectStore)
1701 this._objectStore = objectStore;
1703 var indexNames = {};
1704 for (var indexName in this._objectStore.indexes) {
1705 var index = this._objectStore.indexes[indexName];
1706 indexNames[index.name] = true;
1707 if (!this._idbIndexTreeElements[index.name]) {
1708 var idbIndexTreeElement = new WebInspector.IDBIndexTreeElement(this._storagePanel, this._model, this._databaseId, this._objectStore, index);
1709 this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
1710 this.appendChild(idbIndexTreeElement);
1712 this._idbIndexTreeElements[index.name].update(index);
1714 for (var indexName in this._idbIndexTreeElements) {
1715 if (!indexNames[indexName])
1716 this._indexRemoved(indexName);
1718 for (var indexName in this._idbIndexTreeElements) {
1719 if (!indexNames[indexName]) {
1720 this.removeChild(this._idbIndexTreeElements[indexName]);
1721 delete this._idbIndexTreeElements[indexName];
1725 if (this.children.length) {
1726 this.hasChildren = true;
1731 this._view.update(this._objectStore);
1733 this._updateTooltip();
1736 _updateTooltip: function()
1739 var keyPathString = this._objectStore.keyPathString;
1740 var tooltipString = keyPathString !== null ? (WebInspector.UIString("Key path: ") + keyPathString) : "";
1741 if (this._objectStore.autoIncrement)
1742 tooltipString += "\n" + WebInspector.UIString("autoIncrement");
1743 this.tooltip = tooltipString
1750 onselect: function(selectedByUser)
1752 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1754 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, null);
1756 this._storagePanel.showIndexedDB(this._view);
1761 * @param {string} indexName
1763 _indexRemoved: function(indexName)
1765 var indexTreeElement = this._idbIndexTreeElements[indexName];
1766 indexTreeElement.clear();
1767 this.removeChild(indexTreeElement);
1768 delete this._idbIndexTreeElements[indexName];
1773 for (var indexName in this._idbIndexTreeElements)
1774 this._indexRemoved(indexName);
1779 __proto__: WebInspector.BaseStorageTreeElement.prototype
1784 * @extends {WebInspector.BaseStorageTreeElement}
1785 * @param {!WebInspector.ResourcesPanel} storagePanel
1786 * @param {!WebInspector.IndexedDBModel} model
1787 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1788 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1789 * @param {!WebInspector.IndexedDBModel.Index} index
1791 WebInspector.IDBIndexTreeElement = function(storagePanel, model, databaseId, objectStore, index)
1793 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, index.name, ["indexed-db-index-storage-tree-item"]);
1794 this._model = model;
1795 this._databaseId = databaseId;
1796 this._objectStore = objectStore;
1797 this._index = index;
1800 WebInspector.IDBIndexTreeElement.prototype = {
1803 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name + "/" + this._index.name;
1807 * @param {!WebInspector.IndexedDBModel.Index} index
1809 update: function(index)
1811 this._index = index;
1814 this._view.update(this._index);
1816 this._updateTooltip();
1819 _updateTooltip: function()
1821 var tooltipLines = [];
1822 var keyPathString = this._index.keyPathString;
1823 tooltipLines.push(WebInspector.UIString("Key path: ") + keyPathString);
1824 if (this._index.unique)
1825 tooltipLines.push(WebInspector.UIString("unique"));
1826 if (this._index.multiEntry)
1827 tooltipLines.push(WebInspector.UIString("multiEntry"));
1828 this.tooltip = tooltipLines.join("\n");
1835 onselect: function(selectedByUser)
1837 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1839 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, this._index);
1841 this._storagePanel.showIndexedDB(this._view);
1851 __proto__: WebInspector.BaseStorageTreeElement.prototype
1856 * @extends {WebInspector.BaseStorageTreeElement}
1858 WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className)
1860 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.securityOrigin ? domStorage.securityOrigin : WebInspector.UIString("Local Files"), ["domstorage-storage-tree-item", className]);
1861 this._domStorage = domStorage;
1864 WebInspector.DOMStorageTreeElement.prototype = {
1867 return "storage://" + this._domStorage.securityOrigin + "/" + (this._domStorage.isLocalStorage ? "local" : "session");
1874 onselect: function(selectedByUser)
1876 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1877 this._storagePanel._showDOMStorage(this._domStorage);
1881 __proto__: WebInspector.BaseStorageTreeElement.prototype
1886 * @extends {WebInspector.BaseStorageTreeElement}
1888 WebInspector.CookieTreeElement = function(storagePanel, cookieDomain)
1890 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), ["cookie-storage-tree-item"]);
1891 this._cookieDomain = cookieDomain;
1894 WebInspector.CookieTreeElement.prototype = {
1897 return "cookies://" + this._cookieDomain;
1900 onattach: function()
1902 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1903 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1907 * @param {!Event} event
1909 _handleContextMenuEvent: function(event)
1911 var contextMenu = new WebInspector.ContextMenu(event);
1912 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearCookies.bind(this));
1917 * @param {string} domain
1919 _clearCookies: function(domain)
1921 this._storagePanel.clearCookies(this._cookieDomain);
1928 onselect: function(selectedByUser)
1930 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1931 this._storagePanel.showCookies(this, this._cookieDomain);
1935 __proto__: WebInspector.BaseStorageTreeElement.prototype
1940 * @extends {WebInspector.BaseStorageTreeElement}
1942 WebInspector.ApplicationCacheManifestTreeElement = function(storagePanel, manifestURL)
1944 var title = new WebInspector.ParsedURL(manifestURL).displayName;
1945 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["application-cache-storage-tree-item"]);
1946 this.tooltip = manifestURL;
1947 this._manifestURL = manifestURL;
1950 WebInspector.ApplicationCacheManifestTreeElement.prototype = {
1953 return "appcache://" + this._manifestURL;
1958 return this._manifestURL;
1965 onselect: function(selectedByUser)
1967 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1968 this._storagePanel.showCategoryView(this._manifestURL);
1972 __proto__: WebInspector.BaseStorageTreeElement.prototype
1977 * @extends {WebInspector.BaseStorageTreeElement}
1979 WebInspector.ApplicationCacheFrameTreeElement = function(storagePanel, frameId, manifestURL)
1981 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
1982 this._frameId = frameId;
1983 this._manifestURL = manifestURL;
1984 this._refreshTitles();
1987 WebInspector.ApplicationCacheFrameTreeElement.prototype = {
1990 return "appcache://" + this._manifestURL + "/" + encodeURI(this.displayName);
1995 return this._frameId;
2000 return this._manifestURL;
2003 _refreshTitles: function()
2005 var frame = WebInspector.resourceTreeModel.frameForId(this._frameId);
2007 this.subtitleText = WebInspector.UIString("new frame");
2010 this.titleText = frame.name;
2011 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
2014 frameNavigated: function()
2016 this._refreshTitles();
2023 onselect: function(selectedByUser)
2025 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2026 this._storagePanel.showApplicationCache(this._frameId);
2030 __proto__: WebInspector.BaseStorageTreeElement.prototype
2035 * @extends {WebInspector.BaseStorageTreeElement}
2036 * @param {!WebInspector.ResourcesPanel} storagePanel
2037 * @param {!WebInspector.FileSystemModel.FileSystem} fileSystem
2039 WebInspector.FileSystemTreeElement = function(storagePanel, fileSystem)
2041 var displayName = fileSystem.type + " - " + fileSystem.origin;
2042 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, ["file-system-storage-tree-item"]);
2043 this._fileSystem = fileSystem;
2046 WebInspector.FileSystemTreeElement.prototype = {
2047 get fileSystemName()
2049 return this._fileSystem.name;
2054 return "filesystem://" + this._fileSystem.name;
2061 onselect: function(selectedByUser)
2063 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2064 this._fileSystemView = new WebInspector.FileSystemView(this._fileSystem);
2065 this._storagePanel.showFileSystem(this._fileSystemView);
2071 if (this.fileSystemView && this._storagePanel.visibleView === this.fileSystemView)
2072 this._storagePanel.closeVisibleView();
2075 __proto__: WebInspector.BaseStorageTreeElement.prototype
2080 * @extends {WebInspector.View}
2082 WebInspector.StorageCategoryView = function()
2084 WebInspector.View.call(this);
2086 this.element.classList.add("storage-view");
2087 this._emptyView = new WebInspector.EmptyView("");
2088 this._emptyView.show(this.element);
2091 WebInspector.StorageCategoryView.prototype = {
2092 setText: function(text)
2094 this._emptyView.text = text;
2097 __proto__: WebInspector.View.prototype